@applicaster/zapp-react-native-ui-components 15.1.0-rc.8 → 16.0.0-alpha.1011304583

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 (178) hide show
  1. package/Components/BackgroundImage/BackgroundImage.android.tv.tsx +28 -0
  2. package/Components/BackgroundImage/BackgroundImage.ios.tv.tsx +24 -0
  3. package/Components/BackgroundImage/BackgroundImage.tsx +42 -0
  4. package/Components/BackgroundImage/index.ts +1 -0
  5. package/Components/BaseFocusable/index.ios.ts +12 -2
  6. package/Components/Cell/FocusableWrapper.tsx +3 -0
  7. package/Components/Cell/TvOSCellComponent.tsx +6 -3
  8. package/Components/CellRendererResolver/index.ts +2 -2
  9. package/Components/ComponentResolver/__tests__/componentResolver.test.js +1 -1
  10. package/Components/Focusable/Focusable.tsx +4 -2
  11. package/Components/Focusable/FocusableTvOS.tsx +18 -1
  12. package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +1 -0
  13. package/Components/FocusableGroup/FocusableTvOS.tsx +41 -8
  14. package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +39 -0
  15. package/Components/GeneralContentScreen/__tests__/GeneralContentScreenHookAdapter.test.tsx +64 -0
  16. package/Components/GeneralContentScreen/__tests__/HookContentFocusGroup.web.test.tsx +91 -0
  17. package/Components/GeneralContentScreen/hookAdapter/__tests__/networkService.test.ts +74 -0
  18. package/Components/GeneralContentScreen/hookAdapter/__tests__/runInBackground.test.ts +139 -0
  19. package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +124 -0
  20. package/Components/GeneralContentScreen/hookAdapter/logger.ts +6 -0
  21. package/Components/GeneralContentScreen/hookAdapter/networkService.ts +53 -0
  22. package/Components/GeneralContentScreen/hookAdapter/runInBackground.ts +48 -0
  23. package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +72 -0
  24. package/Components/GeneralContentScreen/hookFocus/index.tsx +13 -0
  25. package/Components/GeneralContentScreen/hookFocus/index.web.tsx +69 -0
  26. package/Components/GeneralContentScreen/index.ts +2 -0
  27. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
  28. package/Components/HandlePlayable/HandlePlayable.tsx +13 -8
  29. package/Components/Layout/FullWidthRow.tsx +38 -0
  30. package/Components/Layout/TV/NavBarContainer.tsx +1 -10
  31. package/Components/Layout/TV/ScreenContainer.tsx +2 -6
  32. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
  33. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
  34. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +0 -1
  35. package/Components/Layout/TV/index.tsx +5 -7
  36. package/Components/Layout/TV/index.web.tsx +5 -7
  37. package/Components/LinkHandler/LinkHandler.tsx +2 -2
  38. package/Components/MasterCell/CONFIG_BUILDER_TO_REACT_COMPONENT.md +144 -0
  39. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +16 -5
  40. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  41. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
  42. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  43. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  44. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +165 -0
  45. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +405 -0
  46. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/index.ts +1 -0
  47. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  48. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
  49. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  50. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  51. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  52. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -10
  53. package/Components/MasterCell/DefaultComponents/Button.tsx +0 -15
  54. package/Components/MasterCell/DefaultComponents/ButtonContainerView/components/HorizontalSeparator.tsx +8 -0
  55. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.android.tv.tsx +58 -0
  56. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.tsx +15 -0
  57. package/Components/MasterCell/DefaultComponents/{tv/ButtonContainerView/index.tsx → ButtonContainerView/index.tv.tsx} +3 -11
  58. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.web.ts +1 -0
  59. package/Components/MasterCell/DefaultComponents/ButtonContainerView/types.ts +40 -0
  60. package/Components/MasterCell/DefaultComponents/DataProvider/index.tsx +163 -0
  61. package/Components/MasterCell/DefaultComponents/FocusableView/index.android.tsx +2 -23
  62. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -22
  63. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +8 -2
  64. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -3
  65. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +9 -1
  66. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +15 -14
  67. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +1 -2
  68. package/Components/MasterCell/DefaultComponents/PressableView.tsx +34 -0
  69. package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +7 -6
  70. package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +11 -0
  71. package/Components/MasterCell/DefaultComponents/__tests__/DataProvider.test.tsx +141 -0
  72. package/Components/MasterCell/DefaultComponents/index.ts +9 -3
  73. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +135 -0
  74. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +33 -0
  75. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +22 -0
  76. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +125 -0
  77. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
  78. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  79. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +37 -0
  80. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +393 -0
  81. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +141 -0
  82. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +343 -0
  83. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  84. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +122 -0
  85. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
  86. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +238 -0
  87. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Asset.ts +4 -18
  88. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Button.ts +24 -73
  89. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TextLabelsContainer.ts +37 -18
  90. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TvActionButton.tsx +27 -0
  91. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +89 -0
  92. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/renderedTree.test.tsx +231 -0
  93. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +47 -48
  94. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +115 -29
  95. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +101 -144
  96. package/Components/MasterCell/MappingFunctions/index.js +3 -2
  97. package/Components/MasterCell/README.md +4 -0
  98. package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +24 -0
  99. package/Components/MasterCell/__tests__/configInflater.test.js +1 -0
  100. package/Components/MasterCell/__tests__/elementMapper.test.js +46 -0
  101. package/Components/MasterCell/dataAdapter.ts +19 -6
  102. package/Components/MasterCell/elementMapper.tsx +52 -7
  103. package/Components/MasterCell/index.tsx +30 -5
  104. package/Components/MasterCell/utils/__tests__/cloneChildrenWithIds.test.tsx +43 -0
  105. package/Components/MasterCell/utils/__tests__/resolveColor.test.js +169 -132
  106. package/Components/MasterCell/utils/__tests__/resolveColorForProp.test.js +92 -0
  107. package/Components/MasterCell/utils/__tests__/useFilterChildren.test.tsx +80 -0
  108. package/Components/MasterCell/utils/index.ts +170 -61
  109. package/Components/OfflineHandler/NotificationView/NotificationView.tsx +2 -2
  110. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +17 -18
  111. package/Components/OfflineHandler/__tests__/index.test.tsx +27 -18
  112. package/Components/PlayerContainer/PlayerContainer.tsx +22 -17
  113. package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +284 -0
  114. package/Components/River/ComponentsMap/ComponentsMap.tsx +8 -21
  115. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
  116. package/Components/River/RefreshControl.tsx +19 -88
  117. package/Components/River/River.tsx +9 -82
  118. package/Components/River/TV/River.tsx +31 -14
  119. package/Components/River/TV/index.tsx +8 -4
  120. package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +30 -0
  121. package/Components/River/TV/utils/index.ts +4 -0
  122. package/Components/River/TV/withFocusableGroupForContent.tsx +71 -0
  123. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -15
  124. package/Components/River/__tests__/componentsMap.test.js +38 -0
  125. package/Components/River/hooks/__tests__/usePullToRefresh.test.ts +132 -0
  126. package/Components/River/hooks/index.ts +1 -0
  127. package/Components/River/hooks/usePullToRefresh.ts +51 -0
  128. package/Components/Screen/TV/index.web.tsx +4 -2
  129. package/Components/Screen/__tests__/Screen.test.tsx +65 -42
  130. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +68 -44
  131. package/Components/Screen/hooks.ts +2 -3
  132. package/Components/Screen/index.tsx +10 -7
  133. package/Components/Screen/orientationHandler.ts +3 -3
  134. package/Components/ScreenResolver/index.tsx +9 -5
  135. package/Components/ScreenRevealManager/Overlay.tsx +34 -0
  136. package/Components/ScreenRevealManager/ScreenRevealManager.ts +40 -8
  137. package/Components/ScreenRevealManager/__tests__/Overlay.test.tsx +88 -0
  138. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +86 -69
  139. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +9 -20
  140. package/Components/Tabs/TabContent.tsx +7 -4
  141. package/Components/TopCutoffOverlay/__tests__/TopCutoffOverlay.test.tsx +201 -0
  142. package/Components/TopCutoffOverlay/hooks/__tests__/useMarginTop.test.ts +130 -0
  143. package/Components/TopCutoffOverlay/hooks/index.ts +1 -0
  144. package/Components/TopCutoffOverlay/hooks/useMarginTop.ts +59 -0
  145. package/Components/TopCutoffOverlay/index.tsx +55 -0
  146. package/Components/Transitioner/index.js +3 -3
  147. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +5 -5
  148. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +15 -7
  149. package/Components/VideoModal/utils.ts +18 -10
  150. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
  151. package/Components/Viewport/ViewportAware/index.tsx +16 -7
  152. package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
  153. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +9 -4
  154. package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
  155. package/Contexts/CachedDimensionsContext/__tests__/index.test.ts +154 -0
  156. package/Contexts/CachedDimensionsContext/index.ts +17 -2
  157. package/Contexts/ScreenContext/index.tsx +25 -18
  158. package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
  159. package/Decorators/Analytics/index.tsx +6 -5
  160. package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +1 -0
  161. package/Decorators/ConfigurationWrapper/const.ts +1 -0
  162. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
  163. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
  164. package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
  165. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
  166. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
  167. package/Helpers/ComponentCellSelectionHelper/index.js +0 -6
  168. package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +80 -0
  169. package/Helpers/DataSourceHelper/index.ts +19 -0
  170. package/Helpers/index.js +7 -40
  171. package/package.json +5 -5
  172. package/Components/Layout/TV/LayoutBackground.tsx +0 -28
  173. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +0 -135
  174. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/types.ts +0 -25
  175. package/Components/River/TV/withTVEventHandler.tsx +0 -36
  176. package/Components/Screen/utils.ts +0 -16
  177. package/Helpers/Analytics/index.js +0 -95
  178. package/Helpers/DataSourceHelper/index.js +0 -19
