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 Maps from './maps/Maps';
  16. import MapTool from './maps/MapTool';
  17. import SearchTool from './maps/SearchTool';
  18. import TopInfo from './maps/TopInfo';
  19. export default class HomePage extends Component {
  20. constructor(props) {
  21. super(props);
  22. this.state = {
  23. region: {
  24. latitude: 1.3532623163977149,
  25. longitude: 103.87092316860532,
  26. latitudeDelta: 0.0922,
  27. longitudeDelta: 0.0421
  28. },
  29. mapReady: false,
  30. stationInfo: {},
  31. stopList: [],
  32. hasPermission: isIOS
  33. };
  34. this.denied = true;
  35. this.backSeconds = 0;
  36. this.refreshTime = 0;
  37. this.settingInfo = {}
  38. this.filter = {
  39. parkingFee: 'ALL',
  40. connectorType: ''
  41. };
  42. }
  43. componentDidMount() {
  44. const navigation = this.props.navigation;
  45. navigation.addListener('focus', () => {
  46. //toastShort('onResume')
  47. this.setState({
  48. stationInfo: {}
  49. });
  50. SettingUtil.getSettings(set => {
  51. console.log("获取设置信息", set);
  52. this.settingInfo = set;
  53. this.checkPermission2Geo();
  54. })
  55. });
  56. navigation.addListener('blur', () => {
  57. //toastShort('onStop')
  58. setTimeout(() => {
  59. navigation.closeDrawer();
  60. }, 200);
  61. });
  62. navigation.addListener('beforeRemove', (e) => {
  63. if (isIOS) {
  64. e.preventDefault();
  65. } else {
  66. let time = new Date().getTime();
  67. if (time - this.backSeconds < 2000) {
  68. BackHandler.exitApp();
  69. } else {
  70. toastShort("Press the back button again to exit the program");
  71. this.backSeconds = time;
  72. e.preventDefault();
  73. }
  74. }
  75. });
  76. }
  77. getPermission() {
  78. request(
  79. isIOS
  80. ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
  81. : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
  82. .then(res => {
  83. console.log('getPermission', res)
  84. this.setState({
  85. hasPermission: true
  86. });
  87. this.checkPermission2Geo();
  88. }).catch(err => {
  89. console.info('getPermission', err)
  90. });
  91. }
  92. checkPermission2Geo(refresh) {
  93. if (this.state.hasPermission) {
  94. if (refresh) {
  95. //避免关闭自动移动地图后无法点击按钮移动地图
  96. this.state.stopList = []
  97. }
  98. this.infoGeoLocation();
  99. return;
  100. }
  101. check(
  102. isIOS
  103. ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
  104. : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
  105. .then(res => {
  106. //console.log('checkPermission2Geo', res);
  107. switch (res) {
  108. case RESULTS.UNAVAILABLE:
  109. console.log('此功能不可用(在此设备上/在此上下文中)');
  110. if (isIOS) {
  111. this.setState({
  112. hasPermission: true
  113. });
  114. this.infoGeoLocation();
  115. }
  116. break;
  117. case RESULTS.DENIED:
  118. console.log('权限未被请求/被拒绝,但可以请求');
  119. if (this.denied) {
  120. this.denied = false;
  121. this.getPermission();
  122. } else {
  123. this.denied = true;
  124. }
  125. break;
  126. case RESULTS.LIMITED:
  127. console.log('权限是有限的:有些操作是可能的');
  128. this.setState({
  129. hasPermission: true
  130. });
  131. this.infoGeoLocation();
  132. break;
  133. case RESULTS.GRANTED:
  134. console.log('许可被授予');
  135. this.setState({
  136. hasPermission: true
  137. });
  138. this.infoGeoLocation();
  139. break;
  140. case RESULTS.BLOCKED:
  141. console.log('权限被拒绝,不再可请求');
  142. Dialog.showDialog({
  143. title: 'Error',
  144. message: 'Can not get charge station, Please grant location permissions.',
  145. ok: 'SETTING',
  146. callback: btn => {
  147. if (btn == Dialog.BUTTON_OK) {
  148. console.log('ok');
  149. openSettings().catch(() => console.warn('cannot open settings'));
  150. }
  151. }
  152. });
  153. //toastShort('Save to gallery failed');
  154. break;
  155. }
  156. }).catch(err => {
  157. console.log('checkPermission2Geo-error', err);
  158. });
  159. }
  160. infoGeoLocation(again) {
  161. if (this.state.mapReady) {
  162. navigator.geolocation.getCurrentPosition(location => {
  163. let region = {
  164. latitude: location.coords.latitude,
  165. longitude: location.coords.longitude,
  166. latitudeDelta: 0.0922,
  167. longitudeDelta: 0.0421
  168. }
  169. //console.log("getGeoLocation", region);
  170. //if (this.state.stopList.length == 0) { //只加载一次
  171. let time = new Date().getTime();
  172. let interval = this.settingInfo.refreshInterval * 1000;
  173. let first = this.state.stopList.length == 0;
  174. if (first || time - this.refreshTime > interval) { //一分钟(10秒)加载一次
  175. this.getStationList(region, first);
  176. this.refreshTime = time;
  177. } else if (this.settingInfo.alwaysLocation) {
  178. this.setState({
  179. region: region
  180. });
  181. }
  182. }, error => {
  183. console.info("getGeoLocation", error);
  184. if (!again) {
  185. setTimeout(() => {
  186. this.infoGeoLocation(true);
  187. }, 2000);
  188. }
  189. });
  190. }
  191. }
  192. findFilter(data) {
  193. this.filter = data;
  194. this.getStationList();
  195. }
  196. getStationList(region, first) {
  197. Dialog.showProgressDialog('Loading...');
  198. apiStation.getAllStation(this.filter).then(res => {
  199. Dialog.dismissLoading();
  200. if (res.data.sites) {
  201. const list = [];
  202. res.data.sites.forEach(item => {
  203. let available = false
  204. if (item.allConnector && item.allConnector.available) {
  205. available = true
  206. }
  207. list.push({
  208. id: item.sitePk,
  209. name: item.siteName,
  210. //address: item.siteAddress,
  211. available: available,
  212. siteType: item.siteType,
  213. latitude: item.locationLatitude,
  214. longitude: item.locationLongitude,
  215. /*latitude: item.locationLatitude,
  216. longitude: item.locationLongitude,
  217. acConnector: item.acConnector,
  218. allConnector: item.allConnector,
  219. dcConnector: item.dcConnector,
  220. distance: utils.getDistance(item.distance)*/
  221. });
  222. });
  223. this.setState({
  224. stopList: list
  225. });
  226. if (region && (this.settingInfo.alwaysLocation || first)) {
  227. setTimeout(() => {
  228. this.setState({
  229. region: region
  230. });
  231. }, 500);
  232. }
  233. }
  234. }).catch(err => {
  235. Dialog.dismissLoading();
  236. this.setState({
  237. stopList: []
  238. });
  239. })
  240. }
  241. //点击Marker获取StaionInfo
  242. viewChargeStation(id, index) {
  243. //console.log('info', this.state.stopList[index]);
  244. //const stationInfo = this.state.stopList[index];
  245. navigator.geolocation.getCurrentPosition(location => {
  246. let params = {
  247. lat: location.coords.latitude,
  248. lng: location.coords.longitude,
  249. sitePk: id//stationInfo.id
  250. }
  251. apiStation.getStationRate(params).then(res => {
  252. if (res.data.sitePk) {
  253. var info = utils.getSiteInfo(res.data);
  254. this.setState({
  255. stationInfo: info
  256. });
  257. } else {
  258. this.setState({
  259. stationInfo: stationInfo
  260. });
  261. }
  262. }).catch(err => {
  263. this.setState({
  264. stationInfo: stationInfo
  265. });
  266. });
  267. });
  268. //startPage(PageList.chargeDetail, {...this.state.stopList[index]});
  269. }
  270. render() {
  271. return (
  272. <View style={ui.flex1}>
  273. <View style={Styles.toolbar}>
  274. <Pressable
  275. style={Styles.backIcon}
  276. android_ripple = {rippleLess}
  277. onPress={() => {
  278. this.props.navigation.toggleDrawer();
  279. }}>
  280. <EvilIcons name={'navicon'} size={28} color={colorPrimary} />
  281. </Pressable>
  282. <View style={styles.logoView}>
  283. <Image
  284. source={require('../../images/tool-logo.png')}
  285. style={Styles.logo}
  286. />
  287. </View>
  288. <Text style={ui.flex1}></Text>
  289. <Pressable
  290. style={Styles.backIcon}
  291. android_ripple = {rippleLess}
  292. onPress={() => {
  293. this.props.navigation.toggleDrawer();
  294. }}>
  295. <MaterialCommunityIcons
  296. name='line-scan'
  297. size={28}
  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. <TopInfo 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. })