react-native-navigation的迁移库

platformSpecificDeprecated.ios.js 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. import Navigation from './../Navigation';
  2. import Controllers, {Modal, Notification} from 'react-native-controllers';
  3. const React = Controllers.hijackReact();
  4. const {
  5. ControllerRegistry,
  6. TabBarControllerIOS,
  7. NavigationControllerIOS,
  8. DrawerControllerIOS
  9. } = React;
  10. import _ from 'lodash';
  11. import PropRegistry from '../PropRegistry';
  12. function startTabBasedApp(params) {
  13. if (!params.tabs) {
  14. console.error('startTabBasedApp(params): params.tabs is required');
  15. return;
  16. }
  17. params.tabs.map(function(tab, index) {
  18. const navigatorID = controllerID + '_nav' + index;
  19. const screenInstanceID = _.uniqueId('screenInstanceID');
  20. if (!tab.screen) {
  21. console.error('startTabBasedApp(params): every tab must include a screen property, take a look at tab#' + (index + 1));
  22. return;
  23. }
  24. const {
  25. navigatorStyle,
  26. navigatorButtons,
  27. navigatorEventID
  28. } = _mergeScreenSpecificSettings(tab.screen, screenInstanceID, tab);
  29. tab.navigationParams = {
  30. screenInstanceID,
  31. navigatorStyle,
  32. navigatorButtons,
  33. navigatorEventID,
  34. navigatorID
  35. };
  36. });
  37. const controllerID = _.uniqueId('controllerID');
  38. const Controller = Controllers.createClass({
  39. render: function() {
  40. if (!params.drawer || (!params.drawer.left && !params.drawer.right)) {
  41. return this.renderBody();
  42. } else {
  43. const navigatorID = controllerID + '_drawer';
  44. return (
  45. <DrawerControllerIOS id={navigatorID}
  46. componentLeft={params.drawer.left ? params.drawer.left.screen : undefined}
  47. passPropsLeft={{navigatorID: navigatorID}}
  48. componentRight={params.drawer.right ? params.drawer.right.screen : undefined}
  49. passPropsRight={{navigatorID: navigatorID}}
  50. disableOpenGesture={params.drawer.disableOpenGesture}
  51. type={params.drawer.type ? params.drawer.type : 'MMDrawer'}
  52. animationType={params.drawer.animationType ? params.drawer.animationType : 'slide'}
  53. >
  54. {this.renderBody()}
  55. </DrawerControllerIOS>
  56. );
  57. }
  58. },
  59. renderBody: function() {
  60. return (
  61. <TabBarControllerIOS
  62. id={controllerID + '_tabs'}
  63. style={params.tabsStyle}>
  64. {
  65. params.tabs.map(function(tab, index) {
  66. return (
  67. <TabBarControllerIOS.Item {...tab} title={tab.label}>
  68. <NavigationControllerIOS
  69. id={tab.navigationParams.navigatorID}
  70. title={tab.title}
  71. titleImage={tab.titleImage}
  72. component={tab.screen}
  73. passProps={{
  74. navigatorID: tab.navigationParams.navigatorID,
  75. screenInstanceID: tab.navigationParams.screenInstanceID,
  76. navigatorEventID: tab.navigationParams.navigatorEventID
  77. }}
  78. style={tab.navigationParams.navigatorStyle}
  79. leftButtons={tab.navigationParams.navigatorButtons.leftButtons}
  80. rightButtons={tab.navigationParams.navigatorButtons.rightButtons}
  81. />
  82. </TabBarControllerIOS.Item>
  83. );
  84. })
  85. }
  86. </TabBarControllerIOS>
  87. );
  88. }
  89. });
  90. savePassProps(params);
  91. ControllerRegistry.registerController(controllerID, () => Controller);
  92. ControllerRegistry.setRootController(controllerID, params.animationType, params.passProps || {});
  93. }
  94. function startSingleScreenApp(params) {
  95. if (!params.screen) {
  96. console.error('startSingleScreenApp(params): params.screen is required');
  97. return;
  98. }
  99. const controllerID = _.uniqueId('controllerID');
  100. const screen = params.screen;
  101. if (!screen.screen) {
  102. console.error('startSingleScreenApp(params): screen must include a screen property');
  103. return;
  104. }
  105. const navigatorID = controllerID + '_nav';
  106. const screenInstanceID = _.uniqueId('screenInstanceID');
  107. const {
  108. navigatorStyle,
  109. navigatorButtons,
  110. navigatorEventID
  111. } = _mergeScreenSpecificSettings(screen.screen, screenInstanceID, screen);
  112. params.navigationParams = {
  113. screenInstanceID,
  114. navigatorStyle,
  115. navigatorButtons,
  116. navigatorEventID,
  117. navigatorID
  118. };
  119. const Controller = Controllers.createClass({
  120. render: function() {
  121. if (!params.drawer || (!params.drawer.left && !params.drawer.right)) {
  122. return this.renderBody();
  123. } else {
  124. const navigatorID = controllerID + '_drawer';
  125. return (
  126. <DrawerControllerIOS id={navigatorID}
  127. componentLeft={params.drawer.left ? params.drawer.left.screen : undefined}
  128. passPropsLeft={{navigatorID: navigatorID}}
  129. componentRight={params.drawer.right ? params.drawer.right.screen : undefined}
  130. passPropsRight={{navigatorID: navigatorID}}
  131. disableOpenGesture={params.drawer.disableOpenGesture}
  132. type={params.drawer.type ? params.drawer.type : 'MMDrawer'}
  133. animationType={params.drawer.animationType ? params.drawer.animationType : 'slide'}
  134. >
  135. {this.renderBody()}
  136. </DrawerControllerIOS>
  137. );
  138. }
  139. },
  140. renderBody: function() {
  141. return (
  142. <NavigationControllerIOS
  143. id={navigatorID}
  144. title={screen.title}
  145. subtitle={params.subtitle}
  146. titleImage={screen.titleImage}
  147. component={screen.screen}
  148. passProps={{
  149. navigatorID: navigatorID,
  150. screenInstanceID: screenInstanceID,
  151. navigatorEventID: navigatorEventID
  152. }}
  153. style={navigatorStyle}
  154. leftButtons={navigatorButtons.leftButtons}
  155. rightButtons={navigatorButtons.rightButtons}
  156. />
  157. );
  158. }
  159. });
  160. savePassProps(params);
  161. ControllerRegistry.registerController(controllerID, () => Controller);
  162. ControllerRegistry.setRootController(controllerID, params.animationType, params.passProps || {});
  163. }
  164. function _mergeScreenSpecificSettings(screenID, screenInstanceID, params) {
  165. const screenClass = Navigation.getRegisteredScreen(screenID);
  166. if (!screenClass) {
  167. console.error('Cannot create screen ' + screenID + '. Are you it was registered with Navigation.registerScreen?');
  168. return;
  169. }
  170. const navigatorStyle = Object.assign({}, screenClass.navigatorStyle);
  171. if (params.navigatorStyle) {
  172. Object.assign(navigatorStyle, params.navigatorStyle);
  173. }
  174. const navigatorEventID = screenInstanceID + '_events';
  175. const navigatorButtons = Object.assign({}, screenClass.navigatorButtons);
  176. if (params.navigatorButtons) {
  177. Object.assign(navigatorButtons, params.navigatorButtons);
  178. }
  179. if (navigatorButtons.leftButtons) {
  180. for (let i = 0; i < navigatorButtons.leftButtons.length; i++) {
  181. navigatorButtons.leftButtons[i].onPress = navigatorEventID;
  182. }
  183. }
  184. if (navigatorButtons.rightButtons) {
  185. for (let i = 0; i < navigatorButtons.rightButtons.length; i++) {
  186. navigatorButtons.rightButtons[i].onPress = navigatorEventID;
  187. }
  188. }
  189. return {navigatorStyle, navigatorButtons, navigatorEventID};
  190. }
  191. function navigatorPush(navigator, params) {
  192. if (!params.screen) {
  193. console.error('Navigator.push(params): params.screen is required');
  194. return;
  195. }
  196. const screenInstanceID = _.uniqueId('screenInstanceID');
  197. const {
  198. navigatorStyle,
  199. navigatorButtons,
  200. navigatorEventID
  201. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  202. const passProps = Object.assign({}, params.passProps);
  203. passProps.navigatorID = navigator.navigatorID;
  204. passProps.screenInstanceID = screenInstanceID;
  205. passProps.navigatorEventID = navigatorEventID;
  206. params.navigationParams = {
  207. screenInstanceID,
  208. navigatorStyle,
  209. navigatorButtons,
  210. navigatorEventID,
  211. navigatorID: navigator.navigatorID
  212. };
  213. savePassProps(params);
  214. Controllers.NavigationControllerIOS(navigator.navigatorID).push({
  215. title: params.title,
  216. subtitle:params.subtitle,
  217. titleImage: params.titleImage,
  218. component: params.screen,
  219. animated: params.animated,
  220. passProps: passProps,
  221. style: navigatorStyle,
  222. backButtonTitle: params.backButtonTitle,
  223. backButtonHidden: params.backButtonHidden,
  224. leftButtons: navigatorButtons.leftButtons,
  225. rightButtons: navigatorButtons.rightButtons
  226. });
  227. }
  228. function navigatorPop(navigator, params) {
  229. Controllers.NavigationControllerIOS(navigator.navigatorID).pop({
  230. animated: params.animated
  231. });
  232. }
  233. function navigatorPopToRoot(navigator, params) {
  234. Controllers.NavigationControllerIOS(navigator.navigatorID).popToRoot({
  235. animated: params.animated
  236. });
  237. }
  238. function navigatorResetTo(navigator, params) {
  239. if (!params.screen) {
  240. console.error('Navigator.resetTo(params): params.screen is required');
  241. return;
  242. }
  243. const screenInstanceID = _.uniqueId('screenInstanceID');
  244. const {
  245. navigatorStyle,
  246. navigatorButtons,
  247. navigatorEventID
  248. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  249. const passProps = Object.assign({}, params.passProps);
  250. passProps.navigatorID = navigator.navigatorID;
  251. passProps.screenInstanceID = screenInstanceID;
  252. passProps.navigatorEventID = navigatorEventID;
  253. params.navigationParams = {
  254. screenInstanceID,
  255. navigatorStyle,
  256. navigatorButtons,
  257. navigatorEventID,
  258. navigatorID: navigator.navigatorID
  259. };
  260. savePassProps(params);
  261. Controllers.NavigationControllerIOS(navigator.navigatorID).resetTo({
  262. title: params.title,
  263. subtitle: params.subtitle,
  264. titleImage: params.titleImage,
  265. component: params.screen,
  266. animated: params.animated,
  267. passProps: passProps,
  268. style: navigatorStyle,
  269. leftButtons: navigatorButtons.leftButtons,
  270. rightButtons: navigatorButtons.rightButtons
  271. });
  272. }
  273. function navigatorSetTitle(navigator, params) {
  274. Controllers.NavigationControllerIOS(navigator.navigatorID).setTitle({
  275. title: params.title,
  276. subtitle: params.subtitle,
  277. titleImage: params.titleImage,
  278. style: params.navigatorStyle
  279. });
  280. }
  281. function navigatorSetTitleImage(navigator, params) {
  282. Controllers.NavigationControllerIOS(navigator.navigatorID).setTitleImage({
  283. titleImage: params.titleImage
  284. });
  285. }
  286. function navigatorToggleNavBar(navigator, params) {
  287. Controllers.NavigationControllerIOS(navigator.navigatorID).setHidden({
  288. hidden: ((params.to === 'hidden') ? true : false),
  289. animated: params.animated
  290. });
  291. }
  292. function navigatorToggleDrawer(navigator, params) {
  293. const controllerID = navigator.navigatorID.split('_')[0];
  294. if (params.to == 'open') {
  295. Controllers.DrawerControllerIOS(controllerID + '_drawer').open({
  296. side: params.side,
  297. animated: params.animated
  298. });
  299. } else if (params.to == 'closed') {
  300. Controllers.DrawerControllerIOS(controllerID + '_drawer').close({
  301. side: params.side,
  302. animated: params.animated
  303. });
  304. } else {
  305. Controllers.DrawerControllerIOS(controllerID + '_drawer').toggle({
  306. side: params.side,
  307. animated: params.animated
  308. });
  309. }
  310. }
  311. function navigatorToggleTabs(navigator, params) {
  312. const controllerID = navigator.navigatorID.split('_')[0];
  313. Controllers.TabBarControllerIOS(controllerID + '_tabs').setHidden({
  314. hidden: params.to == 'hidden',
  315. animated: !(params.animated === false)
  316. });
  317. }
  318. function navigatorSetTabBadge(navigator, params) {
  319. const controllerID = navigator.navigatorID.split('_')[0];
  320. if (params.tabIndex || params.tabIndex === 0) {
  321. Controllers.TabBarControllerIOS(controllerID + '_tabs').setBadge({
  322. tabIndex: params.tabIndex,
  323. badge: params.badge
  324. });
  325. } else {
  326. Controllers.TabBarControllerIOS(controllerID + '_tabs').setBadge({
  327. contentId: navigator.navigatorID,
  328. contentType: 'NavigationControllerIOS',
  329. badge: params.badge
  330. });
  331. }
  332. }
  333. function navigatorSwitchToTab(navigator, params) {
  334. const controllerID = navigator.navigatorID.split('_')[0];
  335. if (params.tabIndex || params.tabIndex === 0) {
  336. Controllers.TabBarControllerIOS(controllerID + '_tabs').switchTo({
  337. tabIndex: params.tabIndex
  338. });
  339. } else {
  340. Controllers.TabBarControllerIOS(controllerID + '_tabs').switchTo({
  341. contentId: navigator.navigatorID,
  342. contentType: 'NavigationControllerIOS'
  343. });
  344. }
  345. }
  346. function navigatorSetButtons(navigator, navigatorEventID, params) {
  347. if (params.leftButtons) {
  348. const buttons = params.leftButtons.slice(); // clone
  349. for (let i = 0; i < buttons.length; i++) {
  350. buttons[i].onPress = navigatorEventID;
  351. }
  352. Controllers.NavigationControllerIOS(navigator.navigatorID).setLeftButtons(buttons, params.animated);
  353. }
  354. if (params.rightButtons) {
  355. const buttons = params.rightButtons.slice(); // clone
  356. for (let i = 0; i < buttons.length; i++) {
  357. buttons[i].onPress = navigatorEventID;
  358. }
  359. Controllers.NavigationControllerIOS(navigator.navigatorID).setRightButtons(buttons, params.animated);
  360. }
  361. }
  362. function showModal(params) {
  363. if (!params.screen) {
  364. console.error('showModal(params): params.screen is required');
  365. return;
  366. }
  367. const controllerID = _.uniqueId('controllerID');
  368. const navigatorID = controllerID + '_nav';
  369. const screenInstanceID = _.uniqueId('screenInstanceID');
  370. const {
  371. navigatorStyle,
  372. navigatorButtons,
  373. navigatorEventID
  374. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  375. const passProps = Object.assign({}, params.passProps);
  376. passProps.navigatorID = navigatorID;
  377. passProps.screenInstanceID = screenInstanceID;
  378. passProps.navigatorEventID = navigatorEventID;
  379. params.navigationParams = {
  380. screenInstanceID,
  381. navigatorStyle,
  382. navigatorButtons,
  383. navigatorEventID,
  384. navigatorID: navigator.navigatorID
  385. };
  386. const Controller = Controllers.createClass({
  387. render: function() {
  388. return (
  389. <NavigationControllerIOS
  390. id={navigatorID}
  391. title={params.title}
  392. subtitle={params.subtitle}
  393. titleImage={params.titleImage}
  394. component={params.screen}
  395. passProps={passProps}
  396. style={navigatorStyle}
  397. leftButtons={navigatorButtons.leftButtons}
  398. rightButtons={navigatorButtons.rightButtons}/>
  399. );
  400. }
  401. });
  402. savePassProps(params);
  403. ControllerRegistry.registerController(controllerID, () => Controller);
  404. Modal.showController(controllerID, params.animationType);
  405. }
  406. function dismissModal(params) {
  407. Modal.dismissController(params.animationType);
  408. }
  409. function dismissAllModals(params) {
  410. Modal.dismissAllControllers(params.animationType);
  411. }
  412. function showLightBox(params) {
  413. if (!params.screen) {
  414. console.error('showLightBox(params): params.screen is required');
  415. return;
  416. }
  417. const controllerID = _.uniqueId('controllerID');
  418. const navigatorID = controllerID + '_nav';
  419. const screenInstanceID = _.uniqueId('screenInstanceID');
  420. const {
  421. navigatorStyle,
  422. navigatorButtons,
  423. navigatorEventID
  424. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  425. const passProps = Object.assign({}, params.passProps);
  426. passProps.navigatorID = navigatorID;
  427. passProps.screenInstanceID = screenInstanceID;
  428. passProps.navigatorEventID = navigatorEventID;
  429. params.navigationParams = {
  430. screenInstanceID,
  431. navigatorStyle,
  432. navigatorButtons,
  433. navigatorEventID,
  434. navigatorID
  435. };
  436. savePassProps(params);
  437. Modal.showLightBox({
  438. component: params.screen,
  439. passProps: passProps,
  440. style: params.style
  441. });
  442. }
  443. function dismissLightBox(params) {
  444. Modal.dismissLightBox();
  445. }
  446. function showInAppNotification(params) {
  447. if (!params.screen) {
  448. console.error('showInAppNotification(params): params.screen is required');
  449. return;
  450. }
  451. const controllerID = _.uniqueId('controllerID');
  452. const navigatorID = controllerID + '_nav';
  453. const screenInstanceID = _.uniqueId('screenInstanceID');
  454. const {
  455. navigatorStyle,
  456. navigatorButtons,
  457. navigatorEventID
  458. } = _mergeScreenSpecificSettings(params.screen, screenInstanceID, params);
  459. const passProps = Object.assign({}, params.passProps);
  460. passProps.navigatorID = navigatorID;
  461. passProps.screenInstanceID = screenInstanceID;
  462. passProps.navigatorEventID = navigatorEventID;
  463. params.navigationParams = {
  464. screenInstanceID,
  465. navigatorStyle,
  466. navigatorButtons,
  467. navigatorEventID,
  468. navigatorID
  469. };
  470. Notification.show({
  471. component: params.screen,
  472. passProps: passProps,
  473. style: params.style,
  474. animation: params.animation || Notification.AnimationPresets.default,
  475. position: params.position,
  476. shadowRadius: params.shadowRadius,
  477. dismissWithSwipe: params.dismissWithSwipe || true,
  478. autoDismissTimerSec: params.autoDismissTimerSec || 5
  479. });
  480. }
  481. function dismissInAppNotification(params) {
  482. Notification.dismiss(params);
  483. }
  484. function savePassProps(params) {
  485. //TODO this needs to be handled in a common place,
  486. //TODO also, all global passProps should be handled differently
  487. if (params.navigationParams && params.passProps) {
  488. PropRegistry.save(params.navigationParams.screenInstanceID, params.passProps);
  489. }
  490. if (params.screen && params.screen.passProps) {
  491. PropRegistry.save(params.screen.navigationParams.screenInstanceID, params.screen.passProps);
  492. }
  493. if (_.get(params, 'screen.topTabs')) {
  494. _.forEach(params.screen.topTabs, (tab) => savePassProps(tab));
  495. }
  496. if (params.tabs) {
  497. _.forEach(params.tabs, (tab) => {
  498. if (!tab.passProps) {
  499. tab.passProps = params.passProps;
  500. }
  501. savePassProps(tab);
  502. });
  503. }
  504. }
  505. export default {
  506. startTabBasedApp,
  507. startSingleScreenApp,
  508. navigatorPush,
  509. navigatorPop,
  510. navigatorPopToRoot,
  511. navigatorResetTo,
  512. showModal,
  513. dismissModal,
  514. dismissAllModals,
  515. showLightBox,
  516. dismissLightBox,
  517. showInAppNotification,
  518. dismissInAppNotification,
  519. navigatorSetButtons,
  520. navigatorSetTitle,
  521. navigatorSetTitleImage,
  522. navigatorToggleDrawer,
  523. navigatorToggleTabs,
  524. navigatorSetTabBadge,
  525. navigatorSwitchToTab,
  526. navigatorToggleNavBar
  527. };