@applicaster/zapp-react-native-utils 12.0.0-rc.14 → 12.0.0-rc.141

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 (133) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +16 -8
  2. package/analyticsUtils/AnalyticPlayerListener.ts +141 -0
  3. package/analyticsUtils/AnalyticsEvents/index.ts +13 -0
  4. package/analyticsUtils/AnalyticsEvents/searchEvents.ts +21 -0
  5. package/analyticsUtils/AnalyticsEvents/sendShareEvent.ts +21 -0
  6. package/analyticsUtils/PlayerAnalyticsManager.ts +90 -0
  7. package/analyticsUtils/__tests__/analyticsManager.test.js +75 -73
  8. package/analyticsUtils/analyticsPlugins.ts +25 -0
  9. package/analyticsUtils/events.ts +12 -0
  10. package/analyticsUtils/helpers/hooks.ts +1 -1
  11. package/analyticsUtils/index.tsx +12 -0
  12. package/analyticsUtils/{analyticsTracker.ts → playerAnalyticsTracker.ts} +19 -10
  13. package/appUtils/HooksManager/index.js +3 -1
  14. package/appUtils/accessibilityManager/const.ts +50 -0
  15. package/appUtils/accessibilityManager/hooks.ts +40 -0
  16. package/appUtils/accessibilityManager/index.ts +155 -0
  17. package/appUtils/accessibilityManager/logger.ts +5 -0
  18. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +2 -3
  19. package/appUtils/focusManager/__tests__/focusManager.test.js +4 -24
  20. package/appUtils/focusManager/__tests__/index.test.ts +2 -3
  21. package/appUtils/focusManager/index.ts +76 -57
  22. package/appUtils/focusManager/treeDataStructure/Utils/index.js +75 -35
  23. package/appUtils/focusManager/utils/index.ts +100 -0
  24. package/appUtils/focusManagerAux/index.ts +76 -0
  25. package/appUtils/focusManagerAux/utils/index.ts +100 -0
  26. package/appUtils/index.js +2 -0
  27. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +1 -1
  28. package/appUtils/keyCodes/__tests__/keyCodes.test.js +80 -85
  29. package/appUtils/keyCodes/keys.web.js +9 -0
  30. package/appUtils/keyCodes/keysByPlatform.js +11 -1
  31. package/appUtils/platform/const.ts +25 -0
  32. package/appUtils/platform/index.ts +3 -0
  33. package/appUtils/platform/platformUtils.ts +218 -0
  34. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +53 -0
  35. package/appUtils/playerManager/conts.ts +6 -0
  36. package/appUtils/playerManager/index.ts +20 -32
  37. package/appUtils/playerManager/nativePlayerManager.ts +12 -0
  38. package/appUtils/playerManager/player.ts +56 -7
  39. package/appUtils/playerManager/playerFactory.ts +20 -5
  40. package/appUtils/playerManager/playerHooks/usePlayerCurrentTime.tsx +57 -0
  41. package/appUtils/playerManager/playerNative.ts +41 -15
  42. package/appUtils/playerManager/usePlayerControllerSetup.tsx +8 -2
  43. package/appUtils/playerManager/usePlayerState.tsx +20 -23
  44. package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +50 -0
  45. package/arrayUtils/__tests__/isFilledArray.test.ts +63 -0
  46. package/arrayUtils/index.ts +16 -0
  47. package/booleanUtils/index.ts +4 -4
  48. package/cellUtils/__tests__/cellUtils.test.ts +48 -0
  49. package/cellUtils/__tests__/fixtures.ts +13 -0
  50. package/cellUtils/index.ts +78 -7
  51. package/dateUtils/index.ts +11 -0
  52. package/focusManager/FocusManager.ts +20 -5
  53. package/focusManager/__tests__/FocusManager.test.ts +0 -1
  54. package/focusManager/index.ts +1 -1
  55. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +2 -2
  56. package/functionUtils/__tests__/functionUtils.test.js +244 -248
  57. package/functionUtils/index.ts +38 -0
  58. package/headersUtils/index.ts +1 -0
  59. package/index.d.ts +15 -0
  60. package/inflatedUrlUtils/index.ts +4 -4
  61. package/keyboardState/index.ts +0 -0
  62. package/localizationUtils/__tests__/localizationUtils.test.ts +78 -55
  63. package/localizationUtils/index.ts +13 -19
  64. package/logger/index.ts +1 -1
  65. package/manifestUtils/defaultManifestConfigurations/generalContent.js +6 -0
  66. package/manifestUtils/defaultManifestConfigurations/player.js +131 -1
  67. package/manifestUtils/index.js +5 -1
  68. package/manifestUtils/keys.js +2 -1
  69. package/manifestUtils/secondaryImage/index.js +18 -15
  70. package/modalState/index.ts +57 -0
  71. package/navigationUtils/index.ts +105 -8
  72. package/numberUtils/__tests__/isLikeNumber.test.ts +18 -0
  73. package/numberUtils/__tests__/toNumber.test.ts +2 -2
  74. package/numberUtils/__tests__/toPositiveNumberWithDefault.test.ts +66 -0
  75. package/numberUtils/__tests__/toPositiveNumberWithDefaultZero.test.ts +66 -0
  76. package/numberUtils/index.ts +27 -16
  77. package/package.json +3 -2
  78. package/playerUtils/configurationGenerator.ts +131 -1
  79. package/playerUtils/imaScriptDom.ts +59 -0
  80. package/pluginUtils/index.ts +20 -7
  81. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +2 -0
  82. package/reactHooks/autoscrolling/__tests__/{useTrackedView.test.ts → useTrackedView.test.tsx} +18 -1
  83. package/reactHooks/cell-click/__tests__/index.test.js +16 -3
  84. package/reactHooks/cell-click/index.ts +30 -16
  85. package/reactHooks/debugging/__tests__/index.test.js +81 -11
  86. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +69 -6
  87. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +30 -70
  88. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +6 -2
  89. package/reactHooks/feed/__tests__/useInflatedUrl.test.ts +18 -3
  90. package/reactHooks/feed/useBatchLoading.ts +52 -28
  91. package/reactHooks/feed/useBuildPipesUrl.ts +7 -10
  92. package/reactHooks/feed/useFeedRefresh.tsx +9 -7
  93. package/reactHooks/feed/useInflatedUrl.ts +44 -15
  94. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -9
  95. package/reactHooks/index.ts +2 -0
  96. package/reactHooks/layout/__tests__/{index.test.js → index.test.tsx} +66 -59
  97. package/reactHooks/layout/getDeviceInfo/index.ts +4 -2
  98. package/reactHooks/layout/types/index.ts +2 -0
  99. package/reactHooks/layout/useDimensions/__tests__/useDimensions.test.ts +134 -0
  100. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +11 -16
  101. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +12 -14
  102. package/reactHooks/layout/useDimensions/useDimensions.ts +15 -7
  103. package/reactHooks/navigation/__mocks__/index.ts +15 -0
  104. package/reactHooks/navigation/__mocks__/useNavigation.ts +7 -0
  105. package/reactHooks/navigation/__tests__/index.test.tsx +240 -81
  106. package/reactHooks/navigation/index.ts +240 -81
  107. package/reactHooks/player/useAutoSeek.tsx +9 -7
  108. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +3 -1
  109. package/reactHooks/resolvers/useCellResolver.ts +5 -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/useConfiguration.ts +2 -2
  119. package/reactHooks/useListenEventBusEvent.ts +1 -4
  120. package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +10 -9
  121. package/reactUtils/index.ts +104 -0
  122. package/riverComponetsMeasurementProvider/index.tsx +2 -2
  123. package/services/localStorageServiceSync.web.ts +48 -0
  124. package/services/sessionStorageServiceSync.web.ts +32 -0
  125. package/services/storageServiceSync.web.ts +24 -0
  126. package/services/storageWebUtils.web.ts +10 -0
  127. package/stringUtils/index.ts +5 -0
  128. package/testUtils/getByTestId.ts +14 -0
  129. package/testUtils/index.tsx +71 -23
  130. package/types.ts +4 -0
  131. package/appUtils/focusManager/FocusableEvents.ts +0 -8
  132. package/appUtils/focusManager/treeDataStructure/Utils/__tests__/Utils_android.test.js +0 -1094
  133. package/appUtils/focusManager/treeDataStructure/Utils/index.android.js +0 -261
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-use-before-define */
2
2
  /* eslint max-len: off */
