@applicaster/zapp-react-native-utils 12.0.0-rc.3 → 12.0.0-rc.30

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 (51) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +16 -8
  2. package/analyticsUtils/__tests__/analyticsManager.test.js +75 -73
  3. package/analyticsUtils/helpers/hooks.ts +1 -1
  4. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +1 -1
  5. package/appUtils/keyCodes/__tests__/keyCodes.test.js +80 -85
  6. package/appUtils/keyCodes/keys.web.js +1 -0
  7. package/appUtils/orientationHelper.ts +1 -1
  8. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +53 -0
  9. package/appUtils/playerManager/player.ts +12 -4
  10. package/appUtils/playerManager/playerFactory.ts +13 -1
  11. package/appUtils/playerManager/playerNative.ts +26 -0
  12. package/appUtils/playerManager/usePlayerState.tsx +13 -1
  13. package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +50 -0
  14. package/cellUtils/__tests__/cellUtils.test.ts +59 -0
  15. package/cellUtils/__tests__/fixtures.ts +13 -0
  16. package/cellUtils/index.ts +42 -0
  17. package/focusManager/index.ts +1 -1
  18. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +2 -2
  19. package/functionUtils/__tests__/functionUtils.test.js +244 -248
  20. package/localizationUtils/__tests__/localizationUtils.test.ts +17 -13
  21. package/localizationUtils/index.ts +6 -3
  22. package/logger/index.ts +1 -1
  23. package/manifestUtils/defaultManifestConfigurations/player.js +8 -0
  24. package/modalState/index.ts +57 -0
  25. package/navigationUtils/index.ts +52 -7
  26. package/package.json +3 -2
  27. package/playerUtils/configurationGenerator.ts +8 -0
  28. package/pluginUtils/index.ts +11 -7
  29. package/reactHooks/cell-click/__tests__/index.test.js +6 -2
  30. package/reactHooks/cell-click/index.ts +2 -2
  31. package/reactHooks/device/index.ts +0 -1
  32. package/reactHooks/device/useIsTablet.tsx +28 -3
  33. package/reactHooks/device/useMemoizedIsTablet.ts +1 -1
  34. package/reactHooks/device/useOrientation.tsx +3 -1
  35. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -9
  36. package/reactHooks/index.ts +2 -0
  37. package/reactHooks/layout/__tests__/index.test.js +22 -30
  38. package/reactHooks/layout/index.ts +2 -1
  39. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +11 -16
  40. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +12 -14
  41. package/reactHooks/navigation/__tests__/index.test.tsx +216 -75
  42. package/reactHooks/navigation/index.ts +201 -85
  43. package/reactHooks/screen/index.ts +2 -0
  44. package/reactHooks/state/useRivers.ts +3 -1
  45. package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +10 -9
  46. package/riverComponetsMeasurementProvider/index.tsx +2 -2
  47. package/screenState/index.ts +8 -0
  48. package/zappFrameworkUtils/loginPluginUtils.ts +12 -2
  49. package/reactHooks/device/useIsTablet.android.tsx +0 -14
  50. package/reactHooks/device/useIsTablet.ios.tsx +0 -7
  51. package/reactHooks/device/useIsTablet.web.tsx +0 -3
@@ -1,12 +1,12 @@
1
1
  import React from "react";
2
2
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
3
3
  import { renderHook } from "@testing-library/react-hooks";
4
- import { useRoute } from "../index";
4
+ import { useRoute, isNavBarVisible } from "../";
5
5
  import { Provider } from "react-redux";
6
6
  import configureMockStore from "redux-mock-store";
7
7
  import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
