Home.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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. /**
  198. * 获取所有充电桩
  199. * @param {Location} region 当前位置
  200. * @param {boolean} first 是否初始化
  201. */
  202. getStationList(region, first) {
  203. Dialog.showProgressDialog('Loading...');
  204. apiStation.getAllStation(this.filter).then(res => {
  205. Dialog.dismissLoading();
  206. if (res.data.sites) {
  207. const list = [];
  208. res.data.sites.forEach(item => {
  209. let available = false
  210. if (item.allConnector && item.allConnector.available) {
  211. available = true
  212. }
  213. list.push({
  214. id: item.sitePk,
  215. name: item.siteName,
  216. //address: item.siteAddress,
  217. available: available,
  218. siteType: item.siteType,
  219. latitude: item.locationLatitude,
  220. longitude: item.locationLongitude,
  221. /*acConnector: item.acConnector,
  222. allConnector: item.allConnector,
  223. dcConnector: item.dcConnector,
  224. distance: utils.getDistance(item.distance)*/
  225. });
  226. });
  227. this.setState({
  228. stopList: list
  229. });
  230. if (region && (this.settingInfo.alwaysLocation || first)) {
  231. setTimeout(() => {
  232. this.setState({
  233. region: region
  234. });
  235. }, 500);
  236. }
  237. }
  238. }).catch(err => {
  239. Dialog.dismissLoading();
  240. toastShort(err);
  241. this.setState({
  242. stopList: []
  243. });
  244. })
  245. }
  246. //点击Marker获取StaionInfo
  247. viewChargeStation(id, index) {
  248. //console.log('info', this.state.stopList[index]);
  249. //const stationInfo = this.state.stopList[index];
  250. navigator.geolocation.getCurrentPosition(location => {
  251. let params = {
  252. lat: location.coords.latitude,
  253. lng: location.coords.longitude,
  254. sitePk: id//stationInfo.id
  255. }
  256. apiStation.getStationRate(params).then(res => {
  257. if (res.data.sitePk) {
  258. var info = utils.getSiteInfo(res.data);
  259. this.setState({
  260. stationInfo: info
  261. });
  262. } else {
  263. this.setState({
  264. stationInfo: stationInfo
  265. });
  266. }
  267. }).catch(err => {
  268. this.setState({
  269. stationInfo: stationInfo
  270. });
  271. });
  272. });
  273. //startPage(PageList.chargeDetail, {...this.state.stopList[index]});
  274. }
  275. render() {
  276. return (
  277. <View style={ui.flex1}>
  278. <View style={Styles.toolbar}>
  279. <Pressable
  280. style={Styles.backIcon}
  281. android_ripple = {rippleLess}
  282. onPress={() => {
  283. this.props.navigation.toggleDrawer();
  284. }}>
  285. <EvilIcons name={'navicon'} size={28} color={colorPrimary} />
  286. </Pressable>
  287. <View style={styles.logoView}>
  288. <Image
  289. source={require('../../images/tool-logo.png')}
  290. style={Styles.logo}
  291. />
  292. </View>
  293. <Text style={ui.flex1}></Text>
  294. <Pressable
  295. style={Styles.backIcon}
  296. android_ripple = {rippleLess}
  297. onPress={() => startPage(PageList.scanqr, {actionDetail: true})}>
  298. <MaterialCommunityIcons
  299. name='line-scan'
  300. size={20}
  301. color={colorPrimary}
  302. />
  303. </Pressable>
  304. </View>
  305. <SearchTool
  306. count={this.state.stopList.length}
  307. mapReady={this.state.mapReady}
  308. onFilter={data => this.findFilter(data)}
  309. onLocation={() => this.checkPermission2Geo(true)}
  310. />
  311. <View style={styles.mapContent}>
  312. { this.state.hasPermission &&
  313. <Maps.Maps3
  314. region={this.state.region}
  315. stopList={this.state.stopList}
  316. onMapReady={() => {
  317. this.setState({
  318. mapReady: true
  319. }, () => {
  320. this.checkPermission2Geo();
  321. });
  322. }}
  323. onMarkerPress={id => this.viewChargeStation(id)}
  324. />
  325. }
  326. <BottomSiteInfo stationInfo={this.state.stationInfo}/>
  327. </View>
  328. <View style={styles.drawerLeftTouchView}></View>
  329. </View>
  330. );
  331. }
  332. }
  333. const styles = StyleSheet.create({
  334. logoView: {
  335. top: 0,
  336. left: 0,
  337. right: 0,
  338. bottom: 0,
  339. alignItems: 'center',
  340. position: 'absolute',
  341. justifyContent: 'center'
  342. },
  343. searchView: {
  344. ...$padding(8, 16, 16),
  345. backgroundColor: colorThemes
  346. },
  347. searchInput: {
  348. alignItems: 'center',
  349. borderWidth: 1,
  350. borderStyle: 'solid',
  351. borderRadius: 60,
  352. borderColor: colorAccent,
  353. flexDirection: 'row',
  354. paddingLeft: 16,
  355. paddingRight: 16,
  356. backgroundColor: 'rgba(255, 255, 255, 0.5)'
  357. },
  358. searchText: {
  359. flex: 1,
  360. color: '#444',
  361. padding: 8,
  362. fontSize: 15
  363. },
  364. drawerLeftTouchView: {
  365. top: 0,
  366. left: 0,
  367. bottom: 0,
  368. width: 4,
  369. zIndex: 5,
  370. position: 'absolute',
  371. backgroundColor: 'rgba(0,0,0,0)'
  372. },
  373. mapContent: {
  374. flex: 1,
  375. zIndex: 4,
  376. position: 'relative',
  377. }
  378. })