Router.js 12 KB

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