Router.js 10 KB

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