@applicaster/zapp-react-native-ui-components 15.0.0-alpha.4153840309 → 15.0.0-alpha.4200413542

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 (85) hide show
  1. package/Components/BaseFocusable/index.ios.ts +12 -2
  2. package/Components/Cell/Cell.tsx +6 -0
  3. package/Components/Cell/CellWithFocusable.tsx +9 -0
  4. package/Components/Cell/FocusableWrapper.tsx +3 -0
  5. package/Components/Cell/TvOSCellComponent.tsx +17 -5
  6. package/Components/Focusable/Focusable.tsx +4 -2
  7. package/Components/Focusable/FocusableTvOS.tsx +18 -1
  8. package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +1 -0
  9. package/Components/FocusableGroup/FocusableTvOS.tsx +32 -1
  10. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
  11. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +22 -6
  12. package/Components/HandlePlayable/HandlePlayable.tsx +10 -7
  13. package/Components/Layout/TV/LayoutBackground.tsx +5 -2
  14. package/Components/Layout/TV/ScreenContainer.tsx +2 -6
  15. package/Components/Layout/TV/index.tsx +3 -4
  16. package/Components/Layout/TV/index.web.tsx +3 -4
  17. package/Components/LinkHandler/LinkHandler.tsx +2 -2
  18. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -10
  19. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +5 -1
  20. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -3
  21. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +9 -1
  22. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +15 -14
  23. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +40 -39
  24. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/Image.test.tsx +95 -0
  25. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +86 -0
  26. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/index.test.ts +141 -0
  27. package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +7 -6
  28. package/Components/MasterCell/DefaultComponents/SecondaryImage/index.ts +1 -1
  29. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -2
  30. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +233 -11
  31. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +19 -15
  32. package/Components/MasterCell/hoc/__tests__/withAsyncRender.test.tsx +219 -0
  33. package/Components/MasterCell/hoc/withAsyncRender.tsx +9 -7
  34. package/Components/MasterCell/utils/__tests__/resolveColor.test.js +82 -3
  35. package/Components/MasterCell/utils/index.ts +61 -31
  36. package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +102 -87
  37. package/Components/MeasurmentsPortal/__tests__/MeasurementsPortal.test.tsx +355 -0
  38. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +17 -9
  39. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +16 -8
  40. package/Components/OfflineHandler/NotificationView/NotificationView.tsx +2 -2
  41. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +17 -18
  42. package/Components/OfflineHandler/NotificationView/utils.ts +34 -0
  43. package/Components/OfflineHandler/__tests__/index.test.tsx +27 -18
  44. package/Components/PlayerContainer/PlayerContainer.tsx +51 -40
  45. package/Components/PlayerContainer/useRestrictMobilePlayback.tsx +101 -0
  46. package/Components/River/ComponentsMap/ComponentsMap.tsx +16 -0
  47. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
  48. package/Components/River/TV/River.tsx +31 -14
  49. package/Components/River/TV/index.tsx +8 -4
  50. package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +30 -0
  51. package/Components/River/TV/utils/index.ts +4 -0
  52. package/Components/River/TV/withFocusableGroupForContent.tsx +71 -0
  53. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  54. package/Components/River/__tests__/componentsMap.test.js +38 -0
  55. package/Components/Screen/TV/index.web.tsx +4 -2
  56. package/Components/Screen/__tests__/Screen.test.tsx +65 -42
  57. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +68 -44
  58. package/Components/Screen/hooks.ts +2 -3
  59. package/Components/Screen/index.tsx +2 -3
  60. package/Components/Screen/navigationHandler.ts +49 -24
  61. package/Components/Screen/orientationHandler.ts +10 -13
  62. package/Components/ScreenResolver/index.tsx +13 -7
  63. package/Components/Tabs/TabContent.tsx +7 -4
  64. package/Components/Transitioner/index.js +3 -3
  65. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +13 -9
  66. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +15 -7
  67. package/Components/VideoModal/utils.ts +12 -9
  68. package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
  69. package/Contexts/ScreenContext/index.tsx +25 -18
  70. package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
  71. package/Contexts/ZappHookModalContext/index.tsx +37 -61
  72. package/Contexts/index.ts +0 -2
  73. package/Decorators/Analytics/index.tsx +6 -5
  74. package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +1 -0
  75. package/Decorators/ConfigurationWrapper/const.ts +1 -0
  76. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
  77. package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
  78. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
  79. package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +80 -0
  80. package/Helpers/DataSourceHelper/index.ts +19 -0
  81. package/events/index.ts +3 -0
  82. package/events/scrollEndReached.ts +15 -0
  83. package/package.json +6 -5
  84. package/Components/River/TV/withTVEventHandler.tsx +0 -27
  85. package/Helpers/DataSourceHelper/index.js +0 -19
