@applicaster/zapp-react-native-ui-components 15.1.0-rc.1 → 16.0.0-rc.1

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 (144) hide show
  1. package/Components/BaseFocusable/index.ios.ts +12 -2
  2. package/Components/Cell/FocusableWrapper.tsx +3 -0
  3. package/Components/Cell/TvOSCellComponent.tsx +6 -3
  4. package/Components/Focusable/Focusable.tsx +4 -2
  5. package/Components/Focusable/FocusableTvOS.tsx +18 -1
  6. package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +1 -0
  7. package/Components/FocusableGroup/FocusableTvOS.tsx +30 -1
  8. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
  9. package/Components/HandlePlayable/HandlePlayable.tsx +13 -8
  10. package/Components/Layout/TV/LayoutBackground.tsx +5 -2
  11. package/Components/Layout/TV/NavBarContainer.tsx +1 -10
  12. package/Components/Layout/TV/ScreenContainer.tsx +2 -6
  13. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
  14. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
  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/CONFIG_BUILDER_TO_REACT_COMPONENT.md +144 -0
  19. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  20. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
  21. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  22. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  23. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +165 -0
  24. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +405 -0
  25. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/index.ts +1 -0
  26. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  27. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
  28. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  29. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  30. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  31. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -10
  32. package/Components/MasterCell/DefaultComponents/Button.tsx +0 -15
  33. package/Components/MasterCell/DefaultComponents/ButtonContainerView/components/HorizontalSeparator.tsx +8 -0
  34. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.tsx +15 -0
  35. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.tv.android.tsx +58 -0
  36. package/Components/MasterCell/DefaultComponents/{tv/ButtonContainerView/index.tsx → ButtonContainerView/index.tv.tsx} +3 -11
  37. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.web.ts +1 -0
  38. package/Components/MasterCell/DefaultComponents/ButtonContainerView/types.ts +40 -0
  39. package/Components/MasterCell/DefaultComponents/DataProvider/index.tsx +163 -0
  40. package/Components/MasterCell/DefaultComponents/FocusableView/index.android.tsx +2 -23
  41. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -22
  42. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +8 -2
  43. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -3
  44. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +9 -1
  45. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +15 -14
  46. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +1 -2
  47. package/Components/MasterCell/DefaultComponents/PressableView.tsx +34 -0
  48. package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +7 -6
  49. package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +11 -0
  50. package/Components/MasterCell/DefaultComponents/__tests__/DataProvider.test.tsx +141 -0
  51. package/Components/MasterCell/DefaultComponents/index.ts +9 -3
  52. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +135 -0
  53. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +33 -0
  54. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +22 -0
  55. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +125 -0
  56. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
  57. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  58. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +37 -0
  59. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +393 -0
  60. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +141 -0
  61. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +343 -0
  62. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  63. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +122 -0
  64. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
  65. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +238 -0
  66. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Asset.ts +4 -18
  67. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Button.ts +24 -73
  68. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TextLabelsContainer.ts +37 -18
  69. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TvActionButton.tsx +27 -0
  70. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +89 -0
  71. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/renderedTree.test.tsx +231 -0
  72. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +47 -48
  73. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +115 -29
  74. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +101 -144
  75. package/Components/MasterCell/MappingFunctions/index.js +3 -2
  76. package/Components/MasterCell/README.md +4 -0
  77. package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +24 -0
  78. package/Components/MasterCell/__tests__/configInflater.test.js +1 -0
  79. package/Components/MasterCell/__tests__/elementMapper.test.js +46 -0
  80. package/Components/MasterCell/dataAdapter.ts +4 -1
  81. package/Components/MasterCell/elementMapper.tsx +52 -7
  82. package/Components/MasterCell/utils/__tests__/cloneChildrenWithIds.test.tsx +43 -0
  83. package/Components/MasterCell/utils/__tests__/useFilterChildren.test.tsx +80 -0
  84. package/Components/MasterCell/utils/index.ts +85 -15
  85. package/Components/OfflineHandler/NotificationView/NotificationView.tsx +2 -2
  86. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +17 -18
  87. package/Components/OfflineHandler/__tests__/index.test.tsx +27 -18
  88. package/Components/PlayerContainer/PlayerContainer.tsx +14 -13
  89. package/Components/River/ComponentsMap/ComponentsMap.tsx +6 -19
  90. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
  91. package/Components/River/RefreshControl.tsx +19 -88
  92. package/Components/River/River.tsx +9 -82
  93. package/Components/River/TV/River.tsx +31 -14
  94. package/Components/River/TV/index.tsx +8 -4
  95. package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +30 -0
  96. package/Components/River/TV/utils/index.ts +4 -0
  97. package/Components/River/TV/withFocusableGroupForContent.tsx +71 -0
  98. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -0
  99. package/Components/River/__tests__/componentsMap.test.js +38 -0
  100. package/Components/River/hooks/__tests__/usePullToRefresh.test.ts +132 -0
  101. package/Components/River/hooks/index.ts +1 -0
  102. package/Components/River/hooks/usePullToRefresh.ts +51 -0
  103. package/Components/Screen/TV/index.web.tsx +4 -2
  104. package/Components/Screen/__tests__/Screen.test.tsx +65 -42
  105. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +68 -44
  106. package/Components/Screen/hooks.ts +2 -3
  107. package/Components/Screen/index.tsx +2 -3
  108. package/Components/Screen/orientationHandler.ts +3 -3
  109. package/Components/ScreenResolver/index.tsx +9 -5
  110. package/Components/ScreenRevealManager/ScreenRevealManager.ts +40 -8
  111. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +86 -69
  112. package/Components/Tabs/TabContent.tsx +7 -4
  113. package/Components/TopCutoffOverlay/__tests__/TopCutoffOverlay.test.tsx +201 -0
  114. package/Components/TopCutoffOverlay/hooks/__tests__/useMarginTop.test.ts +130 -0
  115. package/Components/TopCutoffOverlay/hooks/index.ts +1 -0
  116. package/Components/TopCutoffOverlay/hooks/useMarginTop.ts +59 -0
  117. package/Components/TopCutoffOverlay/index.tsx +55 -0
  118. package/Components/Transitioner/index.js +3 -3
  119. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +5 -5
  120. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +15 -7
  121. package/Components/VideoModal/utils.ts +12 -9
  122. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
  123. package/Components/Viewport/ViewportAware/index.tsx +16 -7
  124. package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
  125. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -6
  126. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
  127. package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
  128. package/Contexts/ScreenContext/index.tsx +25 -18
  129. package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
  130. package/Decorators/Analytics/index.tsx +6 -5
  131. package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +1 -0
  132. package/Decorators/ConfigurationWrapper/const.ts +1 -0
  133. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
  134. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
  135. package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
  136. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
  137. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
  138. package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +80 -0
  139. package/Helpers/DataSourceHelper/index.ts +19 -0
  140. package/package.json +5 -5
  141. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +0 -135
  142. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/types.ts +0 -25
  143. package/Components/River/TV/withTVEventHandler.tsx +0 -36
  144. package/Helpers/DataSourceHelper/index.js +0 -19
