Home.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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 { SettingUtil } from '../Settings';
  14. import BottomSiteInfo from './maps/BottomSiteInfo';
  15. import Maps from './maps/Maps';
  16. import SearchTool from './maps/SearchTool';
  17. export default class HomePage extends Component {
  18. constructor(props) {
  19. super(props);
  20. this.state = {
  21. region: {
  22. latitude: 1.3532623163977149,
  23. longitude: 103.87092316860532,
  24. latitudeDelta: 0.0922,
  25. longitudeDelta: 0.0421
  26. },
  27. mapReady: false,
  28. stationInfo: {},
  29. stopList: [],
  30. hasPermission: isIOS
  31. };
  32. this.denied = true;
  33. this.backSeconds = 0;
  34. this.refreshTime = 0;
  35. this.settingInfo = {}
  36. this.filter = {
  37. parkingFee: 'ALL',
  38. connectorType: ''
  39. };
  40. }
  41. componentDidMount() {
  42. const navigation = this.props.navigation;
  43. navigation.addListener('focus', () => {
  44. //toastShort('onResume')
  45. this.setState({
  46. stationInfo: {}
  47. });
  48. SettingUtil.getSettings(set => {
  49. console.log("获取设置信息", set);
  50. this.settingInfo = set;
  51. this.checkPermission2Geo();
  52. })
  53. });
  54. navigation.addListener('blur', () => {
  55. //toastShort('onStop')
  56. setTimeout(() => {
  57. navigation.closeDrawer();
  58. }, 200);
  59. });
  60. navigation.addListener('beforeRemove', (e) => {
  61. if (isIOS) {
  62. e.preventDefault();
  63. } else {
  64. let time = new Date().getTime();
  65. if (time - this.backSeconds < 2000) {
  66. BackHandler.exitApp();
  67. } else {
  68. toastShort("Press the back button again to exit the program");
  69. this.backSeconds = time;
  70. e.preventDefault();
  71. }
  72. }
  73. });
  74. }
  75. getPermission() {
  76. request(
  77. isIOS
  78. ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
  79. : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
  80. .then(res => {
  81. console.log('getPermission', res)
  82. this.setState({
  83. hasPermission: true
  84. });
  85. this.checkPermission2Geo();
  86. }).catch(err => {
  87. console.info('getPermission', err)
  88. });
  89. }
  90. checkPermission2Geo(refresh) {
  91. if (this.state.hasPermission) {
  92. if (refresh) {
  93. //避免关闭自动移动地图后无法点击按钮移动地图
  94. this.state.stopList = []
  95. }
  96. this.infoGeoLocation();
  97. return;
  98. }
  99. check(
  100. isIOS
  101. ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
  102. : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
  103. .then(res => {
  104. //console.log('checkPermission2Geo', res);
  105. switch (res) {
  106. case RESULTS.UNAVAILABLE:
  107. console.log('此功能不可用(在此设备上/在此上下文中)');
  108. if (isIOS) {
  109. this.setState({
  110. hasPermission: true
  111. });
  112. this.infoGeoLocation();
  113. }
  114. break;
  115. case RESULTS.DENIED:
  116. console.log('权限未被请求/被拒绝,但可以请求');
  117. if (this.denied) {
  118. this.denied = false;
  119. this.getPermission();
  120. } else {
  121. this.denied = true;
  122. }
  123. break;
  124. case RESULTS.LIMITED:
  125. console.log('权限是有限的:有些操作是可能的');
  126. this.setState({
  127. hasPermission: true
  128. });
  129. this.infoGeoLocation();
  130. break;
  131. case RESULTS.GRANTED:
  132. console.log('许可被授予');
  133. this.setState({
  134. hasPermission: true
  135. });
  136. this.infoGeoLocation();
  137. break;
  138. case RESULTS.BLOCKED:
  139. console.log('权限被拒绝,不再可请求');
  140. Dialog.showDialog({
  141. title: 'Error',
  142. message: 'Can not get charge station, Please grant location permissions.',
  143. ok: 'SETTING',
  144. callback: btn => {
  145. if (btn == Dialog.BUTTON_OK) {
  146. console.log('ok');
  147. openSettings().catch(() => console.warn('cannot open settings'));
  148. }
  149. }
  150. });
  151. //toastShort('Save to gallery failed');
  152. break;
  153. }
  154. }).catch(err => {
  155. console.log('checkPermission2Geo-error', err);
  156. });
  157. }
  158. infoGeoLocation(again) {
  159. if (this.state.mapReady) {
  160. navigator.geolocation.getCurrentPosition(location => {
  161. let region = {
  162. latitude: location.coords.latitude,
  163. longitude: location.coords.longitude,
  164. latitudeDelta: 0.0922,
  165. longitudeDelta: 0.0421
  166. }
  167. //console.log("getGeoLocation", region);
  168. //if (this.state.stopList.length == 0) { //只加载一次
  169. let time = new Date().getTime();
  170. let interval = this.settingInfo.refreshInterval * 1000;
  171. let first = this.state.stopList.length == 0;
  172. if (first || time - this.refreshTime > interval) { //一分钟(10秒)加载一次
  173. this.getStationList(region, first);
  174. this.refreshTime = time;
  175. } else if (this.settingInfo.alwaysLocation) {
  176. this.setState({
  177. region: region
  178. });
  179. }
  180. }, error => {
  181. console.info("getGeoLocation", error);
  182. if (!again) {
  183. setTimeout(() => {
  184. this.infoGeoLocation(true);
  185. }, 2000);
  186. }
  187. });
  188. }
  189. }
  190. findFilter(data) {
  191. this.filter = data;
  192. this.getStationList();
  193. }
  194. /**
  195. * 获取所有充电桩
  196. * @param {Location} region 当前位置
  197. * @param {boolean} first 是否初始化
  198. */
  199. getStationList(region, first) {
  200. Dialog.showProgressDialog('Loading...');
  201. apiStation.getAllStation(this.filter).then(res => {
  202. Dialog.dismissLoading();
  203. if (res.data.sites) {
  204. const list = [];
  205. res.data.sites.forEach(item => {
  206. let available = false
  207. if (item.allConnector && item.allConnector.available) {
  208. available = true
  209. }
  210. list.push({
  211. id: item.sitePk,
  212. name: item.siteName,
  213. //address: item.siteAddress,
  214. available: available,
  215. siteType: item.siteType,
  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. zIndex: 1,
  337. alignItems: 'center',
  338. position: 'absolute',
  339. justifyContent: 'center',
  340. paddingTop: isIOS ? statusHeight : 0
  341. },
  342. searchView: {
  343. ...$padding(8, 16, 16),
  344. backgroundColor: colorThemes
  345. },
  346. searchInput: {
  347. alignItems: 'center',
  348. borderWidth: 1,
  349. borderStyle: 'solid',
  350. borderRadius: 60,
  351. borderColor: colorAccent,
  352. flexDirection: 'row',
  353. paddingLeft: 16,
  354. paddingRight: 16,
  355. backgroundColor: 'rgba(255, 255, 255, 0.5)'
  356. },
  357. searchText: {
  358. flex: 1,
  359. color: '#444',
  360. padding: 8,
  361. fontSize: 15
  362. },
  363. drawerLeftTouchView: {
  364. top: 0,
  365. left: 0,
  366. bottom: 0,
  367. width: 4,
  368. zIndex: 5,
  369. position: 'absolute',
  370. backgroundColor: 'rgba(0,0,0,0)'
  371. },
  372. mapContent: {
  373. flex: 1,
  374. zIndex: 4,
  375. position: 'relative',
  376. }
  377. })