@applicaster/zapp-react-native-utils 12.0.0-alpha.5035843303 → 12.0.0-alpha.5050333009

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.
Files changed (138) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +16 -8
  2. package/analyticsUtils/AnalyticsEvents/index.ts +13 -0
  3. package/analyticsUtils/AnalyticsEvents/searchEvents.ts +21 -0
  4. package/analyticsUtils/AnalyticsEvents/sendShareEvent.ts +21 -0
  5. package/analyticsUtils/__tests__/analyticsManager.test.js +75 -73
  6. package/analyticsUtils/analyticsPlugins.ts +25 -0
  7. package/analyticsUtils/events.ts +12 -0
  8. package/analyticsUtils/helpers/hooks.ts +1 -1
  9. package/analyticsUtils/index.tsx +12 -0
  10. package/appUtils/HooksManager/{Hook.js → Hook.ts} +35 -23
  11. package/appUtils/HooksManager/{constants.js → constants.ts} +1 -1
  12. package/appUtils/HooksManager/{index.js → index.ts} +121 -112
  13. package/appUtils/HooksManager/types.ts +116 -0
  14. package/appUtils/RiverFocusManager/index.js +17 -12
  15. package/appUtils/accessibilityManager/const.ts +50 -0
  16. package/appUtils/accessibilityManager/hooks.ts +31 -0
  17. package/appUtils/accessibilityManager/index.ts +150 -0
  18. package/appUtils/accessibilityManager/logger.ts +5 -0
  19. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +2 -3
  20. package/appUtils/focusManager/__tests__/focusManager.test.js +4 -24
  21. package/appUtils/focusManager/__tests__/index.test.ts +2 -3
  22. package/appUtils/focusManager/index.ts +76 -57
  23. package/appUtils/focusManager/treeDataStructure/Tree/index.js +2 -3
  24. package/appUtils/focusManager/treeDataStructure/Utils/index.js +76 -38
  25. package/appUtils/focusManager/utils/index.ts +100 -0
  26. package/appUtils/focusManagerAux/index.ts +76 -0
  27. package/appUtils/focusManagerAux/utils/index.ts +100 -0
  28. package/appUtils/{index.js → index.ts} +2 -0
  29. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +1 -1
  30. package/appUtils/keyCodes/__tests__/keyCodes.test.js +80 -85
  31. package/appUtils/keyCodes/{index.js → index.ts} +2 -0
  32. package/appUtils/keyCodes/keys/index.ts +3 -0
  33. package/appUtils/keyCodes/{keys.android.js → keys/keyEventMapper.ts} +0 -19
  34. package/appUtils/keyCodes/keys/keys.android.ts +18 -0
  35. package/appUtils/keyCodes/keys/keys.ios.ts +25 -0
  36. package/appUtils/keyCodes/keys/keys.ts +15 -0
  37. package/appUtils/keyCodes/{keys.web.js → keys/keys.web.ts} +9 -0
  38. package/appUtils/keyCodes/{keysByPlatform.js → keys/keysByPlatform.ts} +11 -1
  39. package/appUtils/orientationHelper.ts +1 -1
  40. package/appUtils/platform/const.ts +25 -0
  41. package/appUtils/platform/index.ts +3 -0
  42. package/appUtils/platform/platformUtils.ts +171 -0
  43. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +53 -0
  44. package/appUtils/playerManager/conts.ts +5 -0
  45. package/appUtils/playerManager/index.ts +11 -5
  46. package/appUtils/playerManager/nativePlayerManager.ts +12 -0
  47. package/appUtils/playerManager/player.ts +48 -7
  48. package/appUtils/playerManager/playerFactory.ts +15 -1
  49. package/appUtils/playerManager/playerNative.ts +40 -14
  50. package/appUtils/playerManager/usePlayerControllerSetup.tsx +7 -1
  51. package/appUtils/playerManager/usePlayerState.tsx +13 -1
  52. package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +50 -0
  53. package/arrayUtils/__tests__/isFilledArray.test.ts +63 -0
  54. package/arrayUtils/index.ts +5 -0
  55. package/booleanUtils/index.ts +4 -4
  56. package/cellUtils/__tests__/cellUtils.test.ts +48 -0
  57. package/cellUtils/__tests__/fixtures.ts +13 -0
  58. package/cellUtils/index.ts +40 -2
  59. package/dateUtils/index.ts +11 -0
  60. package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
  61. package/focusManager/index.ts +1 -1
  62. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +2 -2
  63. package/functionUtils/__tests__/functionUtils.test.js +244 -248
  64. package/functionUtils/index.ts +15 -11
  65. package/headersUtils/index.ts +1 -0
  66. package/inflatedUrlUtils/index.ts +4 -4
  67. package/keyboardState/index.ts +0 -0
  68. package/localizationUtils/__tests__/localizationUtils.test.ts +78 -55
  69. package/localizationUtils/index.ts +13 -19
  70. package/logger/index.ts +1 -1
  71. package/manifestUtils/defaultManifestConfigurations/generalContent.js +6 -0
  72. package/manifestUtils/defaultManifestConfigurations/player.js +10 -1
  73. package/manifestUtils/index.js +5 -1
  74. package/manifestUtils/secondaryImage/index.js +18 -15
  75. package/modalState/index.ts +53 -0
  76. package/navigationUtils/index.ts +118 -12
  77. package/numberUtils/__tests__/isLikeNumber.test.ts +18 -0
  78. package/numberUtils/index.ts +9 -18
  79. package/package.json +3 -2
  80. package/playerUtils/configurationGenerator.ts +11 -1
  81. package/pluginUtils/index.ts +20 -7
  82. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +2 -0
  83. package/reactHooks/autoscrolling/__tests__/{useTrackedView.test.ts → useTrackedView.test.tsx} +18 -1
  84. package/reactHooks/cell-click/__tests__/index.test.js +16 -3
  85. package/reactHooks/cell-click/index.ts +14 -14
  86. package/reactHooks/device/index.ts +0 -1
  87. package/reactHooks/device/useIsTablet.tsx +28 -3
  88. package/reactHooks/device/useMemoizedIsTablet.ts +1 -1
  89. package/reactHooks/device/useOrientation.tsx +3 -1
  90. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +30 -70
  91. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +6 -2
  92. package/reactHooks/feed/__tests__/useInflatedUrl.test.ts +18 -3
  93. package/reactHooks/feed/useBuildPipesUrl.ts +7 -10
  94. package/reactHooks/feed/useFeedRefresh.tsx +9 -7
  95. package/reactHooks/feed/useInflatedUrl.ts +44 -15
  96. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -9
  97. package/reactHooks/index.ts +2 -0
  98. package/reactHooks/layout/__tests__/{index.test.js → index.test.tsx} +66 -59
  99. package/reactHooks/layout/getDeviceInfo/index.ts +4 -2
  100. package/reactHooks/layout/index.ts +2 -1
  101. package/reactHooks/layout/types/index.ts +2 -0
  102. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +11 -16
  103. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +12 -14
  104. package/reactHooks/layout/useDimensions/useDimensions.ts +13 -7
  105. package/reactHooks/navigation/__mocks__/index.ts +15 -0
  106. package/reactHooks/navigation/__mocks__/useNavigation.ts +7 -0
  107. package/reactHooks/navigation/__tests__/index.test.tsx +240 -81
  108. package/reactHooks/navigation/index.ts +246 -84
  109. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +3 -1
  110. package/reactHooks/screen/__mocks__/useScreenContext.ts +3 -1
  111. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +21 -23
  112. package/reactHooks/screen/index.ts +4 -0
  113. package/reactHooks/screen/useScreenBackgroundColor.ts +23 -0
  114. package/reactHooks/screen/useScreenContext.ts +4 -4
  115. package/reactHooks/screen/useScreenData.ts +1 -1
  116. package/reactHooks/screen/useTargetScreenData.ts +7 -0
  117. package/reactHooks/state/useRivers.ts +3 -1
  118. package/reactHooks/useListenEventBusEvent.ts +6 -15
  119. package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +10 -9
  120. package/reactUtils/index.ts +91 -0
  121. package/riverComponetsMeasurementProvider/index.tsx +2 -2
  122. package/stringUtils/index.ts +5 -0
  123. package/testUtils/getByTestId.ts +14 -0
  124. package/testUtils/index.tsx +38 -23
  125. package/types.ts +4 -0
  126. package/zappFrameworkUtils/loginPluginUtils.ts +12 -2
  127. package/appUtils/focusManager/FocusableEvents.ts +0 -8
  128. package/appUtils/focusManager/treeDataStructure/Utils/__tests__/Utils_android.test.js +0 -1094
  129. package/appUtils/focusManager/treeDataStructure/Utils/index.android.js +0 -261
  130. package/appUtils/keyCodes/keys.ios.js +0 -46
  131. package/reactHooks/device/useIsTablet.android.tsx +0 -14
  132. package/reactHooks/device/useIsTablet.ios.tsx +0 -7
  133. package/reactHooks/device/useIsTablet.web.tsx +0 -3
  134. /package/appUtils/HooksManager/{logger.js → logger.ts} +0 -0
  135. /package/appUtils/{directionHelper.js → directionHelper.ts} +0 -0
  136. /package/appUtils/keyCodes/{androidTVKeys.js → androidTVKeys.ts} +0 -0
  137. /package/appUtils/{localizationsHelper.js → localizationsHelper.ts} +0 -0
  138. /package/domUtils/{logger.js → logger.ts} +0 -0