@@ -1,18 +1,16 @@
1
- import React, { useLayoutEffect } from "react";
1
+ import { useLayoutEffect } from "react";
2
2
 
3
3
  import {
4
4
  allowedOrientationsForScreen,
5
- ORIENTATIONS,
6
5
  getOrientation,
6
+ ORIENTATIONS,
7
7
  useGetScreenOrientation,
8
8
  } from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
9
9
  import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
10
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
10
+ import { usePlugins, useAppData } from "@applicaster/zapp-react-native-redux";
11
11
  import { findPluginByType } from "@applicaster/zapp-react-native-utils/pluginUtils";
12
12
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
13
-
14
- import { ZappHookModalContext } from "../../Contexts";
15
- import { HookModalContextT } from "../../Contexts/ZappHookModalContext";
13
+ import { zappHookModalStore } from "../../Contexts/ZappHookModalContext";
16
14
 
17
15
  /**
18
16
  * This function calls the native module needed to set orientation
@@ -65,8 +63,8 @@ export function useNewOrientationForScreenData({
65
63
  }: OrientationHookArgs) {
66
64
  const isTablet = useIsTablet();
67
65
 
68
- const { appData, plugins } = usePickFromState(["appData", "plugins"]);
69
- const isTabletPortrait = appData?.isTabletPortrait;
66
+ const plugins = usePlugins();
67
+ const { isTabletPortrait } = useAppData();
70
68
  const isLandscapeTablet = isTablet && !isTabletPortrait;
71
69
 
72
70
  const screenOrientation = useGetScreenOrientation(screenData);
@@ -89,10 +87,6 @@ type Props = {
89
87
  };
90
88
 
91
89
  export function useScreenOrientationHandler({ screenData, isActive }: Props) {
92
- const { isHooksExecutionInProgress } = React.useContext<HookModalContextT>(
93
- ZappHookModalContext.ReactContext
94
- );
95
-
96
90
  const prevIsActive = usePrevious(isActive);
97
91
 
98
92
  const newOrientation = useNewOrientationForScreenData({
@@ -105,6 +99,9 @@ export function useScreenOrientationHandler({ screenData, isActive }: Props) {
105
99
  return;
106
100
  }
107
101
 
102
+ // TODO: make sure it can be static getter and subscription is not needed
103
+ const { isHooksExecutionInProgress } = zappHookModalStore.getState();
104
+
108
105
  // If modal hook presented we need to skip
109
106
  // Change orientation for presenter screen
110
107
  if (isHooksExecutionInProgress) {
@@ -116,7 +113,7 @@ export function useScreenOrientationHandler({ screenData, isActive }: Props) {
116
113
 
117
114
  setOrientation(newOrientation);
118
115
  }
119
- }, [newOrientation, isHooksExecutionInProgress, prevIsActive, isActive]);
116
+ }, [newOrientation, prevIsActive, isActive]);
120
117
  }
121
118
 
122
119
  export function useOrientationHandler({ screenData }: OrientationHookArgs) {
@@ -11,12 +11,19 @@ import { LinkHandler } from "../LinkHandler";
11
11
  import { Favorites } from "../Favorites";
12
12
  import { ZappPipesScreenContext } from "../../Contexts";
13
13
  import { componentsLogger } from "../../Helpers/logger";
14
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
15
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
14
+ import {
15
+ useAppSelector,
16
+ usePlugins,
17
+ } from "@applicaster/zapp-react-native-redux/hooks";
18
+ import {
19
+ useNavigation,
20
+ useRivers,
21
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
16
22
  import { useScreenAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
17
23
 
18
24
  import { useCallbackActions } from "@applicaster/zapp-react-native-utils/zappFrameworkUtils/HookCallback/useCallbackActions";
19
25
  import { ScreenResultCallback } from "@applicaster/zapp-react-native-utils/zappFrameworkUtils/HookCallback/callbackNavigationAction";
26
+ import { selectComponents } from "@applicaster/zapp-react-native-redux";
20
27
 
21
28
  const logger = componentsLogger.addSubsystem("ScreenResolver");
22
29
 
@@ -49,11 +56,10 @@ export function ScreenResolverComponent(props: Props) {
49
56
 
50
57
  const { hookPlugin } = screenData || {};
51
58
 
52
- const { components, plugins, rivers } = usePickFromState([
53
- "components",
54
- "plugins",
55
- "rivers",
56
- ]);
59
+ const plugins = usePlugins();
60
+ const rivers = useRivers();
61
+
62
+ const components = useAppSelector(selectComponents);
57
63
 
58
64
  const {
59
65
  videoModalState: { mode },
@@ -1,11 +1,10 @@
1
1
  import React from "react";
2
- import { View, ViewStyle } from "react-native";
2
+ import { View, StyleSheet } from "react-native";
3
3
 
4
4
  import { River } from "@applicaster/zapp-react-native-ui-components/Components";
5
5
  import { withNestedNavigationContextProvider } from "@applicaster/zapp-react-native-ui-components/Contexts/NestedNavigationContext";
6
6
 
7
7
  type Props = {
8
- styles: Record<string, ViewStyle>;
9
8
  minHeight: number;
10
9
  changingTab: boolean;
11
10
  feedUrl: string;
@@ -14,9 +13,14 @@ type Props = {
14
13
  backgroundColor: string;
15
14
  };
16
15
 
16
+ const styles = StyleSheet.create({
17
+ riverWrapper: {
18
+ flex: 1,
19
+ },
20
+ });
21
+
17
22
  function TabContentComponent(props: Props) {
18
23
  const {
19
- styles,
20
24
  minHeight,
21
25
  backgroundColor,
22
26
  changingTab,
@@ -29,7 +33,6 @@ function TabContentComponent(props: Props) {
29
33
  <View
30
34
  style={[
31
35
  styles.riverWrapper,
32
-
33
36
  {
34
37
  backgroundColor,
35
38
  minHeight,
@@ -1,7 +1,8 @@
1
1
  import * as React from "react";
2
2
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
3
3
  import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
4
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
4
+ import { useAppData } from "@applicaster/zapp-react-native-redux";
5
+
5
6
  import { TransitionerComponent } from "./Transitioner";
6
7
 
7
8
  export const Transitioner = (props) => {
@@ -16,8 +17,7 @@ export const Transitioner = (props) => {
16
17
  deviceInfo: true,
17
18
  });
18
19
 
19
- const { appData } = usePickFromState(["appData"]);
20
- const isTabletPortrait = appData?.isTabletPortrait;
20
+ const { isTabletPortrait } = useAppData();
21
21
 
22
22
  return (
23
23
  <TransitionerComponent
@@ -4,8 +4,11 @@ import { Animated, Dimensions } from "react-native";
4
4
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
5
5
 
6
6
  import { useConfiguration } from "../utils";
7
- import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
8
- import { isMenuVisible } from "../../Screen/navigationHandler";
7
+ import {
8
+ useAppData,
9
+ usePlugins,
10
+ } from "@applicaster/zapp-react-native-redux/hooks";
11
+ import { isBottomTabVisible } from "../../Screen/navigationHandler";
9
12
 
10
13
  import {
11
14
  useSafeAreaFrame,
@@ -18,7 +21,6 @@ import {
18
21
  import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/getTabBarHeight";
19
22
  import { PROGRESS_BAR_HEIGHT } from "./utils";
20
23
  import { useIsTablet as getIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
21
- import { useAppSelector } from "@applicaster/zapp-react-native-redux";
22
24
 
23
25
  export type ModalAnimationContextT = {
24
26
  yTranslate: React.MutableRefObject<Animated.AnimatedInterpolation<number>>;
@@ -64,13 +66,15 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
64
66
  screenData,
65
67
  } = useNavigation();
66
68
 
67
- const isTabletPortrait = useAppSelector(
68
- (state) => state.appData.isTabletPortrait
69
- );
69
+ const { isTabletPortrait } = useAppData();
70
70
 
71
71
  const plugins = usePlugins();
72
72
 
73
- const menuVisible = isMenuVisible(currentRoute, screenData, plugins);
73
+ const bottomTabsVisible = isBottomTabVisible(
74
+ currentRoute,
75
+ screenData,
76
+ plugins
77
+ );
74
78
 
75
79
  const frame = useSafeAreaFrame();
76
80
  const insets = useSafeAreaInsets();
@@ -115,7 +119,7 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
115
119
  React.useEffect(() => {
116
120
  const collapsedHeight =
117
121
  minimisedHeight +
118
- (menuVisible ? bottomTabBarHeight : 0) +
122
+ (bottomTabsVisible ? bottomTabBarHeight : 0) +
119
123
  (isOldAndroidDevice ? 0 : insets.bottom) + // insets.bottom is added to properly display docked modal
120
124
  PROGRESS_BAR_HEIGHT;
121
125
 
@@ -136,7 +140,7 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
136
140
  setHeightAboveMinimised(heightAboveMinimised);
137
141
  offset.current = heightAboveMinimised;
138
142
  }
139
- }, [frame.height, insets.bottom, menuVisible, minimisedHeight]);
143
+ }, [frame.height, insets.bottom, bottomTabsVisible, minimisedHeight]);
140
144
 
141
145
  return (
142
146
  <ReactContext.Provider
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { act, renderHook, waitFor } from "@testing-library/react-native";
2
2
  import { useDelayedPlayerDetails } from "../useDelayedPlayerDetails";
3
3
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
4
4
 
@@ -13,16 +13,20 @@ describe("useDelayedPlayerDetails", () => {
13
13
  jest.clearAllMocks();
14
14
  });
15
15
 
16
- it("should return false initially, that changes after 1 second", () => {
16
+ it("should return false initially, that changes after 1 second", async () => {
17
17
  const { result } = renderHook(() =>
18
18
  useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
19
19
  );
20
20
 
21
21
  expect(result.current).toBe(false);
22
22
 
23
- jest.advanceTimersByTime(1000);
23
+ act(() => {
24
+ jest.advanceTimersByTime(1000);
25
+ });
24
26
 
25
- expect(result.current).toBe(true);
27
+ await waitFor(() => {
28
+ expect(result.current).toBe(true);
29
+ });
26
30
  });
27
31
 
28
32
  it("should return false when isPip is true", () => {
@@ -41,7 +45,7 @@ describe("useDelayedPlayerDetails", () => {
41
45
  expect(result.current).toBe(false);
42
46
  });
43
47
 
44
- it("should return true for tablet regardless of other flags", () => {
48
+ it("should return true for tablet regardless of other flags", async () => {
45
49
  (useIsTablet as jest.Mock).mockReturnValue(true);
46
50
 
47
51
  const { result } = renderHook(() =>
@@ -52,8 +56,12 @@ describe("useDelayedPlayerDetails", () => {
52
56
  })
53
57
  );
54
58
 
55
- jest.advanceTimersByTime(1000);
59
+ act(() => {
60
+ jest.advanceTimersByTime(1000);
61
+ });
56
62
 
57
- expect(result.current).toBe(true);
63
+ await waitFor(() => {
64
+ expect(result.current).toBe(true);
65
+ });
58
66
  });
59
67
  });
@@ -1,32 +1,35 @@
1
1
  import { mergeRight } from "ramda";
2
2
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
3
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
+ import {
4
+ useAppSelector,
5
+ useContentTypes,
6
+ } from "@applicaster/zapp-react-native-redux/hooks";
4
7
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
5
8
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
6
9
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
7
10
  import { create } from "zustand";
11
+ import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks";
12
+ import { selectPluginConfigurationsByPluginId } from "@applicaster/zapp-react-native-redux";
8
13
 
9
14
  export const useConfiguration = () => {
10
15
  const {
11
16
  videoModalState: { item },
12
17
  } = useNavigation();
13
18
 
14
- const { rivers, contentTypes, pluginConfigurations } = usePickFromState([
15
- "rivers",
16
- "contentTypes",
17
- "pluginConfigurations",
18
- ]);
19
+ const rivers = useRivers();
20
+ const contentTypes = useContentTypes();
19
21
 
20
22
  const targetScreenId = contentTypes?.[item?.type?.value]?.screen_id;
21
23
  const targetScreenConfiguration = rivers?.[targetScreenId];
22
24
 
23
- const pluginConfiguration =
24
- pluginConfigurations[targetScreenConfiguration?.type]?.configuration_json;
25
+ const { configuration_json } = useAppSelector((state) =>
26
+ selectPluginConfigurationsByPluginId(state, targetScreenConfiguration?.type)
27
+ );
25
28
 
26
29
  const playerPluginConfig = playerManager.getPluginConfiguration();
27
30
 
28
31
  const config = mergeRight(playerPluginConfig, {
29
- ...pluginConfiguration,
32
+ ...configuration_json,
30
33
  ...targetScreenConfiguration?.general,
31
34
  ...targetScreenConfiguration?.styles,
32
35
  });
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { renderHook } from "@testing-library/react-hooks";
2
+ import { renderHook } from "@testing-library/react-native";
3
3
  import {
4
4
  ViewportEvents,
5
5
  useViewportEventsContext,
@@ -16,6 +16,7 @@ import { useNestedNavigationContext } from "@applicaster/zapp-react-native-ui-co
16
16
  import { create } from "zustand";
17
17
  import { subscribeWithSelector } from "zustand/middleware";
18
18
  import { useShallow } from "zustand/react/shallow";
19
+
19
20
  import { Animated } from "react-native";
20
21
 
21
22
  interface NavBarStoreState {
@@ -29,6 +30,8 @@ interface NavBarStoreState {
29
30
  scrollState: number;
30
31
  contentPosition: string;
31
32
  scrollYAnimated: Animated.Value;
33
+ hideOnScrollAnimated: Animated.Value;
34
+ hideOnScroll: boolean;
32
35
  }
33
36
 
34
37
  interface NavBarState {
@@ -62,24 +65,28 @@ const createStateStore = () =>
62
65
  );
63
66
 
64
67
  const createStore = () =>
65
- create<NavBarStoreState>((set) => ({
66
- title: "",
67
- summary: "",
68
- visible: true,
69
- height: 0,
70
- scrollState: 0,
71
- contentPosition: "",
72
- scrollYAnimated: new Animated.Value(0),
73
- setTitle(title) {
74
- set({ title });
75
- },
76
- setSummary(summary) {
77
- set({ summary });
78
- },
79
- setVisible(visible) {
80
- set({ visible });
81
- },
82
- }));
68
+ create(
69
+ subscribeWithSelector<NavBarStoreState>((set) => ({
70
+ title: "",
71
+ summary: "",
72
+ visible: true,
73
+ height: 0,
74
+ scrollState: 0,
75
+ contentPosition: "",
76
+ scrollYAnimated: new Animated.Value(0),
77
+ hideOnScrollAnimated: new Animated.Value(0),
78
+ hideOnScroll: false,
79
+ setTitle(title) {
80
+ set({ title });
81
+ },
82
+ setSummary(summary) {
83
+ set({ summary });
84
+ },
85
+ setVisible(visible) {
86
+ set({ visible });
87
+ },
88
+ }))
89
+ );
83
90
 
84
91
  type ScreenContextType = {
85
92
  _navBarStore: ReturnType<typeof createStore>;
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
  import {
3
3
  useScreenTrackedViewPositionsContext,
4
4
  ScreenTrackedViewPositionsContext,
@@ -1,4 +1,4 @@
1
- import React, { useCallback } from "react";
1
+ import { create } from "zustand";
2
2
 
3
3
  type HookModalState = {
4
4
  path: string;
@@ -10,11 +10,12 @@ export type HookModalContextT = {
10
10
  setIsHooksExecutionInProgress: (hookExecutionState?: boolean) => void;
11
11
  isRunningInBackground: boolean;
12
12
  isPresentationFullScreen: boolean;
13
- setIsRunningInBackground: (hookBackgroundProcessState?: boolean) => void;
14
- setIsPresentingFullScreen: (hookBackgroundProcessState?: boolean) => void;
13
+ setIsRunningInBackground: () => void;
14
+ setIsPresentingFullScreen: () => void;
15
15
  state: HookModalState;
16
16
  setState: (state: HookModalState) => void;
17
17
  resetState: () => void;
18
+ hookPresentationMode: HookPresentationMode;
18
19
  };
19
20
 
20
21
  const initialState = {
@@ -24,68 +25,43 @@ const initialState = {
24
25
 
25
26
  type HookPresentationMode = "background" | "fullScreen";
26
27
 
27
- const ReactContext = React.createContext<HookModalContextT>({
28
- isHooksExecutionInProgress: false,
29
- setIsHooksExecutionInProgress: () => {},
30
- isRunningInBackground: null,
31
- setIsRunningInBackground: () => {},
32
- setIsPresentingFullScreen: () => {},
33
- isPresentationFullScreen: null,
28
+ // Use useZappHookModalStore() in React components (hooks)
29
+ // Use zappHookModalStore.getState() in non-React functions (utility functions, etc.)
30
+ export const useZappHookModalStore = create<HookModalContextT>()((set) => ({
34
31
  state: initialState,
35
- setState: () => null,
36
- resetState: () => null,
37
- });
38
-
39
- const Provider = ({ children }: { children: React.ReactNode }) => {
40
- const [state, setState] = React.useState<HookModalState>(initialState);
41
-
42
- const [hookPresentationMode, setHookPresentationMode] =
43
- React.useState<HookPresentationMode>(null);
44
-
45
- const resetState = useCallback(() => {
46
- setState(initialState);
47
- }, [setState]);
48
-
49
- const [isHooksExecutionInProgress, setIsHooksExecutionInProgress] =
50
- React.useState(false);
32
+ isHooksExecutionInProgress: false,
33
+ hookPresentationMode: null as HookPresentationMode,
34
+ isRunningInBackground: false,
35
+ isPresentationFullScreen: false,
51
36
 
52
- const setIsRunningInBackground = () => {
53
- setHookPresentationMode("background");
54
- };
37
+ setState: (newState: HookModalState) => {
38
+ set({ state: newState });
39
+ },
55
40
 
56
- const setIsPresentingFullScreen = () => {
57
- setHookPresentationMode("fullScreen");
58
- };
41
+ setIsHooksExecutionInProgress: (hookExecutionState?: boolean) => {
42
+ set({ isHooksExecutionInProgress: hookExecutionState ?? false });
43
+ },
59
44
 
60
- return (
61
- <ReactContext.Provider
62
- value={{
63
- isRunningInBackground: hookPresentationMode === "background",
64
- setIsRunningInBackground,
65
- setIsPresentingFullScreen,
66
- isPresentationFullScreen: hookPresentationMode === "fullScreen",
67
- isHooksExecutionInProgress,
68
- setIsHooksExecutionInProgress,
69
- state,
70
- setState,
71
- resetState,
72
- }}
73
- >
74
- {children}
75
- </ReactContext.Provider>
76
- );
77
- };
45
+ setIsRunningInBackground: () => {
46
+ set({
47
+ hookPresentationMode: "background",
48
+ isRunningInBackground: true,
49
+ isPresentationFullScreen: false,
50
+ });
51
+ },
78
52
 
79
- const withProvider = (Component) => {
80
- const WithProvider = (props) => {
81
- return (
82
- <Provider>
83
- <Component {...props} />
84
- </Provider>
85
- );
86
- };
53
+ setIsPresentingFullScreen: () => {
54
+ set({
55
+ hookPresentationMode: "fullScreen",
56
+ isRunningInBackground: false,
57
+ isPresentationFullScreen: true,
58
+ });
59
+ },
87
60
 
88
- return WithProvider;
89
- };
61
+ resetState: () => {
62
+ set({ state: initialState });
63
+ },
64
+ }));
90
65
 
91
- export const ZappHookModalContext = { withProvider, ReactContext };
66
+ // Export an alias for clearer non-React usage (utility functions, etc.)
67
+ export const zappHookModalStore = useZappHookModalStore;
package/Contexts/index.ts CHANGED
@@ -12,8 +12,6 @@ export { HorizontalScrollContext } from "./HorizontalScrollContext";
12
12
 
13
13
  export { RiverOffsetContext } from "./RiverOffsetContext";
14
14
 
15
- export { ZappHookModalContext } from "./ZappHookModalContext";
16
-
17
15
  export { MeasurementContext } from "./MeasurementContext";
18
16
 
19
17
  export * from "./ZappPipesContext";
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
 
3
3
  import { getAnalyticsFunctions } from "@applicaster/zapp-react-native-utils/analyticsUtils";
4
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
4
 
6
5
  type ComponentProps = {
7
6
  component: {
@@ -21,11 +20,13 @@ type ComponentProps = {
21
20
 
22
21
  function withAnalytics(Component) {
23
22
  return function WithAnalytics(props: ComponentProps) {
24
- const { appData } = usePickFromState(["appData"]);
25
-
26
23
  const analyticsFunctions = React.useMemo(
27
- () => getAnalyticsFunctions({ props, appData }),
28
- [props, appData]
24
+ () =>
25
+ getAnalyticsFunctions({
26
+ component: props.component,
27
+ zappPipesData: props.zappPipesData,
28
+ } as any),
29
+ [props.component, props.zappPipesData]
29
30
  );
30
31
 
31
32
  return (
@@ -88,6 +88,7 @@ exports[`withConfigurationProvider correctly passes all the configuration keys c
88
88
  tab_cell_padding_right={10}
89
89
  tab_cell_padding_top={14}
90
90
  tablet_theme={false}
91
+ tabs_screen_background_color="transparent"
91
92
  target={false}
92
93
  target_screen_switch={false}
93
94
  text_label_active_font_color="rgba(239, 239, 239, 0.5)"
@@ -208,4 +208,5 @@ export const keysMap: Record<string, Function> = {
208
208
  tab_bar_item_margin_right: castOrDefaultValue(Number, 0),
209
209
  tab_bar_item_margin_bottom: castOrDefaultValue(Number, 0),
210
210
  tab_bar_item_margin_left: castOrDefaultValue(Number, 0),
211
+ tabs_screen_background_color: castOrDefaultValue(R.identity, "transparent"),
211
212
  };
@@ -3,7 +3,7 @@ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUt
3
3
 
4
4
  import * as zappPipesRedux from "@applicaster/zapp-react-native-redux/ZappPipes";
5
5
  import configureStore from "redux-mock-store";
6
- import thunk from "redux-thunk";
6
+ import { thunk } from "redux-thunk";
7
7
 
8
8
  import { zappPipesDataConnector } from "../index";
9
9
 
@@ -2,7 +2,7 @@
2
2
  /// <reference types="@applicaster/zapp-react-native-ui-components" />
3
3
  import React from "react";
4
4
  import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
5
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
+ import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
6
6
  import { ZappPipesSearchContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
7
7
  import { useScreenContext } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
8
8
  import { ResolverSelector } from "./ResolverSelector";
@@ -23,7 +23,7 @@ export function zappPipesDataConnector(
23
23
  ) {
24
24
  return function WrappedWithZappPipesData(props: Props) {
25
25
  const { screenData } = useRoute();
26
- const { plugins } = usePickFromState(["plugins"]);
26
+ const plugins = usePlugins();
27
27
  const screenContextData = useScreenContext();
28
28
 
29
29
  const {
@@ -76,7 +76,7 @@ export function StaticFeedResolver({
76
76
 
77
77
  const zappPipesDataProps = useMemo(
78
78
  () => ({
79
- zappPipesData: { url, loading, data, error },
79
+ zappPipesData: { url, loading, data, error }, // todo: add applyItemLimit
80
80
  reloadData,
81
81
  loadNextData: undefined, // Static resolver doesn't support pagination
82
82
  }),