@@ -0,0 +1,59 @@
1
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
2
+ import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks";
3
+ import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
4
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
5
+
6
+ /**
7
+ * The MarginTop is essentially a feature used for managing the visibility of components on your screen.
8
+ * A more accurate term for this might be something like a 'component visibility threshold' or 'cut-off point'.
9
+ * In practical terms, MarginTop determines a specific vertical position (given in the 'y' coordinate)
10
+ * on your screen above which components aren't shown.
11
+ * You might visualize this as a horizontal line across your screen, and any component crossing this line becomes invisible.
12
+ *
13
+ * Classic use case for this feature is making sure that component aren't displayed underneath the navigation bar.
14
+ */
15
+
16
+ export const useMarginTop = (targetScreenId: string): number => {
17
+ const theme = useTheme<BaseThemePropertiesTV>();
18
+ const screenData = useCurrentScreenData(targetScreenId);
19
+ const isGeneralContentScreen = screenData?.plugin_type === "general_content";
20
+ const supportsUiComponents = screenData?.ui_components;
21
+
22
+ /**
23
+ * ScreenPicker is a component but should really be a screen.
24
+ * We need to skip margin top for it as it's already applied to the target screen
25
+ **/
26
+
27
+ // ignore margin on screenPicker
28
+ if (isFirstComponentScreenPicker(screenData?.ui_components)) {
29
+ return 0;
30
+ }
31
+
32
+ const isPlayer = screenData?.plugin_type === "player";
33
+
34
+ // ignore margin on inlinePlayer (remove if better way of identifying cases for plugins that don't have marginTop)
35
+ if (isPlayer) {
36
+ return 0;
37
+ }
38
+
39
+ // Empty string means that value is blank in the CMS. Fallback to theme
40
+ if (String(screenData?.styles?.screen_margin_top) === "") {
41
+ return toNumberWithDefaultZero(theme.screen_margin_top);
42
+ }
43
+
44
+ /**
45
+ * If value is undefined it means one of three things
46
+ * 1. Screen is not a general content screen and it doesn't handle ui components (return 0)
47
+ * 2. Screen is a general content screen but it doesn't have a margin top value (return theme value)
48
+ * 3. Screen isn't general content screen but it handles the ui components (return theme value)
49
+ */
50
+ if (screenData?.styles?.screen_margin_top === undefined) {
51
+ if (isGeneralContentScreen || supportsUiComponents) {
52
+ return toNumberWithDefaultZero(theme.screen_margin_top);
53
+ }
54
+
55
+ return 0;
56
+ }
57
+
58
+ return toNumberWithDefaultZero(screenData?.styles?.screen_margin_top);
59
+ };
@@ -0,0 +1,55 @@
1
+ import React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
4
+ import { useScreenConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/River/useScreenConfiguration";
5
+
6
+ import { useMarginTop } from "./hooks";
7
+
8
+ interface IProps {
9
+ targetScreenId?: string;
10
+ children?: React.ReactNode;
11
+ applyTopCutoff?: boolean;
12
+ }
13
+
14
+ const styles = StyleSheet.create({
15
+ container: {
16
+ flex: 1,
17
+ },
18
+ });
19
+
20
+ export const TopCutoffOverlay: React.FC<IProps> = ({
21
+ targetScreenId,
22
+ children,
23
+ applyTopCutoff = true,
24
+ }: IProps) => {
25
+ const cutoffHeight = useMarginTop(targetScreenId);
26
+
27
+ const { backgroundColor: screenBackgroundColor } =
28
+ useScreenConfiguration(targetScreenId);
29
+
30
+ const theme = useTheme();
31
+ const themeBackgroundColor = theme?.app_background_color;
32
+
33
+ if (!applyTopCutoff) {
34
+ return children;
35
+ }
36
+
37
+ return (
38
+ <View style={styles.container}>
39
+ {children}
40
+
41
+ <View
42
+ style={{
43
+ position: "absolute",
44
+ top: 0,
45
+ left: 0,
46
+ right: 0,
47
+ height: cutoffHeight,
48
+
49
+ backgroundColor:
50
+ screenBackgroundColor || themeBackgroundColor || "transparent",
51
+ }}
52
+ />
53
+ </View>
54
+ );
55
+ };
@@ -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,7 +4,10 @@ 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";
7
+ import {
8
+ useAppData,
9
+ usePlugins,
10
+ } from "@applicaster/zapp-react-native-redux/hooks";
8
11
  import { isBottomTabVisible } from "../../Screen/navigationHandler";
9
12
 
10
13
  import {
@@ -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,9 +66,7 @@ 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
 
@@ -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
  });
