From 4b01d81d3daed894bc93f77dbbbe5501a4552447 Mon Sep 17 00:00:00 2001 From: Alexander NeonXP Kiryukhin Date: Thu, 16 May 2019 03:59:50 +0300 Subject: Navigation and optimisation --- app.json | 6 ++---- assets/icon.orig.png | Bin 2976 -> 0 bytes assets/icon.png | Bin 1506 -> 64520 bytes assets/splash.png | Bin 7178 -> 73127 bytes package.json | 5 +++-- src/Actions/entity.ts | 13 ++++++++++-- src/Api/types.ts | 2 ++ src/Components/Map.tsx | 10 +++++---- src/Components/MapObjects.tsx | 46 ++++++++++++++++++++++++++++++++++------- src/Components/PortalPanel.tsx | 25 +++++++++++++++++----- src/Components/Settings.tsx | 2 +- src/Main.js | 1 + src/Store/store.ts | 2 +- src/colors.ts | 4 ---- src/constants.ts | 20 ++++++++++++++++++ yarn.lock | 25 ++++++++++++++++++++++ 16 files changed, 131 insertions(+), 30 deletions(-) delete mode 100644 assets/icon.orig.png delete mode 100644 src/colors.ts create mode 100644 src/constants.ts diff --git a/app.json b/app.json index 9589a0b..fd61f01 100644 --- a/app.json +++ b/app.json @@ -9,7 +9,8 @@ "android" ], "ios": { - "bundleIdentifier": "ru.neonxp.ingresshelper" + "bundleIdentifier": "ru.neonxp.ingresshelper", + "supportsTablet": true }, "android": { "package": "ru.neonxp.ingresshelper" @@ -28,8 +29,5 @@ "assetBundlePatterns": [ "**/*" ], - "ios": { - "supportsTablet": true - } } } \ No newline at end of file diff --git a/assets/icon.orig.png b/assets/icon.orig.png deleted file mode 100644 index 3f5bbc0..0000000 Binary files a/assets/icon.orig.png and /dev/null differ diff --git a/assets/icon.png b/assets/icon.png index 9f90de3..aaddceb 100644 Binary files a/assets/icon.png and b/assets/icon.png differ diff --git a/assets/splash.png b/assets/splash.png index 4f9ade6..4642297 100644 Binary files a/assets/splash.png and b/assets/splash.png differ diff --git a/package.json b/package.json index dca8642..8637644 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "expo": "^32.0.0", "react": "16.5.0", "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz", + "react-native-map-clustering": "^1.3.2", "react-navigation": "^3.9.1", "react-redux": "^6.0.1", "redux": "^4.0.1", @@ -18,13 +19,13 @@ "redux-thunk": "^2.3.0" }, "devDependencies": { - "babel-preset-expo": "^5.0.0", "@types/react": "^16.8.16", "@types/react-native": "^0.57.53", "@types/react-native-vector-icons": "^6.4.0", "@types/react-redux": "^7.0.8", + "babel-preset-expo": "^5.0.0", "react-native-typescript-transformer": "^1.2.12", "typescript": "^3.4.5" }, "private": true -} \ No newline at end of file +} 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 { if (!this.state.user) { return } - + const initialRegion = { ...this.state.user, latitudeDelta: 0.002, longitudeDelta: 0.002 } return ( <> (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 { showsMyLocationButton loadingEnabled type={'hybrid'} + shouldRasterizeIOS + renderToHardwareTextureAndroid > - - {this.state.selectedPortal && } + + {this.state.selectedPortal && } { 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 { static navigationOptions = ({ navigation }) => { return { @@ -41,21 +43,33 @@ class PortalPanel extends PureComponent { Уровeнь: {portal.level}, здоровье: {portal.power} Владелец: {portal.owner || 'нет'} Дата: {portal.timestamp && (new Date(portal.timestamp)).toLocaleString()} + Адрес: {portal.address || 'загрузка...'} Резонаторы {portal.resonators && portal.resonators.map((r, idx) => - r ? ({idx + 1}: {r[1]} [{r[2]}] - {r[0]}) : ({idx + 1}: нет) + r ? + ({idx + 1}: {r[1]} [{r[2]}/{RESO_NRG[r[1]]}] - {r[0]}) : + ({idx + 1}: нет) )} {(!portal.resonators || portal.resonators.length == 0) && (нет)} Моды {portal.mods && portal.mods.map((r, idx) => - r ? ({idx + 1}: {r[1]} [{r[2]}] - {r[0]}) : ({idx + 1}: нет) + r ? + ({idx + 1}: {MOD_TYPE[r[1]] || r[1]} [{r[2]}] - {r[0]}) : + ({idx + 1}: нет) )} + Навигация к порталу + +