Daniel Zlotin преди 8 години
родител
ревизия
330e1a7bb3
променени са 4 файла, в които са добавени 475 реда и са изтрити 5 реда
  1. 6
    0
      .babelrc
  2. 2
    3
      package.json
  3. 3
    1
      src/index.js
  4. 464
    1
      src/platformSpecific.ios.js

+ 6
- 0
.babelrc Целия файл

@@ -0,0 +1,6 @@
1
+{
2
+  "presets": [
3
+    "react-native-stage-0"
4
+  ],
5
+  "retainLines": true
6
+}

+ 2
- 3
package.json Целия файл

@@ -30,6 +30,7 @@
30 30
     "react": ">=0.14.5"
31 31
   },
32 32
   "dependencies": {
33
+    "react-native-controllers": "^2.0.0",
33 34
     "lodash": "^4.13.0"
34 35
   },
35 36
   "optionalDependencies": {
@@ -42,9 +43,7 @@
42 43
     "babel-cli": "^6.8.0",
43 44
     "babel-core": "^6.8.0",
44 45
     "babel-polyfill": "^6.8.0",
45
-    "babel-preset-es2015": "^6.6.0",
46
-    "babel-preset-react": "^6.5.0",
47
-    "babel-preset-stage-0": "^6.5.0",
46
+    "babel-preset-react-native-stage-0": "^1.0.0",
48 47
     "babel-register": "^6.8.0",
49 48
     "eslint": "^2.5.1",
50 49
     "eslint-plugin-babel": "^3.0.0",

+ 3
- 1
src/index.js Целия файл

@@ -1,5 +1,7 @@
1 1
 import Navigation from './Navigation';
2
+import {NavigationToolBarIOS} from 'react-native-controllers';
2 3
 
3 4
 module.exports = {
4
-  Navigation
5
+  Navigation,
6
+  NavigationToolBarIOS
5 7
 };

+ 464
- 1
src/platformSpecific.ios.js Целия файл

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