@@ -10,14 +10,72 @@ import { Hook } from "./Hook";
10
10
  import { HOOKS_EVENTS, HOOKS_TYPE } from "./constants";
11
11
 
12
12
  import { hooksManagerLogger } from "./logger";
13
+ import { HookManager, HookManagerArgs } from "./types";
14
+
15
+ /**
16
+ * orders the hooks according to their weight
17
+ * @param {Array<object>} hooks to sort out
18
+ * @returns {Array<object>} sorted hooks
19
+ */
20
+ function orderHooksByWeight(hooks: Hook[]) {
21
+ return R.sortBy(R.compose(Number, R.prop("weight")), hooks);
22
+ }
23
+
24
+ function executeOnNextHook(
25
+ hooks: Hook[],
26
+ payload: object,
27
+ callback: (hookPlugin: Hook, restOfHooks: Hook[], payload: object) => void
28
+ ) {
29
+ const [nextHook, ...restOfHooks] = orderHooksByWeight(hooks);
30
+
31
+ if (nextHook) {
32
+ nextHook.execute(payload, callback(nextHook, restOfHooks, payload));
33
+ }
34
+ }
35
+
36
+ /**
37
+ * tells wether the current river is related to a player plugin, or the default player
38
+ * @param {Object} river
39
+ * @returns {boolean}
40
+ */
41
+ function riverIsPlayer(river, plugins) {
42
+ const { screenType, plugin_type } = river;
43
+
44
+ if (screenType || plugin_type) {
45
+ return screenType === "playable" || plugin_type === "player";
46
+ }
47
+
48
+ const { type } = river;
49
+
50
+ return R.compose(
51
+ R.propEq("type", "player"),
52
+ R.defaultTo({}),
53
+ R.find(R.propEq("identifier", type))
54
+ )(plugins);
55
+ }
56
+
57
+ /**
58
+ * Injects the hooks for the player
59
+ * @param _hookType type of hook
60
+ * @param plugins plugins
61
+ * @returns {Array<Object>}
62
+ */
63
+ function injectPlayerHooks(_hookType: string, plugins): Hook[] {
64
+ const playerhooks: Hook[] = R.compose(
65
+ R.sortBy(R.prop("weight")),
66
+ R.map((plugin) => ({
67
+ identifier: plugin.identifier,
68
+ weight: R.path(["module", "weight"], plugin) || 1,
69
+ })),
70
+ R.filter(R.pathEq(["module", "hasPlayerHook"], true))
71
+ )(plugins);
72
+
73
+ return playerhooks;
74
+ }
13
75
 