@@ -1,18 +1,15 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { render } from "@testing-library/react-native";
3
+ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
4
4
 
5
5
  const Mocked_RouteManager = jest.fn((props) => (
6
6
  <View testID="routeManager" {...props} />
7
7
  ));
8
8
 
9
- const mock_navBarVisibleFlag = true;
10
-
11
- const mockIsNavBarVisible = jest.fn(() => mock_navBarVisibleFlag);
12
-
13
9
  const mockIsOrientationCompatible = jest.fn(() => true);
14
10
 
15
11
  jest.mock("react-native-safe-area-context", () => ({
12
+ ...jest.requireActual("react-native-safe-area-context"),
16
13
  useSafeAreaInsets: () => ({ top: 44 }),
17
14
  useSafeAreaFrame: () => ({ x: 0, y: 0, width: 375, height: 812 }),
18
15
  }));
@@ -36,12 +33,14 @@ jest.mock(
36
33
  );
37
34
 
38
35
  jest.mock("@applicaster/zapp-react-native-utils/analyticsUtils", () => ({
36
+ ...jest.requireActual("@applicaster/zapp-react-native-utils/analyticsUtils"),
39
37
  useAnalytics: jest.fn(() => ({
40
38
  sendScreenEvent: jest.fn(),
41
39
  })),
42
40
  }));