3
3
 
4
- import React, { useEffect, useMemo } from "react";
4
+ import React, { useContext, useEffect, useMemo } from "react";
5
5
  import { BackHandler, InteractionManager, NativeModules } from "react-native";
6
6
  import { useSafeAreaInsets } from "react-native-safe-area-context";
7
7
 
@@ -12,23 +12,117 @@ import {
12
12
  import { HooksManager } from "@applicaster/zapp-react-native-utils/appUtils/HooksManager";
13
13
 
14
14
  import { legacyScreenData } from "@applicaster/quick-brick-core/App/NavigationProvider/utils";
15
- import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
16
- import { useZappHooksModalState } from "@applicaster/zapp-react-dom-ui-components/Components/ZappHooksModal/ZappHooksModal";
15
+ import {
16
+ LONG_KEY_PRESS_TIMEOUT,
17
+ QUICK_BRICK_NAVBAR,
18
+ QUICK_BRICK_CONTENT,
19
+ } from "@applicaster/quick-brick-core/const";
20
+ import { useZappHooksModalState } from "@applicaster/zapp-react-dom-ui-components/Components/ZappHooksModal/hooks/useZappHooksModalState";
17
21
  import { ZappHookModalContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
18
22
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
19
23
  import { HookModalContextT } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
20
- import { getNavigationProps } from "@applicaster/zapp-react-native-utils/navigationUtils";
21
24
  import { HOOKS_EVENTS } from "../../appUtils/HooksManager/constants";
22
- import { getRiverFromRoute, getTargetRoute } from "../../navigationUtils";
25
+ import {
26
+ getNavigationProps,
27
+ getRiverFromRoute,
28
+ getTargetRoute,
29
+ } from "../../navigationUtils";
23
30
  import { platformSelect } from "../../reactUtils";
24
31
  import { useConnectionInfo } from "../connection";
25
32
  import { getTargetScreenData } from "../screen/useTargetScreenData";
26
- import { useNavbarState } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
27
33
 
34
+ import { isTV, isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
35
+ import { useNavbarState } from "../screen";
28
36
  import { useNavigation } from "./useNavigation";
37
+ import { useModalStore } from "../../modalState";
38
+ import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
29
39
 
30
40
  export { useNavigation } from "./useNavigation";
31
41
 
42
+ /**
43
+ * This function helps to decide wether the navbar should be presented on the screen
44
+ * based on route and / or screen Data
45
+ *
46
+ * Currently the scenarios include
47
+ * - players => false
48
+ * - search screen plugin => false
49
+ * - hooks with `showNavBar: true` or `presentFullScreen` not set to true, defaults to no navbar for hook screens
50
+ * - screens with `allow_screen_plugin_presentation` in general property => false
51
+ *
52
+ * @param {String} route current route of the screen
53
+ * @param {Object} screenData payload associated with the currently presented screen
54
+ * @returns {Boolean}
55
+ */
56
+ export function isNavBarVisible(
57
+ route: string,
58
+ screenData: ZappRiver = {} as ZappRiver,
59
+ showNavBar: boolean,
60
+ canGoBack: boolean,
61
+ videoModalState: QuickBrickVideoModalState | null = null
62
+ ) {
63
+ /* screenData is not actual navigator.data
64
+ * or navigator.screenData,
65
+ * but navigator.data.screen */
66
+ if (route.includes("playable")) {
67
+ return false;
68
+ }
69
+
70
+ if (
71
+ videoModalState?.mode === "FULLSCREEN" &&
72
+ videoModalState?.visible === true
73
+ ) {
74
+ return false;
75
+ }
76
+
77
+ if (screenData?.type === "qb_search_screen" && !isTV()) {
78
+ return false;
79
+ }
80
+
81
+ if (screenData?.plugin_type === "login" && isTV()) {
82
+ return false;
83
+ }
84
+
85
+ /* Match if screen is Hook */
86
+ if (route.startsWith("/hooks/")) {
87
+ const module = screenData?.module;
88
+
89
+ if (module?.presentFullScreen) {
90
+ return false;
91
+ }
92
+
93
+ return module?.showNavBar ?? false;
94
+ }
95
+
96
+ if (screenData?.hookPlugin) {
97
+ const hookPlugin = screenData?.hookPlugin?.module;
98
+
99
+ return (
100
+ hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true || false
101
+ );
102
+ }
103
+
104
+ if (
105
+ screenData?.general?.allow_screen_plugin_presentation ||
106
+ screenData?.general?.hide_app_nav_bar
107
+ ) {
108
+ return false;
109
+ }
110
+
111
+ const hideSecondaryLevel = screenData?.navigations?.some(
112
+ (navigation) => navigation.styles?.hide_secondary_level_menu
113
+ );
114
+
115
+ if (canGoBack && hideSecondaryLevel) {
116
+ return false;
117
+ }
118
+
119
+ if (typeof showNavBar === "boolean" && !showNavBar) {
120
+ return false;
121
+ }
122
+
123
+ return true;
124
+ }
125
+
32
126
  const { ProfilerBridge } = NativeModules;
33
127
 
34
128
  export const usePathname = () => React.useContext(PathnameContext);
@@ -43,6 +137,88 @@ export const useBackHandler = (cb: () => boolean) => {
43
137
  }, [cb]);
44
138
  };
45
139
 
140
+ // starts with modal/
141
+ const isModalPathname = (pathname: string) => /^modal\//.test(pathname);
142
+
143
+ const isVideoModalPathname = (pathname: string) =>
144
+ /^video-modal\//.test(pathname);
145
+
146
+ const isHookModalPathname = (pathname: string) =>
147
+ /^hooks-modal\//.test(pathname);
148
+
149
+ const isHookPathname = (pathname: string) => /^\/hooks\//.test(pathname);
150
+
151
+ type VariousScreenData = LegacyNavigationScreenData | ZappRiver | ZappEntry;
152
+
153
+ export const useRoute = (): {
154
+ screenData: VariousScreenData;
155
+ pathname: string;
156
+ } => {
157
+ const pathname = usePathname() || "";
158
+ const navigator = useNavigation();
159
+ const screenDataContext = legacyScreenData(useContext(ScreenDataContext));
160
+
161
+ const { plugins, contentTypes, rivers } = usePickFromState([
162
+ "plugins",
163
+ "rivers",
164
+ "contentTypes",
165
+ ]);
166
+
167
+ const { modalState } = useModalStore();
168
+ const hookModalState = useZappHooksModalState();
169
+
170
+ const modalScreenData = modalState.screen;
171
+
172
+ const hookModalScreenData = hookModalState.state.screenData?.payload;
173
+
174
+ const videoModalScreenData =
175
+ navigator.videoModalState?.item &&
176
+ legacyScreenData(
177
+ {
178
+ entry: navigator.videoModalState?.item as ZappEntry,
179
+ screen: getTargetScreenData(
180
+ navigator.videoModalState?.item as ZappEntry,
181
+ rivers,
182
+ contentTypes
183
+ ),
184
+ },
185
+ plugins
186
+ );
187
+
188
+ // There are 4 route scenarios
189
+ // For regular screens take date from navigator stack.
190
+ // is path is model grab screenData from modal state
191
+ // if path is video modal grab screenData from video state
192
+ // if path is hook modal grab screenData from hook state
193
+ // if path is hook grab screenData from screenData
194
+
195
+ if (isModalPathname(pathname)) {
196
+ const screenData = modalScreenData ?? ({} as ZappEntry);
197
+
198
+ return { screenData, pathname };
199
+ }
200
+
201
+ if (isVideoModalPathname(pathname)) {
202
+ const screenData = videoModalScreenData as LegacyNavigationScreenData;
203
+
204
+ return { screenData, pathname };
205
+ }
206
+
207
+ if (isHookModalPathname(pathname)) {
208
+ const screenData = hookModalScreenData;
209
+
210
+ return { screenData, pathname };
211
+ }
212
+
213
+ if (isHookPathname(pathname)) {
214
+ return { screenData: screenDataContext, pathname };
215
+ }
216
+
217
+ const screenData = screenDataContext;
218
+
219
+ return { screenData, pathname };
220
+ };
221
+
46
222
  type Callbacks = Partial<{
47
223
  handleHookPresent: ({
48
224
  route,
@@ -209,7 +385,7 @@ export const useRunIfLongPress = (
209
385
  React.useRef<Nullable<ReturnType<typeof setTimeout>>>(null);
210
386
 
211
387
  const resetTimeout = () => {
212
- clearTimeout(pressTimeout.current);
388
+ clearTimeout(pressTimeout.current as ReturnType<typeof setTimeout>);
213
389
  };
214
390
 
215
391
  const startTimeout = (cb: () => void) => {
@@ -231,102 +407,85 @@ export const useRunIfLongPress = (
231
407
  * @returns boolean - navbar visiblity status
232
408
  */
233
409
  export const useIsNavBarVisible = (): boolean => {
234
- const visible = useNavbarState().visible;
410
+ const { visible } = useNavbarState();
235
411
 
236
412
  return useMemo(() => visible, [visible]);
237
413
  };
238
414
 
239
- const isModalPathname = (pathname: string) => /^modal\//.test(pathname);
415
+ const useGetNavBarTopBorderWidth = (): number => {
416
+ const navigator = useNavigation();
240
417
 
241
- const isVideoModalPathname = (pathname: string) =>
242
- /^video-modal\//.test(pathname);
418
+ const navProps = getNavigationProps({
419
+ navigator,
420
+ title: "",
421
+ category: "menu",
422
+ });
243
423
 
244
- const isHookModalPathname = (pathname: string) =>
245
- /^hooks-modal\//.test(pathname);
424
+ return Number(((navProps?.styles as any)?.top_border_width as number) ?? 0);
425
+ };
246
426
 
247
- export const useRoute = () => {
248
- const pathname = usePathname() || "";
249
- const navigator = useNavigation();
427
+ const TAB_BAR_HEIGHT_IOS = 49;
428
+ const TAB_BAR_HEIGHT_ANDROID = 56;
250
429
 
251
- const { plugins, contentTypes, rivers } = usePickFromState([
252
- "plugins",
253
- "rivers",
254
- "contentTypes",
255
- ]);
430
+ const useGetTabBarHeight = () =>
431
+ platformSelect({
432
+ ios: TAB_BAR_HEIGHT_IOS + (useSafeAreaInsets().bottom ?? 0),
433
+ android: TAB_BAR_HEIGHT_ANDROID,
434
+ }) as number;
256
435
 
257
- const currentStack = navigator.getStackForPathname(pathname);
258
- const modalState = navigator.modalState;
259
- const hookModalState = useZappHooksModalState();
436
+ export const useGetBottomTabBarHeight = (): number => {
437
+ const topBorderWidth = useGetNavBarTopBorderWidth();
438
+ const tabBarHeight = useGetTabBarHeight();
260
439
 
261
- const modalScreenData = modalState.screen;
440
+ const isBottomBarNavigation = useNavigationType() === MenuTypes.bottomTabBar;
262
441
 
263
- const hookModalScreenData = hookModalState.state.screenData?.payload;
442
+ return !isBottomBarNavigation ? 0 : tabBarHeight + topBorderWidth;
443
+ };
264
444
 
265
- const videoModalScreenData =
266
- navigator.videoModalState?.item &&
267
- legacyScreenData(
268
- {
269
- entry: navigator.videoModalState?.item,
270
- screen: getTargetScreenData(
271
- navigator.videoModalState?.item,
272
- rivers,
273
- contentTypes
274
- ),
275
- },
276
- plugins
277
- );
445
+ // If current screen is active/focused (visible to the user)
446
+ export const useIsScreenActive = () => {
447
+ const pathname = usePathname();
448
+ const { currentRoute, videoModalState } = useNavigation();
278
449
 
279
- const currentRouteScreenData = legacyScreenData(
280
- {
281
- screen:
282
- currentStack?.state?.screen ??
283
- navigator.data?.screen ??
284
- ({} as ZappRiver),
285
- entry: currentStack?.state?.entry ?? ({} as ZappEntry),
286
- },
450
+ if (
451
+ videoModalState.visible &&
452
+ ["FULLSCREEN", "MAXIMIZED", "PIP"].includes(videoModalState.mode)
453
+ ) {
454
+ return false;
455
+ }
287
456
 
288
- plugins
289
- );
457
+ return pathname === currentRoute;
458
+ };
290
459
 
291
- // There are 4 route scenarios
292
- // For regular screens take date from navigator stack.
293
- // is path is model grab screenData from modal state
294
- // if path is video modal grab screenData from video state
295
- // if path is hook modal grab screenData from hook state
460
+ type Return = (prefix: string) => string;
296
461
 
297
- const screenData = isModalPathname(pathname)
298
- ? modalScreenData
299
- : isVideoModalPathname(pathname)
300
- ? videoModalScreenData
301
- : isHookModalPathname(pathname)
302
- ? hookModalScreenData
303
- : currentRouteScreenData;
462
+ export const useUniqueRouteSuffix = (): Return => {
463
+ const pathname = usePathname();
464
+ const { currentRoute } = useNavigation();
304
465
 
305
- return { screenData, pathname };
306
- };
466
+ const suffix = `currentRoute:${currentRoute}_pathname:${pathname}`;
307
467
 
308
- export const useGetBottomTabBarHeight = (): number => {
309
- const insets = useSafeAreaInsets();
310
- const navigator = useNavigation();
468
+ const withUniqueRouteSuffix = React.useCallback((prefix: string) => {
469
+ if (isWeb()) {
470
+ // we should use extended route prefix only on Web, where we have stack-navigator
471
+ return `${prefix}___${suffix}`;
472
+ }
311
473
 
312
- const navProps = getNavigationProps({
313
- navigator,
314
- title: "",
315
- category: "menu",
316
- });
474
+ // for other platforms use previous version
475
+ return prefix;
476
+ }, []);
317
477
 
318
- const navType = useNavigationType();
319
- const isBottomBarNavigation = navType === MenuTypes.bottomTabBar;
478
+ return withUniqueRouteSuffix;
479
+ };
320
480
 
321
- const TAB_BAR_HEIGHT_IOS = 49;
322
- const TAB_BAR_HEIGHT_ANDROID = 56;
481
+ export const useNavbarId = () => {
482
+ const withUniqueRouteSuffix = useUniqueRouteSuffix();
323
483
 
324
- if (!isBottomBarNavigation) return 0;
484
+ return withUniqueRouteSuffix(QUICK_BRICK_NAVBAR);
485
+ };
325
486
 
326
- const tabBarHeight = platformSelect({
327
- ios: TAB_BAR_HEIGHT_IOS + insets.bottom,
328
- android: TAB_BAR_HEIGHT_ANDROID,
329
- }) as number;
487
+ export const useContentId = () => {
488
+ const withUniqueRouteSuffix = useUniqueRouteSuffix();
330
489
 
331
- return tabBarHeight + Number(navProps?.styles?.top_border_width ?? 0);
490
+ return withUniqueRouteSuffix(QUICK_BRICK_CONTENT);
332
491
  };
@@ -1,5 +1,4 @@
1
1
  import React, { useEffect, useState } from "react";
2
- import * as R from "ramda";
3
2
  import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
4
3
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
5
4
  import {
@@ -17,10 +16,6 @@ export const useAutoSeek = (resetHUDTimer = noop) => {
17
16
  const intervalTimer = React.useRef(null);
18
17
  const prevRunning = usePrevious(isRunning);
19
18
 
20
- const setIntervalTimer = (cb) => {
21
- intervalTimer.current = setInterval(cb, ON_HOLD_INTERVAL);
22
- };
23
-
24
19
  const clearIntervalTimer = () => {
25
20
  try {
26
21
  clearInterval(intervalTimer.current);
@@ -29,6 +24,11 @@ export const useAutoSeek = (resetHUDTimer = noop) => {
29
24
  }
30
25
  };
31
26
 
27
+ const setIntervalTimer = (cb) => {
28
+ clearIntervalTimer();
29
+ intervalTimer.current = setInterval(cb, ON_HOLD_INTERVAL);
30
+ };
31
+
32
32
  const resetState = () => {
33
33
  setIsRunning(false);
34
34
  setDirection(null);
@@ -42,7 +42,7 @@ export const useAutoSeek = (resetHUDTimer = noop) => {
42
42
  if (!player) return;
43
43
 
44
44
  if (direction) {
45
- player[direction](R.min(MAX_SEEK_TIME, SKIP_TIME_BASE * multiplier));
45
+ player[direction](Math.min(MAX_SEEK_TIME, SKIP_TIME_BASE * multiplier));
46
46
  resetHUDTimer();
47
47
  }
48
48
  }, [multiplier, direction]);
@@ -50,7 +50,9 @@ export const useAutoSeek = (resetHUDTimer = noop) => {
50
50
  useEffect(() => {
51
51
  if (isRunning && isRunning !== prevRunning) {
52
52
  setIntervalTimer(() => {
53
- setMultiplier(R.add(1));
53
+ setMultiplier((prev) => {
54
+ return prev + 1;
55
+ });
54
56
  });
55
57
  } else if (!isRunning && isRunning !== prevRunning) {
56
58
  resetState();
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { renderHook, cleanup } from "@testing-library/react-hooks";
3
+ import { cleanup, renderHook } from "@testing-library/react-hooks";
4
4
  import configureStore from "redux-mock-store";
5
5
  import { Provider } from "react-redux";
6
6
 
@@ -12,6 +12,8 @@ jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
12
12
  useIsRTL: jest.fn(() => mock_rtl_flag),
13
13
  }));
14
14
 
15
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
16
+
15
17
  const { useCellResolver } = require("../useCellResolver");
16
18
 
17
19
  describe("cellResolver", () => {
@@ -48,7 +48,11 @@ export function useCellResolver({
48
48
  ...cellResolverOptions
49
49
  }: Props) {
50
50
  let _component = Object.assign({}, component);
51
- const { width, height } = useDimensions("screen");
51
+
52
+ const { width, height } = useDimensions("screen", {
53
+ updateForInactiveScreens: false,
54
+ });
55
+
52
56
  const { plugins, cellStyles } = usePickFromState(["plugins", "cellStyles"]);
53
57
  const isRTL = useIsRTL();
54
58
 
@@ -1,7 +1,7 @@
1
1
  // @ts-ignore
2
2
  import { View } from "react-native";
3
3
 
4
- const mockData: NavigationScreenData = {
4
+ const mockData = {
5
5
  screen: {
6
6
  id: "screen-id",
7
7
  name: "screen",
@@ -40,3 +40,5 @@ const mockData: NavigationScreenData = {
40
40
  };
41
41
 
42
42
  export const useScreenContext = jest.fn().mockReturnValue(mockData);
43
+
44
+ export const useNavbarState = () => ({ visible: true });
@@ -3,23 +3,28 @@ import { Provider } from "react-redux";
3
3
  import { renderHook } from "@testing-library/react-hooks";
4
4
  import configureStore from "redux-mock-store";
5
5
  import thunk from "redux-thunk";
6
- import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
7
6
 
8
7
  const mockStore = configureStore([thunk]);
9
8
 
10
- import { useCurrentScreenData } from "../useCurrentScreenData";
11
-
12
- describe("useScreenData", function () {
13
- const river_id_2: ZappRiver = {
14
- name: "River 2",
15
- id: "A1234",
16
- home: false,
17
- home_offline: false,
18
- supports_offline: false,
19
- navigations: [],
20
- hooks: { preload_plugins: [] },
21
- };
22
-
9
+ const river_id_2: ZappRiver = {
10
+ name: "River 2",
11
+ id: "A1234",
12
+ home: false,
13
+ home_offline: false,
14
+ supports_offline: false,
15
+ navigations: [],
16
+ hooks: { preload_plugins: [] },
17
+ };
18
+
19
+ jest.mock("../useScreenContext", () => ({
20
+ useScreenContext: () => ({
21
+ screen: river_id_2,
22
+ }),
23
+ }));
24
+
25
+ const { useCurrentScreenData } = require("../useCurrentScreenData");
26
+
27
+ describe("useScreenData", () => {
23
28
  const river_id_1 = { id: "B5678" };
24
29
 
25
30
  const store = mockStore({
@@ -27,17 +32,10 @@ describe("useScreenData", function () {
27
32
  });
28
33
 
29
34
  const wrapper: React.FC<any> = ({ children }) => (
30
- <NavigationContext.Provider
31
- value={{
32
- currentRoute: "/river/river_id_1/river/river_id_2",
33
- data: { screen: river_id_2 },
34
- }}
35
- >
36
- <Provider store={store}>{children}</Provider>
37
- </NavigationContext.Provider>
35
+ <Provider store={store}>{children}</Provider>
38
36
  );
39
37
 
40
- it("should return river data for the current screen/route", function () {
38
+ it("should return river data for the current screen/route", () => {
41
39
  const { result } = renderHook(() => useCurrentScreenData(), { wrapper });
42
40
 
43
41
  expect(result.current).toBe(river_id_2);
@@ -2,9 +2,13 @@ export { useCurrentScreenData } from "./useCurrentScreenData";
2
2
 
3
3
  export { useTargetScreenData } from "./useTargetScreenData";
4
4
 
5
+ export { useScreenData } from "./useScreenData";
6
+
5
7
  export {
6
8
  useScreenContext,
7
9
  useLegacyScreenData,
8
10
  useNavbarState,
9
11
  useSetNavbarState,
10
12
  } from "./useScreenContext";
13
+
14
+ export { useScreenBackgroundColor } from "./useScreenBackgroundColor";
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
3
+ import { useScreenConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/River/useScreenConfiguration";
4
+ import { ifEmptyUseFallback } from "@applicaster/zapp-react-native-utils/cellUtils";
5
+
6
+ export const useScreenBackgroundColor = (screenId: string): string => {
7
+ const { backgroundColor: screenBackgroundColor } =
8
+ useScreenConfiguration(screenId);
9
+
10
+ const theme = useTheme();
11
+
12
+ const themeBackgroundColor = React.useMemo(
13
+ () => theme.app_background_color,
14
+ [theme.app_background_color]
15
+ );
16
+
17
+ const backgroundColor = ifEmptyUseFallback(
18
+ screenBackgroundColor,
19
+ themeBackgroundColor
20
+ );
21
+
22
+ return backgroundColor;
23
+ };
@@ -2,11 +2,12 @@ import { useContext, useMemo } from "react";
2
2
 
3
3
  import { useModalNavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ModalNavigationContext";
4
4
  import { useNestedNavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NestedNavigationContext";
5
- import { useNavigation } from "../navigation";
5
+ import { useNavigation } from "../navigation/useNavigation";
6
6
 
7
7
  import { ScreenContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenContext";
8
+ import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
8
9
 
9
- function useScreenContextV2() {
10
+ export function useScreenContextV2() {
10
11
  return useContext(ScreenContext);
11
12
  }
12
13
 
@@ -44,9 +45,8 @@ export function useSetNavbarState() {
44
45
 
45
46
  export function useScreenContext(): NavigationScreenData {
46
47
  const navigator = useNavigation();
48
+ const screenData = useContext(ScreenDataContext);
47
49
 
48
- const screenKey = useMemo(() => navigator?.key, [navigator]);
49
- const screenData = useMemo(() => navigator?.data, [screenKey]);
50
50
  const modalScreenData = navigator?.modalData;
51
51
 
52
52
  const isModal = useModalNavigationContext();
@@ -4,7 +4,7 @@ import { useRivers } from "../state";
4
4
 
5
5
  const logger = utilsLogger.addSubsystem("useScreenData");
6
6
 
7
- export const useScreenData = (screenId?: string): ZappRiver => {
7
+ export const useScreenData = (screenId: string): ZappRiver => {
8
8
  const rivers = useRivers();
9
9
 
10
10
  React.useEffect(() => {
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
3
  import * as R from "ramda";
4
+ import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
4
5
 
5
6
  export function getTargetScreenData(
6
7
  entry: ZappEntry,
@@ -35,6 +36,12 @@ export function getTargetScreenData(
35
36
  return rivers?.[screenId];
36
37
  }
37
38
 
39
+ export function getTargetScreenDataFromEntry(entry: ZappEntry): ZappRiver {
40
+ const { rivers, contentTypes } = appStore.get(["rivers", "contentTypes"]);
41
+
42
+ return getTargetScreenData(entry, rivers, contentTypes);
43
+ }
44
+
38
45
  export const useTargetScreenData = (entry: ZappEntry) => {
39
46
  const { rivers, contentTypes } = usePickFromState(["rivers", "contentTypes"]);
40
47
 
@@ -1,7 +1,9 @@
1
1
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
2
2
 
3
+ const riversSelector = ["rivers"];
4
+
3
5
  export const useRivers = () => {
4
- const { rivers } = usePickFromState(["rivers"]);
6
+ const { rivers } = usePickFromState(riversSelector as any);
5
7
 
6
8
  return rivers;
7
9
  };
@@ -67,7 +67,7 @@ export const useConfiguration = ({
67
67
  if (component) {
68
68
  const remappedStylesConfiguration = remapUpdatedKeys(
69
69
  pluginManifest,
70
- component.styles
70
+ component
71
71
  );
72
72
 
73
73
  R.forEachObjIndexed((value, key) => {
@@ -83,7 +83,7 @@ export const useConfiguration = ({
83
83
 
84
84
  const styles = populateConfigurationValues(
85
85
  pluginManifest?.styles?.fields,
86
- remappedStylesConfiguration,
86
+ remappedStylesConfiguration.styles,
87
87
  skipDefaults
88
88
  );
89
89