@applicaster/zapp-react-native-utils 15.0.0-rc.1 → 15.0.0-rc.100

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 (145) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +3 -6
  2. package/actionsExecutor/feedDecorator.ts +6 -6
  3. package/adsUtils/__tests__/createVMAP.test.ts +419 -0
  4. package/adsUtils/index.ts +2 -2
  5. package/analyticsUtils/AnalyticPlayerListener.ts +5 -2
  6. package/analyticsUtils/README.md +1 -1
  7. package/analyticsUtils/analyticsMapper.ts +10 -2
  8. package/appDataUtils/__tests__/urlScheme.test.ts +678 -0
  9. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +0 -188
  10. package/appUtils/HooksManager/__tests__/hooksManager.test.js +16 -2
  11. package/appUtils/HooksManager/index.ts +10 -10
  12. package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
  13. package/appUtils/accessibilityManager/__tests__/utils.test.ts +360 -0
  14. package/appUtils/accessibilityManager/const.ts +4 -0
  15. package/appUtils/accessibilityManager/hooks.ts +20 -13
  16. package/appUtils/accessibilityManager/index.ts +28 -1
  17. package/appUtils/accessibilityManager/utils.ts +59 -8
  18. package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +7 -2
  19. package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +48 -0
  20. package/appUtils/contextKeysManager/contextResolver.ts +51 -22
  21. package/appUtils/contextKeysManager/index.ts +65 -10
  22. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +4 -0
  23. package/appUtils/focusManager/index.ios.ts +59 -3
  24. package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
  25. package/appUtils/focusManagerAux/utils/index.ts +19 -1
  26. package/appUtils/focusManagerAux/utils/utils.ios.ts +231 -0
  27. package/appUtils/keyCodes/keys/keys.web.ts +1 -4
  28. package/appUtils/orientationHelper.ts +2 -4
  29. package/appUtils/platform/platformUtils.ts +117 -18
  30. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +94 -4
  31. package/appUtils/playerManager/OverlayObserver/utils.ts +32 -20
  32. package/appUtils/playerManager/conts.ts +21 -0
  33. package/appUtils/playerManager/player.ts +4 -0
  34. package/appUtils/playerManager/playerNative.ts +29 -16
  35. package/appUtils/playerManager/usePlayerState.tsx +14 -2
  36. package/arrayUtils/__tests__/allTruthy.test.ts +24 -0
  37. package/arrayUtils/__tests__/anyThruthy.test.ts +24 -0
  38. package/arrayUtils/index.ts +5 -0
  39. package/cellUtils/index.ts +32 -0
  40. package/cloudEventsUtils/__tests__/index.test.ts +529 -0
  41. package/cloudEventsUtils/index.ts +65 -1
  42. package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +38 -0
  43. package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
  44. package/configurationUtils/index.ts +17 -11
  45. package/dateUtils/__tests__/dayjs.test.ts +330 -0
  46. package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +207 -0
  47. package/errorUtils/__tests__/GeneralError.test.ts +97 -0
  48. package/errorUtils/__tests__/HttpStatusCode.test.ts +344 -0
  49. package/errorUtils/__tests__/MissingPluginError.test.ts +113 -0
  50. package/errorUtils/__tests__/NetworkError.test.ts +202 -0
  51. package/errorUtils/__tests__/getParsedResponse.test.ts +188 -0
  52. package/errorUtils/__tests__/invariant.test.ts +112 -0
  53. package/focusManager/aux/index.ts +1 -1
  54. package/headersUtils/__tests__/headersUtils.test.js +11 -1
  55. package/headersUtils/index.ts +2 -1
  56. package/manifestUtils/defaultManifestConfigurations/player.js +125 -11
  57. package/manifestUtils/keys.js +21 -0
  58. package/manifestUtils/platformIsTV.js +13 -0
  59. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +1 -0
  60. package/manifestUtils/tvAction/container/index.js +1 -1
  61. package/navigationUtils/index.ts +34 -21
  62. package/numberUtils/__tests__/toNumber.test.ts +12 -0
  63. package/numberUtils/__tests__/toPositiveNumber.test.ts +165 -0
  64. package/numberUtils/index.ts +19 -1
  65. package/package.json +4 -4
  66. package/playerUtils/usePlayerTTS.ts +8 -3
  67. package/pluginUtils/index.ts +4 -0
  68. package/reactHooks/advertising/index.ts +2 -2
  69. package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +537 -0
  70. package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
  71. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  72. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
  73. package/reactHooks/cell-click/__tests__/index.test.js +1 -3
  74. package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
  75. package/reactHooks/connection/__tests__/index.test.js +1 -1
  76. package/reactHooks/debugging/__tests__/index.test.js +4 -4
  77. package/reactHooks/dev/__tests__/useReRenderLog.test.ts +188 -0
  78. package/reactHooks/device/useIsTablet.tsx +14 -19
  79. package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
  80. package/reactHooks/events/index.ts +20 -0
  81. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
  82. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
  83. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +4 -1
  84. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
  85. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
  86. package/reactHooks/feed/__tests__/{useInflatedUrl.test.ts → useInflatedUrl.test.tsx} +62 -7
  87. package/reactHooks/feed/useBatchLoading.ts +7 -1
  88. package/reactHooks/feed/useEntryScreenId.ts +2 -2
  89. package/reactHooks/feed/useFeedLoader.tsx +0 -9
  90. package/reactHooks/feed/useInflatedUrl.ts +57 -37
  91. package/reactHooks/feed/usePipesCacheReset.ts +3 -1
  92. package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +13 -16
  93. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +12 -8
  94. package/reactHooks/index.ts +2 -0
  95. package/reactHooks/layout/__tests__/index.test.tsx +1 -1
  96. package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
  97. package/reactHooks/layout/index.ts +1 -1
  98. package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
  99. package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
  100. package/reactHooks/navigation/__tests__/index.test.tsx +40 -9
  101. package/reactHooks/navigation/index.ts +27 -11
  102. package/reactHooks/navigation/useRoute.ts +11 -7
  103. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
  104. package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
  105. package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
  106. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
  107. package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
  108. package/reactHooks/resolvers/useCellResolver.ts +6 -2
  109. package/reactHooks/resolvers/useComponentResolver.ts +8 -2
  110. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
  111. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
  112. package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
  113. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +12 -4
  114. package/reactHooks/screen/useTargetScreenData.ts +4 -2
  115. package/reactHooks/state/useRefWithInitialValue.ts +10 -0
  116. package/reactHooks/state/useRivers.ts +1 -1
  117. package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +580 -0
  118. package/reactHooks/usePluginConfiguration.ts +2 -2
  119. package/reactHooks/utils/__tests__/index.test.js +1 -1
  120. package/rectUtils/__tests__/index.test.ts +549 -0
  121. package/rectUtils/index.ts +2 -2
  122. package/screenPickerUtils/__tests__/index.test.ts +333 -0
  123. package/screenState/__tests__/index.test.ts +1 -1
  124. package/searchUtils/const.ts +7 -0
  125. package/searchUtils/index.ts +3 -0
  126. package/services/storageServiceSync.web.ts +1 -1
  127. package/stringUtils/index.ts +1 -1
  128. package/testUtils/index.tsx +30 -21
  129. package/time/__tests__/BackgroundTimer.test.ts +156 -0
  130. package/time/__tests__/Timer.test.ts +236 -0
  131. package/typeGuards/__tests__/isString.test.ts +21 -0
  132. package/typeGuards/index.ts +4 -0
  133. package/utils/__tests__/mapAccum.test.ts +73 -0
  134. package/utils/__tests__/mergeRight.test.ts +48 -0
  135. package/utils/__tests__/selectors.test.ts +124 -0
  136. package/utils/index.ts +20 -0
  137. package/utils/mapAccum.ts +23 -0
  138. package/utils/mergeRight.ts +5 -0
  139. package/utils/path.ts +6 -3
  140. package/utils/pathOr.ts +5 -1
  141. package/utils/selectors.ts +46 -0
  142. package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +128 -38
  143. package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +26 -10
  144. package/zappFrameworkUtils/HookCallback/useCallbackActions.ts +6 -9
  145. package/reactHooks/componentsMap/index.ts +0 -55