14
76
  /**
15
77
  * creates a hooksManager object to handle the hooks process.
16
78
  * it is based on the `subscriber` object
17
- * @param {object} options
18
- * @param {object} rivers map of rivers in the app
19
- * @param {object} targetScreen rivers which we are navigating to
20
- * @param {Array<object>} plugins array of plugins in the app
21
79
  * @returns {object} hooksManager object - see Navigator for usage
22
80
  */
23
81
  export function HooksManager({
@@ -25,7 +83,7 @@ export function HooksManager({
25
83
  targetScreen,
26
84
  plugins,
27
85
  startUpHooksData = {},
28
- }) {
86
+ }: HookManagerArgs): HookManager {
29
87
  hooksManagerLogger.addContext({ targetScreen });
30
88
 
31
89
  function logHookEvent(func, message, data) {
@@ -35,7 +93,8 @@ export function HooksManager({
35
93
  });
36
94
  }
37
95
 
38
- const hooksManager = subscriber();
96
+ const hooksManager: Partial<HookManager> = {};
97
+ hooksManager.subscriber = subscriber();
39
98
 
40
99
  /**
41
100
  * attaches the screen data to the hook object if the hook
@@ -100,15 +159,6 @@ export function HooksManager({
100
159
  };
101
160
  }
102
161
 
103
- /**
104
- * orders the hooks according to their weight
105
- * @param {Array<object>} hooks to sort out
106
- * @returns {Array<object>} sorted hooks
107
- */
108
- function orderHooksByWeight(hooks) {
109
- return R.sortBy(R.compose(Number, R.prop("weight")), hooks);
110
- }
111
-
112
162
  /**
113
163
  * extracts the hooks form the target river. returns null if there are none
114
164
  * if there are hooks, gathers all required data and constructs a Hook object
@@ -117,10 +167,10 @@ export function HooksManager({
117
167
  * @returns {Array<Hooks>} list of hooks to go through
118
168
  */
119
169
  function getHooks(hookType, river) {
120
- const playerhooks = [];
170
+ const playerhooks: Hook[] = [];
121
171
 
122
- if (riverIsPlayer(river)) {
123
- playerhooks.push(...injectPlayerHooks(hookType));
172
+ if (riverIsPlayer(river, plugins)) {
173
+ playerhooks.push(...injectPlayerHooks(hookType, plugins));
124
174
  }
125
175
 
126
176
  let hooks = R.concat(playerhooks, R.pathOr([], ["hooks", hookType], river));
@@ -130,8 +180,10 @@ export function HooksManager({
130
180
  const { startUpHooks, setStartUpHooks } = startUpHooksData;
131
181
 
132
182
  if (startUpHooks && startUpHooks !== "in_process") {
133
- hooks.unshift(...startUpHooks);
134
- setStartUpHooks("in_process");
183
+ if (Array.isArray(startUpHooks)) {
184
+ hooks.unshift(...startUpHooks);
185
+ setStartUpHooks("in_process");
186
+ }
135
187
  }
136
188
 
137
189
  if (!R.length(hooks)) {
@@ -158,45 +210,6 @@ export function HooksManager({
158
210
  )(hooks);
159
211
  }
160
212
 
161
- /**
162
- * tells wether the current river is related to a player plugin, or the default player
163
- * @param {Object} river
164
- * @returns {boolean}
165
- */
166
- function riverIsPlayer(river) {
167
- const { screenType, plugin_type } = river;
168
-
169
- if (screenType || plugin_type) {
170
- return screenType === "playable" || plugin_type === "player";
171
- }
172
-
173
- const { type } = river;
174
-
175
- return R.compose(
176
- R.propEq("type", "player"),
177
- R.defaultTo({}),
178
- R.find(R.propEq("identifier", type))
179
- )(plugins);
180
- }
181
-
182
- /**
183
- * Injects the hooks for the player
184
- * @param {String} hookType type of hook
185
- * @returns {Array<Object>}
186
- */
187
- function injectPlayerHooks(_hookType) {
188
- const playerhooks = R.compose(
189
- R.sortBy(R.prop("weight")),
190
- R.map((plugin) => ({
191
- identifier: plugin.identifier,
192
- weight: R.path(["module", "weight"], plugin) || 1,
193
- })),
194
- R.filter(R.pathEq(["module", "hasPlayerHook"], true))
195
- )(plugins);
196
-
197
- return playerhooks;
198
- }
199
-
200
213
  /**
201
214
  * tells wether the given hook is the last one or not
202
215
  * @param {Hook} hookPlugin
@@ -209,6 +222,32 @@ export function HooksManager({
209
222
  return hookPlugin.lastHook;
210
223
  }
211
224
 
225
+ /**
226
+ * flags a hook as succeeded, and pass hook data along
227
+ * @param {Hook} hookPlugin
228
+ * @param {object} payload returned by the hook plugin
229
+ */
230
+ function completeHook(hookPlugin, payload, callback) {
231
+ logHookEvent(
232
+ hooksManagerLogger.info,
233
+ `completeHook: hook sequence completed successfully: ${hookPlugin["identifier"]}`,
234
+ {
235
+ payload,
236
+ hook: hookPlugin,
237
+ }
238
+ );
239
+
240
+ // eslint-disable-next-line
241
+ // TODO: Temporary hack to pass getLoginProtocol to other plugins to refresh in case token expired, need be deleted later
242
+ delete payload.getLoginProtocol;
243
+
244
+ hookPlugin.setStateAndNotify(HOOKS_EVENTS.COMPLETE, {
245
+ hookPlugin,
246
+ payload,
247
+ callback,
248
+ });
249
+ }
250
+
212
251
  /**
213
252
  * creates the callback to invoke in order to proceed to the next hook
214
253
  * covers the scenarios of failure & flow blocking
@@ -228,9 +267,11 @@ export function HooksManager({
228
267
  success,
229
268
  error,
230
269
  payload = initialPayload,
231
- callback,
270
+ callback: callbackArg,
232
271
  cancelled,
233
272
  }) {
273
+ let callback = callbackArg;
274
+
234
275
  if (error) {
235
276
  logHookEvent(
236
277
  hooksManagerLogger.error,
@@ -270,7 +311,9 @@ export function HooksManager({
270
311
  });
271
312
 
272
313
  const isHookInHomescreen = payload?.home;
273
- const isHookFlowBlocker = hookPlugin?.module?.isFlowBlocker();
314
+
315
+ const isHookFlowBlocker =
316
+ hookPlugin?.module?.isFlowBlocker?.() ?? false;
274
317
 
275
318
  // TODO: We technically need to also support the case where there is more than one hook in the stack,
276
319
  // if needed we could add differentiation explicit user cancellation (when we should go to background) and other types of cancellation
@@ -299,6 +342,18 @@ export function HooksManager({
299
342
  }
300
343
  );
301
344
 
345
+ if (!callback) {
346
+ logHookEvent(
347
+ hooksManagerLogger.warn,
348
+ `hookCallback: ${hookPlugin["identifier"]} is missing \`callback\`, using hookCallback(default one)`,
349
+ {
350
+ hookPlugin,
351
+ }
352
+ );
353
+
354
+ callback = hookCallback;
355
+ }
356
+
302
357
  hookPlugin.setStateAndNotify(HOOKS_EVENTS.SUCCESS, {
303
358
  hookPlugin,
304
359
  payload,
@@ -307,37 +362,11 @@ export function HooksManager({
307
362
 
308
363
  isLastHook(hookPlugin, restOfHooks)
309
364
  ? completeHook(hookPlugin, payload, callback)
310
- : handleNextHook(restOfHooks, payload);
365
+ : executeOnNextHook(restOfHooks, payload, callback);
311
366
  }
312
367
  };
313
368
  }
314
369
 
315
- /**
316
- * flags a hook as succeeded, and pass hook data along
317
- * @param {Hook} hookPlugin
318
- * @param {object} payload returned by the hook plugin
319
- */
320
- function completeHook(hookPlugin, payload, callback) {
321
- logHookEvent(
322
- hooksManagerLogger.info,
323
- `completeHook: hook sequence completed successfully: ${hookPlugin["identifier"]}`,
324
- {
325
- payload,
326
- hook: hookPlugin,
327
- }
328
- );
329
-
330
- // eslint-disable-next-line
331
- // TODO: Temporary hack to pass getLoginProtocol to other plugins to refresh in case token expired, need be deleted later
332
- delete payload.getLoginProtocol;
333
-
334
- hookPlugin.setStateAndNotify(HOOKS_EVENTS.COMPLETE, {
335
- hookPlugin,
336
- payload,
337
- callback,
338
- });
339
- }
340
-
341
370
  /**
342
371
  * presents a screen hook by triggering an event invoking the handler with
343
372
  * the appropriate route & payload
@@ -374,9 +403,6 @@ export function HooksManager({
374
403
 
375
404
  /**
376
405
  * executes a headless hook
377
- * @param {Hook} hookPlugin to present
378
- * @param {object} payload to pass to the hook module
379
- * @param {function} callback to invoke when the hook is successful
380
406
  */
381
407
  hooksManager.executeHook = function (hookPlugin, payload, callback) {
382
408
  logHookEvent(
@@ -442,30 +468,13 @@ export function HooksManager({
442
468
  }
443
469
  };
444
470
 
445
- /**
446
- * handles the next hook in the list of provided hooks, passing the payload along
447
- * @param {Array<Hook>} hooks to process
448
- * @param {object} payload to pass to the hook
449
- */
450
- function handleNextHook(hooks, payload) {
451
- const [hookPlugin, ...restOfHooks] = orderHooksByWeight(hooks);
452
-
453
- /**
454
- * Commenting out part of the code which is trying to run the next hook
455
- * in parallel - it's not in use, and it's creating unexpected side
456
- * effects
457
- * */
458
-
459
- hookPlugin.execute(payload, hookCallback(hookPlugin, restOfHooks, payload));
460
- }
461
-
462
471
  /**
463
472
  * function exposes on the hooks manager to trigger the handling of the hooks for
464
473
  * the given targetScreen
465
474
  * @param {object} payload to send to the hooks
466
475
  * @returns {object} returns the hooks manager so methods can be chained
467
476
  */
468
- hooksManager.handleHooks = function (payload) {
477
+ hooksManager.handleHooks = function (payload: object) {
469
478
  const preloadHooks = getHooks(HOOKS_TYPE.PRELOAD, targetScreen);
470
479
 
471
480
  if (preloadHooks?.length) {
@@ -480,9 +489,9 @@ export function HooksManager({
480
489
  }
481
490
  );
482
491
 
483
- handleNextHook(preloadHooks, payload);
492
+ executeOnNextHook(preloadHooks, payload, hookCallback);
484
493
  } else {
485
- hooksManager.invokeHandler(HOOKS_EVENTS.COMPLETE, {
494
+ hooksManager.subscriber.invokeHandler(HOOKS_EVENTS.COMPLETE, {
486
495
  hookPlugin: { lastHook: true },
487
496
  payload,
488
497
  });
@@ -491,5 +500,5 @@ export function HooksManager({
491
500
  return hooksManager;
492
501
  };
493
502
 
494
- return hooksManager;
503
+ return hooksManager as HookManager;
495
504
  }
@@ -0,0 +1,116 @@
1
+ import { SubscriberObj } from "../../functionUtils";
2
+ import { HOOKS_EVENTS } from "./constants";
3
+
4
+ export interface HookConfiguration {}
5
+
6
+ /* existing Hook Plugn props: sample */
7
+ interface _HookModulePlugin {
8
+ Component:
9
+ | React.FC<HookPluginProps>
10
+ | React.Component<HookPluginProps, any>
11
+ | React.ReactNode;
12
+ ModalContainer?: React.FC<ModalProps> | React.Component<ModalProps, any>;
13
+ skipHook?: (payload: ZappRiver | ZappEntry) => boolean;
14
+ presentFullScreen: boolean;
15
+ showNavBar?: boolean;
16
+ isFlowBlocker: (() => boolean) | boolean; // narrow this
17
+ hasPlayerHook?: boolean;
18
+ name: string;
19
+ runInBackground?: (
20
+ item: HookPluginProps["payload"],
21
+ callback: hookCallback,
22
+ hookPlugin: HookScreenData,
23
+ presentUI: (payload?: HookPluginProps["payload"]) => void
24
+ ) => any;
25
+ }
26
+
27
+ //* Derived from usage */
28
+ export interface HookModule {
29
+ ModalContainer?: React.ComponentType<any>;
30
+ Component: React.ComponentType<any>;
31
+ presentFullScreen: boolean;
32
+ run?: (
33
+ arg0: unknown,
34
+ callback: () => void,
35
+ configuration: HookConfiguration
36
+ ) => void; // not sure about optional parameter
37
+ hasPlayerHook?: boolean;
38
+ configuration?: HookConfiguration;
39
+ isFlowBlocker: () => boolean;
40
+ skipHook?: (payload?: ZappRiver | ZappEntry) => boolean;
41
+ runInBackground?: (
42
+ arg0: unknown,
43
+ callback: () => void,
44
+ hookPlugin: Hook,
45
+ presentUI: (payload?: HookPluginProps["payload"]) => void
46
+ ) => void;
47
+ name: string;
48
+ showNavBar?: boolean; // unsure
49
+ }
50
+
51
+ export type HookManagerArgs = {
52
+ rivers: Record<string, ZappRiver>;
53
+ plugins: ZappPlugin[];
54
+ targetScreen: ZappRiver;
55
+ startUpHooksData?: {
56
+ startUpHooks?: unknown[] | "in_process";
57
+ setStartUpHooks?: (arg0: string) => void;
58
+ };
59
+ };
60
+
61
+ export interface HookManager {
62
+ subscriber: SubscriberObj;
63
+ presentScreenHook: (
64
+ hook: Hook,
65
+ payload: unknown,
66
+ callback: (...any) => void
67
+ ) => void;
68
+ executeHook: (
69
+ hook: Hook,
70
+ payload: unknown,
71
+ callback: (...any) => void
72
+ ) => void;
73
+ handleHooks: (payload: unknown) => void;
74
+ runInBackground: (
75
+ hook: Hook,
76
+ payload: unknown,
77
+ callback: (...any) => void,
78
+ presentUI: (payload?: HookPluginProps["payload"]) => void
79
+ ) => void;
80
+ }
81
+
82
+ export type HookIniObj = {
83
+ hook: HookModule & {
84
+ module: HookModule;
85
+ general: unknown;
86
+ screen_id?: string;
87
+ identifier?: string;
88
+ weight?: number | string;
89
+ };
90
+ hooks: Hook<any>[];
91
+ manager: HookManager;
92
+ };
93
+
94
+ export interface Hook<T extends HookModule = HookModule> {
95
+ manager: HookManager;
96
+ lastHook: boolean;
97
+ state: number;
98
+ module: T;
99
+ screen_id: string;
100
+ identifier: string;
101
+ configuration: T["configuration"];
102
+ setStateAndNotify(
103
+ event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
104
+ opts: {
105
+ error?: typeof Error;
106
+ route?: string;
107
+ hookPlugin: Hook<T>;
108
+ payload: unknown;
109
+ }
110
+ );
111
+ general?: {
112
+ transition_type: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS];
113
+ allow_screen_plugin_presentation: boolean;
114
+ is_flow_blocker: boolean;
115
+ };
116
+ }
@@ -26,7 +26,7 @@ export const riverFocusManager = (function () {
26
26
  /**
27
27
  * Retrieve screen focus data by id
28
28
  *
29
- * @param {String} screenFocusableGroupId Id that was used to save screen data.
29
+ * @param {{screenFocusableGroupId: string}} screenFocusableGroupId Unique Id of the screen from layout.json
30
30
  *
31
31
  */
32
32
  function screenFocusableData({ screenFocusableGroupId }) {
@@ -36,8 +36,9 @@ export const riverFocusManager = (function () {
36
36
  /**
37
37
  * Clear screen data for specific screen
38
38
  *
39
- * @param {String} screenId Unique Id of the screen from layout.json
40
- * @param {boolean} isInsideContainer If this screen a screen picker child
39
+ * @param {{ screenId: string, isInsideContainer: boolean }}
40
+ * screenId Unique Id of the screen from layout.json
41
+ * isInsideContainer If this screen a screen picker child
41
42
  *
42
43
  */
43
44
  function clearScreenData({ screenId, isInsideContainer }) {
@@ -60,9 +61,13 @@ export const riverFocusManager = (function () {
60
61
  /**
61
62
  * Focus on selected items
62
63
  *
63
- * @param {String} screenFocusableGroupId Top group id that was saved as screenn
64
- * @param {String} screenFocusedOnItem focusable item to focus
65
- * @param {object} history navigator history object
64
+ * @param {{
65
+ * screenFocusableGroupId: string,
66
+ * screenFocusedOnItem: () => void,
67
+ * previousAction: QuickBrickNavigationActionType,
68
+ * isDeepLink: boolean }} object contains data for focus
69
+ * - `screenFocusedOnItem` focusable item to focus
70
+ * - `previousActionhistory` navigator history object
66
71
  *
67
72
  */
68
73
  function focusOnSelectedItem({
@@ -115,15 +120,15 @@ export const riverFocusManager = (function () {
115
120
 
116
121
  /**
117
122
  * Create unique key that will be used for save focused group data inside specific screen
118
- *
119
- * @param {String} screenId Unique Id of the screen from layout.json
120
- * @param {boolean} isInsideContainer If this screen a screen picker child
123
+ * @param {{ screenId: string, isInsideContainer: boolean }}
124
+ * screenId Unique Id of the screen from layout.json
125
+ * isInsideContainer If this screen a screen picker child
121
126
  *
122
127
  */
123
128
  function screenFocusableGroupId({ screenId, isInsideContainer }) {
124
- return R.isNil(isInsideContainer)
125
- ? `RiverFocusableGroup-${screenId}`
126
- : `RiverFocusableGroup-${screenId}-isInsideContainer`;
129
+ return `RiverFocusableGroup-${screenId}${
130
+ R.isNil(isInsideContainer) ? "" : "-isInsideContainer"
131
+ }`;
127
132
  }
128
133
 
129
134
  return {
@@ -0,0 +1,50 @@
1
+ export const BUTTON_ACCESSIBILITY_KEYS = {
2
+ play: {
3
+ label: "accessibility_play_label",
4
+ hint: "accessibility_play_hint",
5
+ mini: {
6
+ label: "accessibility_play_mini_label",
7
+ hint: "accessibility_play_mini_hint",
8
+ },
9
+ },
10
+ pause: {
11
+ label: "accessibility_pause_label",
12
+ hint: "accessibility_pause_hint",
13
+ mini: {
14
+ label: "accessibility_pause_mini_label",
15
+ hint: "accessibility_pause_mini_hint",
16
+ },
17
+ },
18
+ rewind: {
19
+ label: "accessibility_rewind_label",
20
+ hint: "accessibility_rewind_hint",
21
+ },
22
+ forward: {
23
+ label: "accessibility_forward_label",
24
+ hint: "accessibility_forward_hint",
25
+ },
26
+ close: {
27
+ label: "accessibility_close_label",
28
+ hint: "accessibility_close_hint",
29
+ mini: {
30
+ label: "accessibility_close_mini_label",
31
+ hint: "accessibility_close_mini_hint",
32
+ },
33
+ },
34
+ maximize: {
35
+ label: "accessibility_maximize_label",
36
+ hint: "accessibility_maximize_hint",
37
+ },
38
+ subtitles: {
39
+ label: "accessibility_subtitle_label",
40
+ hint: "accessibility_subtitle_hint",
41
+ },
42
+ back: {
43
+ label: "accessibility_back_label",
44
+ hint: "accessibility_back_hint",
45
+ },
46
+ fullscreen: {
47
+ label: "accessibility_fullscreen_label",
48
+ hint: "accessibility_fullscreen_hint",
49
+ },
50
+ } as const;
@@ -0,0 +1,31 @@
1
+ import { useEffect, useMemo } from "react";
2
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
+ import { AccessibilityManager } from "./index";
4
+
5
+ export const useAccessibilityManager = () => {
6
+ const { remoteConfigurations } = usePickFromState(["remoteConfigurations"]);
7
+ const { localizations } = remoteConfigurations;
8
+
9
+ const accessibilityManager = useMemo(() => {
10
+ return AccessibilityManager.getInstance();
11
+ }, []);
12
+
13
+ useEffect(() => {
14
+ accessibilityManager.updateLocalizations(localizations);
15
+ }, [localizations]);
16
+
17
+ useEffect(() => {
18
+ const subscription = accessibilityManager.getStateAsObservable().subscribe({
19
+ next: () => {
20
+ // TODO: handle accessibility states
21
+ // screenReaderEnabled: false
22
+ // reduceMotionEnabled: false
23
+ // boldTextEnabled: false
24
+ },
25
+ });
26
+
27
+ return () => subscription.unsubscribe();
28
+ }, [accessibilityManager]);
29
+
30
+ return accessibilityManager;
31
+ };