@applicaster/zapp-react-dom-app 12.0.0-rc.104 → 12.0.0-rc.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,9 +35,9 @@ import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
35
35
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
36
36
  import { confirmationDialogStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfirmDialogState";
37
37
  import {
38
- isVizioPlatform,
39
- isSamsungPlatform,
40
38
  isLgPlatform,
39
+ isSamsungPlatform,
40
+ isVizioPlatform,
41
41
  } from "@applicaster/zapp-react-native-utils/reactUtils";
42
42
 
43
43
  import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
@@ -72,590 +72,555 @@ type KeyCode = { code: string; keyCode: number | string };
72
72
  export const alertConfirmationMesage =
73
73
  "Are you sure you want to exit application?";
74
74
 
75
- export function withInteractionManager(Component: React.FC) {
76
- class InteractionManager extends React.Component<Props, State> {
77
- onKeyDownListener: (keyCode: KeyCode) => void;
78
- onMouseDownListener: (event: MouseEvent) => void;
79
- onMouseMoveListener: (event: MouseEvent) => void;
80
- onScrollListener: (event: MouseEvent) => void;
75
+ class InteractionManagerClass extends React.Component<Props, State> {
76
+ onKeyDownListener: (keyCode: KeyCode) => void;
77
+ onMouseDownListener: (event: MouseEvent) => void;
78
+ onMouseMoveListener: (event: MouseEvent) => void;
79
+ onScrollListener: (event: MouseEvent) => void;
81
80
 
82
- longKeyPressTimeout: any | null;
83
- longPressActive: boolean;
84
- timeout: any | null;
85
- sequenceTimeout: NodeJS.Timeout | null; // timeoutID
86
- userSequence: number[] = [];
87
- confirmDialog: any;
88
- isDismissing = false;
81
+ longKeyPressTimeout: any | null;
82
+ longPressActive: boolean;
83
+ timeout: any | null;
84
+ sequenceTimeout: NodeJS.Timeout | null; // timeoutID
85
+ userSequence: number[] = [];
86
+ confirmDialog: any;
87
+ isDismissing = false;
89
88
 
90
- constructor(props) {
91
- super(props);
92
-
93
- this.onKeyDownListener = this.onKeyDown.bind(this);
94
-
95
- this.state = {
96
- isKeyboardVisible: false,
97
- keyboardInput: "",
98
- };
89
+ constructor(props) {
90
+ super(props);
99
91
 
100
- this.onMouseMoveListener = debounce({
101
- fn: this.onMouseMove,
102
- context: this,
103
- });
92
+ this.onKeyDownListener = this.onKeyDown.bind(this);
104
93
 
105
- this.onScrollListener = debounce({
106
- fn: this.onScroll,
107
- wait: 100,
108
- context: this,
109
- });
94
+ this.state = {
95
+ isKeyboardVisible: false,
96
+ keyboardInput: "",
97
+ };
110
98
 
111
- this.onMouseDownListener = debounce({
112
- fn: this.onMouseDown,
113
- context: this,
114
- });
99
+ this.onMouseMoveListener = debounce({
100
+ fn: this.onMouseMove,
101
+ context: this,
102
+ });
103
+
104
+ this.onScrollListener = debounce({
105
+ fn: this.onScroll,
106
+ wait: 100,
107
+ context: this,
108
+ });
109
+
110
+ this.onMouseDownListener = debounce({
111
+ fn: this.onMouseDown,
112
+ context: this,
113
+ });
114
+
115
+ this.longKeyPressTimeout = null;
116
+ this.longPressActive = false;
117
+ this.confirmDialog = confirmationDialogStore.getState();
118
+ this.resetHudTimeout = this.resetHudTimeout.bind(this);
119
+ this.cursorVisibilityChange = this.cursorVisibilityChange.bind(this);
120
+ this.onKeyDown = this.onKeyDown.bind(this);
121
+ this.onKeyUp = this.onKeyUp.bind(this);
122
+ this.onMouseMove = this.onMouseMove.bind(this);
123
+ this.onScroll = this.onScroll.bind(this);
124
+ this.onMouseDown = this.onMouseDown.bind(this);
125
+ this.onKeyboardStateChange = this.onKeyboardStateChange.bind(this);
126
+ this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
127
+ this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
128
+ this.performExit = this.performExit.bind(this);
129
+ this.handleInputFocus = this.handleInputFocus.bind(this);
130
+ this.handleInputBlur = this.handleInputBlur.bind(this);
131
+ this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
132
+ this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
133
+
134
+ this.confirmDialog.setConfirmAction(this.performExit);
135
+ this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
136
+ }
115
137
 
116
- this.longKeyPressTimeout = null;
117
- this.longPressActive = false;
118
- this.confirmDialog = confirmationDialogStore.getState();
119
- this.resetHudTimeout = this.resetHudTimeout.bind(this);
120
- this.cursorVisibilityChange = this.cursorVisibilityChange.bind(this);
121
- this.onKeyDown = this.onKeyDown.bind(this);
122
- this.onKeyUp = this.onKeyUp.bind(this);
123
- this.onMouseMove = this.onMouseMove.bind(this);
124
- this.onScroll = this.onScroll.bind(this);
125
- this.onMouseDown = this.onMouseDown.bind(this);
126
- this.onKeyboardStateChange = this.onKeyboardStateChange.bind(this);
127
- this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
128
- this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
129
- this.performExit = this.performExit.bind(this);
130
- this.handleInputFocus = this.handleInputFocus.bind(this);
131
- this.handleInputBlur = this.handleInputBlur.bind(this);
132
- this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
133
- this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
134
-
135
- this.confirmDialog.setConfirmAction(this.performExit);
136
- this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
137
- }
138
+ componentDidMount() {
139
+ window.addEventListener("keydown", this.onKeyDownListener);
140
+ window.addEventListener("keyup", this.onKeyUp);
141
+ window.addEventListener("mousemove", this.onMouseMoveListener);
138
142
 
139
- componentDidMount() {
140
- window.addEventListener("keydown", this.onKeyDownListener);
141
- window.addEventListener("keyup", this.onKeyUp);
142
- window.addEventListener("mousemove", this.onMouseMoveListener);
143
+ document.addEventListener("wheel", this.onScrollListener, {
144
+ passive: true,
145
+ });
143
146
 
144
- document.addEventListener("wheel", this.onScrollListener, {
145
- passive: true,
146
- });
147
+ document.addEventListener("mousedown", this.onMouseDownListener);
147
148
 
148
- document.addEventListener("mousedown", this.onMouseDownListener);
149
+ document.addEventListener(
150
+ "keyboardStateChange",
151
+ this.onKeyboardStateChange,
152
+ false
153
+ );
149
154
 
150
- document.addEventListener(
151
- "keyboardStateChange",
152
- this.onKeyboardStateChange,
153
- false
154
- );
155
+ document.addEventListener("focusin", this.handleInputFocus);
155
156
 
156
- document.addEventListener("focusin", this.handleInputFocus);
157
+ document.addEventListener(
158
+ "cursorStateChange",
159
+ this.cursorVisibilityChange,
160
+ false
161
+ );
162
+ }
157
163
 
158
- document.addEventListener(
159
- "cursorStateChange",
160
- this.cursorVisibilityChange,
161
- false
162
- );
163
- }
164
+ componentWillUnmount() {
165
+ window.removeEventListener("keydown", this.onKeyDownListener);
166
+ window.removeEventListener("keyup", this.onKeyUp);
167
+ document.removeEventListener("wheel", this.onScrollListener);
164
168
 
165
- componentWillUnmount() {
166
- window.removeEventListener("keydown", this.onKeyDownListener);
167
- window.removeEventListener("keyup", this.onKeyUp);
168
- document.removeEventListener("wheel", this.onScrollListener);
169
+ document.removeEventListener(
170
+ "cursorStateChange",
171
+ this.cursorVisibilityChange
172
+ );
169
173
 
170
- document.removeEventListener(
171
- "cursorStateChange",
172
- this.cursorVisibilityChange
173
- );
174
+ document.removeEventListener("focusin", this.handleInputFocus);
174
175
 
175
- document.removeEventListener("focusin", this.handleInputFocus);
176
+ document.removeEventListener("mousedown", this.onMouseDownListener);
176
177
 
177
- document.removeEventListener("mousedown", this.onMouseDownListener);
178
+ if (this.timeout) {
179
+ this.clearTimeout();
180
+ }
178
181
 
179
- if (this.timeout) {
180
- this.clearTimeout();
181
- }
182
+ this.isDismissing = false;
183
+ }
182
184
 
183
- this.isDismissing = false;
185
+ performExit() {
186
+ if (isSamsungPlatform()) {
187
+ this.onConfirmDialogClose();
188
+ sendQuickBrickEvent(QUICK_BRICK_EVENTS.MOVE_APP_TO_BACKGROUND);
184
189
  }
185
190
 
186
- performExit() {
187
- if (isSamsungPlatform()) {
188
- this.onConfirmDialogClose();
189
- sendQuickBrickEvent(QUICK_BRICK_EVENTS.MOVE_APP_TO_BACKGROUND);
190
- }
191
-
192
- if (isLgPlatform()) {
193
- // webOS recommend to use this method when implemention a custom exit
194
- globalAny.close();
195
- }
191
+ if (isLgPlatform()) {
192
+ // webOS recommend to use this method when implemention a custom exit
193
+ globalAny.close();
194
+ }
196
195
 
197
- if (isVizioPlatform()) {
198
- window?.VIZIO?.exitApplication();
199
- }
196
+ if (isVizioPlatform()) {
197
+ window?.VIZIO?.exitApplication();
200
198
  }
199
+ }
201
200
 
202
- handleWebOsBack() {
203
- const systemBack = globalAny?.webOS?.platformBack;
201
+ handleWebOsBack() {
202
+ const systemBack = globalAny?.webOS?.platformBack;
204
203
 
205
- if (systemBack) {
206
- systemBack();
207
- } else {
208
- /**
209
- * In case webOS failed to show the exit pop-up, we show a regular promtp as fallback
210
- */
211
- showConfirmationDialog({
212
- title: "",
213
- message: alertConfirmationMesage,
214
- confirmCompletion: this.performExit,
215
- });
216
- }
204
+ if (systemBack) {
205
+ systemBack();
206
+ } else {
207
+ /**
208
+ * In case webOS failed to show the exit pop-up, we show a regular promtp as fallback
209
+ */
210
+ showConfirmationDialog({
211
+ title: "",
212
+ message: alertConfirmationMesage,
213
+ confirmCompletion: this.performExit,
214
+ });
217
215
  }
216
+ }
218
217
 
219
- /**
220
- * This methods sends the app to background in whatever way is appropriate for each platform
221
- * In the case of Tizen it shows a custom dialog on confirm it exits the app
222
- * WebOS behavior depends on the SDK version, WebOS 4 would pull up the launcher menu
223
- * following versions would show a native exit prompt
224
- */
225
- platformBack() {
226
- try {
227
- // TODO: temporary hack until this code is refactored
228
- if (isSamsungPlatform() || isVizioPlatform()) {
229
- const { isDialogVisible } = confirmationDialogStore.getState();
230
-
231
- if (isDialogVisible) {
232
- this.onConfirmDialogClose();
233
- } else {
234
- showConfirmationDialog({
235
- title: "",
236
- message: alertConfirmationMesage,
237
- confirmCompletion: this.performExit,
238
- cancelCompletion: this.onConfirmDialogClose,
239
- });
240
- }
241
- } else if (isLgPlatform()) {
242
- this.handleWebOsBack();
218
+ /**
219
+ * This methods sends the app to background in whatever way is appropriate for each platform
220
+ * In the case of Tizen it shows a custom dialog on confirm it exits the app
221
+ * WebOS behavior depends on the SDK version, WebOS 4 would pull up the launcher menu
222
+ * following versions would show a native exit prompt
223
+ */
224
+ platformBack() {
225
+ try {
226
+ // TODO: temporary hack until this code is refactored
227
+ if (isSamsungPlatform() || isVizioPlatform()) {
228
+ const { isDialogVisible } = confirmationDialogStore.getState();
229
+
230
+ if (isDialogVisible) {
231
+ this.onConfirmDialogClose();
232
+ } else {
233
+ showConfirmationDialog({
234
+ title: "",
235
+ message: alertConfirmationMesage,
236
+ confirmCompletion: this.performExit,
237
+ cancelCompletion: this.onConfirmDialogClose,
238
+ });
243
239
  }
244
- } catch (e) {
245
- // eslint-disable-next-line no-console
246
- console.warn("Failed to execute platformBack", e);
240
+ } else if (isLgPlatform()) {
241
+ this.handleWebOsBack();
247
242
  }
243
+ } catch (e) {
244
+ // eslint-disable-next-line no-console
245
+ console.warn("Failed to execute platformBack", e);
248
246
  }
247
+ }
249
248
 
250
- cursorVisibilityChange(event) {
251
- const visible = event.detail.visibility;
252
- const { setDisplayState, displayState } = this.props;
249
+ cursorVisibilityChange(event) {
250
+ const visible = event.detail.visibility;
251
+ const { setDisplayState, displayState } = this.props;
253
252
 
254
- if (visible && displayState === DISPLAY_STATES.PLAYER) {
255
- setDisplayState(DISPLAY_STATES.HUD);
256
- this.resetHudTimeout();
257
- }
253
+ if (visible && displayState === DISPLAY_STATES.PLAYER) {
254
+ setDisplayState(DISPLAY_STATES.HUD);
255
+ this.resetHudTimeout();
258
256
  }
257
+ }
259
258
 
260
- onMouseMove() {
261
- const { setDisplayState, displayState } = this.props;
259
+ onMouseMove() {
260
+ const { setDisplayState, displayState } = this.props;
262
261
 
263
- if (displayState === DISPLAY_STATES.PLAYER) {
264
- setDisplayState(DISPLAY_STATES.HUD);
265
- this.resetHudTimeout();
266
- }
262
+ if (displayState === DISPLAY_STATES.PLAYER) {
263
+ setDisplayState(DISPLAY_STATES.HUD);
264
+ this.resetHudTimeout();
267
265
  }
266
+ }
268
267
 
269
- isHomeScreen() {
270
- const { navigator } = this.props;
271
- const { rivers } = this.props;
268
+ isHomeScreen() {
269
+ const { navigator } = this.props;
270
+ const { rivers } = this.props;
272
271
 
273
- const homeId = R.compose(
274
- R.prop("id"),
275
- R.find(R.prop("home")),
276
- R.values
277
- )(rivers);
272
+ const homeId = R.compose(
273
+ R.prop("id"),
274
+ R.find(R.prop("home")),
275
+ R.values
276
+ )(rivers);
278
277
 
279
- const homePath = `/river/${homeId}`;
278
+ const homePath = `/river/${homeId}`;
280
279
 
281
- return homePath === navigator.currentRoute;
282
- }
280
+ return homePath === navigator.currentRoute;
281
+ }
283
282
 
284
- goToHome() {
285
- const { navigator } = this.props;
286
- const { rivers } = this.props;
287
- const homeRiver = R.find(R.propEq("home", true), R.values(rivers));
283
+ goToHome() {
284
+ const { navigator } = this.props;
285
+ const { rivers } = this.props;
286
+ const homeRiver = R.find(R.propEq("home", true), R.values(rivers));
288
287
 
289
- navigator.replace(homeRiver);
290
- }
288
+ navigator.replace(homeRiver);
289
+ }
291
290
 
292
- resetHudTimeout() {
293
- const { resetHudTimer = noop } = this.props;
291
+ resetHudTimeout() {
292
+ const { resetHudTimer = noop } = this.props;
294
293
 
295
- resetHudTimer?.();
296
- }
294
+ resetHudTimer?.();
295
+ }
297
296
 
298
- clearTimeout() {
299
- if (this.timeout) {
300
- clearTimeout(this.timeout);
301
- this.timeout = null;
302
- }
297
+ clearTimeout() {
298
+ if (this.timeout) {
299
+ clearTimeout(this.timeout);
300
+ this.timeout = null;
303
301
  }
302
+ }
304
303
 
305
- clearLongPressTimeout() {
306
- if (this.longKeyPressTimeout) {
307
- clearTimeout(this.longKeyPressTimeout);
308
- this.longKeyPressTimeout = null;
309
- }
304
+ clearLongPressTimeout() {
305
+ if (this.longKeyPressTimeout) {
306
+ clearTimeout(this.longKeyPressTimeout);
307
+ this.longKeyPressTimeout = null;
310
308
  }
309
+ }
311
310
 
312
- /**
313
- * If the keySupportsLongPress this method is called on longpress of key
314
- * Register your longpress handlers here, and make sure to add it to list of supported keys
315
- */
316
- onLongPress(event) {
317
- this.longPressActive = true;
318
- // Legacy way of determining whether controls are being displayed
319
- // Or if the player is in a playback state.
320
- const { displayState } = this.props;
321
- const playerState = displayState === DISPLAY_STATES.PLAYER;
322
- const hudState = displayState === DISPLAY_STATES.HUD;
323
- const playbackState = playerState || hudState;
324
-
325
- switch (event.code) {
326
- case KEYS.Back.code:
327
- // If you longpress the back button we probably want to exit
328
- this.platformBack();
311
+ /**
312
+ * If the keySupportsLongPress this method is called on longpress of key
313
+ * Register your longpress handlers here, and make sure to add it to list of supported keys
314
+ */
315
+ onLongPress(event) {
316
+ this.longPressActive = true;
317
+ // Legacy way of determining whether controls are being displayed
318
+ // Or if the player is in a playback state.
319
+ const { displayState } = this.props;
320
+ const playerState = displayState === DISPLAY_STATES.PLAYER;
321
+ const hudState = displayState === DISPLAY_STATES.HUD;
322
+ const playbackState = playerState || hudState;
323
+
324
+ switch (event.code) {
325
+ case KEYS.Back.code:
326
+ // If you longpress the back button we probably want to exit
327
+ this.platformBack();
329
328
 
330
- break;
329
+ break;
331
330
 
332
- case KEYS.Enter.code:
333
- focusManager.longPress();
331
+ case KEYS.Enter.code:
332
+ focusManager.longPress();
334
333
 
335
- break;
334
+ break;
336
335
 
337
- case KEYS.Forward.code:
338
- playbackState && this.props.seekMethods.onForwardLongPress();
336
+ case KEYS.Forward.code:
337
+ playbackState && this.props.seekMethods.onForwardLongPress();
339
338
 
340
- break;
339
+ break;
341
340
 
342
- case KEYS.Rewind.code:
343
- playbackState && this.props.seekMethods.onRewindLongPress();
341
+ case KEYS.Rewind.code:
342
+ playbackState && this.props.seekMethods.onRewindLongPress();
344
343
 
345
- break;
344
+ break;
346
345
 
347
- default:
348
- break;
349
- }
346
+ default:
347
+ break;
350
348
  }
349
+ }
351
350
 
352
- /**
353
- * If the keySupportsLongPress this method is called on keyup of a longpress key
354
- * If you need to handle the release or keyup of a longpress key register the handler here
355
- */
356
- onLongPressRelease(event) {
357
- this.longPressActive = false;
358
- this.resetHudTimeout();
351
+ /**
352
+ * If the keySupportsLongPress this method is called on keyup of a longpress key
353
+ * If you need to handle the release or keyup of a longpress key register the handler here
354
+ */
355
+ onLongPressRelease(event) {
356
+ this.longPressActive = false;
357
+ this.resetHudTimeout();
359
358
 
360
- focusManager.pressOut();
359
+ focusManager.pressOut();
361
360
 
362
- switch (event.code) {
363
- case KEYS.Forward.code:
364
- this.props.seekMethods.onForwardPressOut();
361
+ switch (event.code) {
362
+ case KEYS.Forward.code:
363
+ this.props.seekMethods.onForwardPressOut();
365
364
 
366
- break;
365
+ break;
367
366
 
368
- case KEYS.Rewind.code:
369
- this.props.seekMethods.onForwardPressOut();
367
+ case KEYS.Rewind.code:
368
+ this.props.seekMethods.onForwardPressOut();
370
369
 
371
- break;
370
+ break;
372
371
 
373
- default:
374
- break;
375
- }
372
+ default:
373
+ break;
376
374
  }
375
+ }
377
376
 
378
- /**
379
- * Resets the sequence of keys we captured.
380
- * Clear ensures that we don't interpret regular interactions
381
- * as a sequence used to unlock certain features
382
- */
383
- resetSequenceTimeout() {
384
- const SEQUENCE_ENTRY_TIME = 1900;
377
+ /**
378
+ * Resets the sequence of keys we captured.
379
+ * Clear ensures that we don't interpret regular interactions
380
+ * as a sequence used to unlock certain features
381
+ */
382
+ resetSequenceTimeout() {
383
+ const SEQUENCE_ENTRY_TIME = 1900;
384
+
385
+ if (this.sequenceTimeout) {
386
+ // Start timer over
387
+ clearTimeout(this.sequenceTimeout);
388
+ }
385
389
 
386
- if (this.sequenceTimeout) {
387
- // Start timer over
388
- clearTimeout(this.sequenceTimeout);
389
- }
390
+ this.sequenceTimeout = setTimeout(() => {
391
+ // User needs to complete sequence before SEQUENCE_ENTRY_TIME
392
+ // or we set userSequence, and prev sequenceTimeout to empty values
393
+ this.sequenceTimeout = null;
394
+ this.userSequence = [];
395
+ }, SEQUENCE_ENTRY_TIME);
396
+ }
390
397
 
391
- this.sequenceTimeout = setTimeout(() => {
392
- // User needs to complete sequence before SEQUENCE_ENTRY_TIME
393
- // or we set userSequence, and prev sequenceTimeout to empty values
394
- this.sequenceTimeout = null;
395
- this.userSequence = [];
396
- }, SEQUENCE_ENTRY_TIME);
398
+ /**
399
+ * If a certain sequence of keys are pressed we enable special menus or settings
400
+ * Each supported sequence can be stored as a constant
401
+ */
402
+ checkSequence(key) {
403
+ const SINK_SEQUENCE = [
404
+ KEYS.ArrowUp.keyCode,
405
+ KEYS.ArrowUp.keyCode,
406
+ KEYS.ArrowDown.keyCode,
407
+ KEYS.ArrowDown.keyCode,
408
+ KEYS.ArrowLeft.keyCode,
409
+ KEYS.ArrowRight.keyCode,
410
+ KEYS.ArrowLeft.keyCode,
411
+ KEYS.ArrowRight.keyCode,
412
+ ];
413
+
414
+ this.resetSequenceTimeout();
415
+ this.userSequence.push(key);
416
+
417
+ // Remember [1,2,3] !== [1,2,3] in js, so string comparison is better
418
+ const shouldAddSink =
419
+ this.userSequence.toString() === SINK_SEQUENCE.toString();
420
+
421
+ if (shouldAddSink) {
422
+ this.props.xray.addRemoteSink({});
397
423
  }
424
+ }
398
425
 
399
- /**
400
- * If a certain sequence of keys are pressed we enable special menus or settings
401
- * Each supported sequence can be stored as a constant
402
- */
403
- checkSequence(key) {
404
- const SINK_SEQUENCE = [
405
- KEYS.ArrowUp.keyCode,
406
- KEYS.ArrowUp.keyCode,
407
- KEYS.ArrowDown.keyCode,
408
- KEYS.ArrowDown.keyCode,
409
- KEYS.ArrowLeft.keyCode,
410
- KEYS.ArrowRight.keyCode,
411
- KEYS.ArrowLeft.keyCode,
412
- KEYS.ArrowRight.keyCode,
413
- ];
414
-
415
- this.resetSequenceTimeout();
416
- this.userSequence.push(key);
417
-
418
- // Remember [1,2,3] !== [1,2,3] in js, so string comparison is better
419
- const shouldAddSink =
420
- this.userSequence.toString() === SINK_SEQUENCE.toString();
421
-
422
- if (shouldAddSink) {
423
- this.props.xray.addRemoteSink({});
424
- }
425
- }
426
+ /**
427
+ * Determines whether the key supports or handles longpress
428
+ * At the moment the only keys that support are the ones defined in
429
+ * supportedEvents array. This logic just prevents us from registering timeouts for every key
430
+ */
431
+ keySupportsLongPress(event): boolean {
432
+ const supportedEvents = [KEYS.Back, KEYS.Enter, KEYS.Rewind, KEYS.Forward];
426
433
 
427
- /**
428
- * Determines whether the key supports or handles longpress
429
- * At the moment the only keys that support are the ones defined in
430
- * supportedEvents array. This logic just prevents us from registering timeouts for every key
431
- */
432
- keySupportsLongPress(event): boolean {
433
- const supportedEvents = [
434
- KEYS.Back,
435
- KEYS.Enter,
436
- KEYS.Rewind,
437
- KEYS.Forward,
438
- ];
434
+ const eventMatcher = R.compose(R.prop("matches"), keyCode)(event);
439
435
 
440
- const eventMatcher = R.compose(R.prop("matches"), keyCode)(event);
436
+ const supportsLongPress = R.compose(
437
+ R.any(R.equals(true)),
438
+ R.map(eventMatcher)
439
+ )(supportedEvents);
441
440
 
442
- const supportsLongPress = R.compose(
443
- R.any(R.equals(true)),
444
- R.map(eventMatcher)
445
- )(supportedEvents);
446
-
447
- return supportsLongPress;
448
- }
441
+ return supportsLongPress;
442
+ }
449
443
 
450
- onKeyUp(event: KeyboardEvent) {
451
- // If this is a supported longpress key we need to clear the timeout and handle release of key
452
- // This logic is handled by onLongPressRelease
453
- if (this.keySupportsLongPress(event)) {
454
- if (this.longPressActive) {
455
- this.onLongPressRelease(event);
456
- } else {
457
- this.clearLongPressTimeout();
458
- }
444
+ onKeyUp(event: KeyboardEvent) {
445
+ // If this is a supported longpress key we need to clear the timeout and handle release of key
446
+ // This logic is handled by onLongPressRelease
447
+ if (this.keySupportsLongPress(event)) {
448
+ if (this.longPressActive) {
449
+ this.onLongPressRelease(event);
450
+ } else {
451
+ this.clearLongPressTimeout();
459
452
  }
460
453
  }
454
+ }
461
455
 
462
- onKeyDown(event) {
463
- const { displayState, setDisplayState, navigator } = this.props;
464
- const { isKeyboardVisible } = this.state;
456
+ onKeyDown(event) {
457
+ const { displayState, setDisplayState, navigator } = this.props;
458
+ const { isKeyboardVisible } = this.state;
465
459
 
466
- const { isDialogVisible } = confirmationDialogStore.getState();
460
+ const { isDialogVisible } = confirmationDialogStore.getState();
467
461
 
468
- // If this is a supported longpress key we need to set the timeout and handle the longpress
469
- if (this.keySupportsLongPress(event)) {
470
- this.longKeyPressTimeout = setTimeout(() => {
471
- this.onLongPress(event);
472
- }, LONG_KEY_PRESS_TIMEOUT);
473
- }
462
+ // If this is a supported longpress key we need to set the timeout and handle the longpress
463
+ if (this.keySupportsLongPress(event)) {
464
+ this.longKeyPressTimeout = setTimeout(() => {
465
+ this.onLongPress(event);
466
+ }, LONG_KEY_PRESS_TIMEOUT);
467
+ }
474
468
 
475
- if (isKeyboardVisible && shouldUseOnScreenKeyboard()) {
476
- if (keyCode(event).matchesAny("Escape", "Back")) {
477
- event.preventDefault();
478
- event.stopPropagation();
479
- this.handleKeyboardDismiss();
469
+ if (isKeyboardVisible && shouldUseOnScreenKeyboard()) {
470
+ if (keyCode(event).matchesAny("Escape", "Back")) {
471
+ event.preventDefault();
472
+ event.stopPropagation();
473
+ this.handleKeyboardDismiss();
480
474
 
481
- return;
482
- }
475
+ return;
483
476
  }
477
+ }
484
478
 
479
+ /**
480
+ When the player is displayed, we listen to Native Play / Pause / Stop
481
+ buttons. Any other key press will display the transport controls
482
+ */
483
+ if (
484
+ displayState === DISPLAY_STATES.PLAYER ||
485
+ displayState === DISPLAY_STATES.HUD
486
+ ) {
485
487
  /**
486
- When the player is displayed, we listen to Native Play / Pause / Stop
487
- buttons. Any other key press will display the transport controls
488
+ registering native keys for playback
488
489
  */
489
- if (
490
- displayState === DISPLAY_STATES.PLAYER ||
491
- displayState === DISPLAY_STATES.HUD
492
- ) {
493
- /**
494
- registering native keys for playback
495
- */
496
- if (keyCode(event).matches(KEYS.TogglePlayPause)) {
497
- const { playing } = playerManager.getState() || {};
498
-
499
- if (!playing) {
500
- return playerManager.togglePlayPause();
501
- }
502
- }
490
+ if (keyCode(event).matches(KEYS.TogglePlayPause)) {
491
+ const { playing } = playerManager.getState() || {};
503
492
 
504
- if (keyCode(event).matches(KEYS.Play)) {
505
- return playerManager.play();
493
+ if (!playing) {
494
+ return playerManager.togglePlayPause();
506
495
  }
496
+ }
507
497
 
508
- if (keyCode(event).matches(KEYS.Pause)) {
509
- setDisplayState(DISPLAY_STATES.HUD);
498
+ if (keyCode(event).matches(KEYS.Play)) {
499
+ return playerManager.play();
500
+ }
510
501
 
511
- return playerManager.pause();
512
- }
502
+ if (keyCode(event).matches(KEYS.Pause)) {
503
+ setDisplayState(DISPLAY_STATES.HUD);
513
504
 
514
- if (keyCode(event).matches(KEYS.Stop)) {
515
- setDisplayState(DISPLAY_STATES.DEFAULT);
516
- navigator.goBack();
505
+ return playerManager.pause();
506
+ }
517
507
 
518
- return;
519
- }
508
+ if (keyCode(event).matches(KEYS.Stop)) {
509
+ setDisplayState(DISPLAY_STATES.DEFAULT);
510
+ navigator.goBack();
511
+
512
+ return;
513
+ }
520
514
 
521
- if (keyCode(event).matches(KEYS.Forward)) {
522
- setDisplayState(DISPLAY_STATES.HUD);
523
- this.props.seekMethods.onForwardPress();
515
+ if (keyCode(event).matches(KEYS.Forward)) {
516
+ setDisplayState(DISPLAY_STATES.HUD);
517
+ this.props.seekMethods.onForwardPress();
524
518
 
525
- return;
526
- }
519
+ return;
520
+ }
527
521
 
528
- if (keyCode(event).matches(KEYS.Rewind)) {
529
- setDisplayState(DISPLAY_STATES.HUD);
530
- this.props.seekMethods.onRewindPress();
522
+ if (keyCode(event).matches(KEYS.Rewind)) {
523
+ setDisplayState(DISPLAY_STATES.HUD);
524
+ this.props.seekMethods.onRewindPress();
531
525
 
532
- return;
533
- }
526
+ return;
534
527
  }
528
+ }
535
529
 
536
- /**
537
- When pressing backspace or the Native "Back" button:
538
- if on the transport controls: we show the player
539
- if on the player : we show the UI
540
- if on the UI : we exit the app
541
- */
530
+ /**
531
+ When pressing backspace or the Native "Back" button:
532
+ if on the transport controls: we show the player
533
+ if on the player : we show the UI
534
+ if on the UI : we exit the app
535
+ */
542
536
 
543
- if (
544
- keyCode(event).matchesAny(
545
- KEYS.Back,
546
- KEYS.Escape,
547
- KEYS.EscapeDevice,
548
- KEYS.Backspace
549
- )
550
- ) {
551
- switch (displayState) {
552
- case DISPLAY_STATES.DEFAULT:
553
- case DISPLAY_STATES.PLAYER:
554
- if (isDialogVisible) {
555
- this.onConfirmDialogClose();
556
- } else if (navigator.canGoBack()) {
557
- navigator.goBack();
558
- } else if (this.isHomeScreen()) {
537
+ if (
538
+ keyCode(event).matchesAny(
539
+ KEYS.Back,
540
+ KEYS.Escape,
541
+ KEYS.EscapeDevice,
542
+ KEYS.Backspace
543
+ )
544
+ ) {
545
+ switch (displayState) {
546
+ case DISPLAY_STATES.DEFAULT:
547
+ case DISPLAY_STATES.PLAYER:
548
+ if (isDialogVisible) {
549
+ this.onConfirmDialogClose();
550
+ } else if (navigator.canGoBack()) {
551
+ navigator.goBack();
552
+ } else if (this.isHomeScreen()) {
553
+ this.platformBack();
554
+ } else if (navigator.currentRoute.includes("hook")) {
555
+ // If code reaches this block navigator cant go back, it is not home,
556
+ // and this is a login plugin that was pushed on top of the home
557
+ // Treat it like a home screen and run platformBack()
558
+ const entryData = navigator?.data?.entry;
559
+ const isHookInHomescreen = entryData?.payload?.home;
560
+
561
+ const isHookFlowBlocker =
562
+ entryData?.hookPlugin?.module?.isFlowBlocker();
563
+
564
+ if (isHookInHomescreen && isHookFlowBlocker) {
559
565
  this.platformBack();
560
- } else if (navigator.currentRoute.includes("hook")) {
561
- // If code reaches this block navigator cant go back, it is not home,
562
- // and this is a login plugin that was pushed on top of the home
563
- // Treat it like a home screen and run platformBack()
564
- const entryData = navigator?.data?.entry;
565
- const isHookInHomescreen = entryData?.payload?.home;
566
-
567
- const isHookFlowBlocker =
568
- entryData?.hookPlugin?.module?.isFlowBlocker();
569
-
570
- if (isHookInHomescreen && isHookFlowBlocker) {
571
- this.platformBack();
572
- } else {
573
- navigator.goBack(false, true);
574
- }
575
566
  } else {
576
- this.goToHome();
567
+ navigator.goBack(false, true);
577
568
  }
569
+ } else {
570
+ this.goToHome();
571
+ }
578
572
 
579
- break;
580
- case DISPLAY_STATES.HUD:
581
- // IF transport controls are open, close them instead of closing player
582
- setDisplayState(DISPLAY_STATES.PLAYER);
583
- break;
584
- default:
585
- setDisplayState(DISPLAY_STATES.PLAYER);
586
- break;
587
- }
573
+ break;
574
+ case DISPLAY_STATES.HUD:
575
+ // IF transport controls are open, close them instead of closing player
576
+ setDisplayState(DISPLAY_STATES.PLAYER);
577
+ break;
578
+ default:
579
+ setDisplayState(DISPLAY_STATES.PLAYER);
580
+ break;
588
581
  }
582
+ }
589
583
 
590
- if (keyCode(event).matches(KEYS.Enter)) {
591
- if (displayState === DISPLAY_STATES.PLAYER) {
592
- setDisplayState(DISPLAY_STATES.HUD);
593
- } else {
594
- focusManager.press();
595
- }
596
-
597
- return true;
584
+ if (keyCode(event).matches(KEYS.Enter)) {
585
+ if (displayState === DISPLAY_STATES.PLAYER) {
586
+ setDisplayState(DISPLAY_STATES.HUD);
587
+ } else {
588
+ focusManager.press();
598
589
  }
599
590
 
600
- if (keyCode(event).matches(KEYS.Exit)) {
601
- if (isSamsungPlatform() || shouldUseOnScreenKeyboard()) {
602
- this.performExit();
591
+ return true;
592
+ }
603
593
 
604
- return;
605
- }
594
+ if (keyCode(event).matches(KEYS.Exit)) {
595
+ if (isSamsungPlatform() || shouldUseOnScreenKeyboard()) {
596
+ this.performExit();
606
597
 
607
- this.platformBack();
598
+ return;
608
599
  }
609
600
 
610
- if (
611
- keyCode(event).matchesAny(...ARROW_KEYS) &&
612
- !this.state.isKeyboardVisible
613
- ) {
614
- if (displayState === DISPLAY_STATES.PLAYER) {
615
- setDisplayState(DISPLAY_STATES.HUD);
616
- }
617
-
618
- this.checkSequence(event.keyCode);
619
-
620
- const direction = keyCode(event).direction();
621
-
622
- if (!isDialogVisible || !["up", "down"].includes(direction.value)) {
623
- focusManager.moveFocus(direction);
624
- }
625
-
626
- if (!isDialogVisible) {
627
- // run focus recovery on user interaction attempt
628
- // probably we failed to set initial focus for some reason
629
- focusManager.recoverFocus();
630
- }
631
-
632
- if (
633
- displayState === DISPLAY_STATES.PLAYER ||
634
- displayState === DISPLAY_STATES.HUD
635
- ) {
636
- this.resetHudTimeout();
637
- }
601
+ this.platformBack();
602
+ }
638
603
 
639
- return true;
604
+ if (
605
+ keyCode(event).matchesAny(...ARROW_KEYS) &&
606
+ !this.state.isKeyboardVisible
607
+ ) {
608
+ if (displayState === DISPLAY_STATES.PLAYER) {
609
+ setDisplayState(DISPLAY_STATES.HUD);
640
610
  }
641
- }
642
611
 
643
- onScroll(event) {
644
- const { displayState } = this.props;
612
+ this.checkSequence(event.keyCode);
645
613
 
646
- const deltaY = event?.deltaY;
614
+ const direction = keyCode(event).direction();
647
615
 
648
- const DIRECTION = {
649
- axis: "y",
650
- isHorizontal: false,
651
- isVertical: true,
652
- value: "",
653
- };
616
+ if (!isDialogVisible || !["up", "down"].includes(direction.value)) {
617
+ focusManager.moveFocus(direction);
618
+ }
654
619
 
655
- if (deltaY > 0) {
656
- DIRECTION.value = isLgPlatform() ? "down" : "up";
657
- } else if (deltaY < 0) {
658
- DIRECTION.value = isLgPlatform() ? "up" : "down";
620
+ if (!isDialogVisible) {
621
+ // run focus recovery on user interaction attempt
622
+ // probably we failed to set initial focus for some reason
623
+ focusManager.recoverFocus();
659
624
  }
660
625
 
661
626
  if (
@@ -663,112 +628,138 @@ export function withInteractionManager(Component: React.FC) {
663
628
  displayState === DISPLAY_STATES.HUD
664
629
  ) {
665
630
  this.resetHudTimeout();
666
- } else {
667
- focusManager.moveFocus(DIRECTION);
668
631
  }
632
+
633
+ return true;
669
634
  }
635
+ }
670
636
 
671
- onMouseDown(event) {
672
- const { button } = event;
673
- const { displayState } = this.props;
637
+ onScroll(event) {
638
+ const { displayState } = this.props;
674
639
 
675
- if (
676
- button === 1 && // number 1 represents press on the scroll wheel
677
- (displayState === DISPLAY_STATES.PLAYER ||
678
- displayState === DISPLAY_STATES.HUD)
679
- ) {
680
- this.resetHudTimeout();
681
- }
682
- }
640
+ const deltaY = event?.deltaY;
683
641
 
684
- onKeyboardStateChange(event) {
685
- this.setState({ isKeyboardVisible: event.visibility });
642
+ const DIRECTION = {
643
+ axis: "y",
644
+ isHorizontal: false,
645
+ isVertical: true,
646
+ value: "",
647
+ };
648
+
649
+ if (deltaY > 0) {
650
+ DIRECTION.value = isLgPlatform() ? "down" : "up";
651
+ } else if (deltaY < 0) {
652
+ DIRECTION.value = isLgPlatform() ? "up" : "down";
686
653
  }
687
654
 
688
- onConfirmDialogOpen() {
689
- this.confirmDialog.showDialog();
655
+ if (
656
+ displayState === DISPLAY_STATES.PLAYER ||
657
+ displayState === DISPLAY_STATES.HUD
658
+ ) {
659
+ this.resetHudTimeout();
660
+ } else {
661
+ focusManager.moveFocus(DIRECTION);
690
662
  }
663
+ }
691
664
 
692
- onConfirmDialogClose() {
693
- this.confirmDialog.hideDialog();
665
+ onMouseDown(event) {
666
+ const { button } = event;
667
+ const { displayState } = this.props;
694
668
 
695
- // restore initial focus after closing dialog
696
- focusManager.setInitialFocus();
669
+ if (
670
+ button === 1 && // number 1 represents press on the scroll wheel
671
+ (displayState === DISPLAY_STATES.PLAYER ||
672
+ displayState === DISPLAY_STATES.HUD)
673
+ ) {
674
+ this.resetHudTimeout();
697
675
  }
676
+ }
698
677
 
699
- handleInputFocus = (event: FocusEvent) => {
700
- if (!shouldUseOnScreenKeyboard()) return;
701
- const target = event.target as HTMLElement;
678
+ onKeyboardStateChange(event) {
679
+ this.setState({ isKeyboardVisible: event.visibility });
680
+ }
702
681
 
703
- if (this.isDismissing) {
704
- return;
705
- }
682
+ onConfirmDialogOpen() {
683
+ this.confirmDialog.showDialog();
684
+ }
706
685
 
707
- if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
708
- this.setState({
709
- isKeyboardVisible: true,
710
- keyboardInput: (target as HTMLInputElement).value || "",
711
- });
712
- }
713
- };
686
+ onConfirmDialogClose() {
687
+ this.confirmDialog.hideDialog();
714
688
 
715
- handleInputBlur(event: FocusEvent) {
716
- if (!shouldUseOnScreenKeyboard()) return;
689
+ // restore initial focus after closing dialog
690
+ focusManager.setInitialFocus();
691
+ }
717
692
 
718
- const target = event.target as HTMLElement;
693
+ handleInputFocus = (event: FocusEvent) => {
694
+ if (!shouldUseOnScreenKeyboard()) return;
695
+ const target = event.target as HTMLElement;
719
696
 
720
- if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
721
- const relatedTarget = event.relatedTarget as HTMLElement;
697
+ if (this.isDismissing) {
698
+ return;
699
+ }
722
700
 
723
- if (
724
- !relatedTarget ||
725
- (relatedTarget.tagName !== "INPUT" &&
726
- relatedTarget.tagName !== "TEXTAREA")
727
- ) {
728
- this.setState({ isKeyboardVisible: false });
729
- }
730
- }
701
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
702
+ this.setState({
703
+ isKeyboardVisible: true,
704
+ keyboardInput: (target as HTMLInputElement).value || "",
705
+ });
731
706
  }
707
+ };
732
708
 
733
- handleKeyboardDismiss = () => {
734
- this.isDismissing = true;
709
+ handleInputBlur(event: FocusEvent) {
710
+ if (!shouldUseOnScreenKeyboard()) return;
735
711
 
736
- this.setState(
737
- {
738
- isKeyboardVisible: false,
739
- keyboardInput: "",
740
- },
741
- () => {
742
- this.isDismissing = false;
743
- }
744
- );
745
- };
712
+ const target = event.target as HTMLElement;
746
713
 
747
- handleKeyboardInput(value: string) {
748
- this.setState({ keyboardInput: value });
749
- }
714
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
715
+ const relatedTarget = event.relatedTarget as HTMLElement;
750
716
 
751
- render() {
752
- return (
753
- <>
754
- <Component {...this.props} />
755
- {shouldUseOnScreenKeyboard() && this.state.isKeyboardVisible && (
756
- <OnScreenKeyboard
757
- initialValue={this.state.keyboardInput}
758
- onInput={this.handleKeyboardInput}
759
- onDismiss={this.handleKeyboardDismiss}
760
- />
761
- )}
762
- </>
763
- );
717
+ if (
718
+ !relatedTarget ||
719
+ (relatedTarget.tagName !== "INPUT" &&
720
+ relatedTarget.tagName !== "TEXTAREA")
721
+ ) {
722
+ this.setState({ isKeyboardVisible: false });
723
+ }
764
724
  }
765
725
  }
766
726
 
767
- return R.compose(
768
- withNavigator,
769
- withUseSeek,
770
- withXray,
771
- PlayerContentContext.withConsumer,
772
- DisplayStateContext.withConsumer
773
- )(InteractionManager);
727
+ handleKeyboardDismiss = () => {
728
+ this.isDismissing = true;
729
+
730
+ this.setState(
731
+ {
732
+ isKeyboardVisible: false,
733
+ keyboardInput: "",
734
+ },
735
+ () => {
736
+ this.isDismissing = false;
737
+ }
738
+ );
739
+ };
740
+
741
+ handleKeyboardInput(value: string) {
742
+ this.setState({ keyboardInput: value });
743
+ }
744
+
745
+ render() {
746
+ return (
747
+ (shouldUseOnScreenKeyboard() && this.state.isKeyboardVisible && (
748
+ <OnScreenKeyboard
749
+ initialValue={this.state.keyboardInput}
750
+ onInput={this.handleKeyboardInput}
751
+ onDismiss={this.handleKeyboardDismiss}
752
+ />
753
+ )) ||
754
+ null
755
+ );
756
+ }
774
757
  }
758
+
759
+ export const InteractionManager = R.compose(
760
+ withNavigator,
761
+ withUseSeek,
762
+ withXray,
763
+ PlayerContentContext.withConsumer,
764
+ DisplayStateContext.withConsumer
765
+ )(InteractionManagerClass);
package/index.js CHANGED
@@ -1,23 +1,22 @@
1
1
  /// <reference types="@applicaster/applicaster-types" />
2
2
  import * as R from "ramda";
3
- import { useLocation, useHistory } from "react-router-dom";
3
+ import { useHistory, useLocation } from "react-router-dom";
4
4
 
5
5
  import { createQuickBrickApp } from "@applicaster/quick-brick-core";
6
6
  import * as QuickBrickManager from "@applicaster/zapp-react-native-bridge/QuickBrick";
7
7
  import * as Contexts from "@applicaster/zapp-react-native-ui-components/Contexts";
8
8
  import { OfflineHandler } from "@applicaster/zapp-react-native-ui-components/Components/OfflineHandler";
9
9
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
10
-
11
- const { withXray } = getXray();
12
-
13
10
  import { ZappDomRouter } from "./App/Router";
14
11
  import { Layout } from "./App/Layout";
15
12
  import { SplashLoader } from "./App/Loader/SplashLoader";
16
13
  import { appLoader } from "./App/Loader";
17
14
 
18
- import { withInteractionManager } from "./App/InteractionManager";
15
+ import { InteractionManager } from "./App/InteractionManager";
19
16
  import "./main.css";
20
17
 
18
+ const { withXray } = getXray();
19
+
21
20
  const contextProviders = R.map(R.prop("withProvider"), R.values(Contexts));
22
21
 
23
22
  // Add DOM specific providers
@@ -33,7 +32,7 @@ export const ZappApp = createQuickBrickApp({
33
32
  QuickBrickManager,
34
33
  Layout,
35
34
  OfflineHandler,
36
- InteractionManager: withInteractionManager,
35
+ InteractionManager,
37
36
  appLoader,
38
37
  SplashLoader,
39
38
  ContextProviders: contextProviders,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-dom-app",
3
- "version": "12.0.0-rc.104",
3
+ "version": "12.0.0-rc.106",
4
4
  "description": "Zapp App Component for Applicaster's Quick Brick React Native App",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "homepage": "https://github.com/applicaster/zapp-react-dom-app#readme",
24
24
  "dependencies": {
25
- "@applicaster/zapp-react-dom-ui-components": "12.0.0-rc.104",
26
- "@applicaster/zapp-react-native-bridge": "12.0.0-rc.104",
27
- "@applicaster/zapp-react-native-redux": "12.0.0-rc.104",
28
- "@applicaster/zapp-react-native-ui-components": "12.0.0-rc.104",
29
- "@applicaster/zapp-react-native-utils": "12.0.0-rc.104",
25
+ "@applicaster/zapp-react-dom-ui-components": "12.0.0-rc.106",
26
+ "@applicaster/zapp-react-native-bridge": "12.0.0-rc.106",
27
+ "@applicaster/zapp-react-native-redux": "12.0.0-rc.106",
28
+ "@applicaster/zapp-react-native-ui-components": "12.0.0-rc.106",
29
+ "@applicaster/zapp-react-native-utils": "12.0.0-rc.106",
30
30
  "abortcontroller-polyfill": "^1.7.5",
31
31
  "history": "^4.7.2",
32
32
  "react-router-dom": "^5.1.2",