@@ -1,3 +1,34 @@
1
+ import React from "react";
2
+
3
+ import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
4
+
5
+ import {
6
+ getInflatedDataSourceUrl,
7
+ getSearchContext,
8
+ useGetUrlInflater,
9
+ } from "../useInflatedUrl";
10
+
11
+ import { reactHooksLogger } from "../../logger";
12
+
13
+ jest.mock("../../navigation", () => ({
14
+ useRoute: () => ({ pathname: "/mock/path" }),
15
+ }));
16
+
17
+ // mock contexts hooks
18
+ jest.mock("@applicaster/zapp-react-native-ui-components/Contexts", () => ({
19
+ ZappPipesEntryContext: {
20
+ useZappPipesContext: () => [
21
+ { id: "entry-1", extensions: { showId: "A123" } },
22
+ ],
23
+ },
24
+ ZappPipesSearchContext: {
25
+ useZappPipesContext: () => ["user%20query"],
26
+ },
27
+ ZappPipesScreenContext: {
28
+ useZappPipesContext: () => [{ id: "screen-1" }],
29
+ },
30
+ }));
31
+
1
32
  jest.mock("../../logger", () => ({
2
33
  reactHooksLogger: {
3
34
  warning: jest.fn(),
@@ -5,13 +36,6 @@ jest.mock("../../logger", () => ({
5
36
  },
6
37
  }));
7
38
 
8
- const {
9
- getInflatedDataSourceUrl,
10
- getSearchContext,
11
- } = require("../useInflatedUrl");
12
-
13
- const { reactHooksLogger } = require("../../logger");
14
-
15
39
  let mockStore;
16
40
 
17
41
  describe("getInflatedDataSourceUrl", () => {
@@ -188,3 +212,34 @@ describe("getSearchContext", () => {
188
212
  expect(result).toHaveProperty(mapping.queryParam.property, searchContext);
189
213
  });
190
214
  });
215
+
216
+ describe("useGetUrlInflater", () => {
217
+ const { renderHook } = require("@testing-library/react-native");
218
+
219
+ it("returns original url when mapping is not provided", () => {
220
+ const { result } = renderHook(() => useGetUrlInflater(), {
221
+ wrapper: WrappedWithProviders,
222
+ });
223
+
224
+ const src = "https://foo.com/feed";
225
+ expect(result.current(src)).toBe(src);
226
+ });
227
+
228
+ it("inflates url using entry/search/screen contexts when mapping provided", () => {
229
+ const { result } = renderHook(() => useGetUrlInflater(), {
230
+ wrapper: ({ children }) => (
231
+ <WrappedWithProviders>{children}</WrappedWithProviders>
232
+ ),
233
+ });
234
+
235
+ const source = "https://foo.com/shows/{{showId}}?q={{q}}";
236
+
237
+ const mapping = {
238
+ showId: { source: "entry", property: "extensions.showId" },
239
+ q: { source: "search", property: "q" },
240
+ };
241
+
242
+ const url = result.current(source, mapping);
243
+ expect(url).toBe("https://foo.com/shows/A123?q=user%20query");
244
+ });
245
+ });
@@ -151,7 +151,13 @@ export const useBatchLoading = (
151
151
  }
152
152
  }
153
153
  });
