summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander NeonXP Kiryukhin <a.kiryukhin@mail.ru>2019-05-16 03:59:50 +0300
committerAlexander NeonXP Kiryukhin <a.kiryukhin@mail.ru>2019-05-16 03:59:50 +0300
commit4b01d81d3daed894bc93f77dbbbe5501a4552447 (patch)
tree04f95ad5de601687f7517bb7939ebeefabdd25da /src
parent51d12073b36cf858e3edd1c906f1815f63b6ab47 (diff)
Navigation and optimisation
Diffstat (limited to 'src')
-rw-r--r--src/Actions/entity.ts13
-rw-r--r--src/Api/types.ts2
-rw-r--r--src/Components/Map.tsx10
-rw-r--r--src/Components/MapObjects.tsx46
-rw-r--r--src/Components/PortalPanel.tsx25
-rw-r--r--src/Components/Settings.tsx2
-rw-r--r--src/Main.js1
-rw-r--r--src/Store/store.ts2
-rw-r--r--src/colors.ts4
-rw-r--r--src/constants.ts20
10 files changed, 101 insertions, 24 deletions
diff --git a/src/Actions/entity.ts b/src/Actions/entity.ts
index d373d9d..d23022a 100644
--- a/src/Actions/entity.ts
+++ b/src/Actions/entity.ts
@@ -3,7 +3,6 @@ import { Dispatch, Store } from 'redux';
import { Region } from 'react-native-maps';
import { getTilesToLoad, loadTiles, getPortalDetails } from '../Api/api';
import { Portal, Link, Field } from '../Api/types';
-import { LoadedResult } from '../Api/interfaces';
import { decodePortal } from '../Api/entityDecoder';
const entity = {
@@ -46,10 +45,20 @@ const entity = {
const store = getStore()
const { v, csrf } = store.auth
const params = { v, csrf }
- getPortalDetails(guid, params).then(j => {
+ getPortalDetails(guid, params).then(async j => {
const portal = decodePortal(j.result)
portal.fullLoad = true
dispatch(entity.portalSet(guid, portal))
+ let addr = "нет"
+ try {
+ addr = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&polygon_geojson=1&lat=${portal.coords.latitude}&lon=${portal.coords.longitude}`)
+ .then(r => r.json())
+ .then(j => [j.address.city, j.address.road, j.address.house_number].filter(p => !!p).join(', ') || 'нет')
+ } catch (e) {
+ addr = "ошибка"
+ }
+ portal.address = addr
+ dispatch(entity.portalSet(guid, portal))
})
},
'setLoadQueue': (queue: string[][]) => ({
diff --git a/src/Api/types.ts b/src/Api/types.ts
index 7a26bc8..5543f79 100644
--- a/src/Api/types.ts
+++ b/src/Api/types.ts
@@ -2,6 +2,7 @@ import { LatLng } from "./interfaces";
export class Portal {
fullLoad: boolean
+ address: string
constructor(
public name: string,
public photo: string,
@@ -17,6 +18,7 @@ export class Portal {
public owner: string
) {
+ this.address = ""
this.fullLoad = false
}
}
diff --git a/src/Components/Map.tsx b/src/Components/Map.tsx
index 68698f4..bb0b660 100644
--- a/src/Components/Map.tsx
+++ b/src/Components/Map.tsx
@@ -98,13 +98,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 }
return (
<>
<MapView
ref={r => (r != null) ? this.map = r : null}
style={styles.container}
- initialRegion={{ ...this.state.user, latitudeDelta: 0.002, longitudeDelta: 0.002 }}
+ initialRegion={initialRegion}
onRegionChangeComplete={this.onRegionChange}
showsCompass={false}
showsScale
@@ -112,9 +112,11 @@ class Map extends Component<Props, State> {
showsMyLocationButton
loadingEnabled
type={'hybrid'}
+ shouldRasterizeIOS
+ renderToHardwareTextureAndroid
>
- <MapObjects onPortalClick={this.onPortalClick} />
- {this.state.selectedPortal && <Marker coordinate={this.state.selectedPortal.coords} />}
+ <MapObjects onPortalClick={this.onPortalClick} region={this.state.region || initialRegion} />
+ {this.state.selectedPortal && <Marker cluster={false} coordinate={this.state.selectedPortal.coords} />}
</MapView>
<MapOverlay
goToMe={this.goToMe}
diff --git a/src/Components/MapObjects.tsx b/src/Components/MapObjects.tsx
index af0afec..4b11225 100644
--- a/src/Components/MapObjects.tsx
+++ b/src/Components/MapObjects.tsx
@@ -4,7 +4,7 @@ import { Polyline, Polygon, Marker, Region } from 'react-native-maps';
import Icon from 'react-native-vector-icons/FontAwesome';
import { Link, Portal, Field } from '../Api/types';
import { connect } from 'react-redux';
-import { COLORS, COLORS_LVL } from '../colors';
+import { COLORS, COLORS_LVL } from '../constants';
const fillPortalColor = { "R": "rgba(2, 140, 227, 0.5)", "E": "rgba(38, 205, 30, 0.5)", "N": "rgba(139, 0, 255, 0.5)" }
// const fillPortalColor = { "R": COLORS[1], "E": COLORS[2], "N": COLORS[0] }
@@ -16,17 +16,49 @@ type Props = {
portals: { [guid: string]: Portal }
links: { [guid: string]: Link }
fields: { [guid: string]: Field }
+ region: Region
onPortalClick: Function
}
class MapObjects extends PureComponent<Props> {
render() {
- const props = this.props
- const renderPortal = Object.keys(props.portals).map(guid => this.drawPortal(guid, props.portals[guid], props.onPortalClick))
- const renderField = Object.keys(props.fields).map(guid => this.drawField(guid, props.fields[guid]))
- const renderLink = Object.keys(props.links).map(guid => this.drawLink(guid, props.links[guid]))
+ 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 = Object.keys(portals)
+ .filter(guid => portals[guid].coords.latitude > lat1 && portals[guid].coords.latitude < lat2 && portals[guid].coords.longitude > lng1 && portals[guid].coords.longitude < lng2)
+ .map(guid => this.drawPortal(guid, portals[guid], this.props.onPortalClick))
+ const renderLink = Object.keys(links)
+ .filter(guid => {
+ const l1 = links[guid].coords[0].latitude
+ const l2 = links[guid].coords[1].latitude
+ const n1 = links[guid].coords[0].longitude
+ const n2 = links[guid].coords[1].longitude
+ return !(l1 < lat1 && l2 < lat1 || l1 > lat2 && l2 > lat2 || n1 < lng1 && n2 < lng1 || n1 > lng2 && n2 > lng2)
+ })
+ .map(guid => this.drawLink(guid, links[guid]))
+ const renderField = Object.keys(fields)
+ .filter(guid => {
+ const l1 = fields[guid].coords[0].latitude
+ const l2 = fields[guid].coords[1].latitude
+ const l3 = fields[guid].coords[2].latitude
+ const n1 = fields[guid].coords[0].longitude
+ const n2 = fields[guid].coords[1].longitude
+ const n3 = fields[guid].coords[2].longitude
+ return !(
+ l1 < lat1 && l2 < lat1 && l3 < lat1 || l1 > lat2 && l2 > lat2 && l3 > lat2 ||
+ n1 < lng1 && n2 < lng1 && n3 < lng1 || n1 > lng2 && n2 > lng2 && n3 > lng2
+ )
+ })
+ .map(guid => this.drawField(guid, fields[guid]))
- if (props.zoom <= 14) {
+ if (zoom <= 14) {
return [...renderField, ...renderLink]
} else {
return [...renderField, ...renderLink, ...renderPortal]
@@ -77,4 +109,4 @@ const styles = StyleSheet.create({
});
-export default connect((store) => ({ portals: store.entities.portals, fields: store.entities.fields, links: store.entities.links }), {})(MapObjects) \ No newline at end of file
+export default connect((store, props: Props) => ({ portals: store.entities.portals, fields: store.entities.fields, links: store.entities.links }), {})(MapObjects) \ No newline at end of file
diff --git a/src/Components/PortalPanel.tsx b/src/Components/PortalPanel.tsx
index d49d88a..e372259 100644
--- a/src/Components/PortalPanel.tsx
+++ b/src/Components/PortalPanel.tsx
@@ -1,18 +1,20 @@
import React, { Component, PureComponent } from 'react';
-import { StyleSheet, View, Text, GestureResponderEvent, ActivityIndicator, Image } from 'react-native';
+import { StyleSheet, View, Text, GestureResponderEvent, ActivityIndicator, Image, Dimensions, Button, Linking } from 'react-native';
// import { Button } from 'react-native-vector-icons/FontAwesome';
import { getStatusBarHeight } from '../helper';
import { connect } from 'react-redux';
import actions from '../Actions/actions';
import { Portal } from '../Api/types';
import { bindActionCreators } from 'redux';
-import { COLORS_FRACTION } from '../colors';
+import { COLORS_FRACTION, RESO_NRG, COLORS_LVL, COLORS_MOD, MOD_TYPE, NavTo } from '../constants';
type Props = {
guid: string
portal?: Portal
}
+const { width, height } = Dimensions.get("screen")
+
class PortalPanel extends PureComponent<Props> {
static navigationOptions = ({ navigation }) => {
return {
@@ -41,21 +43,33 @@ 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>
<View>
{portal.resonators && portal.resonators.map((r, idx) =>
- r ? (<Text style={styles.subtitle}>{idx + 1}: {r[1]} [{r[2]}] - {r[0]}</Text>) : (<Text style={styles.subtitle}>{idx + 1}: нет</Text>)
+ r ?
+ (<Text key={idx} style={[styles.subtitle, { color: COLORS_LVL[r[1]] }]}>{idx + 1}: {r[1]} [{r[2]}/{RESO_NRG[r[1]]}] - {r[0]}</Text>) :
+ (<Text key={idx} style={styles.subtitle}>{idx + 1}: нет</Text>)
)}
{(!portal.resonators || portal.resonators.length == 0) && (<Text style={styles.subtitle}>нет</Text>)}
</View>
<Text style={styles.title}>Моды</Text>
<View>
{portal.mods && portal.mods.map((r, idx) =>
- r ? (<Text style={styles.subtitle}>{idx + 1}: {r[1]} [{r[2]}] - {r[0]}</Text>) : (<Text style={styles.subtitle}>{idx + 1}: нет</Text>)
+ r ?
+ (<Text key={idx} style={[styles.subtitle, { color: COLORS_MOD[r[2]] }]}>{idx + 1}: {MOD_TYPE[r[1]] || r[1]} [{r[2]}] - {r[0]}</Text>) :
+ (<Text key={idx} style={styles.subtitle}>{idx + 1}: нет</Text>)
)}
</View>
+ <Text style={styles.title}>Навигация к порталу</Text>
+ <View>
+ <Button onPress={() => Linking.openURL(NavTo(portal.coords.latitude, portal.coords.longitude, portal.name, 'ymaps'))} title={'Яндекс Навигатор'} />
+ <Button onPress={() => Linking.openURL(NavTo(portal.coords.latitude, portal.coords.longitude, portal.name, 'maps.me'))} title={'Maps.me'} />
+ <Button onPress={() => Linking.openURL(NavTo(portal.coords.latitude, portal.coords.longitude, portal.name, '2gis'))} title={'2ГИС'} />
+ <Button onPress={() => Linking.openURL(NavTo(portal.coords.latitude, portal.coords.longitude, portal.name, 'default'))} title={'Другие карты/навигаторы'} />
+ </View>
</View>
);
}
@@ -78,7 +92,8 @@ const styles = StyleSheet.create({
flexDirection: 'row',
},
panelRight: {
- paddingLeft: 8
+ paddingLeft: 8,
+ width: width - 116
},
title: {
fontWeight: 'bold',
diff --git a/src/Components/Settings.tsx b/src/Components/Settings.tsx
index daf3216..a99e46e 100644
--- a/src/Components/Settings.tsx
+++ b/src/Components/Settings.tsx
@@ -22,7 +22,7 @@ class Settings extends PureComponent<Props> {
render() {
return (
<View style={styles.overlay}>
- <Text>{JSON.stringify(this.props)}</Text>
+ {/* <Text>{JSON.stringify(this.props)}</Text> */}
</View>
);
}
diff --git a/src/Main.js b/src/Main.js
index 4e5c128..20baaaa 100644
--- a/src/Main.js
+++ b/src/Main.js
@@ -31,6 +31,7 @@ const AppNavigator = createBottomTabNavigator({
Settings: {
screen: Settings,
navigationOptions: {
+ title: 'Настройки',
tabBarLabel: 'Настройки',
tabBarIcon: ({tintColor}) => <IconComponent name={'ios-settings'} size={25} color={tintColor} />
}
diff --git a/src/Store/store.ts b/src/Store/store.ts
index c26f019..b8f4169 100644
--- a/src/Store/store.ts
+++ b/src/Store/store.ts
@@ -11,7 +11,7 @@ const reducers = {
}, { v: "", csrf: "", user: null, loading: false }),
'entities': createReducer({
'portalSet': (store: any, action: { guid: string, portal: Portal }) =>
- ({ ...store, portals: { ...store.portals, [action.guid]: action.portal } }),
+ ({ ...store, portals: { ...store.portals, [action.guid]: { ...action.portal } } }),
'linkSet': (store: any, action: { guid: string, link: Link }) =>
({ ...store, links: { ...store.links, [action.guid]: action.link } }),
'fieldSet': (store: any, action: { guid: string, field: Field }) =>
diff --git a/src/colors.ts b/src/colors.ts
deleted file mode 100644
index 8a3a508..0000000
--- a/src/colors.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const COLORS = ['#FF6600', '#0088FF', '#03DC03']; // none, res, enl
-export const COLORS_FRACTION = { 'N': COLORS[0], 'R': COLORS[1], 'E': COLORS[2] }; // none, res, enl
-export const COLORS_LVL = ['#000', '#FECE5A', '#FFA630', '#FF7315', '#E40000', '#FD2992', '#EB26CD', '#C124E0', '#9627F4'];
-export const COLORS_MOD = { VERY_RARE: '#b08cff', RARE: '#73a8ff', COMMON: '#8cffbf' }; \ No newline at end of file
diff --git a/src/constants.ts b/src/constants.ts
new file mode 100644
index 0000000..e24771a
--- /dev/null
+++ b/src/constants.ts
@@ -0,0 +1,20 @@
+export const COLORS = ['#FF6600', '#0088FF', '#03DC03']; // none, res, enl
+export const COLORS_FRACTION = { 'N': COLORS[0], 'R': COLORS[1], 'E': COLORS[2] }; // none, res, enl
+export const COLORS_LVL = ['#000', '#FECE5A', '#FFA630', '#FF7315', '#E40000', '#FD2992', '#EB26CD', '#C124E0', '#9627F4'];
+export const COLORS_MOD = { VERY_RARE: '#b08cff', RARE: '#73a8ff', COMMON: '#8cffbf' };
+
+export const RESO_NRG = [0, 1000, 1500, 2000, 2500, 3000, 4000, 5000, 6000];
+export const MOD_TYPE = { RES_SHIELD: 'Shield', MULTIHACK: 'Multi-hack', FORCE_AMP: 'Force Amp', HEATSINK: 'Heat Sink', TURRET: 'Turret', LINK_AMPLIFIER: 'Link Amp' };
+
+export const NAVIGATORS = {
+ "ymaps": "yandexnavi://build_route_on_map?lat_to=<lat>&lon_to=<lon>&no-balloon=0&desc=<title>",
+ "2gis": "dgis://2gis.ru/routeSearch/rsType/car/to/<lon>,<lat>",
+ "maps.me": "https://dlink.maps.me/map?v=1&ll=<lat>,<lon>&n=<title>&id=<title>&appname=IngressHelper&type=vehicle",
+ "default": "geo:<lat>,<lon>"
+}
+export const NavTo = (lat, lon, title, by) => {
+ if (!by) {
+ by = 'default'
+ }
+ return NAVIGATORS[by].replace('<lat>', lat).replace('<lon>', lon).replace('<title>', title)
+} \ No newline at end of file