8
8
  import { ZappHookModalContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
9
- import { ROUTE_TYPES } from "../../../navigationUtils/routeTypes";
9
+ import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
10
10
 
11
11
  const plugins = [];
12
12
 
@@ -45,13 +45,9 @@ const videoItem = {
45
45
  type: { value: "video" },
46
46
  };
47
47
 
48
- const modalItem = {
49
- id: "modal-1",
50
- };
51
-
52
48
  const mainStackNavigator = {
53
49
  getStackForPathname: jest.fn().mockReturnValue(homeStack),
54
- modalState: {},
50
+ getModalState: () => {},
55
51
  videoModalState: {},
56
52
  };
57
53
 
@@ -60,13 +56,6 @@ const videoModalNavigator = {
60
56
  videoModalState: { item: videoItem },
61
57
  };
62
58
 
63
- const modalNavigator = {
64
- ...mainStackNavigator,
65
- modalState: {
66
- screen: modalItem,
67
- },
68
- };
69
-
70
59
  const hookModalNavigator = {
71
60
  ...mainStackNavigator,
72
61
  };
@@ -86,7 +75,6 @@ const hookModalContextState = {
86
75
  resetState: jest.fn(),
87
76
  };
88
77
 
89
- const modalPathname = `${ROUTE_TYPES.MODAL}/${modalItem.id}`;
90
78
  const hooksModalPathname = `${ROUTE_TYPES.HOOKS_MODAL}/${hookModalContextState.state.screenData.payload.id}`;
91
79
  const videoModalPathname = `${ROUTE_TYPES.VIDEO_MODAL}/${videoModalNavigator.videoModalState.item.id}`;
92
80
  const mockStore = configureMockStore();
@@ -117,16 +105,6 @@ const videoModalWrapper = ({ children }) => (
117
105
  </Provider>
118
106
  );
119
107
 
120
- const modalWrapper = ({ children }) => (
121
- <Provider store={store}>
122
- <NavigationContext.Provider value={modalNavigator}>
123
- <PathnameContext.Provider value={modalPathname}>
124
- {children}
125
- </PathnameContext.Provider>
126
- </NavigationContext.Provider>
127
- </Provider>
128
- );
129
-
130
108
  const hookModalWrapper = ({ children }) => (
131
109
  <Provider store={store}>
132
110
  <ZappHookModalContext.ReactContext.Provider value={hookModalContextState}>
@@ -139,88 +117,251 @@ const hookModalWrapper = ({ children }) => (
139
117
  </Provider>
140
118
  );
141
119
 
142
- describe("useRoute", () => {
143
- describe("Main stack components", () => {
144
- it("should return a correct pathname", () => {
145
- const { result } = renderHook(() => useRoute(), {
146
- wrapper: mainStackWrapper,
120
+ jest.mock("../../../modalState", () => ({
121
+ useModalStore: jest.fn(),
122
+ }));
123
+
124
+ describe("navigation", () => {
125
+ describe("useRoute", () => {
126
+ describe("Main stack components", () => {
127
+ it("should return a correct pathname", () => {
128
+ const { result } = renderHook(() => useRoute(), {
129
+ wrapper: mainStackWrapper,
130
+ });
131
+
132
+ expect(result.current.pathname).toEqual(homeStack.route);
147
133
  });
148
134
 
149
- expect(result.current.pathname).toEqual(homeStack.route);
135
+ it("should return correct screenData information", () => {
136
+ const { result } = renderHook(() => useRoute(), {
137
+ wrapper: mainStackWrapper,
138
+ });
139
+
140
+ expect(result.current.screenData.id).toEqual(entry.id);
141
+
142
+ expect(result.current.screenData.targetScreen.id).toEqual(screen.id);
143
+ });
150
144
  });
151
145
 
152
- it("should return correct screenData information", () => {
153
- const { result } = renderHook(() => useRoute(), {
154
- wrapper: mainStackWrapper,
146
+ describe("Hook modal components", () => {
147
+ it("should return a correct pathname", () => {
148
+ const { result } = renderHook(() => useRoute(), {
149
+ wrapper: hookModalWrapper,
150
+ });
151
+
152
+ expect(result.current.pathname).toEqual(hooksModalPathname);
155
153
  });
156
154
 
157
- expect(result.current.screenData.id).toEqual(entry.id);
155
+ it("should return correct screenData information", () => {
156
+ const { result } = renderHook(() => useRoute(), {
157
+ wrapper: hookModalWrapper,
158
+ });
158
159
 
159
- expect(result.current.screenData.targetScreen.id).toEqual(screen.id);
160
+ expect(result.current.screenData.id).toEqual(
161
+ hookModalContextState.state.screenData.payload.id
162
+ );
163
+ });
160
164
  });
161
- });
162
165
 
163
- describe("Hook modal components", () => {
164
- it("should return a correct pathname", () => {
165
- const { result } = renderHook(() => useRoute(), {
166
- wrapper: hookModalWrapper,
166
+ describe("Video modal components", () => {
167
+ it("should return a correct pathname", () => {
168
+ const { result } = renderHook(() => useRoute(), {
169
+ wrapper: videoModalWrapper,
170
+ });
171
+
172
+ expect(result.current.pathname).toEqual(videoModalPathname);
167
173
  });
168
174
 
169
- expect(result.current.pathname).toEqual(hooksModalPathname);
170
- });
175
+ it("should return correct screenData information", () => {
176
+ const { result } = renderHook(() => useRoute(), {
177
+ wrapper: videoModalWrapper,
178
+ });
179
+
180
+ expect(result.current.screenData.id).toEqual(
181
+ videoModalNavigator.videoModalState.item.id
182
+ );
171
183
 
172
- it("should return correct screenData information", () => {
173
- const { result } = renderHook(() => useRoute(), {
174
- wrapper: hookModalWrapper,
184
+ expect(result.current.screenData.targetScreen.id).toEqual(
185
+ rivers["river-player"].id
186
+ );
175
187
  });
188
+ });
189
+ });
176
190
 
177
- expect(result.current.screenData.id).toEqual(
178
- hookModalContextState.state.screenData.payload.id
191
+ describe("isNavBarVisible", () => {
192
+ it("returns false when the route is a player route", () => {
193
+ const navBarVisible = isNavBarVisible(
194
+ "/playable/some_vod_item",
195
+ {} as ZappRiver,
196
+ false,
197
+ false
179
198
  );
199
+
200
+ expect(navBarVisible).toBe(false);
180
201
  });
181
- });
182
202
 
183
- describe("Video modal components", () => {
184
- it("should return a correct pathname", () => {
185
- const { result } = renderHook(() => useRoute(), {
186
- wrapper: videoModalWrapper,
187
- });
203
+ it("returns false when the next screen is the QB search screen", () => {
204
+ const navBarVisible = isNavBarVisible(
205
+ "/river/A1234",
206
+ {
207
+ type: "qb_search_screen",
208
+ } as any,
209
+ false,
210
+ false
211
+ );
188
212
 
189
- expect(result.current.pathname).toEqual(videoModalPathname);
213
+ expect(navBarVisible).toBe(false);
190
214
  });
191
215
 
192
- it("should return correct screenData information", () => {
193
- const { result } = renderHook(() => useRoute(), {
194
- wrapper: videoModalWrapper,
216
+ describe("when screen is a hook", () => {
217
+ it("returns true if the `showNavBar` flag is set to true", () => {
218
+ const navBarVisible = isNavBarVisible(
219
+ "",
220
+ {
221
+ hookPlugin: {
222
+ module: {
223
+ showNavBar: true,
224
+ },
225
+ },
226
+ } as any,
227
+ false,
228
+ false
229
+ );
230
+
231
+ expect(navBarVisible).toBe(true);
232
+ });
233
+
234
+ it("returns true if presentFullScreen flag is set to false", () => {
235
+ const navBarVisible = isNavBarVisible(
236
+ "",
237
+ {
238
+ hookPlugin: {
239
+ module: {
240
+ presentFullScreen: false,
241
+ },
242
+ },
243
+ } as any,
244
+ false,
245
+ false
246
+ );
247
+
248
+ expect(navBarVisible).toBe(true);
195
249
  });
196
250
 
197
- expect(result.current.screenData.id).toEqual(
198
- videoModalNavigator.videoModalState.item.id
251
+ it("returns false if presentFullScreen flag is set to true", () => {
252
+ const navBarVisible = isNavBarVisible(
253
+ "",
254
+ {
255
+ hookPlugin: {
256
+ module: {
257
+ presentFullScreen: true,
258
+ },
259
+ },
260
+ } as any,
261
+ false,
262
+ false
263
+ );
264
+
265
+ expect(navBarVisible).toBe(false);
266
+ });
267
+ });
268
+
269
+ it("returns false if the screen's general settings allow screen presentation", () => {
270
+ const navBarVisible = isNavBarVisible(
271
+ "",
272
+ {
273
+ general: {
274
+ allow_screen_plugin_presentation: true,
275
+ },
276
+ } as any,
277
+ false,
278
+ false
199
279
  );
200
280
 
201
- expect(result.current.screenData.targetScreen.id).toEqual(
202
- rivers["river-player"].id
281
+ expect(navBarVisible).toBe(false);
282
+ });
283
+
284
+ it("returns false if the screen's general settings hide app nav bar", () => {
285
+ const navBarVisible = isNavBarVisible(
286
+ "",
287
+ {
288
+ general: {
289
+ hide_app_nav_bar: true,
290
+ },
291
+ } as any,
292
+ false,
293
+ false
203
294
  );
295
+
296
+ expect(navBarVisible).toBe(false);
204
297
  });
205
- });
206
298
 
207
- describe("Modal components", () => {
208
- it("should return a correct pathname", () => {
209
- const { result } = renderHook(() => useRoute(), {
210
- wrapper: modalWrapper,
211
- });
299
+ it("returns false if it's secondary nav bar and hide_secondary_level_menu is true", () => {
300
+ const navBarVisible = isNavBarVisible(
301
+ "",
302
+ {
303
+ navigations: [
304
+ {
305
+ styles: {
306
+ hide_secondary_level_menu: true,
307
+ },
308
+ },
309
+ ],
310
+ } as any,
311
+ false,
312
+ true
313
+ );
212
314
 
213
- expect(result.current.pathname).toEqual(modalPathname);
315
+ expect(navBarVisible).toBe(false);
214
316
  });
215
317
 
216
- it("should return correct screenData information", () => {
217
- const { result } = renderHook(() => useRoute(), {
218
- wrapper: modalWrapper,
219
- });
318
+ it("returns true if it's secondary nav bar and hide_secondary_level_menu is false", () => {
319
+ const navBarVisible = isNavBarVisible(
320
+ "",
321
+ {
322
+ navigations: [
323
+ {
324
+ styles: {
325
+ hide_secondary_level_menu: false,
326
+ },
327
+ },
328
+ ],
329
+ } as any,
330
+ true,
331
+ false
332
+ );
333
+
334
+ expect(navBarVisible).toBe(true);
335
+ });
336
+
337
+ it("returns true if it's first level menu and hide_secondary_level_menu is true", () => {
338
+ const navBarVisible = isNavBarVisible(
339
+ "",
340
+ {
341
+ navigations: [
342
+ {
343
+ styles: {
344
+ hide_secondary_level_menu: true,
345
+ },
346
+ },
347
+ ],
348
+ } as any,
349
+ true,
350
+ false
351
+ );
220
352
 
221
- expect(result.current.screenData.id).toEqual(
222
- modalNavigator.modalState.screen.id
353
+ expect(navBarVisible).toBe(true);
354
+ });
355
+
356
+ it("returns true otherwise", () => {
357
+ const navBarVisible = isNavBarVisible(
358
+ "",
359
+ { navigations: [] } as any,
360
+ true,
361
+ true
223
362
  );
363
+
364
+ expect(navBarVisible).toBe(true);
224
365
  });
225
366
  });
226
367
  });
@@ -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 { getRiverFromRoute, getTargetRoute } from "../../navigationUtils";
21
+ import {
22
+ getRiverFromRoute,
23
+ getTargetRoute,
24
+ getNavigationProps,
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,102 @@ 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
+ const navigator = useNavigation();
150
+
151
+ const { plugins, contentTypes, rivers } = usePickFromState([
152
+ "plugins",
153
+ "rivers",
154
+ "contentTypes",
155
+ ]);
156
+
157
+ const currentStack = navigator.getStackForPathname(pathname);
158
+ const { modalState } = useModalStore();
159
+ const hookModalState = useZappHooksModalState();
160
+
161
+ const modalScreenData = modalState.screen;
162
+
163
+ const hookModalScreenData = hookModalState.state.screenData?.payload;
164
+
165
+ const videoModalScreenData =
166
+ navigator.videoModalState?.item &&
167
+ legacyScreenData(
168
+ {
169
+ entry: navigator.videoModalState?.item as ZappEntry,
170
+ screen: getTargetScreenData(
171
+ navigator.videoModalState?.item as ZappEntry,
172
+ rivers,
173
+ contentTypes
174
+ ),
175
+ },
176
+ plugins
177
+ );
178
+
179
+ const currentRouteScreenData = legacyScreenData(
180
+ {
181
+ screen: currentStack?.state?.screen ?? navigator.data?.screen ?? {},
182
+ entry: currentStack?.state?.entry ?? {},
183
+ } as NavigationScreenData,
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
+ const screenData =
215
+ "hookPlugin" in currentRouteScreenData
216
+ ? currentRouteScreenData
217
+ : navigator.screenData;
218
+
219
+ return { screenData, pathname };
220
+ }
221
+
222
+ const screenData = currentRouteScreenData;
223
+
224
+ return { screenData, pathname };
225
+ };
226
+
46
227
  type Callbacks = Partial<{
47
228
  handleHookPresent: ({
48
229
  route,
@@ -209,7 +390,7 @@ export const useRunIfLongPress = (
209
390
  React.useRef<Nullable<ReturnType<typeof setTimeout>>>(null);
210
391
 
211
392
  const resetTimeout = () => {
212
- clearTimeout(pressTimeout.current);
393
+ clearTimeout(pressTimeout.current as ReturnType<typeof setTimeout>);
213
394
  };
214
395
 
215
396
  const startTimeout = (cb: () => void) => {
@@ -231,82 +412,12 @@ export const useRunIfLongPress = (
231
412
  * @returns boolean - navbar visiblity status
232
413
  */
233
414
  export const useIsNavBarVisible = (): boolean => {
234
- const visible = useNavbarState().visible;
415
+ const { visible } = useNavbarState();
235
416
 
236
417
  return useMemo(() => visible, [visible]);
237
418
  };
238
419
 
239
- const isModalPathname = (pathname: string) => /^modal\//.test(pathname);
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() || "";
249
- const navigator = useNavigation();
250
-
251
- const { plugins, contentTypes, rivers } = usePickFromState([
252
- "plugins",
253
- "rivers",
254
- "contentTypes",
255
- ]);
256
-
257
- const currentStack = navigator.getStackForPathname(pathname);
258
- const modalState = navigator.modalState;
259
- const hookModalState = useZappHooksModalState();
260
-
261
- const modalScreenData = modalState.screen;
262
-
263
- const hookModalScreenData = hookModalState.state.screenData?.payload;
264
-
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
- );
278
-
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
- },
287
-
288
- plugins
289
- );
290
-
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
296
-
297
- const screenData = isModalPathname(pathname)
298
- ? modalScreenData
299
- : isVideoModalPathname(pathname)
300
- ? videoModalScreenData
301
- : isHookModalPathname(pathname)
302
- ? hookModalScreenData
303
- : currentRouteScreenData;
304
-
305
- return { screenData, pathname };
306
- };
307
-
308
- export const useGetBottomTabBarHeight = (): number => {
309
- const insets = useSafeAreaInsets();
420
+ const useGetNavBarTopBorderWidth = (): number => {
310
421
  const navigator = useNavigation();
311
422
 
312
423
  const navProps = getNavigationProps({
@@ -315,18 +426,23 @@ export const useGetBottomTabBarHeight = (): number => {
315
426
  category: "menu",
316
427
  });
317
428
 
318
- const navType = useNavigationType();
319
- const isBottomBarNavigation = navType === MenuTypes.bottomTabBar;
320
-
321
- const TAB_BAR_HEIGHT_IOS = 49;
322
- const TAB_BAR_HEIGHT_ANDROID = 56;
429
+ return Number(((navProps?.styles as any)?.top_border_width as number) ?? 0);
430
+ };
323
431
 
324
- if (!isBottomBarNavigation) return 0;
432
+ const TAB_BAR_HEIGHT_IOS = 49;
433
+ const TAB_BAR_HEIGHT_ANDROID = 56;
325
434
 
326
- const tabBarHeight = platformSelect({
327
- ios: TAB_BAR_HEIGHT_IOS + insets.bottom,
435
+ const useGetTabBarHeight = () =>
436
+ platformSelect({
437
+ ios: TAB_BAR_HEIGHT_IOS + (useSafeAreaInsets().bottom ?? 0),
328
438
  android: TAB_BAR_HEIGHT_ANDROID,
329
439
  }) as number;
330
440
 
331
- return tabBarHeight + Number(navProps?.styles?.top_border_width ?? 0);
441
+ export const useGetBottomTabBarHeight = (): number => {
442
+ const topBorderWidth = useGetNavBarTopBorderWidth();
443
+ const tabBarHeight = useGetTabBarHeight();
444
+
445
+ const isBottomBarNavigation = useNavigationType() === MenuTypes.bottomTabBar;
446
+
447
+ return !isBottomBarNavigation ? 0 : tabBarHeight + topBorderWidth;
332
448
  };