43
41
 
44
42
  jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
43
+ ...jest.requireActual("@applicaster/zapp-react-native-utils/theme"),
45
44
  useTheme: jest.fn(() => ({
46
45
  app_background_color: "blue",
47
46
  })),
@@ -78,21 +77,44 @@ jest.mock(
78
77
  })
79
78
  );
80
79
 
81
- jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
82
- isNavBarVisible: mockIsNavBarVisible,
83
- useIsScreenActive: jest.fn().mockReturnValue(true),
84
- useNavigation: jest.fn(() => ({
85
- canGoBack: () => false,
86
- currentRoute: "/river/testId",
87
- activeRiver: { id: "testId" },
88
- screenData: { id: "testId" },
89
- data: { screen: { id: "testId" } },
90
- })),
91
- useRoute: jest.fn(() => ({
92
- pathname: "/river/testId",
93
- screenData: { id: "testId" },
94
- })),
95
- }));
80
+ jest.mock(
81
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation",
82
+ () => ({
83
+ ...jest.requireActual(
84
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation"
85
+ ),
86
+ useNavigation: jest.fn(() => ({
87
+ canGoBack: () => false,
88
+ currentRoute: "/river/testId",
89
+ activeRiver: { id: "testId" },
90
+ screenData: { id: "testId" },
91
+ data: { screen: { id: "testId" } },
92
+ })),
93
+ })
94
+ );
95
+
96
+ jest.mock(
97
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
98
+ () => ({
99
+ ...jest.requireActual(
100
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive"
101
+ ),
102
+ useIsScreenActive: jest.fn().mockReturnValue(true),
103
+ })
104
+ );
105
+
106
+ jest.mock(
107
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute",
108
+ () => ({
109
+ ...jest.requireActual(
110
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute"
111
+ ),
112
+ useRoute: jest.fn(() => ({
113
+ pathname: "/river/testId",
114
+ screenData: { id: "testId" },
115
+ })),
116
+ })
117
+ );
96
118
 