154
- }, [feedUrls, feeds, loadPipesDataDispatcher]);
154
+ }, [
155
+ batchComponents,
156
+ feeds,
157
+ getUrl,
158
+ loadPipesDataDispatcher,
159
+ options.riverId,
160
+ ]);
155
161
 
156
162
  React.useEffect(() => {
157
163
  runBatchLoading();
@@ -1,7 +1,7 @@
1
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
1
+ import { useContentTypes } from "@applicaster/zapp-react-native-redux";
2
2
 
3
3
  export const useEntryScreenId = (entry?: ZappEntry): string | undefined => {
4
- const { contentTypes } = usePickFromState("contentTypes");
4
+ const contentTypes = useContentTypes();
5
5
 
6
6
  if (!entry) {
7
7
  return;
@@ -37,15 +37,6 @@ export const useFeedLoader = ({
37
37
  mapping,
38
38
  pipesOptions = {},
39
39
  }: Props): FeedLoaderResponse => {
40
- useEffect(() => {
41
- if (!feedUrl) {
42
- logger.warning({
43
- message: "Required parameter feedUrl is missing",
44
- data: { feedUrl },
45
- });
46
- }
47
- }, []);
48
-
49
40
  const isInitialRender = useIsInitialRender();
50
41
 
51
42
  const callableFeedUrl = useInflatedUrl({ feedUrl, mapping });
@@ -1,4 +1,4 @@
1
- import { useMemo } from "react";
1
+ import { useCallback, useMemo, useRef } from "react";
2
2
  import * as R from "ramda";
3
3
 
4
4
  import {
@@ -18,6 +18,7 @@ import {
18
18
  } from "@applicaster/zapp-pipes-v2-client";
19
19
  import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
20
20
  import { ENDPOINT_TAGS } from "../../types";
21
+ import { isNilOrEmpty } from "../../reactUtils/helpers";
21
22
 
22
23
  /**
23
24
  * will match any occurrence in a string of one or more word characters
@@ -75,15 +76,19 @@ export const getInflatedDataSourceUrl: GetInflatedDataSourceUrl = ({
75
76
  * https://foo.com/shows/A1234
76
77
  */
77
78
 
78
- if (!source) {
79
- // eslint-disable-next-line no-console
80
- console.error("source is empty", {
81
- source,
82
- contexts,
83
- mapping,
84
- });
79
+ if (!isNilOrEmpty(mapping)) {
80
+ if (!source) {
81
+ if (__DEV__) {
82
+ // eslint-disable-next-line no-console
83
+ throw new Error(
84
+ "getInflatedDataSourceUrl: source is empty while mapping is provided"
85
+ );
86
+ }
85
87
 
86
- return null;
88
+ return null;
89
+ }
90
+ } else {
91
+ return source || null;
87
92
  }
88
93
 
89
94
  // Hack because in tv we expect to get key names instead of values from the fake entry
@@ -164,7 +169,7 @@ const encodeIfNeeded: (string) => string = R.tryCatch(
164
169
 
165
170
  export function getSearchContext(
166
171
  searchContext: string,
167
- mapping: ZappTypeMapping
172
+ mapping: Nullable<ZappTypeMapping>
168
173
  ) {
169
174
  if (!mapping) {
170
175
  return {};
@@ -178,6 +183,45 @@ export function getSearchContext(
178
183
  return { [property]: encodeIfNeeded(searchContext) };
179
184
  }
180
185
 
186
+ /**
187
+ * Hook returns a function that replace placeholders with context values
188
+ * @returns function that inflates urls based on contexts
189
+ */
190
+ export const useGetUrlInflater = () => {
191
+ const { pathname } = useRoute();
192
+
193
+ const [entryContext] = ZappPipesEntryContext.useZappPipesContext(pathname);
194
+ const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
195
+ const [screenContext] = ZappPipesScreenContext.useZappPipesContext();
196
+
197
+ const entryContextRef = useRef(entryContext);
198
+ entryContextRef.current = entryContext;
199
+
200
+ const screenContextRef = useRef(screenContext);
201
+ screenContextRef.current = screenContext;
202
+
203
+ const searchContextRef = useRef(searchContext);
204
+ searchContextRef.current = searchContext;
205
+
206
+ return useCallback(
207
+ (
208
+ feedUrl: Nullable<string>,
209
+ mapping?: Nullable<ZappTypeMapping>
210
+ ): Nullable<string> => {
211
+ return getInflatedDataSourceUrl({
212
+ source: feedUrl,
213
+ contexts: {
214
+ entry: entryContextRef.current,
215
+ screen: screenContextRef.current,
216
+ search: getSearchContext(searchContextRef.current, mapping),
217
+ },
218
+ mapping,
219
+ });
220
+ },
221
+ []
222
+ );
223
+ };
224
+
181
225
  export function useInflatedUrl({
182
226
  feedUrl,
183
227
  mapping,
@@ -185,36 +229,12 @@ export function useInflatedUrl({
185
229
  feedUrl?: string;
186
230
  mapping?: ZappTypeMapping;
187
231
  }) {
188
- const { pathname } = useRoute();
189
-
190
- const [entryContext] = ZappPipesEntryContext.useZappPipesContext(pathname);
191
- const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
192
- const [screenContext] = ZappPipesScreenContext.useZappPipesContext();
232
+ const urlInflater = useGetUrlInflater();
193
233
 
194
234
  const url = useMemo(
195
- () =>
196
- mapping
197
- ? getInflatedDataSourceUrl({
198
- source: feedUrl,
199
- contexts: {
200
- entry: entryContext,
201
- screen: screenContext,
202
- search: getSearchContext(searchContext, mapping),
203
- },
204
- mapping,
205
- })
206
- : feedUrl,
207
- [feedUrl, mapping]
235
+ () => urlInflater(feedUrl, mapping),
236
+ [urlInflater, feedUrl, mapping]
208
237
  );
209
238
 
210
- if (!feedUrl) {
211
- logger.warning({
212
- message: "Required parameter feedUrl is missing",
213
- data: { feedUrl },
214
- });
215
-
216
- return null;
217
- }
218
-
219
239
  return url;
220
240
  }
@@ -34,7 +34,9 @@ export const usePipesCacheReset = (riverId, riverComponents) => {
34
34
  component
35
35
  );
36
36
 
37
- dispatch(clearPipesData(url, { riverId }));
37
+ if (url) {
38
+ dispatch(clearPipesData(url, { riverId }));
39
+ }
38
40
  }
39
41
  });
40
42
  };
@@ -1,10 +1,8 @@
1
1
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
2
2
  import React from "react";
3
3
 
4
- type Return = (index: number) => void;
5
-
6
4
  type Predicate = (
7
- entry: ZappUIComponentProps["zappPipesData"]["data"]["entry"],
5
+ entryLength: number,
8
6
  index: number,
9
7
  numberOfColumns: number
10
8
  ) => boolean;
@@ -12,19 +10,15 @@ type Predicate = (
12
10
  type Props = {
13
11
  ifNeeded: Predicate;
14
12
  loadNextData: () => void;
15
- entry: ZappUIComponentProps["zappPipesData"]["data"]["entry"];
13
+ entryLength: number;
16
14
  numberOfColumns?: number;
17
15
  };
18
16
 
19
17
  const handleLoadNextPage =
20
18
  (
21
- ifNeeded: (
22
- entry: ZappEntry[],
23
- index: number,
24
- numberOfColumns?: number
25
- ) => boolean,
19
+ ifNeeded: Predicate,
26
20
  loadNextData: () => void,
27
- entry: ZappEntry[],
21
+ entryLength: number,
28
22
  numberOfColumns
29
23
  ) =>
30
24
  (index: number) => {
@@ -32,7 +26,7 @@ const handleLoadNextPage =
32
26
  * Lazy-Loading, invoke nextLoadData if we reach the end of the List
33
27
  */
34
28
 
35
- if (ifNeeded(entry, index, numberOfColumns)) {
29
+ if (ifNeeded(entryLength, index, numberOfColumns)) {
36
30
  loadNextData();
37
31
  }
38
32
  };
@@ -40,11 +34,14 @@ const handleLoadNextPage =
40
34
  export const useLoadNextPageIfNeeded = ({
41
35
  ifNeeded,
42
36
  loadNextData = noop,
43
- entry,
37
+ entryLength,
44
38
  numberOfColumns = 0,
45
- }: Props): Return => {
46
- return React.useCallback(
47
- handleLoadNextPage(ifNeeded, loadNextData, entry, numberOfColumns),
48
- [ifNeeded, loadNextData, entry, numberOfColumns]
39
+ }: Props) => {
40
+ const memoFn = React.useMemo(
41
+ () =>
42
+ handleLoadNextPage(ifNeeded, loadNextData, entryLength, numberOfColumns),
43
+ [ifNeeded, loadNextData, entryLength, numberOfColumns]
49
44
  );
45
+
46
+ return memoFn;
50
47
  };
@@ -1,20 +1,24 @@
1
1
  import { reactHooksLogger } from "../../logger";
2
- import { useZappHooksModalState } from "@applicaster/zapp-react-dom-ui-components/Components/ZappHooksModal/hooks/useZappHooksModalState";
2
+ import { useZappHookModalStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
3
3
 
4
4
  const logger = reactHooksLogger.addSubsystem("useHookModalScreenData");
5
5
 
6
6
  type VariousScreenData = LegacyNavigationScreenData | ZappRiver | ZappEntry;
7
7
 
8
- export const useHookModalScreenData = (): VariousScreenData | undefined => {
9
- const hookModalState = useZappHooksModalState();
8
+ export const useHookModalScreenData = (
9
+ skipSubscription: boolean
10
+ ): VariousScreenData | undefined => {
11
+ const hookModalState = useZappHookModalStore((state) =>
12
+ skipSubscription ? undefined : state.state
13
+ );
10
14
 
11
- if (!hookModalState.state?.screenData) {
15
+ if (!hookModalState?.screenData) {
12
16
  return;
13
17
  }
14
18
 
15
19
  try {
16
- const screenData = hookModalState.state.screenData?.payload;
17
- const hookPlugin = hookModalState.state.screenData.hookPlugin;
20
+ const screenData = hookModalState.screenData?.payload;
21
+ const hookPlugin = hookModalState.screenData.hookPlugin;
18
22
 
19
23
  if (hookPlugin?.screen_id) {
20
24
  return {
@@ -23,7 +27,7 @@ export const useHookModalScreenData = (): VariousScreenData | undefined => {
23
27
  };
24
28
  }
25
29
 
26
- return hookModalState.state.screenData?.payload;
30
+ return hookModalState.screenData?.payload;
27
31
  } catch (error) {
28
32
  logger.error({
29
33
  message: "Hook modal screen data creation failed",
@@ -34,6 +38,6 @@ export const useHookModalScreenData = (): VariousScreenData | undefined => {
34
38
  jsOnly: true,
35
39
  });
36
40
 
37
- return hookModalState.state.screenData?.payload;
41
+ return hookModalState.screenData?.payload;
38
42
  }
39
43
  };
@@ -15,3 +15,5 @@ export * from "./device";
15
15
  export * from "./screen";
16
16
 
17
17
  export * from "./state";
18
+
19
+ export * from "./events";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { cleanup, renderHook } from "@testing-library/react-hooks";
3
+ import { cleanup, renderHook } from "@testing-library/react-native";
4
4
  import { Provider } from "react-redux";
5
5
  import configureStore from "redux-mock-store";
6
6
 
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
  import configureStore from "redux-mock-store";
3
3
 
4
4
  const mockStore = configureStore();
@@ -44,7 +44,7 @@ export function useStatusBarHeight() {
44
44
 
45
45
  return platformSelect({
46
46
  ios: StatusBarHeight,
47
- android: StatusBar.currentHeight,
47
+ android: StatusBar.currentHeight ?? 0,
48
48
  default: 0,
49
49
  });
50
50
  }
@@ -1,16 +1,10 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import React from "react";
2
+ import { renderHook } from "@testing-library/react-native";
2
3
  import { Dimensions, StatusBar } from "react-native";
3
4
  import { useDimensions } from "../useDimensions";
4
- import { usePickFromState } from "@applicaster/zapp-react-native-redux";
5
5
 
6
6
  import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive";
7
-
8
- jest.mock("@applicaster/zapp-react-native-redux/hooks", () => {
9
- return {
10
- ...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
11
- usePickFromState: jest.fn(),
12
- };
13
- });
7
+ import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
14
8
 
15
9
  jest.mock(
16
10
  "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
@@ -42,12 +36,22 @@ describe("useDimensions", () => {
42
36
 
43
37
  beforeEach(() => {
44
38
  StatusBar.currentHeight = 20;
45
- (usePickFromState as jest.Mock).mockReturnValue({ appData: mockAppData });
46
39
  });
47
40
 
48
41
  it("returns correct initial dimensions", () => {
49
- const { result } = renderHook(() =>
50
- useDimensions("window", { fullDimensions: false })
42
+ const { result } = renderHook(
43
+ () => useDimensions("window", { fullDimensions: false }),
44
+ {
45
+ wrapper: ({ children }) => (
46
+ <WrappedWithProviders
47
+ store={{
48
+ appData: mockAppData,
49
+ }}
50
+ >
51
+ {children}
52
+ </WrappedWithProviders>
53
+ ),
54
+ }
51
55
  );
52
56
 
53
57
  expect(result.current).toMatchObject({
@@ -56,7 +60,17 @@ describe("useDimensions", () => {
56
60
  });
57
61
 
58
62
  it("calls handler on mount", () => {
59
- renderHook(() => useDimensions("window", { fullDimensions: false }));
63
+ renderHook(() => useDimensions("window", { fullDimensions: false }), {
64
+ wrapper: ({ children }) => (
65
+ <WrappedWithProviders
66
+ store={{
67
+ appData: mockAppData,
68
+ }}
69
+ >
70
+ {children}
71
+ </WrappedWithProviders>
72
+ ),
73
+ });
60
74
 
61
75
  expect(Dimensions.addEventListener).toHaveBeenCalledWith(
62
76
  "change",
@@ -65,12 +79,23 @@ describe("useDimensions", () => {
65
79
  });
66
80
 
67
81
  it("calls handler on isActive change", () => {
68
- const { rerender } = renderHook(() =>
69
- useDimensions("window", { fullDimensions: false })
82
+ const { rerender } = renderHook(
83
+ () => useDimensions("window", { fullDimensions: false }),
84
+ {
85
+ wrapper: ({ children }) => (
86
+ <WrappedWithProviders
87
+ store={{
88
+ appData: mockAppData,
89
+ }}
90
+ >
91
+ {children}
92
+ </WrappedWithProviders>
93
+ ),
94
+ }
70
95
  );
71
96
 
72
97
  (useIsScreenActive as jest.Mock).mockReturnValue(false);
73
- rerender();
98
+ rerender({});
74
99
 
75
100
  expect(Dimensions.addEventListener).toHaveBeenCalledWith(
76
101
  "change",
@@ -79,8 +104,19 @@ describe("useDimensions", () => {
79
104
  });
80
105
 
81
106
  it("handles fullDimensions option", () => {
82
- const { result } = renderHook(() =>
83
- useDimensions("window", { fullDimensions: true })
107
+ const { result } = renderHook(
108
+ () => useDimensions("window", { fullDimensions: true }),
109
+ {
110
+ wrapper: ({ children }) => (
111
+ <WrappedWithProviders
112
+ store={{
113
+ appData: mockAppData,
114
+ }}
115
+ >
116
+ {children}
117
+ </WrappedWithProviders>
118
+ ),
119
+ }
84
120
  );
85
121
 
86
122
  expect(result.current).toMatchObject({
@@ -91,8 +127,19 @@ describe("useDimensions", () => {
91
127
  });
92
128
 
93
129
  it("handles excludeStatusBar option", () => {
94
- const { result } = renderHook(() =>
95
- useDimensions("window", { excludeStatusBar: true })
130
+ const { result } = renderHook(
131
+ () => useDimensions("window", { excludeStatusBar: true }),
132
+ {
133
+ wrapper: ({ children }) => (
134
+ <WrappedWithProviders
135
+ store={{
136
+ appData: mockAppData,
137
+ }}
138
+ >
139
+ {children}
140
+ </WrappedWithProviders>
141
+ ),
142
+ }
96
143
  );
97
144
 
98
145
  expect(result.current.height).toBe(
@@ -101,8 +148,19 @@ describe("useDimensions", () => {
101
148
  });
102
149
 
103
150
  it("handles rounded option", () => {
104
- const { result } = renderHook(() =>
105
- useDimensions("window", { rounded: true })
151
+ const { result } = renderHook(
152
+ () => useDimensions("window", { rounded: true }),
153
+ {
154
+ wrapper: ({ children }) => (
155
+ <WrappedWithProviders
156
+ store={{
157
+ appData: mockAppData,
158
+ }}
159
+ >
160
+ {children}
161
+ </WrappedWithProviders>
162
+ ),
163
+ }
106
164
  );
107
165
 
108
166
  expect(result.current.width).toBe(Math.ceil(mockDimensions.width));
@@ -110,8 +168,19 @@ describe("useDimensions", () => {
110
168
  });
111
169
 
112
170
  it("handles deviceInfo option", () => {
113
- const { result } = renderHook(() =>
114
- useDimensions("window", { deviceInfo: true })
171
+ const { result } = renderHook(
172
+ () => useDimensions("window", { deviceInfo: true }),
173
+ {
174
+ wrapper: ({ children }) => (
175
+ <WrappedWithProviders
176
+ store={{
177
+ appData: mockAppData,
178
+ }}
179
+ >
180
+ {children}
181
+ </WrappedWithProviders>
182
+ ),
183
+ }
115
184
  );
116
185
 
117
186
  expect(result.current.deviceInfo).toMatchObject({
@@ -121,7 +190,18 @@ describe("useDimensions", () => {
121
190
 
122
191
  it("logs deprecation warning when fullDimensions is boolean", () => {
123
192
  const consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation();
124
- renderHook(() => useDimensions("window", true));
193
+
194
+ renderHook(() => useDimensions("window", true), {
195
+ wrapper: ({ children }) => (
196
+ <WrappedWithProviders
197
+ store={{
198
+ appData: mockAppData,
199
+ }}
200
+ >
201
+ {children}
202
+ </WrappedWithProviders>
203
+ ),
204
+ });
125
205
 
126
206
  expect(consoleWarnSpy).toHaveBeenCalledWith(
127
207
  "Deprecation Warning\nSecond argument is now the options object. {fullDimensions: boolean, ...}"
@@ -3,7 +3,7 @@ import { useLayoutEffect, useMemo, useRef, useState } from "react";
3
3
  import * as R from "ramda";
4
4
 
5
5
  import { Dimensions, Platform, StatusBar } from "react-native";
6
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+ import { useAppData } from "@applicaster/zapp-react-native-redux/hooks";
7
7
 
8
8
  import { isTV } from "../../../reactUtils";
9
9
 
@@ -37,7 +37,7 @@ export const useDimensions: UseDimensions = (
37
37
  ) => {
38
38
  const statusBarHeight = StatusBar?.currentHeight;
39
39
  const isActive = useIsScreenActive();
40
- const { appData } = usePickFromState(["appData"]);
40
+ const appData = useAppData();
41
41
 
42
42
  if (typeof fullDimensions === "boolean") {
43
43
  // eslint-disable-next-line no-console