Router.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /**
  2. * 路由配置文件
  3. * @邠心vbe on 2021/03/22
  4. */
  5. import React, { useEffect, useRef } from 'react';
  6. import { Pressable } from 'react-native';
  7. import { NavigationContainer } from '@react-navigation/native';
  8. import { createStackNavigator, TransitionPresets } from '@react-navigation/stack';
  9. import { enableScreens } from 'react-native-screens';
  10. import { BackButton, Styles } from '../components/Toolbar';
  11. import app from '../../app.json';
  12. import About from './about/AboutV2';
  13. import Launcher from './Launch';
  14. import Login from './sign/Login';
  15. import Regist from './sign/RegisterV2';
  16. import RegisterV3 from './sign/RegisterV3';
  17. import RegisterV4 from './sign/RegisterV4';
  18. import RegisterPublic from './sign/RegisterPublic';
  19. import RegisterDriver from './sign/RegisterDriver';
  20. import Home from './home/Index';
  21. import Search from './search/SearchV2';
  22. import ChargeDetails from './charge/Details';
  23. import QRScan from './charge/QRScan';
  24. import Feedback from './my/Feedback';
  25. import Privacy from './my/Privacy';
  26. import Profile from './my/ProfileV2';
  27. import Condition from './my/Condition';
  28. import Summary from './chargeV2/SummaryV2';
  29. import SummaryV3 from './chargeV2/SummaryV3';
  30. import Rating from './charge/Rating';
  31. import Wallet from './wallet/Wallet';
  32. import EditProfile from './my/EditProfile';
  33. import Referral from './my/Referral';
  34. import Topup from './wallet/Topup'; //not 2C2P
  35. import TopupV2 from './wallet/TopupV2'; //2C2P payment
  36. import TopupNew from './wallet/TopupNew';
  37. import AddCard from './wallet/AddCard';
  38. import FormCard from './payment/FormCard';
  39. import VehicleList from './vehicles/VehicleList';
  40. import AddVehicle from './vehicles/AddVehicle';
  41. import EditVehicle from './vehicles/EditVehicle';
  42. import VehicleDetail from './vehicles/VehicleDetail';
  43. import PayNow from './payment/PayNow';
  44. import CreditCard from './payment/CreditCard';
  45. import EditAddress from './my/EditAddress';
  46. import Notify from './home/Notify';
  47. import Test from './home/maps/Test';
  48. import ResetPassword from './sign/ResetPasswordV2';
  49. import PaymentMethod from './payment/PaymentMethod';
  50. import PayPerUse from './payment/PayPerUse';
  51. import PaymentWeb from './payment/PaymentWeb';
  52. import Settings from './Settings';
  53. import ChargeAdapter from './chargeV2/ChargeAdapter';
  54. import ChargingPage from './chargingV2/ChargingPage';
  55. import ChargingPageV4 from './chargingV3/ChargingPage';
  56. import { BridgePage } from '../utils/routeUtil';
  57. import HeaderTitle from '../components/HeaderTitle';
  58. import Bookmarks from './bookmark/Bookmarks';
  59. import MembersList from './member/MembersList';
  60. import ApplyMember from './member/ApplyMember';
  61. import Contact from './about/Contact';
  62. import Notification from './alert/Notification';
  63. import ViewAlerts from './alert/ViewAlerts';
  64. import ViewCampaign from './alert/ViewCampaign';
  65. import RefundPolicy from './payment/RefundPolicy';
  66. import ViewArticle from './alert/ViewArticle';
  67. import VehicleListV2 from './vehicles/VehicleListV2';
  68. import HistoryList from './wallet/HistoryList';
  69. import VoucherPage from './vouchers/VoucherPage';
  70. import VoucherSelect from './vouchers/VoucherSelect';
  71. export var PageList = {
  72. 'splash': {
  73. component: Launcher
  74. },
  75. 'home': {
  76. component: Home,
  77. options: TransitionPresets.FadeFromBottomAndroid
  78. },
  79. 'bridge': {
  80. component: BridgePage
  81. },
  82. 'search': {
  83. title: 'Search',
  84. titleScope: 'route.search',
  85. component: Search
  86. },
  87. 'login': {
  88. component: Login
  89. },
  90. 'register': {
  91. component: RegisterV4,
  92. title: 'Public Registration',
  93. titleScope: 'route.publicRegister'
  94. },
  95. 'registerPublic': {
  96. component: RegisterPublic,
  97. title: 'Public Registration',
  98. titleScope: 'route.publicRegister'
  99. },
  100. 'registerFleet': {
  101. component: RegisterDriver,
  102. title: 'Fleet / PHV Registration',
  103. titleScope: 'route.driverRegister'
  104. },
  105. 'chargeDetail': {
  106. title: 'Charging Site',
  107. titleScope: 'route.chargingSite',
  108. component: ChargeDetails
  109. },
  110. 'chargeDetailPage': {
  111. title: 'Charging Site',
  112. titleScope: 'route.chargingSite',
  113. component: ChargeAdapter
  114. },
  115. 'chargingPage': {
  116. title: 'Charging',
  117. titleScope: 'route.charging',
  118. component: ChargingPage
  119. },
  120. 'chargingPageV4': {
  121. title: 'Charging',
  122. titleScope: 'route.charging',
  123. component: ChargingPageV4
  124. },
  125. 'scanqr': {
  126. title: 'QR Scan',
  127. titleScope: 'route.qrScan',
  128. component: QRScan
  129. },
  130. 'feedback': {
  131. title: 'Feedback',
  132. titleScope: 'route.feedback',
  133. component: Feedback
  134. },
  135. 'about': {
  136. title: 'About',
  137. titleScope: 'route.about',
  138. component: About
  139. },
  140. 'supportContact': {
  141. title: 'Support Hotline',
  142. titleScope: 'support.supportHotline',
  143. component: Contact
  144. },
  145. 'privacy': {
  146. title: 'Privacy Policy',
  147. titleScope: 'route.privacyPolicy',
  148. component: Privacy
  149. },
  150. 'condition': {
  151. title: 'Terms of Use',
  152. titleScope: 'route.termsOfUse',
  153. component: Condition
  154. },
  155. 'profile': {
  156. title: 'Profile Settings',
  157. titleScope: 'route.profileSettings',
  158. component: Profile
  159. },
  160. 'summary': {
  161. title: 'Summary',
  162. titleScope: 'receipt.receipt',
  163. component: app.charge.newSummary ? SummaryV3 : Summary
  164. },
  165. 'rating': {
  166. title: 'Your Rating',
  167. titleScope: 'route.rating',
  168. component: Rating
  169. },
  170. 'wallet': {
  171. title: 'Transactions',
  172. titleScope: 'route.wallet',
  173. component: Wallet
  174. },
  175. 'history': {
  176. title: 'History',
  177. titleScope: 'route.history',
  178. component: HistoryList
  179. },
  180. 'editProfile': {
  181. title: 'My Profile',
  182. titleScope: 'route.editProfile',
  183. component: EditProfile
  184. },
  185. 'editAddress': {
  186. title: 'Edit Address',
  187. titleScope: 'route.editAddress',
  188. component: EditAddress
  189. },
  190. 'referral': {
  191. title: 'Referral',
  192. titleScope: 'route.referral',
  193. component: Referral
  194. },
  195. 'topup': {
  196. title: 'Top Up',
  197. titleScope: 'route.topUp',
  198. component: Topup
  199. },
  200. 'topupV2': {
  201. title: 'Top Up',
  202. titleScope: 'route.topUp',
  203. component: TopupV2
  204. },
  205. 'topupNew': {
  206. title: 'Top Up',
  207. titleScope: 'route.topUp',
  208. component: TopupNew
  209. },
  210. 'addCard': {
  211. title: 'Add Cards',
  212. titleScope: 'route.addCards',
  213. component: AddCard
  214. },
  215. 'myVehicles': {
  216. title: 'My Vehicles',
  217. titleScope: 'route.myVehicles',
  218. component: VehicleList,
  219. options: {
  220. headerRight: () => (
  221. <Pressable
  222. style={Styles.backIcon}
  223. android_ripple={rippleLessIcon}
  224. onPress={() => startPage(PageList.addVehicle)}>
  225. <MaterialCommunityIcons
  226. name='plus'
  227. color={pageTitleTint}
  228. size={24}
  229. style={Styles.iconOpacity}
  230. />
  231. </Pressable>
  232. )
  233. }
  234. },
  235. 'vehiclesListV2': {
  236. title: 'My Vehicles',
  237. titleScope: 'route.myVehicles',
  238. component: VehicleListV2
  239. },
  240. 'addVehicle': {
  241. title: 'Add Vehicle',
  242. titleScope: 'route.addVehicle',
  243. component: AddVehicle
  244. },
  245. 'editVehicle': {
  246. title: 'Update Vehicle',
  247. titleScope: 'route.editVehicle',
  248. component: EditVehicle
  249. },
  250. 'addVehicleV2': {
  251. title: 'Add Vehicle',
  252. titleScope: 'route.addVehicle',
  253. component: VehicleDetail
  254. },
  255. 'editVehicleV2': {
  256. title: 'Update Detail',
  257. titleScope: 'route.editVehicle',
  258. component: VehicleDetail
  259. },
  260. 'paynow': {
  261. title: 'PAYNOW',
  262. titleScope: 'route.paynow',
  263. component: PayNow
  264. },
  265. 'paycard': {
  266. title: 'Top Up with Card',
  267. titleScope: 'route.topUpWithCard',
  268. component: CreditCard
  269. },
  270. 'formCard': {
  271. title: 'Top Up with Card',
  272. titleScope: 'route.topUpWithCard',
  273. component: FormCard
  274. },
  275. 'paymentMethod': {
  276. title: 'Payment Method',
  277. titleScope: 'route.paymentMethod',
  278. component: PaymentMethod
  279. },
  280. 'paymentWeb': {
  281. title: 'Make Payment',
  282. titleScope: 'route.makePayment',
  283. component: PaymentWeb
  284. },
  285. 'payPeruse': {
  286. title: 'Pay Per Use',
  287. titleScope: 'route.payPerUse',
  288. component: PayPerUse
  289. },
  290. 'notification': {
  291. title: 'Notification',
  292. titleScope: 'route.notifications',
  293. component: Notification
  294. },
  295. 'viewMessage': {
  296. title: 'View Message',
  297. titleScope: 'notification.viewMessage',
  298. component: ViewAlerts
  299. },
  300. 'viewArticle': {
  301. title: 'View Article',
  302. titleScope: 'notification.viewMessage',
  303. component: ViewArticle
  304. },
  305. 'viewCampaign': {
  306. title: 'View Campaign',
  307. titleScope: 'notification.viewMessage',
  308. component: ViewCampaign
  309. },
  310. 'notify': {
  311. title: 'Notification Test',
  312. titleScope: 'route.notificationTest',
  313. component: Notify
  314. },
  315. 'mapTest': {
  316. component: Test
  317. },
  318. 'forgotPassword': {
  319. title: 'Forgot Password',
  320. titleScope: 'route.forgotPassword',
  321. component: ResetPassword
  322. },
  323. 'changePassword': {
  324. title: 'Account Security',
  325. titleScope: 'route.changePassword',
  326. component: ResetPassword
  327. },
  328. 'bookmarks': {
  329. title: "Bookmarks",
  330. titleScope: 'route.bookmarks',
  331. component: Bookmarks
  332. },
  333. 'membersList': {
  334. title: "Your Membership",
  335. titleScope: 'route.yourMembers',
  336. component: MembersList,
  337. options: {
  338. headerRight: () => (
  339. <Pressable
  340. style={Styles.backIcon}
  341. android_ripple={rippleLessIcon}
  342. onPress={() => startPage(PageList.applyMember)}>
  343. <MaterialCommunityIcons
  344. name='plus'
  345. color={pageTitleTint}
  346. size={24}
  347. style={Styles.iconOpacity}
  348. />
  349. </Pressable>
  350. )
  351. }
  352. },
  353. 'applyMember': {
  354. title: "Apply Membership",
  355. titleScope: 'route.applyMember',
  356. component: ApplyMember
  357. },
  358. 'refundPolicy': {
  359. title: "Refund Policy",
  360. titleScope: 'route.refundPolicy',
  361. component: RefundPolicy
  362. },
  363. 'myVoucher': {
  364. title: "Vouchers",
  365. titleScope: 'route.vouchers',
  366. component: VoucherPage
  367. },
  368. 'selectVoucher': {
  369. title: "Vouchers",
  370. titleScope: 'route.vouchers',
  371. component: VoucherSelect
  372. },
  373. 'settings': {
  374. title: 'Settings',
  375. titleScope: 'route.settings',
  376. component: Settings
  377. }
  378. }
  379. const Stack = createStackNavigator();
  380. enableScreens();
  381. /**
  382. * 配置APP主题色
  383. */
  384. const themeColor = {
  385. text: textPrimary,
  386. card: colorThemes,
  387. primary: colorPrimary,
  388. background: pageBackground,
  389. notification: colorDark
  390. }
  391. const noTitle = (opt = {}) => {
  392. return {
  393. title: isIOS ? 'Back' : app.displayName,
  394. headerShown: false,
  395. ...opt
  396. }
  397. }
  398. /**
  399. * 配置标题
  400. * @param {String} title 页面标题
  401. * @param {Object} opt 标题栏选项
  402. * @returns
  403. */
  404. const Title = (title, opt = {}, titleScope) => {
  405. const options = {
  406. headerShown: true,
  407. headerStyle: {
  408. ...titleHeight(),
  409. elevation: 0,
  410. shadowOpacity: 0,
  411. borderBottomWidth: 0,
  412. backgroundColor: app.isWhitelabel ? colorLight : colorPrimary //配置标题栏背景
  413. },
  414. headerTintColor: pageTitleTint, //配置标题栏文字和图标颜色
  415. headerBackTitle: ' ', //配置iOS返回按钮文字
  416. headerBackTitleVisible: false,
  417. ...opt
  418. }
  419. if (titleScope && $t) {
  420. options.headerTitle = () => <HeaderTitle scope={titleScope}/>
  421. } else {
  422. options.title = title
  423. }
  424. options.headerLeft = () => <BackButton/>
  425. return options;
  426. }
  427. var bakPages = undefined;
  428. function getPages() {
  429. let pages = [], keys = {};
  430. if (bakPages == undefined) {
  431. bakPages = Object.assign({}, PageList);
  432. } else {
  433. PageList = bakPages;
  434. }
  435. for (const page in bakPages) {
  436. var p = bakPages[page]
  437. keys[page] = page;
  438. pages.push(
  439. <Stack.Screen
  440. key={page}
  441. name={page}
  442. component={p.component}
  443. options={p.title ? Title(p.title, p.options, p.titleScope) : noTitle(p.options)}
  444. />
  445. );
  446. }
  447. PageList = keys;
  448. return pages;
  449. }
  450. const Router = () => {
  451. const navigation = useRef();
  452. useEffect(() => {
  453. //注入全局方法
  454. global.startPage = (name, params = {}) => {
  455. navigation.current?.navigate(name, params);
  456. }
  457. global.dispatchPage = (params) => {
  458. navigation.current?.dispatch(params);
  459. }
  460. global.goBack = () => {
  461. if (global.pageBackFallback && global.pageBackFallback.names) {
  462. //console.log("覆盖返回", navigation.current.getCurrentRoute()?.name);
  463. if (global.pageBackFallback.names.indexOf(navigation.current.getCurrentRoute()?.name) >= 0) {
  464. global.pageBackFallback?.callback();
  465. global.pageBackFallback = undefined;
  466. return;
  467. }
  468. }
  469. if (navigation.current?.canGoBack()) {
  470. navigation.current?.goBack();
  471. } else {
  472. startPage(PageList.home);
  473. }
  474. }
  475. return (() => {
  476. global.startPage = null;
  477. global.goBack = null;
  478. });
  479. }, []);
  480. return (
  481. <NavigationContainer
  482. ref={navigation}
  483. theme={{
  484. dark: darkMode,
  485. colors: themeColor
  486. }}>
  487. <Stack.Navigator
  488. initialRouteName='splash'
  489. screenOptions={{animationEnabled: true, ...TransitionPresets.SlideFromRightIOS }}>
  490. {getPages()}
  491. </Stack.Navigator>
  492. </NavigationContainer>
  493. )
  494. }
  495. const titleHeight = () => {
  496. return isIOS ? {} : {height: toolbarSize};
  497. }
  498. export default Router;