summaryrefslogtreecommitdiff
path: root/src/Components
diff options
context:
space:
mode:
authorAlexander NeonXP Kiryukhin <a.kiryukhin@mail.ru>2019-06-11 02:51:30 +0300
committerAlexander NeonXP Kiryukhin <a.kiryukhin@mail.ru>2019-06-11 02:51:30 +0300
commitf12a3bccd8c726e59e92123a3d8ef1f5a73d7253 (patch)
treed4b6e126c0f216972562621608a4ba97800a94bf /src/Components
parentb7810c3d6c0164def328c60244bfbd20d7935bc3 (diff)
Fixes
Diffstat (limited to 'src/Components')
-rw-r--r--src/Components/Map.tsx17
-rw-r--r--src/Components/MapObjects.tsx32
-rw-r--r--src/Components/MapOverlay.tsx177
-rw-r--r--src/Components/PortalPanel.tsx1
-rw-r--r--src/Components/Settings.tsx49
5 files changed, 170 insertions, 106 deletions
diff --git a/src/Components/Map.tsx b/src/Components/Map.tsx
index db0bed9..6c3ebab 100644
--- a/src/Components/Map.tsx
+++ b/src/Components/Map.tsx
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-import { StyleSheet, View, Dimensions, ActivityIndicator } from 'react-native';
+import { StyleSheet, View, Dimensions, ActivityIndicator, StatusBar } from 'react-native';
import MapView, { Marker, Region } from 'react-native-maps';
import { connect } from 'redux-su';
import { NavigationActions } from 'react-navigation';
@@ -7,7 +7,7 @@ import { NavigationActions } from 'react-navigation';
import MapOverlay from './MapOverlay';
import MapObjects from './MapObjects';
import PortalPanel from './PortalPanel';
-import { getBottomSpace } from '../helper';
+import debounce, { getBottomSpace } from '../helper';
import actions from '../Actions/actions';
import { LatLng } from '../Api/interfaces';
import { getZoomByRegion, getDataZoomForMapZoom } from '../Api/api';
@@ -35,6 +35,7 @@ class Map extends Component<Props, State> {
region: null,
dataZoom: 15,
}
+ this.load = debounce(this.load, 300)
}
componentDidMount() {
this.refreshTimer = setInterval(() => {
@@ -68,6 +69,7 @@ class Map extends Component<Props, State> {
const zoom = getZoomByRegion(width, region)
const dataZoom = getDataZoomForMapZoom(zoom);
this.setState({ region, dataZoom })
+ this.props.actions.setRegion(region)
setImmediate(() => this.load(false))
}
@@ -110,9 +112,13 @@ class Map extends Component<Props, State> {
if (!this.state.user) {
return <View style={styles.spinnerContainer}><ActivityIndicator size={'large'} /></View>
}
- const initialRegion = { ...this.state.user, latitudeDelta: 0.002, longitudeDelta: 0.002 }
+ const initialRegion = this.props.settings.region || { ...this.state.user, latitudeDelta: 0.002, longitudeDelta: 0.002 }
return (
<>
+ <StatusBar
+ backgroundColor="blue"
+ barStyle="dark-content"
+ />
<MapView
ref={r => (r != null) ? this.map = r : null}
style={styles.container}
@@ -121,6 +127,7 @@ class Map extends Component<Props, State> {
showsCompass={false}
showsScale
showsUserLocation
+ userLocationAnnotationTitle=""
showsMyLocationButton
loadingEnabled
type={'hybrid'}
@@ -131,9 +138,9 @@ class Map extends Component<Props, State> {
onPortalClick={this.onPortalClick}
region={this.state.region || initialRegion}
levels={this.props.settings.filterLevel}
+ selectedPortal={this.state.selectedPortal}
zoom={this.state.dataZoom}
/>
- {this.state.selectedPortal && <Marker cluster={false} coordinate={this.state.selectedPortal.coords} onPress={this.onPortalDismiss} />}
</MapView>
<MapOverlay
goToMe={this.goToMe}
@@ -141,6 +148,8 @@ class Map extends Component<Props, State> {
loading={this.props.entities.loadQueue.length}
selectedPortal={this.state.selectedPortal}
onOpenPortal={this.onOpenPortal}
+ getPortalDetails={this.props.actions.getPortalDetails}
+ portal={this.state.selectedPortal && this.props.entities.portals[this.state.selectedPortal.guid]}
/>
</>
);
diff --git a/src/Components/MapObjects.tsx b/src/Components/MapObjects.tsx
index 2a5e1df..6e9b053 100644
--- a/src/Components/MapObjects.tsx
+++ b/src/Components/MapObjects.tsx
@@ -1,5 +1,5 @@
import React, { PureComponent } from 'react';
-import { View, StyleSheet, Text } from 'react-native';
+import { View, StyleSheet, Text, Image } from 'react-native';
import { Polyline, Polygon, Marker, Region } from 'react-native-maps';
import Icon from 'react-native-vector-icons/FontAwesome';
import { Link, Portal, Field } from '../Api/types';
@@ -43,27 +43,28 @@ type Props = {
class MapObjects extends PureComponent<Props> {
render() {
- const region = this.props.region
- const lat1 = region.latitude - region.latitudeDelta / 2
- const lat2 = region.latitude + region.latitudeDelta / 2
- const lng1 = region.longitude - region.longitudeDelta / 2
- const lng2 = region.longitude + region.longitudeDelta / 2
const portals = this.props.portals
const fields = this.props.fields
const links = this.props.links
- const zoom = this.props.zoom
- const renderPortal = this.props.renderPortal.map(guid => this.drawPortal(guid, portals[guid], this.props.onPortalClick))
+ const renderPortal = this.props.renderPortal.map(guid => guid && this.drawPortal(guid, portals[guid], this.props.onPortalClick))
const renderLink = this.props.renderLink.map(guid => this.drawLink(guid, links[guid]))
const renderField = this.props.renderField.map(guid => this.drawField(guid, fields[guid]))
return [...renderField, ...renderLink, ...renderPortal]
}
drawPortal = (guid: string, entity: Portal, onPortalClick: Function) => {
+ const selected = this.props.selectedPortal && this.props.selectedPortal.guid == guid
return (<Marker
key={guid}
coordinate={entity.coords}
onPress={() => onPortalClick(guid, entity.coords)}
- image={PORTALS[entity.fraction + entity.level]}
- />);
+ style={[selected ? { borderColor: 'red', borderWidth: 4, borderRadius: 13 } : null, { height: 26, width: 26, flex: 1, justifyContent: "center", alignItems: 'center' }]}
+ zIndex={selected ? 10 : entity.level}
+ >
+ <Image
+ source={PORTALS[entity.fraction + entity.level]}
+ style={{ height: 22, width: 22 }}
+ />
+ </Marker>);
}
drawField = (guid: string, entity: Field) => {
return <Polygon
@@ -96,11 +97,12 @@ export default connect((store, props: Props) => {
const lng2 = region.longitude + region.longitudeDelta / 2
const minlvl = DEFAULT_ZOOM_TO_LEVEL[Math.min(props.zoom - 1, DEFAULT_ZOOM_TO_LEVEL.length - 1)]
const minlen = DEFAULT_ZOOM_TO_LINK_LENGTH[Math.min(props.zoom - 1, DEFAULT_ZOOM_TO_LINK_LENGTH.length - 1)] / 1000
- const renderPortal = Object
- .keys(store.entities.portals)
- .filter(guid => store.entities.portals[guid].level >= props.levels[0] && store.entities.portals[guid].level <= props.levels[1])
- .filter(guid => store.entities.portals[guid].coords.latitude > lat1 && store.entities.portals[guid].coords.latitude < lat2 && store.entities.portals[guid].coords.longitude > lng1 && store.entities.portals[guid].coords.longitude < lng2)
-
+ const renderPortal = props.zoom > 14
+ ? Object
+ .keys(store.entities.portals)
+ .filter(guid => store.entities.portals[guid].level >= props.levels[0] && store.entities.portals[guid].level <= props.levels[1])
+ .filter(guid => store.entities.portals[guid].coords.latitude > lat1 && store.entities.portals[guid].coords.latitude < lat2 && store.entities.portals[guid].coords.longitude > lng1 && store.entities.portals[guid].coords.longitude < lng2)
+ : [props.selectedPortal ? props.selectedPortal.guid : null]
const renderLink = Object
.keys(store.entities.links)
.filter(guid => {
diff --git a/src/Components/MapOverlay.tsx b/src/Components/MapOverlay.tsx
index 0e3624b..28da324 100644
--- a/src/Components/MapOverlay.tsx
+++ b/src/Components/MapOverlay.tsx
@@ -1,87 +1,108 @@
import React from 'react';
-import { StyleSheet, View, Text, GestureResponderEvent, ActivityIndicator, Linking, TextInput, Slider } from 'react-native';
+import { StyleSheet, View, Text, GestureResponderEvent, ActivityIndicator, Linking, TextInput, Slider, Image, Dimensions } from 'react-native';
import { FontAwesome } from '@expo/vector-icons';
import { getStatusBarHeight, getBottomSpace } from '../helper';
import { LatLng } from '../Api/interfaces';
+import { COLORS_FRACTION, COLORS_LVL, RESO_NRG } from '../constants';
+
+const { width, height } = Dimensions.get("screen")
type Props = {
goToMe: (e: GestureResponderEvent) => void;
refresh: (e: GestureResponderEvent) => void;
onOpenPortal: (guid: string, coords: LatLng) => void;
+ getPortalDetails: (guid: string) => void;
loading: Number;
selectedPortal: any;
+ portal: any;
}
-export default (props: Props) => (
- <>
- <View style={styles.overlayLeft}>
- {props.selectedPortal ? (
- <>
+export default class extends React.Component<Props> {
+ componentWillReceiveProps(next) {
+ if (this.props.selectedPortal !== next.selectedPortal && next.selectedPortal && next.selectedPortal.guid) {
+ this.props.getPortalDetails(next.selectedPortal.guid)
+ }
+ }
+ render() {
+ const props = this.props
+ const portal = this.props.portal
+ return (
+ <>
+ <View style={styles.overlayLeft}>
+ {props.loading > 0 ? (
+ <View style={styles.loader}>
+ <ActivityIndicator color={"#000"} />
+ </View>
+ ) : null}
+ </View>
+
+ <View style={styles.overlayRight}>
<View style={styles.buttonWrapper}>
<FontAwesome.Button
style={styles.button}
- name={'info'}
- onPress={() => {
- props.onOpenPortal(props.selectedPortal.guid, props.selectedPortal.coords)
- }}
+ name={'crosshairs'}
+ onPress={props.goToMe}
iconStyle={styles.icon}
color={"#000"}
size={25}
- backgroundColor={"#e3e3e3"}
+ backgroundColor={"#fff"}
/>
</View>
- {/* <View style={styles.buttonWrapper}>
+ <View style={styles.buttonWrapper}>
<FontAwesome.Button
style={styles.button}
- name={'location-arrow'}
- onPress={() => Linking.openURL(`geo:${props.selectedPortal.coords.latitude},${props.selectedPortal.coords.longitude}`)}
+ name={'refresh'}
+ onPress={props.refresh}
iconStyle={styles.icon}
color={"#000"}
size={25}
- backgroundColor={"#e3e3e3"}
+ backgroundColor={"#fff"}
/>
- </View> */}
- </>
- ) : null}
- {props.loading > 0 ? (
- <View style={styles.loader}>
- <ActivityIndicator color={"#000"} />
+ </View>
</View>
- ) : null}
- </View>
-
- <View style={styles.overlayRight}>
- <View style={styles.buttonWrapper}>
- <FontAwesome.Button
- style={styles.button}
- name={'crosshairs'}
- onPress={props.goToMe}
- iconStyle={styles.icon}
- color={"#000"}
- size={25}
- backgroundColor={"#e3e3e3"}
- />
- </View>
- <View style={styles.buttonWrapper}>
- <FontAwesome.Button
- style={styles.button}
- name={'refresh'}
- onPress={props.refresh}
- iconStyle={styles.icon}
- color={"#000"}
- size={25}
- backgroundColor={"#e3e3e3"}
- />
- </View>
- </View>
- {props.selectedPortal ? (
- <View style={styles.panel}>
- <Text>{JSON.stringify(props.selectedPortal)}</Text>
- </View>
- ) : null}
- </>
-);
-
+ {props.selectedPortal ? (
+ <View style={styles.panel} tint={'default'} intensity={90}>
+ <Image style={styles.photo} source={{ uri: portal.photo }} />
+ <View style={styles.column}>
+ <Text style={[styles.title, { color: COLORS_FRACTION[portal.fraction] }]} ellipsizeMode={'tail'} numberOfLines={1}>{portal.name}</Text>
+ <Text style={styles.subtitle}>Уровeнь: {portal.level}, здоровье: {portal.power}</Text>
+ <Text style={styles.subtitle}>Владелец: <Text style={[styles.user, { color: COLORS_FRACTION[portal.fraction] }]}>{portal.owner || 'нет'}</Text></Text>
+ <Text style={styles.subtitle}>Резонаторы:</Text>
+ <Text style={styles.subtitle}>
+ {portal.resonators && portal
+ .resonators
+ .filter(r => !!r)
+ .map((r, idx) => (<Text key={idx} style={[styles.subtitle, { color: COLORS_LVL[r[1]] }]}>[{r[1]}]</Text>))}
+ </Text>
+ </View>
+ {/* <FontAwesome.Button
+ style={styles.panelButton}
+ name={'star-o'}
+ onPress={() => {
+ props.onOpenPortal(props.selectedPortal.guid, props.selectedPortal.coords)
+ }}
+ iconStyle={styles.icon}
+ color={"#000"}
+ size={32}
+ backgroundColor={"transparent"}
+ /> */}
+ <FontAwesome.Button
+ style={styles.panelButton}
+ name={'angle-right'}
+ onPress={() => {
+ props.onOpenPortal(props.selectedPortal.guid, props.selectedPortal.coords)
+ }}
+ iconStyle={styles.icon}
+ color={"#000"}
+ size={32}
+ backgroundColor={"transparent"}
+ />
+ </View>
+ ) : null}
+ </>
+ );
+ }
+}
const styles = StyleSheet.create({
overlayLeft: {
position: 'absolute',
@@ -98,7 +119,12 @@ const styles = StyleSheet.create({
alignItems: 'center',
height: 48,
width: 48,
-
+ },
+ panelButton: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ height: 100,
+ width: 64,
},
buttonWrapper: {
margin: 8,
@@ -114,15 +140,20 @@ const styles = StyleSheet.create({
},
panel: {
position: 'absolute',
- bottom: getBottomSpace(),
- left: 8,
- right: 8,
- borderRadius: 8,
- padding: 8,
+ bottom: 0,
+ left: 0,
+ right: 0,
backgroundColor: '#fff',
+ flexDirection: 'row',
+ alignItems: 'center',
+ overflow: 'hidden',
+ borderTopWidth: StyleSheet.hairlineWidth,
+ borderTopColor: '#000',
+ padding: 0,
+ height: 100,
//ios
- shadowOpacity: 0.3,
- shadowRadius: 3,
+ shadowOpacity: 0.6,
+ shadowRadius: 6,
shadowOffset: {
height: 0,
width: 0
@@ -130,11 +161,29 @@ const styles = StyleSheet.create({
//android
elevation: 1
},
+ column: {
+ flexGrow: 1,
+ padding: 8,
+ width: (width - 124)
+ },
icon: {
marginRight: 0,
},
loader: {
margin: 8,
paddingHorizontal: 8,
+ },
+ title: {
+ fontWeight: 'bold',
+ },
+ subtitle: {
+ fontWeight: 'normal',
+ },
+ user: {
+ fontWeight: 'bold',
+ },
+ photo: {
+ width: 55,
+ height: 100,
}
}); \ No newline at end of file
diff --git a/src/Components/PortalPanel.tsx b/src/Components/PortalPanel.tsx
index e372259..30564ca 100644
--- a/src/Components/PortalPanel.tsx
+++ b/src/Components/PortalPanel.tsx
@@ -43,7 +43,6 @@ class PortalPanel extends PureComponent<Props> {
<Text style={styles.subtitle}>Уровeнь: {portal.level}, здоровье: {portal.power}</Text>
<Text style={styles.subtitle}>Владелец: <Text style={[styles.user, { color: COLORS_FRACTION[portal.fraction] }]}>{portal.owner || 'нет'}</Text></Text>
<Text style={styles.subtitle}>Дата: {portal.timestamp && (new Date(portal.timestamp)).toLocaleString()}</Text>
- <Text style={styles.subtitle}>Адрес: {portal.address || 'загрузка...'}</Text>
</View>
</View>
<Text style={styles.title}>Резонаторы</Text>
diff --git a/src/Components/Settings.tsx b/src/Components/Settings.tsx
index ca481a9..ffc176c 100644
--- a/src/Components/Settings.tsx
+++ b/src/Components/Settings.tsx
@@ -23,28 +23,30 @@ class Settings extends PureComponent<Props> {
const { filterLevel } = this.props.settings
return (
<SafeAreaView style={styles.overlay}>
- <Text>Мин. Ур.: {filterLevel[0]}</Text>
- <Slider
- style={{ width: 150, height: 40 }}
- minimumValue={0}
- maximumValue={filterLevel[1]}
- value={filterLevel[0]}
- step={1}
- minimumTrackTintColor="#028ce3"
- maximumTrackTintColor="#000000"
- onSlidingComplete={this.props.setLevelFrom}
- />
- <Text>Макс. Ур.: {filterLevel[1]}</Text>
- <Slider
- style={{ width: 150, height: 40 }}
- minimumValue={filterLevel[0]}
- maximumValue={8}
- value={filterLevel[1]}
- step={1}
- minimumTrackTintColor="#028ce3"
- maximumTrackTintColor="#000000"
- onSlidingComplete={this.props.setLevelTo}
- />
+ <View style={styles.container}>
+ <Text>Мин. Ур.: {filterLevel[0]}</Text>
+ <Slider
+ style={{ height: 40 }}
+ minimumValue={0}
+ maximumValue={filterLevel[1]}
+ value={filterLevel[0]}
+ step={1}
+ minimumTrackTintColor="#028ce3"
+ maximumTrackTintColor="#000000"
+ onSlidingComplete={this.props.setLevelFrom}
+ />
+ <Text>Макс. Ур.: {filterLevel[1]}</Text>
+ <Slider
+ style={{ height: 40 }}
+ minimumValue={filterLevel[0]}
+ maximumValue={8}
+ value={filterLevel[1]}
+ step={1}
+ minimumTrackTintColor="#028ce3"
+ maximumTrackTintColor="#000000"
+ onSlidingComplete={this.props.setLevelTo}
+ />
+ </View>
</SafeAreaView>
);
}
@@ -57,6 +59,9 @@ const styles = StyleSheet.create({
flex: 1,
padding: 8,
},
+ container: {
+ margin: 8,
+ },
title: {
fontWeight: 'bold',
fontSize: 22,