@@ -22,8 +22,6 @@ ReactNative.UIManager.measureLayout = jest.fn(
22
22
  }
23
23
  );
24
24
 
25
- ReactNative.findNodeHandle = () => 1234;
26
-
27
25
  const viewportEventsManager = new ViewportEvents(true);
28
26
 
29
27
  const TestComponent = (props) => {
@@ -32,7 +32,7 @@ function getTestDimensions(testDimensions) {
32
32
  return (process.env.NODE_ENV === "test" && testDimensions) || null;
33
33
  }
34
34
 
35
- function ViewportAwareComponent(props: Props, ref) {
35
+ function ViewportAwareComponent(props: Props, forwardedRef) {
36
36
  const viewportEvents = useViewportEventsContext();
37
37
 
38
38
  const {
@@ -47,13 +47,22 @@ function ViewportAwareComponent(props: Props, ref) {
47
47
  getTestDimensions(testDimensions) || initialDimensions
48
48
  );
49
49
 
50
+ const localRef = React.useRef(null);
51
+
50
52
  const [viewportChangeEvent, setViewportChangeEvent] = React.useState(null);
51
53
 
52
- function assignRef(_ref) {
53
- if (_ref && !ref) {
54
- ref = _ref;
55
- }
56
- }
54
+ const assignRef = React.useCallback(
55
+ (_ref) => {
56
+ localRef.current = _ref;
57
+
58
+ if (typeof forwardedRef === "function") {
59
+ forwardedRef(_ref);
60
+ } else if (forwardedRef) {
61
+ forwardedRef.current = _ref;
62
+ }
63
+ },
64
+ [forwardedRef]
65
+ );
57
66
 
58
67
  const checkInViewport = (viewportChangeEvent, layoutEvent) => {
59
68
  const inVerticalViewport = Utils.isInViewport(
@@ -94,7 +103,7 @@ function ViewportAwareComponent(props: Props, ref) {
94
103
  const onViewportChange = (viewportChangeEvent) => {
95
104
  setViewportChangeEvent(viewportChangeEvent);
96
105
 
97
- const nodeHandle = findNodeHandle(ref);
106
+ const nodeHandle = findNodeHandle(localRef.current);
98
107
 
99
108
  if (!nodeHandle) {
100
109
  return;
@@ -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,
@@ -1,6 +1,5 @@
1
1
  import React from "react";
2
- import { StyleSheet } from "react-native";
3
- import { SafeAreaView } from "react-native-safe-area-context";
2
+ import { StyleSheet, View } from "react-native";
4
3
 
5
4
  import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
6
5
  import CloseButton from "./Buttons/CloseButton";
@@ -45,15 +44,14 @@ const BarView = ({ screenStyles, barState = defaultState }: Props) => {
45
44
  );
46
45
 
47
46
  return (
48
- <SafeAreaView
49
- edges={["top", "left", "right"]}
47
+ <View
50
48
  style={[style.view, isRTL ? style.rtlStyle : {}]}
51
- testID="BarView-safeAreaView"
49
+ testID="BarView-Container"
52
50
  >
53
51
  {backButton}
54
52
  <BarTitle title={barState.title} screenStyles={screenStyles} />
55
53
  {closeButton}
56
- </SafeAreaView>
54
+ </View>
57
55
  );
58
56
  };
59
57
 
@@ -46,7 +46,7 @@ describe("BarView", () => {
46
46
  <BarView screenStyles={screenStyles} barState={barState} />
47
47
  );
48
48
 
49
- expect(getByTestId("BarView-safeAreaView").props.style).toContainEqual({
49
+ expect(getByTestId("BarView-Container").props.style).toContainEqual({
50
50
  transform: [{ scaleX: -1 }],
51
51
  });
52
52
  });
@@ -58,7 +58,7 @@ describe("BarView", () => {
58
58
  <BarView screenStyles={screenStyles} barState={barState} />
59
59
  );
60
60
 
61
- expect(getByTestId("BarView-safeAreaView").props.style).not.toContainEqual({
61
+ expect(getByTestId("BarView-Container").props.style).not.toContainEqual({
62
62
  transform: [{ scaleX: -1 }],
63
63
  });
64
64
  });
@@ -1,7 +1,6 @@
1
1
  import { DefaultCell } from "./DefaultCell";
2
2
  import { GridCell } from "./GridCell";
3
3
  import { HeroCell } from "./HeroCell";
4
- // import { ScreenSelectorLabel } from "./ScreenSelectorLabel";
5
4
 
6
5
  /**
7
6
  * Return a view tree ready to be injected with styles etc. Mapping is done
@@ -15,8 +14,6 @@ export function viewTreeResolver({ component_type }) {
15
14
  switch (component_type) {
16
15
  case "hero":
17
16
  return HeroCell;
18
- // case "screen_picker":
19
- // return ScreenSelectorLabel;
20
17
  case "grid":
21
18
  return GridCell;
22
19
  case "horizontal_list":
@@ -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
  const createScreenComponentsStore = () =>
85
92
  create(subscribeWithSelector<Record<string, unknown>>((_) => ({})));
@@ -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,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
  };
@@ -1,6 +1,5 @@
1
1
  import React from "react";
2
2
  import * as useFeedLoaderModule from "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedLoader";
3
- import * as useFeedRefreshModule from "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedRefresh";
4
3
  import { favoritesListener } from "@applicaster/zapp-react-native-bridge/Favorites";
5
4
  import { UrlFeedResolver } from "../resolvers/UrlFeedResolver";
6
5
  import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
@@ -14,10 +13,6 @@ jest
14
13
 
15
14
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedLoader");
16
15
 
17
- jest.mock(
18
- "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedRefresh"
19
- );
20
-
21
16
  jest.mock("@applicaster/zapp-pipes-v2-client");
22
17
 
23
18
  jest.mock("@applicaster/zapp-react-native-bridge/Favorites", () => ({
@@ -62,6 +57,9 @@ describe("UrlFeedResolver", () => {
62
57
  component: { ...componentRequiredKeys } as any,
63
58
  children: mockChildren,
64
59
  riverId: "test-river",
60
+ screenContext: {
61
+ id: "screenId",
62
+ },
65
63
  };
66
64
 
67
65
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -82,6 +80,9 @@ describe("UrlFeedResolver", () => {
82
80
  } as any,
83
81
  children: mockChildren,
84
82
  riverId: "test-river",
83
+ screenContext: {
84
+ id: "screenId",
85
+ },
85
86
  };
86
87
 
87
88
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -103,6 +104,9 @@ describe("UrlFeedResolver", () => {
103
104
  } as any,
104
105
  children: mockChildren,
105
106
  riverId: "test-river",
107
+ screenContext: {
108
+ id: "screenId",
109
+ },
106
110
  };
107
111
 
108
112
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -132,6 +136,9 @@ describe("UrlFeedResolver", () => {
132
136
  } as any,
133
137
  children: mockChildren,
134
138
  riverId: "test-river",
139
+ screenContext: {
140
+ id: "screenId",
141
+ },
135
142
  };
136
143
 
137
144
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -155,6 +162,9 @@ describe("UrlFeedResolver", () => {
155
162
  children: mockChildren,
156
163
  riverId: "test-river",
157
164
  plugins: [],
165
+ screenContext: {
166
+ id: "screenId",
167
+ },
158
168
  };
159
169
 
160
170
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -173,6 +183,9 @@ describe("UrlFeedResolver", () => {
173
183
  component: { ...componentRequiredKeys } as any,
174
184
  children: mockChildren,
175
185
  riverId: "test-river",
186
+ screenContext: {
187
+ id: "screenId",
188
+ },
176
189
  };
177
190
 
178
191
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -197,6 +210,9 @@ describe("UrlFeedResolver", () => {
197
210
  },
198
211
  },
199
212
  ] as any,
213
+ screenContext: {
214
+ id: "screenId",
215
+ },
200
216
  };
201
217
 
202
218
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -215,6 +231,9 @@ describe("UrlFeedResolver", () => {
215
231
  } as any,
216
232
  children: mockChildren,
217
233
  riverId: "test-river",
234
+ screenContext: {
235
+ id: "screenId",
236
+ },
218
237
  };
219
238
 
220
239
  (useFeedLoaderModule.useFeedLoader as jest.Mock).mockReturnValue({
@@ -250,6 +269,9 @@ describe("UrlFeedResolver", () => {
250
269
  children: mockChildren,
251
270
  riverId: "test-river",
252
271
  isLast: true,
272
+ screenContext: {
273
+ id: "screenId",
274
+ },
253
275
  };
254
276
 
255
277
  renderWithProviders(<UrlFeedResolver {...props1} />);
@@ -272,6 +294,9 @@ describe("UrlFeedResolver", () => {
272
294
  children: mockChildren,
273
295
  riverId: "test-river",
274
296
  isLast: false,
297
+ screenContext: {
298
+ id: "screenId",
299
+ },
275
300
  };
276
301
 
277
302
  renderWithProviders(<UrlFeedResolver {...props2} />);
@@ -294,6 +319,9 @@ describe("UrlFeedResolver", () => {
294
319
  children: mockChildren,
295
320
  riverId: "test-river",
296
321
  isLast: false,
322
+ screenContext: {
323
+ id: "screenId",
324
+ },
297
325
  };
298
326
 
299
327
  renderWithProviders(<UrlFeedResolver {...props3} />);
@@ -311,6 +339,9 @@ describe("UrlFeedResolver", () => {
311
339
  component: { ...componentRequiredKeys } as any,
312
340
  children: mockChildren,
313
341
  riverId: "test-river",
342
+ screenContext: {
343
+ id: "screenId",
344
+ },
314
345
  };
315
346
 
316
347
  renderWithProviders(<UrlFeedResolver {...props} />);
@@ -327,22 +358,6 @@ describe("UrlFeedResolver", () => {
327
358
  });
328
359
  });
329
360
 
330
- it("should apply feed refresh hook", () => {
331
- const props = {
332
- feedUrl: "https://example.com/feed",
333
- component: { ...componentRequiredKeys } as any,
334
- children: mockChildren,
335
- riverId: "test-river",
336
- };
337
-
338
- renderWithProviders(<UrlFeedResolver {...props} />);
339
-
340
- expect(useFeedRefreshModule.useFeedRefresh).toHaveBeenCalledWith({
341
- reloadData: mockReloadData,
342
- component: props.component,
343
- });
344
- });
345
-
346
361
  it("should clean up listeners on unmount", () => {
347
362
  const props = {
348
363
  component: {
@@ -354,6 +369,9 @@ describe("UrlFeedResolver", () => {
354
369
  } as any,
355
370
  children: mockChildren,
356
371
  riverId: "test-river",
372
+ screenContext: {
373
+ id: "screenId",
374
+ },
357
375
  };
358
376
 
359
377
  const { unmount } = renderWithProviders(<UrlFeedResolver {...props} />);