Drawer.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /**
  2. * 首页抽屉菜单
  3. * @邠心vbe on 2021/03/23
  4. */
  5. import React, { Component } from 'react';
  6. import {View, Text, StyleSheet, Image, Pressable, BackHandler, Linking, Touchable} from 'react-native';
  7. import { createDrawerNavigator, DrawerContentScrollView } from '@react-navigation/drawer';
  8. import { Styles } from '../../components/Toolbar';
  9. import app from '../../../app.json';
  10. import Maps from './Home';
  11. import { PageList } from '../Router';
  12. import Dialog from '../../components/Dialog';
  13. import { host, setAccessToken } from '../../api/http';
  14. import { getStorageJsonSync, setStorage, setStorageJson } from '../../utils/storage';
  15. import Button from '../../components/Button';
  16. import { AutoLogin } from '../sign/Login';
  17. import apiCharge from '../../api/apiCharge';
  18. import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
  19. import { toTopupPage } from '../payment/PaymentConfig';
  20. import utils from '../../utils/utils';
  21. import apiNotification from '../../api/apiNotification';
  22. import TextView from '../../components/TextView';
  23. const Drawer = createDrawerNavigator();
  24. const DEBUG = app.debug && !app.product;
  25. export default class Home extends Component {
  26. constructor(props) {
  27. super(props);
  28. this.state = {
  29. isLogin: false,
  30. userInfo: {},
  31. notificationCount: 0
  32. }
  33. }
  34. componentDidMount() {
  35. AutoLogin(() => {
  36. this.setState({
  37. userInfo: userInfo
  38. });
  39. });
  40. this.props.navigation.addListener('focus', () => {
  41. //console.log('drawer focus');
  42. getUserInfo(info => {
  43. this.setState({
  44. userInfo: info
  45. });
  46. }, true);
  47. if (app.modules.notifications && this.state.isLogin) {
  48. this.getNotificationTotal();
  49. }
  50. });
  51. /*BackHandler.addEventListener('hardwareBackPress', (e) => {
  52. if (global.dialogId !== 0) {
  53. Dialog.dismissLoading();
  54. return true;
  55. }
  56. return false;
  57. })*/
  58. }
  59. componentDidUpdate() {
  60. const status = isLogin();
  61. if (this.state.isLogin != status) {
  62. this.setState({
  63. isLogin: status
  64. }, () => {
  65. getUserInfo(info => {
  66. this.setState({
  67. userInfo: info
  68. });
  69. if (info.firebaseToken) {
  70. let token = isIOS ? info.firebaseToken?.ios : info.firebaseToken?.android
  71. if (notifyToken.token) {
  72. utils.registerFirebaseToken(token ?? "");
  73. }
  74. }
  75. }, true);
  76. if (app.modules.notifications) {
  77. this.getNotificationTotal();
  78. }
  79. });
  80. }
  81. }
  82. async requestLogout() {
  83. const data = await getStorageJsonSync('loginData');
  84. if (data && data.email) {
  85. delete data.password
  86. setStorageJson('loginData', data);
  87. setStorage('RegisterTokenDate', "");
  88. }
  89. global.userInfo = {}
  90. this.setState({
  91. isLogin: false,
  92. userInfo: {}
  93. });
  94. setAccessToken('');
  95. Dialog.dismissLoading();
  96. }
  97. getNotificationTotal() {
  98. apiNotification.getUnreadTotal().then(res => {
  99. if (res.data) {
  100. this.setState({
  101. notificationCount: res.data?.toBeReadCount ?? 0
  102. })
  103. } else {
  104. this.setState({
  105. notificationCount: 0
  106. })
  107. }
  108. }).catch(err => {
  109. this.setState({
  110. notificationCount: 0
  111. })
  112. })
  113. }
  114. render () {
  115. return (
  116. <Drawer.Navigator
  117. initialRouteName='maps'
  118. drawerContent={props =>
  119. <CustomerDrawerContent
  120. {...props}
  121. isLogin={this.state.isLogin}
  122. userInfo={this.state.userInfo}
  123. onLogout={() => this.requestLogout()}
  124. notificationCount={this.state.notificationCount}
  125. />
  126. }
  127. drawerType={
  128. global.$width >= 768 ? 'back' : 'front'
  129. }
  130. drawerStyle={{
  131. width: $vw(75) > 320 ? 320 : $vw(75),
  132. backgroundColor: colorLight
  133. }}
  134. screenOptions={{
  135. headerShown: false
  136. }}>
  137. <Drawer.Screen name="maps" component={Maps} />
  138. </Drawer.Navigator>
  139. );
  140. }
  141. };
  142. const CustomerDrawerContent = (props) => {
  143. return (
  144. <DrawerContentScrollView
  145. {...props}
  146. canCancelContentTouches={true}>
  147. <DrawerContent {...props}/>
  148. </DrawerContentScrollView>
  149. );
  150. }
  151. const DrawerContent = ({isLogin, userInfo, onLogout, notificationCount=0, navigation}) => {
  152. const getCharging = () => {
  153. Dialog.showProgressDialog();
  154. apiCharge.getUserCharging().then(res => {
  155. Dialog.dismissLoading();
  156. if (res.data.sitePk) {
  157. startPage(PageList.chargeDetailPage, {stationInfo: {id: res.data.sitePk}, action: 'view', from: PageList.home});
  158. //startPage(PageList.chargeDetail, { stationInfo: {id: res.data.sitePk}, action: 'view'});
  159. } else if (res.msg) {
  160. toastShort(res.msg);
  161. } else {
  162. toastShort($t("drawer.noChargingSession"));
  163. }
  164. }).catch((err) => {
  165. if (app.debug)
  166. console.log(err);
  167. Dialog.dismissLoading();
  168. toastShort($t("drawer.noChargingSession"));
  169. })
  170. }
  171. const logout = () => {
  172. Dialog.showDialog({
  173. title: 'Sign out',
  174. message: 'Are you sure you want to sign out?',
  175. callback: btn => {
  176. if (btn == 'ok') {
  177. Dialog.showProgressDialog();
  178. setTimeout(() => {
  179. onLogout();
  180. }, 500);
  181. }
  182. }
  183. })
  184. }
  185. return (
  186. <View style={styles.drawerView}>
  187. <View style={styles.loginView}>
  188. { (isLogin && userInfo.photoUrl)
  189. ? <TouchableWithoutFeedback onPress={() => startPage(PageList.profile)}>
  190. <Image
  191. style={styles.avatar}
  192. source={{uri: host + userInfo.photoUrl}}/>
  193. </TouchableWithoutFeedback>
  194. : <TouchableWithoutFeedback onPress={() => startPage(PageList.login)}>
  195. <Image
  196. style={styles.avatar}
  197. source={require('../../images/user/ic-avatar-default.png')}/>
  198. </TouchableWithoutFeedback>
  199. }
  200. <Button
  201. style={styles.nickView}
  202. viewStyle={styles.nickViewStyle}
  203. onClick={() => startPage(isLogin ? PageList.profile : PageList.login)}>
  204. <TextView
  205. style={styles.nickname}
  206. ellipsizeMode='tail'
  207. numberOfLines={1}>
  208. { isLogin
  209. ? userInfo.nickName
  210. ? userInfo.nickName
  211. : $t('drawer.logging')
  212. : $t('drawer.sign')
  213. }
  214. </TextView>
  215. <FontAwesome
  216. size={24}
  217. color='#999'
  218. name='angle-right'/>
  219. </Button>
  220. </View>
  221. <View style={styles.divideLogin}></View>
  222. { isLogin
  223. ? <Button
  224. style={styles.itemButton}
  225. viewStyle={styles.itemView}
  226. onClick={() => getCharging()}>
  227. <MaterialCommunityIcons
  228. style={styles.icon}
  229. name="car-electric-outline"
  230. color="#333"
  231. size={26}
  232. />
  233. {/* <Image
  234. style={styles.icon}
  235. source={require('../../images/icon/draw-charge.png')}/> */}
  236. <TextView style={styles.label}>{$t('drawer.charging')}</TextView>
  237. </Button>
  238. : <View
  239. style={styles.disableItem}>
  240. <MaterialCommunityIcons
  241. style={styles.icon}
  242. name="car-electric-outline"
  243. color="#999"
  244. size={26}
  245. />
  246. {/* <Image
  247. style={styles.icon}
  248. source={require('../../images/icon/draw-charge-no.png')}/> */}
  249. <TextView style={styles.disable}>{$t('drawer.charging')}</TextView>
  250. </View>
  251. }
  252. {
  253. isLogin && <>
  254. <Button
  255. style={styles.itemButton}
  256. viewStyle={styles.itemView}
  257. onClick={() => {
  258. startPage(PageList.wallet);
  259. }}>
  260. <Image
  261. style={styles.icon}
  262. source={require('../../images/icon/draw-transaction.png')}/>
  263. <TextView style={styles.label}>{$t('drawer.wallet')}</TextView>
  264. </Button>
  265. <Button
  266. style={styles.itemButton}
  267. viewStyle={styles.itemView}
  268. onClick={() => toTopupPage()}>
  269. <MaterialCommunityIcons
  270. style={styles.icon}
  271. size={26}
  272. name={"wallet-outline"}
  273. color={colorDark}/>
  274. <TextView style={styles.label}>{$t('drawer.topup')}</TextView>
  275. <Text style={styles.balanceText2}>{userInfo.creditStr}</Text>
  276. </Button></>
  277. }
  278. {/*附加功能-开始*/}
  279. { (app.modules.notifications && isLogin) &&
  280. <Button
  281. style={styles.itemButton}
  282. viewStyle={styles.itemView}
  283. onClick={() => {
  284. startPage(PageList.notification);
  285. }}>
  286. <MaterialIcons
  287. style={styles.icon}
  288. name="notifications"
  289. color="#222"
  290. size={26}/>
  291. <TextView style={styles.label}>{$t('route.notifications')}</TextView>
  292. { notificationCount > 0 && (
  293. notificationCount < 100
  294. ? <TextView
  295. style={styles.bridgeText}
  296. fixedAlign={false}>{notificationCount}</TextView>
  297. : <TextView
  298. style={styles.bridgeText2}
  299. fixedAlign={false}>99+</TextView>
  300. )
  301. }
  302. </Button>
  303. }
  304. { (app.modules.bookmarks && isLogin) &&
  305. <Button
  306. style={styles.itemButton}
  307. viewStyle={styles.itemView}
  308. onClick={() => {
  309. startPage(PageList.bookmarks);
  310. }}>
  311. <MaterialIcons
  312. style={styles.icon}
  313. name="stars"
  314. color="#222"
  315. size={26}/>
  316. <TextView style={styles.label}>{$t('route.bookmarks')}</TextView>
  317. </Button>
  318. }
  319. {/*附加功能-结束*/}
  320. { (app.modules.membership && isLogin) &&
  321. <Button
  322. style={styles.itemButton}
  323. viewStyle={styles.itemView}
  324. onClick={() => {
  325. startPage(PageList.membersList);
  326. }}>
  327. <MaterialIcons
  328. style={styles.icon}
  329. name="card-membership"
  330. color="#222"
  331. size={26}/>
  332. <TextView style={styles.label}>{$t('drawer.members')}</TextView>
  333. </Button>
  334. }
  335. <Button
  336. style={styles.itemButton}
  337. viewStyle={styles.itemView}
  338. onClick={() => {
  339. startPage(PageList.feedback);
  340. }}>
  341. <MaterialCommunityIcons
  342. style={styles.icon2}
  343. name="message-alert-outline"
  344. color="#222"
  345. size={24}/>
  346. <TextView style={styles.label}>{$t('drawer.feedback')}</TextView>
  347. </Button>
  348. {/* <Button
  349. style={styles.itemButton}
  350. viewStyle={styles.itemView}
  351. onClick={() => {
  352. Linking.openURL(host+"juicePicture/pdf/FAQ.v1.0.pdf")
  353. }}>
  354. <Feather
  355. style={styles.icon2}
  356. name="download"
  357. color={colorDark}
  358. size={24}
  359. />
  360. <Text style={styles.label}>FAQs</Text>
  361. </Button> */}
  362. <Button
  363. style={styles.itemButton}
  364. viewStyle={styles.itemView}
  365. onClick={() => {
  366. startPage(PageList.settings);
  367. }}>
  368. <MaterialIcons
  369. style={styles.icon}
  370. name="settings"
  371. color="#222"
  372. size={25}
  373. />
  374. <TextView style={styles.label}>{$t('drawer.settings')}</TextView>
  375. </Button>
  376. { app.modules.support &&
  377. <Button
  378. style={styles.itemButton}
  379. viewStyle={styles.itemView}
  380. onClick={() => {
  381. startPage(PageList.supportContact);
  382. }}>
  383. <MaterialCommunityIcons
  384. style={styles.icon}
  385. name="face-agent"
  386. color="#333"
  387. size={26}
  388. />
  389. <TextView style={styles.label}>{$t('drawer.contactSupport')}</TextView>
  390. </Button>
  391. }
  392. <Button
  393. style={styles.itemButton}
  394. viewStyle={styles.itemView}
  395. onClick={() => {
  396. startPage(PageList.about);
  397. }}>
  398. <MaterialCommunityIcons
  399. style={styles.icon}
  400. name="information-outline"
  401. color="#333"
  402. size={26}
  403. />
  404. <TextView style={styles.label}>{$t('drawer.about')}</TextView>
  405. </Button>
  406. {/* <View style={styles.divided}></View> */}
  407. { DEBUG &&
  408. <>
  409. <View style={styles.divideLogin}></View>
  410. <TextView style={{color: "#ccc", paddingLeft: 16, paddingBottom: 8, fontSize: 12}}>{$t('drawer.debugOnly')}</TextView>
  411. <Button
  412. style={styles.itemButton}
  413. viewStyle={styles.itemView}
  414. onClick={() => {
  415. startPage(PageList.privacy);
  416. }}>
  417. <MaterialCommunityIcons
  418. style={styles.icon}
  419. name="file-eye-outline"
  420. color="#222"
  421. size={26}/>
  422. <TextView style={styles.label}>{$t('drawer.privacyPolicy')}</TextView>
  423. </Button>
  424. <Button
  425. style={styles.itemButton}
  426. viewStyle={styles.itemView}
  427. onClick={() => {
  428. startPage(PageList.condition);
  429. }}>
  430. <MaterialCommunityIcons
  431. style={styles.icon}
  432. name="file-eye-outline"
  433. color="#222"
  434. size={26}/>
  435. <TextView style={styles.label}>{$t('drawer.termsOfUse')}</TextView>
  436. </Button>
  437. <Button
  438. style={styles.itemButton}
  439. viewStyle={styles.itemView}
  440. onClick={() => {
  441. startPage(PageList.notify);
  442. }}>
  443. {/* <Image
  444. style={styles.icon2}
  445. source={require('../../images/icon/draw-terms.png')}/> */}
  446. <MaterialIcons
  447. style={styles.icon}
  448. name="notifications-none"
  449. color="#222"
  450. size={26}/>
  451. <TextView style={styles.label}>{$t('route.notificationTest')}</TextView>
  452. </Button>
  453. <Button
  454. style={styles.itemButton}
  455. viewStyle={styles.itemView}
  456. onClick={() => {
  457. startPage(isIOS ? PageList.notify : PageList.mapTest);
  458. }}>
  459. <MaterialCommunityIcons
  460. style={styles.icon}
  461. name="map-legend"
  462. color="#222"
  463. size={26}/>
  464. <TextView style={styles.label}>{$t('drawer.mapsTest')}</TextView>
  465. </Button>
  466. </>}
  467. {/* isLogin
  468. ? <View style={styles.walletView}>
  469. <Pressable
  470. style={styles.balanceView}
  471. android_ripple={ripple}
  472. onPress={() => toTopupPage()}>
  473. <Image
  474. style={styles.icon}
  475. source={require('../../images/icon/draw-wallet.png')}/>
  476. <Text style={styles.balanceText}>{currency}{userInfo.credit}</Text>
  477. </Pressable>
  478. {/* <Pressable
  479. style={styles.balanceView}
  480. android_ripple={ripple}
  481. onPress={() => {
  482. startPage(PageList.referral);
  483. }}>
  484. <Image
  485. style={styles.icon}
  486. source={require('../../images/icon/draw-gift.png')}/>
  487. <Text style={styles.referText}>Refer your friends to get $5 credit!</Text>
  488. </Pressable> *}
  489. </View>
  490. : <View style={ui.flex1}></View>s
  491. */}
  492. <View style={styles.bottomView}>
  493. <Image
  494. style={Styles.logo}
  495. resizeMode='contain'
  496. source={require('../../images/drawer-logo.png')}
  497. />
  498. <Text style={styles.versionText}>{app.displayName + ' ' + app.versionName}</Text>
  499. </View>
  500. {/* isLogin &&
  501. <Button
  502. style={styles.logoutView}
  503. text='Logout'
  504. textColor={textButton}
  505. borderRadius={0}
  506. onClick={() => logout()}/>
  507. */}
  508. </View>
  509. );
  510. }
  511. const styles = StyleSheet.create({
  512. drawerTop: {
  513. top: 0,
  514. left: 0,
  515. right: 0,
  516. height: statusHeight,
  517. position: 'absolute',
  518. fontSize: 10,
  519. backgroundColor: pageBackground
  520. },
  521. drawerView: {
  522. paddingTop: 16,
  523. paddingBottom: 8,
  524. minHeight: $vhs(101)
  525. },
  526. guessView: {
  527. padding: 16
  528. },
  529. loginView: {
  530. paddingTop: 16,
  531. paddingBottom: 4
  532. },
  533. avatar: {
  534. width: 66,
  535. height: 66,
  536. marginLeft: 24,
  537. borderWidth: 2,
  538. borderRadius: 80,
  539. borderColor: colorLight,
  540. },
  541. nickView: {
  542. marginTop: 6,
  543. borderRadius: 0,
  544. backgroundColor: colorLight
  545. },
  546. nickViewStyle: {
  547. flex: 1,
  548. alignItems: 'center',
  549. flexDirection: 'row',
  550. ...$padding(12, 24, 12, 16),
  551. },
  552. nickname: {
  553. flex: 1,
  554. color: textPrimary,
  555. fontSize: 20,
  556. fontWeight: 'bold',
  557. paddingLeft: 16,
  558. },
  559. divideLogin: {
  560. height: 1,
  561. marginTop: 4,
  562. marginRight: 22,
  563. marginBottom: 12,
  564. backgroundColor: '#E5E5E5'
  565. },
  566. itemButton: {
  567. borderRadius: 0,
  568. backgroundColor: colorLight
  569. },
  570. itemView: {
  571. flex: 1,
  572. height: 56,
  573. paddingLeft: 16,
  574. marginBottom: 6,
  575. alignItems: 'center',
  576. flexDirection: 'row'
  577. },
  578. disableItem: {
  579. height: 56,
  580. paddingLeft: 16,
  581. marginBottom: 6,
  582. alignItems: 'center',
  583. flexDirection: 'row'
  584. },
  585. icon: {
  586. width: 26,
  587. height: 26,
  588. marginRight: 16
  589. },
  590. icon2: {
  591. width: 24,
  592. height: 24,
  593. marginLeft: 1,
  594. marginRight: 17
  595. },
  596. label: {
  597. flex: 1,
  598. color: textPrimary,
  599. fontSize: 16,
  600. },
  601. disable: {
  602. color: '#999',
  603. fontSize: 18
  604. },
  605. divided: {
  606. height: 1,
  607. marginTop: 24,
  608. marginLeft: 16,
  609. backgroundColor: colorAccent
  610. },
  611. walletView: {
  612. paddingTop: 16,
  613. paddingLeft: 48,
  614. paddingRight: 48
  615. },
  616. balanceView: {
  617. marginTop: 16,
  618. borderRadius: 8,
  619. ...$padding(13, 22),
  620. alignItems: 'center',
  621. flexDirection: 'row',
  622. justifyContent: 'center',
  623. backgroundColor: 'rgba(0, 20, 137, 0.2)'
  624. },
  625. balanceText: {
  626. color: textPrimary,
  627. fontSize: 22,
  628. fontWeight: 'bold'
  629. },
  630. referText: {
  631. flex: 1,
  632. color: textPrimary,
  633. fontSize: 13
  634. },
  635. bottomView: {
  636. flex: 1,
  637. paddingTop: 48,
  638. paddingBottom: 0,
  639. alignItems: 'center',
  640. justifyContent: 'flex-end'
  641. },
  642. versionText: {
  643. color: textPrimary,
  644. fontSize: 10,
  645. paddingTop: 16
  646. },
  647. logoutView: {
  648. backgroundColor: colorPrimary
  649. },
  650. balanceText2: {
  651. color: textCancel,
  652. fontSize: 14,
  653. marginRight: 20
  654. },
  655. bridgeText: {
  656. width: 20,
  657. height: 20,
  658. color: textLight,
  659. fontSize: 12,
  660. marginRight: 16,
  661. borderRadius: 30,
  662. fontWeight: 'bold',
  663. alignItems: 'center',
  664. flexDirection: 'row',
  665. justifyContent: 'center',
  666. backgroundColor: "#FF3B30"
  667. },
  668. bridgeText2: {
  669. width: 22,
  670. height: 22,
  671. color: textLight,
  672. fontSize: 10,
  673. marginRight: 16,
  674. borderRadius: 30,
  675. fontWeight: 'bold',
  676. alignItems: 'center',
  677. flexDirection: 'row',
  678. justifyContent: 'center',
  679. backgroundColor: "#FF3B30"
  680. }
  681. });