react-native-navigation的迁移库

platformSpecificDeprecated.ios.js 17KB

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