/** * 首页通用页 * @邠心vbe on 2021/08/13 */ import React, { Component } from 'react'; import { View, StyleSheet, BackHandler, Linking, AppState } from 'react-native'; import app from '../../../app.json' import { i18nUtil } from '../../i18n'; import apiBase from '../../api/apiBase'; import apiStation from '../../api/apiStation'; import Dialog from '../../components/Dialog'; import utils from '../../utils/utils'; import { SettingUtil } from '../Settings'; import MyStatusBar from '../../components/MyStatusBar'; import LocationPermission from './maps/LocationPermission'; import MapUI from './MapUI'; import MapUILumi from './MapUILumi'; import storage from '../../utils/storage'; const KEY_STORE_LIST = "map_stop_list" const KEY_STORE_GPS = "map_location_gps" export default class HomePage extends Component { constructor(props) { super(props); this.state = { region: { latitude: 1.3532623163977149, longitude: 103.87092316860532, latitudeDelta: 0.0922, longitudeDelta: 0.0421 }, lastRegion: {}, mapReady: false, showStation: false, stationId: "", stationInfo: {}, stopList: [], hasPermission: false, permissionDenied: false, pinMessages: [] }; this.isHide = true; this.denied = true; this.backSeconds = 0; this.refreshTime = 0; this.settingInfo = {} this.viewIndex = -1; this.filter = { parkingFee: 'ALL', connectorType: '' }; this.refresh = false; this.stateListener; this.forceUpdateDialog = undefined; this.locationListener = undefined; } componentDidMount() { const navigation = this.props.navigation; if (this.locationListener) { this.locationListener.removeListener(); this.locationListener = undefined; } if (!isIOS) { this.locationListener = new LocationPermission.LocationListener(); if (this.locationListener) { this.locationListener.addListener(); } } navigation.addListener('focus', () => { //console.log('------Home------', "Focus") this.onCloseInfo(); SettingUtil.getSettings(set => { //console.log("获取设置信息", set); this.settingInfo = set; this.init(); }) this.isHide = false; /*if (!app.isWhitelabel) { MyStatusBar.setStatusBarThemes(MyStatusBar.DARK_STYLE, colorLight); }*/ MyStatusBar.setTranslucentStatusBar(); }); navigation.addListener('blur', () => { //toastShort('onStop') this.isHide = true; /*if (app.isLumiWhitelabel) { MyStatusBar.setStatusBarThemes(MyStatusBar.DARK_STYLE, colorLight); } else { MyStatusBar.setStatusBarThemes(themeStatusBar, colorPrimaryDark); }*/ setTimeout(() => { MyStatusBar.setStatusBarTheme(MyStatusBar.DEFAULT_STYLE); }, 50); setTimeout(() => { navigation.closeDrawer(); }, 500); }); this.stateListener = AppState.addEventListener("change", state => { if (state == 'active' && this.forceUpdateDialog) { this.showUpdateDialog(this.forceUpdateDialog); } }); BackHandler.addEventListener('hardwareBackPress', this.toExit) this.isHide = false; this.checkUpdateVersion(); this.getPinMessage(); } componentWillUnmount() { /*console.log("componentWillUnmount") if (this.unsubscribe) { this.unsubscribe(); }*/ this.backSeconds = 0; if (this.stateListener) { this.stateListener.remove(); } BackHandler.removeEventListener("hardwareBackPress", this.toExit); } init() { if (this.state.stopList.length == 0 && !this.refresh) { storage.getStorage(KEY_STORE_LIST).then(data => { //console.log("获取站点缓存", "成功"); if (data) { const list = JSON.parse(data); this.setState({ stopList: list }, () => { this.checkPermission2Geo(true); }) } else { this.checkPermission2Geo(true); } }).catch(err => { console.log("获取站点缓存-err", err); this.checkPermission2Geo(true); }) storage.getStorage(KEY_STORE_GPS).then(data => { //console.log("获取GPS缓存", data); if (data) { const location = JSON.parse(data); if (location.latitude) { this.setState({ lastRegion: location }); } } }).catch(err => { console.log("获取GPS缓存-err", err); }) } } toExit = () => { //console.log("beforeRemove", this.isHide); if (this.state.stationInfo?.id) { this.setState({ stationInfo: {} }); return true; } if (!this.isHide) { if (isIOS) { //e.preventDefault(); } else { let time = new Date().getTime(); //console.log("beforeRemove2", time, this.backSeconds); if (time - this.backSeconds < 2000) { BackHandler.exitApp(); } else { toastShort($t("home.backAgainTips")); this.backSeconds = time; //e.preventDefault(); } } return true; } } checkGPS() { if (this.locationListener) { this.locationListener.check(); } } onMapReady() { this.setState({ mapReady: true }, () => { this.init(); }); } checkUpdateVersion() { apiBase.checkUpdate().then(res => { if (res.data.versionCode > app.versionCode) { var desc = JSON.parse(res.data?.versionDesc ?? "{}"); if (desc) { const upLog = i18nUtil.analyzeLocaleData(desc); if (typeof upLog == "string") { const prps = { title: $t("home.versionUpdate"), message: $t("home.newVersionName") + res.data.versionName + "\n\n" + upLog, showCancel: !(res.data.force), ok: $t("home.updateNow"), cancel: $t("home.later"), callback: btn => { if (btn == Dialog.BUTTON_OK) { //TODO 跳转到应用商店 const uri = isIOS ? app.storeUrl.ios : app.storeUrl.android Linking.openURL(uri); } } } if (res.data.force) { prps.onBackPress = () => { } this.forceUpdateDialog = prps; } this.showUpdateDialog(prps); } } } }).catch(err => { }) } showUpdateDialog(options) { if (Dialog.isShowing()) { setTimeout(() => { this.showUpdateDialog(options) }, 500); return; } Dialog.showDialog(options) } getPermission() { LocationPermission.requestPermission(hasPermission => { if (hasPermission) { this.setState({ hasPermission: true }); this.checkPermission2Geo(); } else { this.noPermissionSite(); } }) } checkPermission2Geo(refresh, button) { if (button && this.state.lastRegion.latitude) { this.setState({ region: {...this.state.lastRegion} }); } if (this.refresh == refresh) { return; } if (refresh) { //避免关闭自动移动地图后无法点击按钮移动地图 this.refresh = true } console.log("checkPermission2Geo", refresh, button); this.checkGPS(); if (this.state.hasPermission) { this.infoGeoLocation(); } else { LocationPermission.checkPermission((hasPermission, canRequestPermission) => { if (hasPermission) { this.setState({ hasPermission: true }); this.infoGeoLocation(); } else { if (canRequestPermission) { if (this.denied) { this.denied = false; this.getPermission(); } else { //避免多次请求 this.denied = true; this.noPermissionSite(); } } else { this.noPermissionSite(); } } }) } } noPermissionSite() { console.log("未获取权限也获取站点列表"); this.setState({ hasPermission: false, permissionDenied: true }); let first = this.state.stopList.length == 0;//是否第一次加载 this.getStationList(this.state.region, first); } /** * 获取定位数据 * @param {*} again */ infoGeoLocation(again) { if (this.state.mapReady) { navigator.geolocation.getCurrentPosition(location => { let region = { latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.0922, longitudeDelta: 0.0421 } this.saveGPSCache(region); //console.log("getGeoLocation", region); //if (this.state.stopList.length == 0) { //只加载一次 let time = new Date().getTime(); let interval = this.settingInfo.refreshInterval * 1000;//重复加载时间 let first = this.state.stopList.length == 0;//是否第一次加载 if (first || this.refresh || time - this.refreshTime > interval) { //一分钟(10秒)加载一次 this.getStationList(region, first || this.refresh); this.refreshTime = time; } else if (this.settingInfo.moveMyLocation) { this.setState({ region: region }); } }, error => { console.info("getGeoLocation", error); if (!again) { setTimeout(() => { this.infoGeoLocation(true); }, 2000); } }); } else { setTimeout(() => { this.infoGeoLocation(true); }, 1000); } } findFilter(data) { this.filter = data; console.log("筛选站点", data); this.getStationList(); } /** * 获取所有充电桩 * @param {Location} region 当前位置 * @param {boolean} first 是否初始化 */ getStationList(region, first) { //Dialog.showProgressDialog(); if (getUserId()) { this.filter.operaUserId = getUserId() } if (region && (this.settingInfo.moveMyLocation || first)) { this.setState({ region: region }); } apiStation.getAllStation(this.filter).then(res => { Dialog.dismissLoading(); if (res.data.sites) { const list = []; res.data.sites.forEach(item => { let available = false if (item.allConnector && item.allConnector.available) { available = true } list.push({ id: item.sitePk, name: item.siteName, //address: item.siteAddress, available: available, siteType: item.siteType, latitude: item.locationLatitude, longitude: item.locationLongitude, favorite: item?.favorite ? true : false, hasLabel: item?.hasLabel, upcoming: item?.upcoming /*acConnector: item.acConnector, allConnector: item.allConnector, dcConnector: item.dcConnector, distance: utils.getDistance(item.distance)*/ }); }); this.setState({ stopList: list }); if (this.filter.connectorType == "" && this.filter.parkingFee == "ALL") { storage.setStorageJson(KEY_STORE_LIST, list); } } this.refresh = false; }).catch(err => { Dialog.dismissLoading(); toastShort(err); /*this.setState({ stopList: [] });*/ this.refresh = false; }) } //点击Marker获取StaionInfo viewChargeStation(id) { //console.log('info', this.state.stopList[index]); //const stationInfo = this.state.stopList[index]; if (this.state.stationId == id) { return; } this.setState({ stationId: id, stationInfo: {}, showStation: true }); if (app.modules.bookmarks) { for (let i = 0; i < this.state.stopList.length; i++) { let info = this.state.stopList[i]; if (info.id == id) { this.viewIndex = i; break; } } } if (this.state.hasPermission) { navigator.geolocation.getCurrentPosition(location => { let region = { latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.0922, longitudeDelta: 0.0421 } setTimeout(() => { this.getStationInfo(id, region); }, 500); /*if (this.settingInfo.alwaysLocation) { this.setState({ region: region }); }*/ }); } else { //无定位权限仍然显示 setTimeout(() => { this.getStationInfo(id, this.state.region); }, 500); } //startPage(PageList.chargeDetail, {...this.state.stopList[index]}); } getStationInfo(id, location) { apiStation.getStationRate({ sitePk: id, lat: location?.latitude, lng: location?.longitude }).then(res => { if (res.data.sitePk) { var info = utils.getSiteInfo(res.data); this.setState({ stationInfo: info }); } else { this.setState({ stationInfo: {} }); } }).catch(err => { this.setState({ stationInfo: {} }); toastShort(err); }); } onCloseInfo() { this.viewIndex = -1; this.setState({ stationId: "", stationInfo: {}, showStation: false }); } favoriteSite() { if (this.state.stationInfo?.id) { Dialog.showProgressDialog(); apiStation.bookmarkSite(this.state.stationInfo.id).then(res => { const info = {...this.state.stationInfo, favorite: !this.state.stationInfo.favorite} if (this.viewIndex >= 0) { const list = [...this.state.stopList] const inf = {...list[this.viewIndex], favorite: info.favorite}; list[this.viewIndex] = inf; this.setState({ stopList: list, stationInfo: info }); } else { this.setState({ stationInfo: info }); } }).catch(err => { toastShort(err); console.log(err) }).finally(() => { Dialog.dismissLoading(); }) } } getPinMessage() { apiBase.getPinMessage().then(res => { let list = [] if (res.data) { if (res.data.pinTitle) { list = [res.data]; } else if (Array.isArray(res.data)) { list = res.data; } } this.setState({ pinMessages: list }) }).catch(err => { this.setState({ pinMessages: [] }) }) } hidePermissionPanel() { this.setState({ permissionDenied: false }) } saveGPSCache(location={}) { if (location.latitude) { storage.setStorageJson(KEY_STORE_GPS, location); this.setState({ lastRegion: location }); } } render() { return ( { app.isLumiWhitelabel ? this.findFilter(data)} onMapReady={() => this.onMapReady()} onFavorite={() => this.favoriteSite()} onCloseInfo={() => this.onCloseInfo()} onLocation={() => this.checkPermission2Geo(true, true)} useApplesMap={this.settingInfo.useApplesMap} showUserLocation={this.state.hasPermission && this.settingInfo.alwaysLocation} viewChargeStation={id => this.viewChargeStation(id)}/> : this.findFilter(data)} onMapReady={() => this.onMapReady()} onFavorite={() => this.favoriteSite()} onCloseInfo={() => this.onCloseInfo()} onLocation={() => this.checkPermission2Geo(true, true)} useApplesMap={this.settingInfo.useApplesMap} showUserLocation={this.state.hasPermission && this.settingInfo.alwaysLocation} viewChargeStation={id => this.viewChargeStation(id)} pinMessages={this.state.pinMessages} /> } this.hidePermissionPanel()}/> ); } } const styles = StyleSheet.create({ drawerLeftTouchView: { top: 0, left: 0, bottom: 0, width: 4, zIndex: 5, position: 'absolute', backgroundColor: 'rgba(0,0,0,0)' } })