97
119
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
98
120
  ...jest.requireActual("@applicaster/zapp-react-native-utils/reactHooks"),
@@ -113,26 +135,6 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
113
135
  useIsTablet: jest.fn(() => false),
114
136
  }));
115
137
 
116
- jest.mock("@applicaster/zapp-react-native-redux/hooks", () => {
117
- const View = jest.requireActual("react-native").View;
118
-
119
- return {
120
- ...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
121
- usePickFromState: () => ({
122
- plugins: [
123
- {
124
- name: "Offline Plugin",
125
- identifier: "offline-experience",
126
- type: "general",
127
- module: {
128
- OfflineFallbackScreen: ({ children }) => <View>{children}</View>, // eslint-disable-line
129
- },
130
- },
131
- ],
132
- }),
133
- };
134
- });
135
-
136
138
  const {
137
139
  allowedOrientationsForScreen,
138
140
  getOrientation,
@@ -152,6 +154,19 @@ const screenProps = {
152
154
 
153
155
  const { Screen } = require("..");
154
156
 
157
+ const store = {
158
+ plugins: [
159
+ {
160
+ name: "Offline Plugin",
161
+ identifier: "offline-experience",
162
+ type: "general",
163
+ module: {
164
+ OfflineFallbackScreen: ({ children }) => <View>{children}</View>, // eslint-disable-line
165
+ },
166
+ },
167
+ ],
168
+ };
169
+
155
170
  describe("<Screen Component />", () => {
156
171
  beforeEach(() => {
157
172
  allowedOrientationsForScreen.mockClear();
@@ -161,14 +176,22 @@ describe("<Screen Component />", () => {
161
176
 
162
177
  describe("when the navbar should show", () => {
163
178
  it("renders correctly", () => {
164
- const { toJSON } = render(<Screen {...screenProps} />);
179
+ const { toJSON } = renderWithProviders(
180
+ <Screen {...screenProps} />,
181
+ store
182
+ );
183
+
165
184
  expect(toJSON()).toMatchSnapshot();
166
185
  });
167
186
  });
168
187
 
169
188
  describe("when the navbar should be hidden", () => {
170
189
  it("renders correctly", () => {
171
- const { toJSON } = render(<Screen {...screenProps} />);
190
+ const { toJSON } = renderWithProviders(
191
+ <Screen {...screenProps} />,
192
+ store
193
+ );
194
+
172
195
  expect(toJSON()).toMatchSnapshot();
173
196
  });
174
197
  });
@@ -1,67 +1,91 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<Screen Component /> when the navbar should be hidden renders correctly 1`] = `
4
- <View
5
- importantForAccessibility="yes"
4
+ <RNCSafeAreaProvider
5
+ onInsetsChange={[Function]}
6
6
  style={
7
- {
8
- "backgroundColor": "blue",
9
- "flex": 1,
10
- "paddingTop": 0,
11
- }
7
+ [
8
+ {
9
+ "flex": 1,
10
+ },
11
+ undefined,
12
+ ]
12
13
  }
13
14
  >
14
15
  <View
15
- hasMenu={false}
16
- id="/river/testId"
17
- pathname="/river/testId"
18
- selected="testId"
19
- testID="navBar"
20
- title="Test Title"
21
- />
22
- <View>
16
+ importantForAccessibility="yes"
17
+ style={
18
+ {
19
+ "backgroundColor": "blue",
20
+ "flex": 1,
21
+ "paddingTop": 0,
22
+ }
23
+ }
24
+ >
23
25
  <View
26
+ hasMenu={false}
27
+ id="/river/testId"
24
28
  pathname="/river/testId"
25
- screenData={
26
- {
27
- "id": "testId",
28
- }
29
- }
30
- testID="routeManager"
29
+ selected="testId"
30
+ testID="navBar"
31
+ title="Test Title"
31
32
  />
33
+ <View>
34
+ <View
35
+ pathname="/river/testId"
36
+ screenData={
37
+ {
38
+ "id": "testId",
39
+ }
40
+ }
41
+ testID="routeManager"
42
+ />
43
+ </View>
32
44
  </View>
33
- </View>
45
+ </RNCSafeAreaProvider>
34
46
  `;
35
47
 
36
48
  exports[`<Screen Component /> when the navbar should show renders correctly 1`] = `
37
- <View
38
- importantForAccessibility="yes"
49
+ <RNCSafeAreaProvider
50
+ onInsetsChange={[Function]}
39
51
  style={
40
- {
41
- "backgroundColor": "blue",
42
- "flex": 1,
43
- "paddingTop": 0,
44
- }
52
+ [
53
+ {
54
+ "flex": 1,
55
+ },
56
+ undefined,
57
+ ]
45
58
  }
46
59
  >
47
60
  <View
48
- hasMenu={false}
49
- id="/river/testId"
50
- pathname="/river/testId"
51
- selected="testId"
52
- testID="navBar"
53
- title="Test Title"
54
- />
55
- <View>
61
+ importantForAccessibility="yes"
62
+ style={
63
+ {
64
+ "backgroundColor": "blue",
65
+ "flex": 1,
66
+ "paddingTop": 0,
67
+ }
68
+ }
69
+ >
56
70
  <View
71
+ hasMenu={false}
72
+ id="/river/testId"
57
73
  pathname="/river/testId"
58
- screenData={
59
- {
60
- "id": "testId",
61
- }
62
- }
63
- testID="routeManager"
74
+ selected="testId"
75
+ testID="navBar"
76
+ title="Test Title"
64
77
  />
78
+ <View>
79
+ <View
80
+ pathname="/river/testId"
81
+ screenData={
82
+ {
83
+ "id": "testId",
84
+ }
85
+ }
86
+ testID="routeManager"
87
+ />
88
+ </View>
65
89
  </View>
66
- </View>
90
+ </RNCSafeAreaProvider>
67
91
  `;
@@ -1,4 +1,4 @@
1
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
1
+ import { useAppData } from "@applicaster/zapp-react-native-redux/hooks";
2
2
  import {
3
3
  useGetScreenOrientation,
4
4
  isOrientationCompatible,
@@ -95,8 +95,7 @@ export const useWaitForValidOrientation = () => {
95
95
 
96
96
  const isTablet = useIsTablet();
97
97
 
98
- const { appData } = usePickFromState(["appData"]);
99
- const isTabletPortrait = appData?.isTabletPortrait;
98
+ const { isTabletPortrait } = useAppData();
100
99
 
101
100
  const layoutData = useMemo(
102
101
  () => ({ isTablet, isTabletPortrait, width: screenWidth, height }),
@@ -1,8 +1,7 @@
1
1
  /// <reference types="@applicaster/applicaster-types" />
2
2
  import React from "react";
3
3
  import { AccessibilityInfo, findNodeHandle, View } from "react-native";
4
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
-
4
+ import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
6
5
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
7
6
  import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
8
7
  import {
@@ -19,10 +18,13 @@ import {
19
18
  useScreenData,
20
19
  } from "@applicaster/zapp-react-native-utils/reactHooks";
21
20
  import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
21
+ import {
22
+ isValidColor,
23
+ isTransparentColor,
24
+ } from "@applicaster/zapp-react-native-utils/colorUtils";
22
25
 
23
26
  import { RouteManager } from "../RouteManager";
24
27
  import { useScreenConfiguration } from "../River/useScreenConfiguration";
25
- import { isValidColor } from "./utils";
26
28
  import { useWaitForValidOrientation } from "./hooks";
27
29
 
28
30
  const screenStyles = {
@@ -41,7 +43,7 @@ type Props = {
41
43
  export function Screen(_props: Props) {
42
44
  const theme = useTheme<BaseThemePropertiesMobile>();
43
45
  const navigation = useNavigation();
44
- const { plugins } = usePickFromState(["plugins"]);
46
+ const plugins = usePlugins();
45
47
 
46
48
  // Gets the data for the current screen configuration
47
49
  const currentScreenData = useCurrentScreenData();
@@ -83,9 +85,10 @@ export function Screen(_props: Props) {
83
85
  const style = React.useMemo(
84
86
  () => ({
85
87
  ...screenStyles,
86
- backgroundColor: isValidColor(backgroundColor)
87
- ? backgroundColor
88
- : theme.app_background_color,
88
+ backgroundColor:
89
+ isValidColor(backgroundColor) && !isTransparentColor(backgroundColor)
90
+ ? backgroundColor
91
+ : theme.app_background_color,
89
92
  }),
90
93
  [theme.app_background_color, backgroundColor]
91
94
  );
@@ -7,7 +7,7 @@ import {
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
13
  import { zappHookModalStore } from "../../Contexts/ZappHookModalContext";
@@ -63,8 +63,8 @@ export function useNewOrientationForScreenData({
63
63
  }: OrientationHookArgs) {
64
64
  const isTablet = useIsTablet();
65
65
 
66
- const { appData, plugins } = usePickFromState(["appData", "plugins"]);
67
- const isTabletPortrait = appData?.isTabletPortrait;
66
+ const plugins = usePlugins();
67
+ const { isTabletPortrait } = useAppData();
68
68
  const isLandscapeTablet = isTablet && !isTabletPortrait;
69
69
 
70
70
  const screenOrientation = useGetScreenOrientation(screenData);
@@ -1,10 +1,18 @@
1
1
  import * as React from "react";
2
2
 
3
3
  import { componentsLogger } from "../../Helpers/logger";
4
+
4
5
  import { useScreenAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
6
+
7
+ import { ScreenResultCallback } from "@applicaster/zapp-react-native-utils/zappFrameworkUtils/HookCallback/callbackNavigationAction";
5
8
  import { useScreenComponentResolver } from "./hooks/useScreenComponentResolver";
6
9
  import { withDefaultScreenContext } from "./withDefaultScreenContext";
7
10
 
11
+ export enum PresentationType {
12
+ Standalone = "Standalone",
13
+ Hook = "Hook",
14
+ }
15
+
8
16
  const logger = componentsLogger.addSubsystem("ScreenResolver");
9
17
 
10
18
  type Props = {
@@ -14,6 +22,7 @@ type Props = {
14
22
  feedId?: string;
15
23
  feedTitle?: string;
16
24
  focused?: boolean;
25
+ resultCallback?: ScreenResultCallback;
17
26
  parentFocus?: {
18
27
  nextFocusDown?: React.Ref<any>;
19
28
  nextFocusRight?: React.Ref<any>;
@@ -23,11 +32,6 @@ type Props = {
23
32
  groupId?: string;
24
33
  };
25
34
 
26
- export enum PresentationType {
27
- Standalone = "Standalone",
28
- Hook = "Hook",
29
- }
30
-
31
35
  export function ScreenResolverComponent(props: Props) {
32
36
  const { screenType } = props;
33
37
  const component = useScreenComponentResolver(screenType, props);
@@ -0,0 +1,34 @@
1
+ import * as React from "react";
2
+ import { Animated, StyleSheet } from "react-native";
3
+
4
+ import { BackgroundImage } from "@applicaster/zapp-react-native-ui-components/Components/BackgroundImage";
5
+
6
+ const styles = StyleSheet.create({
7
+ container: {
8
+ ...StyleSheet.absoluteFillObject,
9
+ position: "absolute",
10
+ },
11
+ });
12
+
13
+ export const Overlay = ({
14
+ opacity,
15
+ backgroundColor,
16
+ }: {
17
+ opacity: Animated.Value;
18
+ backgroundColor: string;
19
+ }) => {
20
+ return (
21
+ <Animated.View
22
+ style={[
23
+ styles.container,
24
+ {
25
+ opacity,
26
+ backgroundColor,
27
+ },
28
+ ]}
29
+ testID="animated-component"
30
+ >
31
+ <BackgroundImage />
32
+ </Animated.View>
33
+ );
34
+ };
@@ -1,6 +1,11 @@
1
1
  import { makeListOf } from "@applicaster/zapp-react-native-utils/arrayUtils";
2
2
  import { isFirstComponentGallery } from "@applicaster/zapp-react-native-utils/componentsUtils";
3
- import { once } from "ramda";
3
+ import { race, Subject, Subscription } from "rxjs";
4
+ import { first } from "rxjs/operators";
5
+
6
+ import { withTimeout$ } from "@applicaster/zapp-react-native-utils/idleUtils";
7
+
8
+ const MAX_TIMEOUT_TO_WAIT_COMPONENTS_TO_LOAD = 2000; // 2 seconds
4
9
 
5
10
  const INITIAL_NUMBER_TO_LOAD = 3;
6
11
 
@@ -34,7 +39,8 @@ const getNumberOfComponentsWaitToLoadBeforePresent = (
34
39
  export class ScreenRevealManager {
35
40
  public numberOfComponentsWaitToLoadBeforePresent: number;
36
41
  private renderingState: Array<ComponentLoadingState>;
37
- private callback: Callback;
42
+ private subject$ = new Subject<void>();
43
+ private subscription: Subscription;
38
44
 
39
45
  constructor(componentsToRender: ZappUIComponent[], callback: Callback) {
40
46
  this.numberOfComponentsWaitToLoadBeforePresent =
@@ -45,32 +51,58 @@ export class ScreenRevealManager {
45
51
  this.numberOfComponentsWaitToLoadBeforePresent
46
52
  );
47
53
 
48
- this.callback = once(callback);
54
+ this.subscription = race(
55
+ withTimeout$(MAX_TIMEOUT_TO_WAIT_COMPONENTS_TO_LOAD),
56
+ this.subject$
57
+ )
58
+ .pipe(first())
59
+ .subscribe(callback);
49
60
  }
50
61
 
51
62
  onLoadFinished = (index: number): void => {
63
+ const currentState = this.renderingState[index];
64
+
65
+ if (
66
+ COMPONENT_LOADING_STATE.LOADED_WITH_SUCCESS === currentState ||
67
+ COMPONENT_LOADING_STATE.LOADED_WITH_FAILURE === currentState
68
+ ) {
69
+ return;
70
+ }
71
+
52
72
  this.renderingState[index] = COMPONENT_LOADING_STATE.LOADED_WITH_SUCCESS;
53
73
 
54
74
  if (
55
75
  getNumberOfLoaded(this.renderingState) >=
56
76
  this.numberOfComponentsWaitToLoadBeforePresent
57
77
  ) {
58
- this.setIsReadyToShow();
78
+ this.subject$.next();
79
+ this.subject$.complete();
59
80
  }
60
81
  };
61
82
 
62
83
  onLoadFailed = (index: number): void => {
84
+ const currentState = this.renderingState[index];
85
+
86
+ if (
87
+ COMPONENT_LOADING_STATE.LOADED_WITH_SUCCESS === currentState ||
88
+ COMPONENT_LOADING_STATE.LOADED_WITH_FAILURE === currentState
89
+ ) {
90
+ return;
91
+ }
92
+
63
93
  this.renderingState[index] = COMPONENT_LOADING_STATE.LOADED_WITH_FAILURE;
64
94
 
65
95
  if (
66
96
  getNumberOfLoaded(this.renderingState) >=
67
97
  this.numberOfComponentsWaitToLoadBeforePresent
68
98
  ) {
69
- this.setIsReadyToShow();
99
+ this.subject$.next();
100
+ this.subject$.complete();
70
101
  }
71
102
  };
72
103
 
73
- setIsReadyToShow = (): void => {
74
- this.callback();
75
- };
104
+ dispose(): void {
105
+ this.subscription?.unsubscribe();
106
+ this.subject$.complete();
107
+ }
76
108
  }
@@ -0,0 +1,88 @@
1
+ import React from "react";
2
+ import { Animated } from "react-native";
3
+ import { render } from "@testing-library/react-native";
4
+
5
+ jest.mock(
6
+ "@applicaster/zapp-react-native-ui-components/Components/BackgroundImage",
7
+ () => {
8
+ const { Text } = require("react-native");
9
+
10
+ return {
11
+ BackgroundImage: () => (
12
+ <Text testID="background-image">BackgroundImage</Text>
13
+ ),
14
+ };
15
+ }
16
+ );
17
+
18
+ import { Overlay } from "../Overlay";
19
+
20
+ const flattenStyle = (style: unknown): Record<string, unknown> => {
21
+ if (!style) {
22
+ return {};
23
+ }
24
+
25
+ if (Array.isArray(style)) {
26
+ return style.reduce<Record<string, unknown>>(
27
+ (acc, item) => ({ ...acc, ...flattenStyle(item) }),
28
+ {}
29
+ );
30
+ }
31
+
32
+ if (typeof style === "object") {
33
+ return style as Record<string, unknown>;
34
+ }
35
+
36
+ return {};
37
+ };
38
+
39
+ describe("Overlay", () => {
40
+ it("renders the animated overlay container", () => {
41
+ const opacity = new Animated.Value(1);
42
+
43
+ const { getByTestId } = render(
44
+ <Overlay opacity={opacity} backgroundColor="#000000" />
45
+ );
46
+
47
+ expect(getByTestId("animated-component")).toBeTruthy();
48
+ });
49
+
50
+ it("applies opacity and backgroundColor to the overlay", () => {
51
+ const opacity = new Animated.Value(0.5);
52
+
53
+ const { getByTestId } = render(
54
+ <Overlay opacity={opacity} backgroundColor="#ff0000" />
55
+ );
56
+
57
+ const style = flattenStyle(getByTestId("animated-component").props.style);
58
+
59
+ expect(style.backgroundColor).toBe("#ff0000");
60
+ expect(style.opacity).toBe(0.5);
61
+ });
62
+
63
+ it("positions the overlay with absolute fill layout", () => {
64
+ const opacity = new Animated.Value(1);
65
+
66
+ const { getByTestId } = render(
67
+ <Overlay opacity={opacity} backgroundColor="#000000" />
68
+ );
69
+
70
+ const style = flattenStyle(getByTestId("animated-component").props.style);
71
+
72
+ expect(style.position).toBe("absolute");
73
+ expect(style.top).toBe(0);
74
+ expect(style.left).toBe(0);
75
+ expect(style.right).toBe(0);
76
+ expect(style.bottom).toBe(0);
77
+ });
78
+
79
+ it("renders BackgroundImage inside the overlay", () => {
80
+ const opacity = new Animated.Value(1);
81
+
82
+ const { getByTestId } = render(
83
+ <Overlay opacity={opacity} backgroundColor="#000000" />
84
+ );
85
+
86
+ expect(getByTestId("background-image")).toBeTruthy();
87
+ });
88
+ });