Router.js 12 KB

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