Home.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /**
  2. * 首页地图页
  3. * @邠心vbe on 2021/08/13
  4. */
  5. import React, { Component } from 'react';
  6. import { View, Text, Pressable, Image, StyleSheet, BackHandler } from 'react-native';
  7. import {check, request, openSettings, PERMISSIONS, RESULTS} from 'react-native-permissions';
  8. import apiStation from '../../api/apiStation';
  9. import Button from '../../components/Button';
  10. import Dialog from '../../components/Dialog';
  11. import { Styles } from '../../components/Toolbar';
  12. import utils from '../../utils/utils';
  13. import { PageList } from '../Router';
  14. import { SettingUtil } from '../Settings';
  15. import BottomSiteInfo from './maps/BottomSiteInfo';
  16. import Maps from './maps/Maps';
  17. import MapTool from './maps/MapTool';
  18. import SearchTool from './maps/SearchTool';
  19. import TopInfo from './maps/TopInfo';
  20. export default class HomePage extends Component {
  21. constructor(props) {
  22. super(props);
  23. this.state = {
  24. region: {
  25. latitude: 1.3532623163977149,
  26. longitude: 103.87092316860532,
  27. latitudeDelta: 0.0922,
  28. longitudeDelta: 0.0421
  29. },
  30. mapReady: false,
  31. stationInfo: {},
  32. stopList: [],
  33. hasPermission: isIOS
  34. };
  35. this.denied = true;
  36. this.backSeconds = 0;
  37. this.refreshTime = 0;
  38. this.settingInfo = {}
  39. this.filter = {
  40. parkingFee: 'ALL',
  41. connectorType: ''
  42. };
  43. }
  44. componentDidMount() {
  45. const navigation = this.props.navigation;
  46. navigation.addListener('focus', () => {
  47. //toastShort('onResume')
  48. this.setState({
  49. stationInfo: {}
  50. });
  51. SettingUtil.getSettings(set => {
  52. console.log("获取设置信息", set);
  53. this.settingInfo = set;
  54. this.checkPermission2Geo();
  55. })
  56. });
  57. navigation.addListener('blur', () => {
  58. //toastShort('onStop')
  59. setTimeout(() => {
  60. navigation.closeDrawer();
  61. }, 200);
  62. });
  63. navigation.addListener('beforeRemove', (e) => {
  64. if (isIOS) {
  65. e.preventDefault();
  66. } else {
  67. let time = new Date().getTime();
  68. if (time - this.backSeconds < 2000) {
  69. BackHandler.exitApp();
  70. } else {
  71. toastShort("Press the back button again to exit the program");
  72. this.backSeconds = time;
  73. e.preventDefault();
  74. }
  75. }
  76. });
  77. }
  78. getPermission() {
  79. request(
  80. isIOS
  81. ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
  82. : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
  83. .then(res => {
  84. console.log('getPermission', res)
  85. this.setState({
  86. hasPermission: true
  87. });
  88. this.checkPermission2Geo();
  89. }).catch(err => {
  90. console.info('getPermission', err)
  91. });
  92. }
  93. checkPermission2Geo(refresh) {
  94. if (this.state.hasPermission) {
  95. if (refresh) {
  96. //避免关闭自动移动地图后无法点击按钮移动地图
  97. this.state.stopList = []
  98. }
  99. this.infoGeoLocation();
  100. return;
  101. }
  102. check(
  103. isIOS
  104. ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
  105. : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
  106. .then(res => {
  107. //console.log('checkPermission2Geo', res);
  108. switch (res) {
  109. case RESULTS.UNAVAILABLE:
  110. console.log('此功能不可用(在此设备上/在此上下文中)');
  111. if (isIOS) {
  112. this.setState({
  113. hasPermission: true
  114. });
  115. this.infoGeoLocation();
  116. }
  117. break;
  118. case RESULTS.DENIED:
  119. console.log('权限未被请求/被拒绝,但可以请求');
  120. if (this.denied) {
  121. this.denied = false;
  122. this.getPermission();
  123. } else {
  124. this.denied = true;
  125. }
  126. break;
  127. case RESULTS.LIMITED:
  128. console.log('权限是有限的:有些操作是可能的');
  129. this.setState({
  130. hasPermission: true
  131. });
  132. this.infoGeoLocation();
  133. break;
  134. case RESULTS.GRANTED:
  135. console.log('许可被授予');
  136. this.setState({
  137. hasPermission: true
  138. });
  139. this.infoGeoLocation();
  140. break;
  141. case RESULTS.BLOCKED:
  142. console.log('权限被拒绝,不再可请求');
  143. Dialog.showDialog({
  144. title: 'Error',
  145. message: 'Can not get charge station, Please grant location permissions.',
  146. ok: 'SETTING',
  147. callback: btn => {
  148. if (btn == Dialog.BUTTON_OK) {
  149. console.log('ok');
  150. openSettings().catch(() => console.warn('cannot open settings'));
  151. }
  152. }
  153. });
  154. //toastShort('Save to gallery failed');
  155. break;
  156. }
  157. }).catch(err => {
  158. console.log('checkPermission2Geo-error', err);
  159. });
  160. }
  161. infoGeoLocation(again) {
  162. if (this.state.mapReady) {
  163. navigator.geolocation.getCurrentPosition(location => {
  164. let region = {
  165. latitude: location.coords.latitude,
  166. longitude: location.coords.longitude,
  167. latitudeDelta: 0.0922,
  168. longitudeDelta: 0.0421
  169. }
  170. //console.log("getGeoLocation", region);
  171. //if (this.state.stopList.length == 0) { //只加载一次
  172. let time = new Date().getTime();
  173. let interval = this.settingInfo.refreshInterval * 1000;
  174. let first = this.state.stopList.length == 0;
  175. if (first || time - this.refreshTime > interval) { //一分钟(10秒)加载一次
  176. this.getStationList(region, first);
  177. this.refreshTime = time;
  178. } else if (this.settingInfo.alwaysLocation) {
  179. this.setState({
  180. region: region
  181. });
  182. }
  183. }, error => {
  184. console.info("getGeoLocation", error);
  185. if (!again) {
  186. setTimeout(() => {
  187. this.infoGeoLocation(true);
  188. }, 2000);
  189. }
  190. });
  191. }
  192. }
  193. findFilter(data) {
  194. this.filter = data;
  195. this.getStationList();
  196. }
  197. getStationList(region, first) {
  198. Dialog.showProgressDialog('Loading...');
  199. apiStation.getAllStation(this.filter).then(res => {
  200. Dialog.dismissLoading();
  201. if (res.data.sites) {
  202. const list = [];
  203. res.data.sites.forEach(item => {
  204. let available = false
  205. if (item.allConnector && item.allConnector.available) {
  206. available = true
  207. }
  208. list.push({
  209. id: item.sitePk,
  210. name: item.siteName,
  211. //address: item.siteAddress,
  212. available: available,
  213. siteType: item.siteType,
  214. latitude: item.locationLatitude,
  215. longitude: item.locationLongitude,
  216. /*latitude: item.locationLatitude,
  217. longitude: item.locationLongitude,
  218. acConnector: item.acConnector,
  219. allConnector: item.allConnector,
  220. dcConnector: item.dcConnector,
  221. distance: utils.getDistance(item.distance)*/
  222. });
  223. });
  224. this.setState({
  225. stopList: list
  226. });
  227. if (region && (this.settingInfo.alwaysLocation || first)) {
  228. setTimeout(() => {
  229. this.setState({
  230. region: region
  231. });
  232. }, 500);
  233. }
  234. }
  235. }).catch(err => {
  236. Dialog.dismissLoading();
  237. toastShort(err);
  238. this.setState({
  239. stopList: []
  240. });
  241. })
  242. }
  243. //点击Marker获取StaionInfo
  244. viewChargeStation(id, index) {
  245. //console.log('info', this.state.stopList[index]);
  246. //const stationInfo = this.state.stopList[index];
  247. navigator.geolocation.getCurrentPosition(location => {
  248. let params = {
  249. lat: location.coords.latitude,
  250. lng: location.coords.longitude,
  251. sitePk: id//stationInfo.id
  252. }
  253. apiStation.getStationRate(params).then(res => {
  254. if (res.data.sitePk) {
  255. var info = utils.getSiteInfo(res.data);
  256. this.setState({
  257. stationInfo: info
  258. });
  259. } else {
  260. this.setState({
  261. stationInfo: stationInfo
  262. });
  263. }
  264. }).catch(err => {
  265. this.setState({
  266. stationInfo: stationInfo
  267. });
  268. });
  269. });
  270. //startPage(PageList.chargeDetail, {...this.state.stopList[index]});
  271. }
  272. render() {
  273. return (
  274. <View style={ui.flex1}>
  275. <View style={Styles.toolbar}>
  276. <Pressable
  277. style={Styles.backIcon}
  278. android_ripple = {rippleLess}
  279. onPress={() => {
  280. this.props.navigation.toggleDrawer();
  281. }}>
  282. <EvilIcons name={'navicon'} size={28} color={colorPrimary} />
  283. </Pressable>
  284. <View style={styles.logoView}>
  285. <Image
  286. source={require('../../images/tool-logo.png')}
  287. style={Styles.logo}
  288. />
  289. </View>
  290. <Text style={ui.flex1}></Text>
  291. <Pressable
  292. style={Styles.backIcon}
  293. android_ripple = {rippleLess}
  294. onPress={() => startPage(PageList.scanqr, {actionDetail: true})}>
  295. <MaterialCommunityIcons
  296. name='line-scan'
  297. size={20}
  298. color={colorPrimary}
  299. />
  300. </Pressable>
  301. </View>
  302. <SearchTool
  303. count={this.state.stopList.length}
  304. mapReady={this.state.mapReady}
  305. onFilter={data => this.findFilter(data)}
  306. onLocation={() => this.checkPermission2Geo(true)}
  307. />
  308. <View style={styles.mapContent}>
  309. { this.state.hasPermission &&
  310. <Maps.Maps3
  311. region={this.state.region}
  312. stopList={this.state.stopList}
  313. onMapReady={() => {
  314. this.setState({
  315. mapReady: true
  316. }, () => {
  317. this.checkPermission2Geo();
  318. });
  319. }}
  320. onMarkerPress={id => this.viewChargeStation(id)}
  321. />
  322. }
  323. <BottomSiteInfo stationInfo={this.state.stationInfo}/>
  324. </View>
  325. <View style={styles.drawerLeftTouchView}></View>
  326. </View>
  327. );
  328. }
  329. }
  330. const styles = StyleSheet.create({
  331. logoView: {
  332. top: 0,
  333. left: 0,
  334. right: 0,
  335. bottom: 0,
  336. alignItems: 'center',
  337. position: 'absolute',
  338. justifyContent: 'center'
  339. },
  340. searchView: {
  341. ...$padding(8, 16, 16),
  342. backgroundColor: colorThemes
  343. },
  344. searchInput: {
  345. alignItems: 'center',
  346. borderWidth: 1,
  347. borderStyle: 'solid',
  348. borderRadius: 60,
  349. borderColor: colorAccent,
  350. flexDirection: 'row',
  351. paddingLeft: 16,
  352. paddingRight: 16,
  353. backgroundColor: 'rgba(255, 255, 255, 0.5)'
  354. },
  355. searchText: {
  356. flex: 1,
  357. color: '#444',
  358. padding: 8,
  359. fontSize: 15
  360. },
  361. drawerLeftTouchView: {
  362. top: 0,
  363. left: 0,
  364. bottom: 0,
  365. width: 4,
  366. zIndex: 5,
  367. position: 'absolute',
  368. backgroundColor: 'rgba(0,0,0,0)'
  369. },
  370. mapContent: {
  371. flex: 1,
  372. zIndex: 4,
  373. position: 'relative',
  374. }
  375. })