Drawer.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  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. <Pressable
  201. style={styles.nickView}
  202. android_ripple={ripple}
  203. onPress={() => 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. </Pressable>
  220. </View>
  221. <View style={styles.divideLogin}></View>
  222. {/* isLogin
  223. ? <Button
  224. style={styles.itemButton}
  225. viewStyle={styles.itemView}
  226. onClick={() => {
  227. startPage(PageList.profile)
  228. }}>
  229. <Image
  230. style={styles.icon}
  231. source={require('../../images/icon/draw-user.png')}/>
  232. <Text style={styles.label}>Profile Settings</Text>
  233. </Button>
  234. : <Button
  235. style={styles.itemButton}
  236. viewStyle={styles.itemView}
  237. onClick={() => {
  238. startPage(PageList.login);
  239. }}>
  240. <Image
  241. style={styles.icon}
  242. source={require('../../images/icon/draw-user.png')}/>
  243. <Text style={styles.label}>Sign In</Text>
  244. </Button>
  245. */}
  246. {/* <Button
  247. style={styles.itemButton}
  248. viewStyle={styles.itemView}
  249. onClick={() => {
  250. navigation.toggleDrawer();
  251. }}>
  252. <Image
  253. style={styles.icon}
  254. source={require('../../images/icon/draw-home.png')}/>
  255. <Text style={styles.label}>Home</Text>
  256. </Button> */}
  257. { isLogin
  258. ? <Button
  259. style={styles.itemButton}
  260. viewStyle={styles.itemView}
  261. onClick={() => getCharging()}>
  262. <MaterialCommunityIcons
  263. style={styles.icon}
  264. name="car-electric-outline"
  265. color="#333"
  266. size={26}
  267. />
  268. {/* <Image
  269. style={styles.icon}
  270. source={require('../../images/icon/draw-charge.png')}/> */}
  271. <TextView style={styles.label}>{$t('drawer.charging')}</TextView>
  272. </Button>
  273. : <View
  274. style={styles.disableItem}>
  275. <MaterialCommunityIcons
  276. style={styles.icon}
  277. name="car-electric-outline"
  278. color="#999"
  279. size={26}
  280. />
  281. {/* <Image
  282. style={styles.icon}
  283. source={require('../../images/icon/draw-charge-no.png')}/> */}
  284. <TextView style={styles.disable}>{$t('drawer.charging')}</TextView>
  285. </View>
  286. }
  287. {/* isLogin
  288. ? <Button
  289. style={styles.itemButton}
  290. viewStyle={styles.itemView}
  291. onClick={() => {
  292. startPage(PageList.wallet);
  293. }}>
  294. <Image
  295. style={styles.icon}
  296. source={require('../../images/icon/draw-transaction.png')}/>
  297. <Text style={styles.label}>{$t('drawer.wallet')}</Text>
  298. </Button>
  299. : <View
  300. style={styles.disableItem}>
  301. <Image
  302. style={styles.icon}
  303. source={require('../../images/icon/draw-transaction-no.png')}/>
  304. <Text style={styles.disable}>{$t('drawer.wallet')}</Text>
  305. </View>
  306. */}
  307. {
  308. isLogin && <>
  309. <Button
  310. style={styles.itemButton}
  311. viewStyle={styles.itemView}
  312. onClick={() => {
  313. startPage(PageList.wallet);
  314. }}>
  315. <Image
  316. style={styles.icon}
  317. source={require('../../images/icon/draw-transaction.png')}/>
  318. <TextView style={styles.label}>{$t('drawer.wallet')}</TextView>
  319. </Button>
  320. <Button
  321. style={styles.itemButton}
  322. viewStyle={styles.itemView}
  323. onClick={() => toTopupPage()}>
  324. <MaterialCommunityIcons
  325. style={styles.icon}
  326. size={26}
  327. name={"wallet-outline"}
  328. color={colorDark}/>
  329. <TextView style={styles.label}>{$t('drawer.topup')}</TextView>
  330. <TextView style={styles.balanceText2}>{userInfo.creditStr}</TextView>
  331. </Button></>
  332. }
  333. {/*附加功能-开始*/}
  334. { (app.modules.notifications && isLogin) &&
  335. <Button
  336. style={styles.itemButton}
  337. viewStyle={styles.itemView}
  338. onClick={() => {
  339. startPage(PageList.notification);
  340. }}>
  341. <MaterialIcons
  342. style={styles.icon}
  343. name="notifications"
  344. color="#222"
  345. size={26}/>
  346. <TextView style={styles.label}>{$t('route.notifications')}</TextView>
  347. { notificationCount > 0 && (
  348. notificationCount < 100
  349. ? <Text style={styles.bridgeText} allowFontScaling={false}>{notificationCount}</Text>
  350. : <Text style={styles.bridgeText2} allowFontScaling={false}>99+</Text>)
  351. }
  352. </Button>
  353. }
  354. { (app.modules.bookmarks && isLogin) &&
  355. <Button
  356. style={styles.itemButton}
  357. viewStyle={styles.itemView}
  358. onClick={() => {
  359. startPage(PageList.bookmarks);
  360. }}>
  361. <MaterialIcons
  362. style={styles.icon}
  363. name="stars"
  364. color="#222"
  365. size={26}/>
  366. <TextView style={styles.label}>{$t('route.bookmarks')}</TextView>
  367. </Button>
  368. }
  369. {/*附加功能-结束*/}
  370. { isLogin &&
  371. <Button
  372. style={styles.itemButton}
  373. viewStyle={styles.itemView}
  374. onClick={() => {
  375. startPage(PageList.membersList);
  376. }}>
  377. <MaterialIcons
  378. style={styles.icon}
  379. name="card-membership"
  380. color="#222"
  381. size={26}/>
  382. <TextView style={styles.label}>{$t('drawer.members')}</TextView>
  383. </Button>
  384. }
  385. <Button
  386. style={styles.itemButton}
  387. viewStyle={styles.itemView}
  388. onClick={() => {
  389. startPage(PageList.feedback);
  390. }}>
  391. <MaterialCommunityIcons
  392. style={styles.icon2}
  393. name="message-alert-outline"
  394. color="#222"
  395. size={24}/>
  396. <TextView style={styles.label}>{$t('drawer.feedback')}</TextView>
  397. </Button>
  398. {/* <Button
  399. style={styles.itemButton}
  400. viewStyle={styles.itemView}
  401. onClick={() => {
  402. Linking.openURL(host+"juicePicture/pdf/FAQ.v1.0.pdf")
  403. }}>
  404. <Feather
  405. style={styles.icon2}
  406. name="download"
  407. color={colorDark}
  408. size={24}
  409. />
  410. <Text style={styles.label}>FAQs</Text>
  411. </Button> */}
  412. <Button
  413. style={styles.itemButton}
  414. viewStyle={styles.itemView}
  415. onClick={() => {
  416. startPage(PageList.settings);
  417. }}>
  418. <MaterialIcons
  419. style={styles.icon}
  420. name="settings"
  421. color="#222"
  422. size={25}
  423. />
  424. <TextView style={styles.label}>{$t('drawer.settings')}</TextView>
  425. </Button>
  426. { app.modules.support &&
  427. <Button
  428. style={styles.itemButton}
  429. viewStyle={styles.itemView}
  430. onClick={() => {
  431. startPage(PageList.supportContact);
  432. }}>
  433. <MaterialCommunityIcons
  434. style={styles.icon}
  435. name="face-agent"
  436. color="#333"
  437. size={26}
  438. />
  439. <TextView style={styles.label}>{$t('drawer.contactSupport')}</TextView>
  440. </Button>
  441. }
  442. <Button
  443. style={styles.itemButton}
  444. viewStyle={styles.itemView}
  445. onClick={() => {
  446. startPage(PageList.about);
  447. }}>
  448. <MaterialCommunityIcons
  449. style={styles.icon}
  450. name="information-outline"
  451. color="#333"
  452. size={26}
  453. />
  454. <TextView style={styles.label}>{$t('drawer.about')}</TextView>
  455. </Button>
  456. {/* <View style={styles.divided}></View> */}
  457. { DEBUG &&
  458. <>
  459. <View style={styles.divideLogin}></View>
  460. <TextView style={{color: "#ccc", paddingLeft: 16, paddingBottom: 8, fontSize: 12}}>{$t('drawer.debugOnly')}</TextView>
  461. <Button
  462. style={styles.itemButton}
  463. viewStyle={styles.itemView}
  464. onClick={() => {
  465. startPage(PageList.privacy);
  466. }}>
  467. <MaterialCommunityIcons
  468. style={styles.icon}
  469. name="file-eye-outline"
  470. color="#222"
  471. size={26}/>
  472. <TextView style={styles.label}>{$t('drawer.privacyPolicy')}</TextView>
  473. </Button>
  474. <Button
  475. style={styles.itemButton}
  476. viewStyle={styles.itemView}
  477. onClick={() => {
  478. startPage(PageList.condition);
  479. }}>
  480. <MaterialCommunityIcons
  481. style={styles.icon}
  482. name="file-eye-outline"
  483. color="#222"
  484. size={26}/>
  485. <TextView style={styles.label}>{$t('drawer.termsOfUse')}</TextView>
  486. </Button>
  487. <Button
  488. style={styles.itemButton}
  489. viewStyle={styles.itemView}
  490. onClick={() => {
  491. startPage(PageList.notify);
  492. }}>
  493. {/* <Image
  494. style={styles.icon2}
  495. source={require('../../images/icon/draw-terms.png')}/> */}
  496. <MaterialIcons
  497. style={styles.icon}
  498. name="notifications-none"
  499. color="#222"
  500. size={26}/>
  501. <TextView style={styles.label}>{$t('route.notificationTest')}</TextView>
  502. </Button>
  503. <Button
  504. style={styles.itemButton}
  505. viewStyle={styles.itemView}
  506. onClick={() => {
  507. startPage(isIOS ? PageList.notify : PageList.mapTest);
  508. }}>
  509. <MaterialCommunityIcons
  510. style={styles.icon}
  511. name="map-legend"
  512. color="#222"
  513. size={26}/>
  514. <TextView style={styles.label}>{$t('drawer.mapsTest')}</TextView>
  515. </Button>
  516. </>}
  517. {/* isLogin
  518. ? <View style={styles.walletView}>
  519. <Pressable
  520. style={styles.balanceView}
  521. android_ripple={ripple}
  522. onPress={() => toTopupPage()}>
  523. <Image
  524. style={styles.icon}
  525. source={require('../../images/icon/draw-wallet.png')}/>
  526. <Text style={styles.balanceText}>{currency}{userInfo.credit}</Text>
  527. </Pressable>
  528. {/* <Pressable
  529. style={styles.balanceView}
  530. android_ripple={ripple}
  531. onPress={() => {
  532. startPage(PageList.referral);
  533. }}>
  534. <Image
  535. style={styles.icon}
  536. source={require('../../images/icon/draw-gift.png')}/>
  537. <Text style={styles.referText}>Refer your friends to get $5 credit!</Text>
  538. </Pressable> *}
  539. </View>
  540. : <View style={ui.flex1}></View>s
  541. */}
  542. <View style={styles.bottomView}>
  543. <Image
  544. style={Styles.logo}
  545. resizeMode='contain'
  546. source={require('../../images/drawer-logo.png')}
  547. />
  548. <Text style={styles.versionText}>{app.displayName + ' ' + app.versionName}</Text>
  549. </View>
  550. {/* isLogin &&
  551. <Button
  552. style={styles.logoutView}
  553. text='Logout'
  554. textColor={textButton}
  555. borderRadius={0}
  556. onClick={() => logout()}/>
  557. */}
  558. </View>
  559. );
  560. }
  561. const styles = StyleSheet.create({
  562. drawerTop: {
  563. top: 0,
  564. left: 0,
  565. right: 0,
  566. height: statusHeight,
  567. position: 'absolute',
  568. fontSize: 10,
  569. backgroundColor: pageBackground
  570. },
  571. drawerView: {
  572. paddingTop: 16,
  573. paddingBottom: 8,
  574. minHeight: $vhs(101)
  575. },
  576. guessView: {
  577. padding: 16
  578. },
  579. loginView: {
  580. paddingTop: 16,
  581. paddingBottom: 8
  582. },
  583. avatar: {
  584. width: 66,
  585. height: 66,
  586. marginLeft: 24,
  587. borderWidth: 2,
  588. borderRadius: 80,
  589. borderColor: colorLight,
  590. },
  591. nickView: {
  592. marginTop: 4,
  593. flexDirection: 'row',
  594. ...$padding(12, 16)
  595. },
  596. nickname: {
  597. flex: 1,
  598. color: textPrimary,
  599. fontSize: 20,
  600. fontWeight: 'bold',
  601. paddingLeft: 16,
  602. },
  603. divideLogin: {
  604. height: 1,
  605. marginTop: 4,
  606. marginRight: 32,
  607. marginBottom: 12,
  608. backgroundColor: '#E5E5E5'
  609. },
  610. itemButton: {
  611. borderRadius: 0,
  612. backgroundColor: colorLight
  613. },
  614. itemView: {
  615. flex: 1,
  616. height: 56,
  617. paddingLeft: 16,
  618. marginBottom: 6,
  619. alignItems: 'center',
  620. flexDirection: 'row'
  621. },
  622. disableItem: {
  623. height: 56,
  624. paddingLeft: 16,
  625. marginBottom: 6,
  626. alignItems: 'center',
  627. flexDirection: 'row'
  628. },
  629. icon: {
  630. width: 26,
  631. height: 26,
  632. marginRight: 16
  633. },
  634. icon2: {
  635. width: 24,
  636. height: 24,
  637. marginLeft: 1,
  638. marginRight: 17
  639. },
  640. label: {
  641. flex: 1,
  642. color: textPrimary,
  643. fontSize: 16,
  644. },
  645. disable: {
  646. color: '#999',
  647. fontSize: 18
  648. },
  649. divided: {
  650. height: 1,
  651. marginTop: 24,
  652. marginLeft: 16,
  653. backgroundColor: colorAccent
  654. },
  655. walletView: {
  656. paddingTop: 16,
  657. paddingLeft: 48,
  658. paddingRight: 48
  659. },
  660. balanceView: {
  661. marginTop: 16,
  662. borderRadius: 8,
  663. ...$padding(13, 22),
  664. alignItems: 'center',
  665. flexDirection: 'row',
  666. justifyContent: 'center',
  667. backgroundColor: 'rgba(0, 20, 137, 0.2)'
  668. },
  669. balanceText: {
  670. color: textPrimary,
  671. fontSize: 22,
  672. fontWeight: 'bold'
  673. },
  674. referText: {
  675. flex: 1,
  676. color: textPrimary,
  677. fontSize: 13
  678. },
  679. bottomView: {
  680. flex: 1,
  681. paddingTop: 48,
  682. paddingBottom: 0,
  683. alignItems: 'center',
  684. justifyContent: 'flex-end'
  685. },
  686. versionText: {
  687. color: textPrimary,
  688. fontSize: 10,
  689. paddingTop: 16
  690. },
  691. logoutView: {
  692. backgroundColor: colorPrimary
  693. },
  694. balanceText2: {
  695. color: textCancel,
  696. fontSize: 14,
  697. marginRight: 32
  698. },
  699. bridgeText: {
  700. width: 20,
  701. height: 20,
  702. color: textLight,
  703. fontSize: 12,
  704. lineHeight: 19,
  705. marginRight: 16,
  706. borderRadius: 20,
  707. fontWeight: 'bold',
  708. textAlign: 'center',
  709. backgroundColor: "#FF3B30"
  710. },
  711. bridgeText2: {
  712. width: 22,
  713. height: 22,
  714. color: textLight,
  715. fontSize: 10,
  716. lineHeight: 22,
  717. marginRight: 16,
  718. borderRadius: 22,
  719. fontWeight: 'bold',
  720. textAlign: 'center',
  721. backgroundColor: "#FF3B30"
  722. }
  723. });