@applicaster/zapp-react-native-utils 12.0.0-alpha.9004455836 → 12.0.0-alpha.9233494544
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.
- package/actionsExecutor/ActionExecutorContext.tsx +16 -8
- package/analyticsUtils/__tests__/analyticsManager.test.js +75 -73
- package/analyticsUtils/helpers/hooks.ts +1 -1
- package/appUtils/HooksManager/index.js +3 -1
- package/appUtils/focusManager/index.ts +147 -25
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +83 -33
- package/appUtils/focusManager/utils/index.ts +77 -0
- package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +1 -1
- package/appUtils/keyCodes/__tests__/keyCodes.test.js +80 -85
- package/appUtils/keyCodes/keys.web.js +1 -0
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +53 -0
- package/appUtils/playerManager/conts.ts +5 -0
- package/appUtils/playerManager/player.ts +47 -4
- package/appUtils/playerManager/playerFactory.ts +12 -10
- package/appUtils/playerManager/playerNative.ts +35 -0
- package/appUtils/playerManager/usePlayerState.tsx +13 -1
- package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +50 -0
- package/cellUtils/__tests__/cellUtils.test.ts +59 -0
- package/cellUtils/__tests__/fixtures.ts +13 -0
- package/cellUtils/index.ts +33 -2
- package/focusManager/index.ts +1 -1
- package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +2 -2
- package/functionUtils/__tests__/functionUtils.test.js +244 -248
- package/headersUtils/index.ts +1 -0
- package/localizationUtils/__tests__/localizationUtils.test.ts +17 -13
- package/localizationUtils/index.ts +6 -3
- package/logger/index.ts +1 -1
- package/manifestUtils/defaultManifestConfigurations/generalContent.js +6 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +10 -1
- package/manifestUtils/index.js +5 -1
- package/manifestUtils/secondaryImage/index.js +18 -15
- package/modalState/index.ts +57 -0
- package/navigationUtils/index.ts +56 -7
- package/package.json +3 -2
- package/playerUtils/configurationGenerator.ts +11 -1
- package/pluginUtils/index.ts +2 -2
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +2 -0
- package/reactHooks/autoscrolling/__tests__/{useTrackedView.test.ts → useTrackedView.test.tsx} +18 -1
- package/reactHooks/cell-click/__tests__/index.test.js +6 -2
- package/reactHooks/cell-click/index.ts +2 -2
- package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -9
- package/reactHooks/index.ts +2 -0
- package/reactHooks/layout/__tests__/{index.test.js → index.test.tsx} +66 -59
- package/reactHooks/layout/getDeviceInfo/index.ts +4 -2
- package/reactHooks/layout/types/index.ts +2 -0
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +11 -16
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +12 -14
- package/reactHooks/layout/useDimensions/useDimensions.ts +13 -7
- package/reactHooks/navigation/__mocks__/index.ts +15 -0
- package/reactHooks/navigation/__mocks__/useNavigation.ts +7 -0
- package/reactHooks/navigation/__tests__/index.test.tsx +234 -78
- package/reactHooks/navigation/index.ts +262 -81
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +3 -1
- package/reactHooks/screen/__mocks__/useScreenContext.ts +3 -1
- package/reactHooks/screen/index.ts +2 -0
- package/reactHooks/screen/useScreenContext.ts +5 -4
- package/reactHooks/screen/useScreenData.ts +1 -1
- package/reactHooks/screen/useTargetScreenData.ts +7 -0
- package/reactHooks/state/useRivers.ts +3 -1
- package/reactHooks/useListenEventBusEvent.ts +1 -4
- package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +10 -9
- package/reactUtils/helpers.tsx +1 -1
- package/riverComponetsMeasurementProvider/index.tsx +2 -2
- package/stringUtils/index.ts +5 -0
- package/testUtils/getByTestId.ts +14 -0
- package/testUtils/index.tsx +38 -23
|
@@ -17,18 +17,103 @@ import { useZappHooksModalState } from "@applicaster/zapp-react-dom-ui-component
|
|
|
17
17
|
import { ZappHookModalContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
|
|
18
18
|
import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
|
|
19
19
|
import { HookModalContextT } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
|
|
20
|
-
import { getNavigationProps } from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
21
20
|
import { HOOKS_EVENTS } from "../../appUtils/HooksManager/constants";
|
|
22
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
getNavigationProps,
|
|
23
|
+
getRiverFromRoute,
|
|
24
|
+
getTargetRoute,
|
|
25
|
+
} from "../../navigationUtils";
|
|
23
26
|
import { platformSelect } from "../../reactUtils";
|
|
24
27
|
import { useConnectionInfo } from "../connection";
|
|
25
28
|
import { getTargetScreenData } from "../screen/useTargetScreenData";
|
|
26
|
-
import { useNavbarState } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
|
|
27
29
|
|
|
30
|
+
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
31
|
+
import { useNavbarState } from "../screen";
|
|
28
32
|
import { useNavigation } from "./useNavigation";
|
|
33
|
+
import { useModalStore } from "../../modalState";
|
|
29
34
|
|
|
30
35
|
export { useNavigation } from "./useNavigation";
|
|
31
36
|
|
|
37
|
+
/**
|
|
38
|
+
* This function helps to decide wether the navbar should be presented on the screen
|
|
39
|
+
* based on route and / or screen Data
|
|
40
|
+
*
|
|
41
|
+
* Currently the scenarios include
|
|
42
|
+
* - players => false
|
|
43
|
+
* - search screen plugin => false
|
|
44
|
+
* - hooks with `showNavBar: true` or `presentFullScreen` not set to true, defaults to no navbar for hook screens
|
|
45
|
+
* - screens with `allow_screen_plugin_presentation` in general property => false
|
|
46
|
+
*
|
|
47
|
+
* @param {String} route current route of the screen
|
|
48
|
+
* @param {Object} screenData payload associated with the currently presented screen
|
|
49
|
+
* @returns {Boolean}
|
|
50
|
+
*/
|
|
51
|
+
export function isNavBarVisible(
|
|
52
|
+
route: string,
|
|
53
|
+
screenData: ZappRiver = {} as ZappRiver,
|
|
54
|
+
showNavBar: boolean,
|
|
55
|
+
canGoBack: boolean,
|
|
56
|
+
videoModalState: QuickBrickVideoModalState | null = null
|
|
57
|
+
) {
|
|
58
|
+
/* screenData is not actual navigator.data
|
|
59
|
+
* or navigator.screenData,
|
|
60
|
+
* but navigator.data.screen */
|
|
61
|
+
if (route.includes("playable")) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
videoModalState?.mode === "FULLSCREEN" &&
|
|
67
|
+
videoModalState?.visible === true
|
|
68
|
+
) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (screenData?.type === "qb_search_screen" && !isTV()) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Match if screen is Hook */
|
|
77
|
+
if (route.startsWith("/hooks/")) {
|
|
78
|
+
const module = screenData?.module;
|
|
79
|
+
|
|
80
|
+
if (module?.presentFullScreen) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return module?.showNavBar ?? false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (screenData?.hookPlugin) {
|
|
88
|
+
const hookPlugin = screenData?.hookPlugin?.module;
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true || false
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (
|
|
96
|
+
screenData?.general?.allow_screen_plugin_presentation ||
|
|
97
|
+
screenData?.general?.hide_app_nav_bar
|
|
98
|
+
) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const hideSecondaryLevel = screenData?.navigations?.some(
|
|
103
|
+
(navigation) => navigation.styles?.hide_secondary_level_menu
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
if (canGoBack && hideSecondaryLevel) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (typeof showNavBar === "boolean" && !showNavBar) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
32
117
|
const { ProfilerBridge } = NativeModules;
|
|
33
118
|
|
|
34
119
|
export const usePathname = () => React.useContext(PathnameContext);
|
|
@@ -43,6 +128,137 @@ export const useBackHandler = (cb: () => boolean) => {
|
|
|
43
128
|
}, [cb]);
|
|
44
129
|
};
|
|
45
130
|
|
|
131
|
+
// starts with modal/
|
|
132
|
+
const isModalPathname = (pathname: string) => /^modal\//.test(pathname);
|
|
133
|
+
|
|
134
|
+
const isVideoModalPathname = (pathname: string) =>
|
|
135
|
+
/^video-modal\//.test(pathname);
|
|
136
|
+
|
|
137
|
+
const isHookModalPathname = (pathname: string) =>
|
|
138
|
+
/^hooks-modal\//.test(pathname);
|
|
139
|
+
|
|
140
|
+
const isHookPathname = (pathname: string) => /^\/hooks\//.test(pathname);
|
|
141
|
+
|
|
142
|
+
type VariousScreenData = LegacyNavigationScreenData | ZappRiver | ZappEntry;
|
|
143
|
+
|
|
144
|
+
export const useRoute = (): {
|
|
145
|
+
screenData: VariousScreenData;
|
|
146
|
+
pathname: string;
|
|
147
|
+
} => {
|
|
148
|
+
const pathname = usePathname() || "";
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* compose `useRoute()` output data
|
|
152
|
+
*/
|
|
153
|
+
const composeRouteData = (screenData: VariousScreenData) => ({
|
|
154
|
+
screenData,
|
|
155
|
+
pathname,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const navigator = useNavigation();
|
|
159
|
+
|
|
160
|
+
const { plugins, contentTypes, rivers } = usePickFromState([
|
|
161
|
+
"plugins",
|
|
162
|
+
"rivers",
|
|
163
|
+
"contentTypes",
|
|
164
|
+
]);
|
|
165
|
+
|
|
166
|
+
const currentStack = navigator.getStackForPathname(pathname);
|
|
167
|
+
const { modalState } = useModalStore();
|
|
168
|
+
const hookModalState = useZappHooksModalState();
|
|
169
|
+
const modalScreenData = modalState.screen;
|
|
170
|
+
const hookModalScreenData = hookModalState.state.screenData?.payload;
|
|
171
|
+
|
|
172
|
+
const videoModalScreenData =
|
|
173
|
+
navigator.videoModalState?.item &&
|
|
174
|
+
legacyScreenData(
|
|
175
|
+
{
|
|
176
|
+
entry: navigator.videoModalState?.item as ZappEntry,
|
|
177
|
+
screen: getTargetScreenData(
|
|
178
|
+
navigator.videoModalState?.item as ZappEntry,
|
|
179
|
+
rivers,
|
|
180
|
+
contentTypes
|
|
181
|
+
),
|
|
182
|
+
},
|
|
183
|
+
plugins
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
const currentRouteScreenData = legacyScreenData(
|
|
187
|
+
{
|
|
188
|
+
screen: currentStack?.state?.screen ?? navigator.data?.screen ?? {},
|
|
189
|
+
entry: currentStack?.state?.entry ?? {},
|
|
190
|
+
} as NavigationScreenData,
|
|
191
|
+
|
|
192
|
+
plugins
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
// There are 4 route scenarios
|
|
196
|
+
// For regular screens take date from navigator stack.
|
|
197
|
+
// is path is model grab screenData from modal state
|
|
198
|
+
// if path is video modal grab screenData from video state
|
|
199
|
+
// if path is hook modal grab screenData from hook state
|
|
200
|
+
// if path is hook grab screenData from screenData
|
|
201
|
+
|
|
202
|
+
if (isModalPathname(pathname)) {
|
|
203
|
+
return composeRouteData(modalScreenData ?? ({} as ZappEntry));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (isVideoModalPathname(pathname)) {
|
|
207
|
+
return composeRouteData(videoModalScreenData as LegacyNavigationScreenData);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (isHookModalPathname(pathname)) {
|
|
211
|
+
return composeRouteData(hookModalScreenData);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (isHookPathname(pathname)) {
|
|
215
|
+
/**
|
|
216
|
+
* HACK
|
|
217
|
+
*
|
|
218
|
+
* This condition relies on hacky approach to get the current hook screen data
|
|
219
|
+
* using navigator.screenData for some cases.
|
|
220
|
+
* This is used when hook is in sequence.
|
|
221
|
+
*/
|
|
222
|
+
|
|
223
|
+
// case 1: stack not yet updated in navigator context, but navigator.screenData is updated already.
|
|
224
|
+
if (!currentStack) {
|
|
225
|
+
return composeRouteData(navigator.screenData);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const isValidHookInCurrentRouteScreenData =
|
|
229
|
+
"hookPlugin" in currentRouteScreenData &&
|
|
230
|
+
!!currentRouteScreenData.hookPlugin?.module;
|
|
231
|
+
|
|
232
|
+
let screenData;
|
|
233
|
+
|
|
234
|
+
// case 2: stack has valid hook data
|
|
235
|
+
if (isValidHookInCurrentRouteScreenData) {
|
|
236
|
+
screenData = currentRouteScreenData;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const navigatorScreenData = navigator.screenData as NavigatorEntry;
|
|
240
|
+
|
|
241
|
+
// case 3: current hookPlugin is missing weight, but navigator.screenData has weight, use navigator.screenData
|
|
242
|
+
if (
|
|
243
|
+
screenData.hookPlugin.identifier ===
|
|
244
|
+
navigatorScreenData?.hookPlugin?.identifier &&
|
|
245
|
+
!screenData.hookPlugin?.weight &&
|
|
246
|
+
navigatorScreenData?.hookPlugin?.weight
|
|
247
|
+
) {
|
|
248
|
+
screenData = navigator.screenData;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return composeRouteData(screenData);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// case 1: stack not yet updated in navigator context, but navigator.screenData is updated already.
|
|
255
|
+
if (!currentStack) {
|
|
256
|
+
return composeRouteData(navigator.screenData);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return composeRouteData(currentRouteScreenData);
|
|
260
|
+
};
|
|
261
|
+
|
|
46
262
|
type Callbacks = Partial<{
|
|
47
263
|
handleHookPresent: ({
|
|
48
264
|
route,
|
|
@@ -209,7 +425,7 @@ export const useRunIfLongPress = (
|
|
|
209
425
|
React.useRef<Nullable<ReturnType<typeof setTimeout>>>(null);
|
|
210
426
|
|
|
211
427
|
const resetTimeout = () => {
|
|
212
|
-
clearTimeout(pressTimeout.current);
|
|
428
|
+
clearTimeout(pressTimeout.current as ReturnType<typeof setTimeout>);
|
|
213
429
|
};
|
|
214
430
|
|
|
215
431
|
const startTimeout = (cb: () => void) => {
|
|
@@ -231,102 +447,67 @@ export const useRunIfLongPress = (
|
|
|
231
447
|
* @returns boolean - navbar visiblity status
|
|
232
448
|
*/
|
|
233
449
|
export const useIsNavBarVisible = (): boolean => {
|
|
234
|
-
const visible = useNavbarState()
|
|
450
|
+
const { visible } = useNavbarState();
|
|
235
451
|
|
|
236
452
|
return useMemo(() => visible, [visible]);
|
|
237
453
|
};
|
|
238
454
|
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
const isVideoModalPathname = (pathname: string) =>
|
|
242
|
-
/^video-modal\//.test(pathname);
|
|
243
|
-
|
|
244
|
-
const isHookModalPathname = (pathname: string) =>
|
|
245
|
-
/^hooks-modal\//.test(pathname);
|
|
246
|
-
|
|
247
|
-
export const useRoute = () => {
|
|
248
|
-
const pathname = usePathname() || "";
|
|
455
|
+
const useGetNavBarTopBorderWidth = (): number => {
|
|
249
456
|
const navigator = useNavigation();
|
|
250
457
|
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
"
|
|
254
|
-
"
|
|
255
|
-
|
|
458
|
+
const navProps = getNavigationProps({
|
|
459
|
+
navigator,
|
|
460
|
+
title: "",
|
|
461
|
+
category: "menu",
|
|
462
|
+
});
|
|
256
463
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const hookModalState = useZappHooksModalState();
|
|
464
|
+
return Number(((navProps?.styles as any)?.top_border_width as number) ?? 0);
|
|
465
|
+
};
|
|
260
466
|
|
|
261
|
-
|
|
467
|
+
const TAB_BAR_HEIGHT_IOS = 49;
|
|
468
|
+
const TAB_BAR_HEIGHT_ANDROID = 56;
|
|
262
469
|
|
|
263
|
-
|
|
470
|
+
const useGetTabBarHeight = () =>
|
|
471
|
+
platformSelect({
|
|
472
|
+
ios: TAB_BAR_HEIGHT_IOS + (useSafeAreaInsets().bottom ?? 0),
|
|
473
|
+
android: TAB_BAR_HEIGHT_ANDROID,
|
|
474
|
+
}) as number;
|
|
264
475
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
{
|
|
269
|
-
entry: navigator.videoModalState?.item,
|
|
270
|
-
screen: getTargetScreenData(
|
|
271
|
-
navigator.videoModalState?.item,
|
|
272
|
-
rivers,
|
|
273
|
-
contentTypes
|
|
274
|
-
),
|
|
275
|
-
},
|
|
276
|
-
plugins
|
|
277
|
-
);
|
|
476
|
+
export const useGetBottomTabBarHeight = (): number => {
|
|
477
|
+
const topBorderWidth = useGetNavBarTopBorderWidth();
|
|
478
|
+
const tabBarHeight = useGetTabBarHeight();
|
|
278
479
|
|
|
279
|
-
const
|
|
280
|
-
{
|
|
281
|
-
screen:
|
|
282
|
-
currentStack?.state?.screen ??
|
|
283
|
-
navigator.data?.screen ??
|
|
284
|
-
({} as ZappRiver),
|
|
285
|
-
entry: currentStack?.state?.entry ?? ({} as ZappEntry),
|
|
286
|
-
},
|
|
480
|
+
const isBottomBarNavigation = useNavigationType() === MenuTypes.bottomTabBar;
|
|
287
481
|
|
|
288
|
-
|
|
289
|
-
|
|
482
|
+
return !isBottomBarNavigation ? 0 : tabBarHeight + topBorderWidth;
|
|
483
|
+
};
|
|
290
484
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
// if path is hook modal grab screenData from hook state
|
|
485
|
+
// If current screen is active/focused (visible to the user)
|
|
486
|
+
export const useIsScreenActive = () => {
|
|
487
|
+
const pathname = usePathname();
|
|
488
|
+
const { currentRoute, videoModalState } = useNavigation();
|
|
296
489
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
: currentRouteScreenData;
|
|
490
|
+
if (
|
|
491
|
+
videoModalState.visible &&
|
|
492
|
+
["FULLSCREEN", "MAXIMIZED", "PIP"].includes(videoModalState.mode)
|
|
493
|
+
) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
304
496
|
|
|
305
|
-
return
|
|
497
|
+
return pathname === currentRoute;
|
|
306
498
|
};
|
|
307
499
|
|
|
308
|
-
|
|
309
|
-
const insets = useSafeAreaInsets();
|
|
310
|
-
const navigator = useNavigation();
|
|
500
|
+
type Return = (prefix: string) => string;
|
|
311
501
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
category: "menu",
|
|
316
|
-
});
|
|
502
|
+
export const useUniqueRouteSuffix = (): Return => {
|
|
503
|
+
const pathname = usePathname();
|
|
504
|
+
const { currentRoute } = useNavigation();
|
|
317
505
|
|
|
318
|
-
const
|
|
319
|
-
const isBottomBarNavigation = navType === MenuTypes.bottomTabBar;
|
|
506
|
+
const suffix = `currentRoute:${currentRoute}_pathname:${pathname}`;
|
|
320
507
|
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
if (!isBottomBarNavigation) return 0;
|
|
325
|
-
|
|
326
|
-
const tabBarHeight = platformSelect({
|
|
327
|
-
ios: TAB_BAR_HEIGHT_IOS + insets.bottom,
|
|
328
|
-
android: TAB_BAR_HEIGHT_ANDROID,
|
|
329
|
-
}) as number;
|
|
508
|
+
const withUniqueRouteSuffix = React.useCallback((prefix: string) => {
|
|
509
|
+
return `${prefix}___${suffix}`;
|
|
510
|
+
}, []);
|
|
330
511
|
|
|
331
|
-
return
|
|
512
|
+
return withUniqueRouteSuffix;
|
|
332
513
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import {
|
|
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", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-ignore
|
|
2
2
|
import { View } from "react-native";
|
|
3
3
|
|
|
4
|
-
const mockData
|
|
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 });
|
|
@@ -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/Components/Layout/TV";
|
|
8
9
|
|
|
9
|
-
function useScreenContextV2() {
|
|
10
|
+
export function useScreenContextV2() {
|
|
10
11
|
return useContext(ScreenContext);
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -45,8 +46,8 @@ export function useSetNavbarState() {
|
|
|
45
46
|
export function useScreenContext(): NavigationScreenData {
|
|
46
47
|
const navigator = useNavigation();
|
|
47
48
|
|
|
48
|
-
const
|
|
49
|
-
|
|
49
|
+
const screenData = useContext(ScreenDataContext);
|
|
50
|
+
|
|
50
51
|
const modalScreenData = navigator?.modalData;
|
|
51
52
|
|
|
52
53
|
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
|
|
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(
|
|
6
|
+
const { rivers } = usePickFromState(riversSelector as any);
|
|
5
7
|
|
|
6
8
|
return rivers;
|
|
7
9
|
};
|
|
@@ -13,10 +13,7 @@ export const useListenEventBusEvent = (
|
|
|
13
13
|
// TODO: remove after implementing ReactNativeEventBusBridge on iOS
|
|
14
14
|
if (Platform.OS === "android") {
|
|
15
15
|
// subscribe to DeviceEventEmitter using subsciption ID
|
|
16
|
-
const sub = DeviceEventEmitter.addListener(
|
|
17
|
-
subscriptionID,
|
|
18
|
-
handler
|
|
19
|
-
);
|
|
16
|
+
const sub = DeviceEventEmitter.addListener(subscriptionID, handler);
|
|
20
17
|
|
|
21
18
|
// ask native to start routing these events to RN
|
|
22
19
|
ReactNativeEventBusBridge.subscribe(subscriptionID, { [source]: events });
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
usePickFromState,
|
|
4
|
-
} from "@applicaster/zapp-react-native-redux/hooks";
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useContentTypes } from "@applicaster/zapp-react-native-redux/hooks";
|
|
5
3
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
4
|
+
import { useRivers } from "../../state";
|
|
6
5
|
|
|
7
6
|
export const useVideoModalScreenData = ():
|
|
8
7
|
| (ZappEntry & { targetScreen: any }) // TODO: fix ZappEntry type ( was ZappRiver but conflict )
|
|
@@ -12,11 +11,13 @@ export const useVideoModalScreenData = ():
|
|
|
12
11
|
} = useNavigation();
|
|
13
12
|
|
|
14
13
|
const contentTypes = useContentTypes();
|
|
15
|
-
const
|
|
14
|
+
const rivers = useRivers();
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
return React.useMemo(() => {
|
|
17
|
+
if (item?.type?.value) {
|
|
18
|
+
const screenId = contentTypes[item?.type?.value].screen_id;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
return { ...item, targetScreen: rivers?.[screenId] };
|
|
21
|
+
}
|
|
22
|
+
}, [item]);
|
|
22
23
|
};
|
package/reactUtils/helpers.tsx
CHANGED
|
@@ -7,7 +7,7 @@ export const isAnyNil = R.any(R.isNil);
|
|
|
7
7
|
|
|
8
8
|
export const isNilOrEmpty = R.either(R.isNil, R.isEmpty);
|
|
9
9
|
|
|
10
|
-
export const isNotEmpty = R.complement(R.isEmpty);
|
|
10
|
+
export const isNotEmpty = R.both(isNotNil, R.complement(R.isEmpty));
|
|
11
11
|
|
|
12
12
|
export const withoutNil = R.reject(R.isNil);
|
|
13
13
|
|
|
@@ -3,7 +3,7 @@ import { NativeModules, StyleSheet, View } from "react-native";
|
|
|
3
3
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
4
4
|
|
|
5
5
|
import { isApplePlatform, isWeb } from "../reactUtils";
|
|
6
|
-
import {
|
|
6
|
+
import { useRivers } from "../reactHooks/state";
|
|
7
7
|
|
|
8
8
|
const layoutReducer = (state, { payload }) => {
|
|
9
9
|
return state.map((item, index, _state) => ({
|
|
@@ -58,7 +58,7 @@ export const ScreenLoadingMeasurements = ({
|
|
|
58
58
|
numberOfComponents,
|
|
59
59
|
riverId,
|
|
60
60
|
}: Props) => {
|
|
61
|
-
const
|
|
61
|
+
const rivers = useRivers();
|
|
62
62
|
const screenData = rivers?.[riverId];
|
|
63
63
|
|
|
64
64
|
const [itemsLayout, dispatchItemLayout] = React.useReducer(
|
package/stringUtils/index.ts
CHANGED
|
@@ -152,3 +152,8 @@ export function objectToCamelCase(obj) {
|
|
|
152
152
|
export function isString(value: unknown): value is string {
|
|
153
153
|
return typeof value === "string" || value instanceof String;
|
|
154
154
|
}
|
|
155
|
+
|
|
156
|
+
/** Checks if a value is a non-empty string */
|
|
157
|
+
export function isNotEmptyString(value: unknown): value is string {
|
|
158
|
+
return isString(value) && value.length > 0;
|
|
159
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const getByTestId = (wrapper, testId) => {
|
|
2
|
+
try {
|
|
3
|
+
if (wrapper?.getByTestId) {
|
|
4
|
+
return wrapper?.queryAllByTestId(testId)?.[0] ?? undefined;
|
|
5
|
+
} else if (wrapper?.root?.findByProps) {
|
|
6
|
+
return wrapper.root.findAllByProps({ testID: testId })?.[0] ?? undefined;
|
|
7
|
+
}
|
|
8
|
+
} catch (e) {
|
|
9
|
+
// eslint-disable-next-line no-console
|
|
10
|
+
console.log("getByTestId E:", e);
|
|
11
|
+
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
};
|