Home.js 9.8 KB

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