@applicaster/zapp-react-native-ui-components 14.0.0-rc.9 → 15.0.0-alpha.1351496011

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 (172) hide show
  1. package/Components/AnimatedInOut/index.tsx +5 -3
  2. package/Components/AudioPlayer/index.tsx +15 -0
  3. package/Components/AudioPlayer/mobile/Layout.tsx +66 -0
  4. package/Components/AudioPlayer/{__tests__/__snapshots__/audioPlayer.test.js.snap → mobile/__tests__/__snapshots__/audioPlayerMobileLayout.test.js.snap} +2 -2
  5. package/Components/AudioPlayer/mobile/__tests__/audioPlayerMobileLayout.test.js +18 -0
  6. package/Components/AudioPlayer/mobile/index.tsx +18 -0
  7. package/Components/AudioPlayer/{Artwork.tsx → tv/Artwork.tsx} +3 -2
  8. package/Components/AudioPlayer/{Channel.tsx → tv/Channel.tsx} +7 -7
  9. package/Components/AudioPlayer/tv/Layout.tsx +168 -0
  10. package/Components/AudioPlayer/{Runtime.tsx → tv/Runtime.tsx} +7 -1
  11. package/Components/AudioPlayer/{Summary.tsx → tv/Summary.tsx} +6 -2
  12. package/Components/AudioPlayer/{Title.tsx → tv/Title.tsx} +6 -2
  13. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/Runtime.test.js.snap +2 -2
  14. package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +164 -0
  15. package/Components/AudioPlayer/tv/__tests__/__snapshots__/channel.test.js.snap +19 -0
  16. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/summary.test.js.snap +1 -2
  17. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/title.test.js.snap +1 -2
  18. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/audioPlayer.test.js +7 -3
  19. package/Components/AudioPlayer/{helpers.tsx → tv/helpers.tsx} +11 -5
  20. package/Components/AudioPlayer/{AudioPlayer.tsx → tv/index.tsx} +17 -58
  21. package/Components/AudioPlayer/types.ts +40 -0
  22. package/Components/BaseFocusable/index.tsx +23 -12
  23. package/Components/Cell/Cell.tsx +91 -64
  24. package/Components/Cell/CellWithFocusable.tsx +3 -0
  25. package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
  26. package/Components/Cell/index.js +7 -3
  27. package/Components/ComponentResolver/index.ts +1 -1
  28. package/Components/FeedLoader/FeedLoader.tsx +7 -16
  29. package/Components/FeedLoader/FeedLoaderHOC.tsx +21 -0
  30. package/Components/FeedLoader/index.js +2 -8
  31. package/Components/Focusable/Focusable.tsx +12 -3
  32. package/Components/Focusable/FocusableTvOS.tsx +5 -5
  33. package/Components/Focusable/FocusableiOS.tsx +2 -2
  34. package/Components/Focusable/Touchable.tsx +5 -3
  35. package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
  36. package/Components/Focusable/index.android.tsx +19 -11
  37. package/Components/Focusable/index.tsx +1 -1
  38. package/Components/FocusableGroup/FocusableTvOS.tsx +1 -1
  39. package/Components/FocusableList/FocusableItem.tsx +4 -3
  40. package/Components/FocusableList/FocusableListItemWrapper.tsx +2 -1
  41. package/Components/FocusableList/hooks/useCellState.android.ts +13 -3
  42. package/Components/FocusableList/index.tsx +20 -9
  43. package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
  44. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
  45. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +22 -21
  46. package/Components/HandlePlayable/HandlePlayable.tsx +25 -9
  47. package/Components/HookRenderer/HookRenderer.tsx +5 -1
  48. package/Components/Layout/TV/LayoutBackground.tsx +1 -1
  49. package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
  50. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +6 -2
  51. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
  52. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -39
  53. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
  54. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
  55. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +65 -17
  56. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/Image.test.tsx +21 -3
  57. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +6 -3
  58. package/Components/MasterCell/DefaultComponents/Text/index.tsx +26 -6
  59. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +10 -10
  60. package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +18 -18
  61. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/index.test.tsx +10 -10
  62. package/Components/MasterCell/elementMapper.tsx +1 -2
  63. package/Components/MasterCell/index.tsx +1 -1
  64. package/Components/MasterCell/utils/behaviorProvider.ts +82 -14
  65. package/Components/MasterCell/utils/index.ts +11 -5
  66. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
  67. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
  68. package/Components/OfflineHandler/__tests__/index.test.tsx +26 -35
  69. package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
  70. package/Components/PlayerContainer/PlayerContainer.tsx +46 -33
  71. package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
  72. package/Components/PlayerContainer/index.ts +1 -1
  73. package/Components/PlayerImageBackground/index.tsx +1 -1
  74. package/Components/River/ComponentsMap/ComponentsMap.tsx +49 -43
  75. package/Components/River/ComponentsMap/ContextProviders/ComponentsMapHeightContext.ts +8 -0
  76. package/Components/River/ComponentsMap/ContextProviders/ComponentsMapRefContext.ts +8 -0
  77. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +378 -0
  78. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
  79. package/Components/River/RefreshControl.tsx +11 -17
  80. package/Components/River/RiverItem.tsx +3 -0
  81. package/Components/River/TV/River.tsx +2 -17
  82. package/Components/River/TV/index.tsx +3 -1
  83. package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
  84. package/Components/River/TV/withRiverDataLoader.tsx +17 -0
  85. package/Components/River/TV/withTVEventHandler.tsx +1 -1
  86. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  87. package/Components/River/__tests__/river.test.js +12 -26
  88. package/Components/River/index.tsx +1 -1
  89. package/Components/Screen/TV/hooks/useInitialFocus.ts +16 -4
  90. package/Components/Screen/__tests__/Screen.test.tsx +28 -29
  91. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
  92. package/Components/Screen/__tests__/navigationHandler.test.ts +133 -22
  93. package/Components/Screen/index.tsx +22 -5
  94. package/Components/Screen/navigationHandler.ts +20 -2
  95. package/Components/ScreenResolver/index.tsx +22 -1
  96. package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
  97. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
  98. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
  99. package/Components/ScreenRevealManager/index.ts +1 -0
  100. package/Components/ScreenRevealManager/utils/index.ts +25 -0
  101. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +91 -0
  102. package/Components/Tabs/TV/Tabs.android.tsx +1 -3
  103. package/Components/Tabs/Tabs.tsx +2 -3
  104. package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +13 -0
  105. package/Components/TextInputTv/index.tsx +11 -0
  106. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +34 -0
  107. package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
  108. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
  109. package/Components/VideoLive/animationUtils.ts +3 -3
  110. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +6 -10
  111. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.web.tsx +294 -0
  112. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.web.tsx +93 -0
  113. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +73 -29
  114. package/Components/VideoModal/PlayerDetails.tsx +29 -7
  115. package/Components/VideoModal/PlayerWrapper.tsx +26 -142
  116. package/Components/VideoModal/VideoModal.tsx +3 -17
  117. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
  118. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
  119. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -240
  120. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +9 -1
  121. package/Components/VideoModal/hooks/index.ts +0 -2
  122. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +40 -15
  123. package/Components/VideoModal/hooks/useModalSize.ts +18 -2
  124. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +2 -2
  125. package/Components/VideoModal/hooks/utils/index.ts +4 -0
  126. package/Components/VideoModal/utils.ts +6 -0
  127. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
  128. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
  129. package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
  130. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -6
  131. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
  132. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
  133. package/Contexts/CellFocusedStateContext/index.tsx +27 -0
  134. package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
  135. package/Contexts/ScreenContext/index.tsx +46 -6
  136. package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
  137. package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
  138. package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +221 -209
  139. package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +14 -16
  140. package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -20
  141. package/Decorators/RiverFeedLoader/index.tsx +22 -4
  142. package/Decorators/RiverFeedLoader/utils/getDatasourceUrl.ts +6 -10
  143. package/Decorators/RiverFeedLoader/utils/index.ts +0 -18
  144. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
  145. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
  146. package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
  147. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
  148. package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
  149. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
  150. package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
  151. package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
  152. package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
  153. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
  154. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +266 -0
  155. package/Decorators/ZappPipesDataConnector/types.ts +29 -0
  156. package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
  157. package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +157 -0
  158. package/events/index.ts +3 -0
  159. package/package.json +5 -10
  160. package/Components/AudioPlayer/AudioPlayerLayout.tsx +0 -202
  161. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +0 -66
  162. package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +0 -28
  163. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +0 -26
  164. package/Components/AudioPlayer/index.ts +0 -1
  165. package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
  166. package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
  167. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/Runtime.test.js +0 -0
  168. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/artWork.test.js.snap +0 -0
  169. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/artWork.test.js +0 -0
  170. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/channel.test.js +0 -0
  171. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/summary.test.js +0 -0
  172. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/title.test.js +0 -0
@@ -1,25 +1,12 @@
1
1
  /// <reference types="@applicaster/applicaster-types" />
2
2
  /// <reference types="@applicaster/zapp-react-native-ui-components" />
3
- import React, { useEffect, useMemo } from "react";
4
-
5
- import * as R from "ramda";
6
- import { Platform } from "react-native";
7
- import Url from "url";
8
- import { favoritesListener } from "@applicaster/zapp-react-native-bridge/Favorites";
9
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
+ import React from "react";
10
4
  import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
11
- import {
12
- getInflatedDataSourceUrl,
13
- getSearchContext,
14
- useFeedLoader,
15
- useFeedRefresh,
16
- } from "@applicaster/zapp-react-native-utils/reactHooks";
17
-
5
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
18
6
  import { ZappPipesSearchContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
19
7
  import { useScreenContext } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
20
-
21
- import { isVerticalListOrGrid } from "./utils";
22
- import { subscribeForUrlContextKeyChanges } from "@applicaster/zapp-pipes-v2-client";
8
+ import { ResolverSelector } from "./ResolverSelector";
9
+ import { ComponentDataSourceContext } from "./types";
23
10
 
24
11
  type Props = {
25
12
  component: ZappUIComponent;
@@ -27,186 +14,16 @@ type Props = {
27
14
  riverId: string;
28
15
  getStaticComponentFeed?: GeneralContentScreenProps["getStaticComponentFeed"];
29
16
  componentIndex?: number;
30
-
31
17
  isScreenWrappedInContainer?: boolean;
32
18
  isLast?: boolean;
33
19
  };
34
20
 
35
- const FAVORITES_TYPE = "FAVOURITES";
36
-
37
- function getDataSourceUrl({
38
- component,
39
- feedUrl,
40
- screenData,
41
- entryContext,
42
- searchContext,
43
- screenContext,
44
- }): { dataSourceUrl: string | null; type: string | null } {
45
- if (feedUrl) {
46
- return { dataSourceUrl: feedUrl, type: null };
47
- }
48
-
49
- if (component.data) {
50
- const {
51
- data: { source, type, mapping },
52
- } = component;
53
-
54
- if (type === FAVORITES_TYPE) {
55
- return { dataSourceUrl: source || FAVORITES_TYPE, type };
56
- }
57
-
58
- if (source) {
59
- if (type === "APPLICASTER_COLLECTION" && !R.includes("://", source)) {
60
- return {
61
- dataSourceUrl: `applicaster://fetchData?type=${type}&collectionId=${source}`,
62
- type,
63
- };
64
- }
65
-
66
- if (type === "APPLICASTER_CATEGORY" && !R.includes("://", source)) {
67
- return {
68
- dataSourceUrl: `applicaster://fetchData?type=${type}&categoryId=${source}&platform=${Platform.OS}`,
69
- type,
70
- };
71
- }
72
-
73
- if (mapping) {
74
- const contexts = {
75
- entry: entryContext,
76
- screen: screenContext || screenData,
77
- search: getSearchContext(searchContext, mapping),
78
- };
79
-
80
- const dataSourceUrl = getInflatedDataSourceUrl({
81
- source,
82
- mapping,
83
- contexts,
84
- });
85
-
86
- if (!dataSourceUrl) {
87
- return { dataSourceUrl: null, type: null };
88
- }
89
-
90
- return { dataSourceUrl, type };
91
- }
92
-
93
- return { dataSourceUrl: source, type };
94
- }
95
- }
96
-
97
- return { dataSourceUrl: null, type: null };
98
- }
99
-
100
- function applyItemLimit(zappPipesData, component) {
101
- if (!zappPipesData || !zappPipesData.data) {
102
- return zappPipesData;
103
- }
104
-
105
- const { data } = zappPipesData;
106
-
107
- const {
108
- rules: { item_limit },
109
- } = component;
110
-
111
- if (item_limit && data.entry && data.entry.length) {
112
- return {
113
- ...zappPipesData,
114
- data: {
115
- ...data,
116
- entry: R.slice(
117
- 0,
118
- Math.min(Number(item_limit), R.length(data.entry)),
119
- data.entry
120
- ),
121
- },
122
- };
123
- }
124
-
125
- return zappPipesData;
126
- }
127
-
128
- function getListenerFromPlugin(
129
- dataSourceUrl: string,
130
- plugins: QuickBrickPlugin[]
131
- ): AddDataSourceListener | void {
132
- const url = Url.parse(dataSourceUrl, false);
133
-
134
- const addListener = R.compose(
135
- R.path(["module", "addDataSourceListener"]),
136
- R.find(R.propEq("identifier", url.host))
137
- )(plugins);
138
-
139
- return addListener;
140
- }
141
-
142
- const getMethodAndParams = (component) => {
143
- const method: "get" | "post" = R.pathOr("get", ["data", "method"], component);
144
-
145
- const bodyParams: Record<string, unknown> = R.pathOr(
146
- {},
147
- ["data", "bodyParams"],
148
- component
149
- );
150
-
151
- return {
152
- method,
153
- bodyParams,
154
- };
155
- };
156
-
157
- const generateStaticUrl = (component: ZappUIComponent) => {
158
- const { id, position } = component || {};
159
-
160
- return `static://component?id=${id}&position=${position}`;
161
- };
162
-
163
- const reducer = (state, action) => {
164
- switch (action.type) {
165
- case "SET_DATA":
166
- return { ...state, data: action.payload, loading: false };
167
- case "SET_ERROR":
168
- return { ...state, error: action.payload, loading: false };
169
- default:
170
- return state;
171
- }
172
- };
173
-
174
- const useGetStaticFeed = (getter, component, index) => {
175
- const url = generateStaticUrl(component);
176
-
177
- // refactor above 3 states to use reducer
178
-
179
- const [{ loading, data, error }, dispatch] = React.useReducer(reducer, {
180
- loading: true,
181
- data: null,
182
- error: null,
183
- });
184
-
185
- React.useEffect(() => {
186
- const getData = async () => {
187
- try {
188
- const res = await getter({ index, component });
189
- dispatch({ type: "SET_DATA", payload: res });
190
- } catch (err) {
191
- dispatch({ type: "SET_ERROR", payload: err });
192
- }
193
- };
194
-
195
- if (getter) {
196
- getData();
197
- }
198
- }, [getter, component, index]);
199
-
200
- return { url, loading, data, error };
201
- };
202
-
203
21
  export function zappPipesDataConnector(
204
22
  Component: React.FC<any> | React.ComponentClass<any>
205
23
  ) {
206
24
  return function WrappedWithZappPipesData(props: Props) {
207
25
  const { screenData } = useRoute();
208
26
  const { plugins } = usePickFromState(["plugins"]);
209
-
210
27
  const screenContextData = useScreenContext();
211
28
 
212
29
  const {
@@ -219,12 +36,8 @@ export function zappPipesDataConnector(
219
36
  isLast = false,
220
37
  } = props;
221
38
 
222
- /**
223
- * TODO: HACK for the tabs screen which needs to use 2 types of context.
224
- * ui_components rendered above tabs selector need to use entryContext
225
- * Screens rendered inside tabs selector need to use nested context.
226
- * This hack works because ui_components are rendered using ComponentsMap which doesn't have riverId prop
227
- **/
39
+ // Handle context determination
40
+ // HACK for the tabs screen which needs to use 2 types of context.
228
41
  const shouldUseNestedContext = isScreenWrappedInContainer && riverId;
229
42
 
230
43
  const entryContext =
@@ -240,108 +53,28 @@ export function zappPipesDataConnector(
240
53
 
241
54
  const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
242
55
 
243
- const { dataSourceUrl, type } = useMemo(
244
- () =>
245
- getDataSourceUrl({
246
- component,
247
- feedUrl,
248
- screenData,
249
- entryContext,
250
- searchContext,
251
- screenContext,
252
- }),
253
- [
254
- component.id,
255
- feedUrl,
256
- entryContext,
257
- searchContext,
258
- screenContext,
259
- screenData.id,
260
- ]
261
- );
262
-
263
- const shouldClearCache = useMemo(
264
- () => Boolean(component?.rules?.clear_cache_on_reload),
265
- [component?.id]
266
- );
267
-
268
- const pipesOptions = useMemo(
269
- () => ({
270
- clearCache: type === FAVORITES_TYPE,
271
- loadLocalFavorites: type === FAVORITES_TYPE,
272
- silentRefresh: !shouldClearCache,
273
- ...getMethodAndParams(component),
274
- }),
275
- [type, shouldClearCache, component]
276
- );
277
-
278
- const { reloadData, loadNext, error, loading, url, data } = useFeedLoader({
279
- feedUrl: dataSourceUrl ?? "",
280
- pipesOptions,
281
- });
282
-
283
- const staticFeed = useGetStaticFeed(
284
- getStaticComponentFeed,
56
+ // Prepare context for resolvers
57
+ const resolverProps: ComponentDataSourceContext = {
285
58
  component,
286
- componentIndex
287
- );
288
-
289
- useEffect(() => {
290
- if (dataSourceUrl?.includes("pipesv2://") && reloadData) {
291
- const addListener = getListenerFromPlugin(dataSourceUrl, plugins);
292
-
293
- if (addListener) {
294
- return addListener(reloadData);
295
- }
296
- } else {
297
- return subscribeForUrlContextKeyChanges(dataSourceUrl, {}, reloadData);
298
- }
299
- }, [dataSourceUrl, reloadData]);
300
-
301
- useEffect(() => {
302
- if (type === FAVORITES_TYPE && reloadData) {
303
- favoritesListener.on("FAVORITES_CHANGED", reloadData);
304
-
305
- return () => {
306
- favoritesListener.removeHandler("FAVORITES_CHANGED", reloadData);
307
- };
308
- }
309
- }, [type]);
310
-
311
- const getZappPipesData = React.useCallback(
312
- () =>
313
- getStaticComponentFeed && !url
314
- ? staticFeed
315
- : { error, loading, url, data },
316
- [staticFeed?.loading, staticFeed?.data, data?.next, loading, data]
317
- );
318
-
319
- const zappPipesDataProps = useMemo(() => {
320
- const loadNextData =
321
- !isLast && isVerticalListOrGrid(component) ? undefined : loadNext;
322
-
323
- return {
324
- zappPipesData: applyItemLimit(getZappPipesData(), component),
325
- reloadData,
326
- loadNextData,
327
- };
328
- }, [
329
- dataSourceUrl,
330
- data?.next,
331
- loading,
332
- reloadData,
333
- loadNext,
334
- getZappPipesData,
335
- data,
59
+ feedUrl,
60
+ getStaticComponentFeed,
61
+ componentIndex,
62
+ isScreenWrappedInContainer,
63
+ riverId,
336
64
  isLast,
337
- component,
338
- ]);
339
-
340
- useFeedRefresh({
341
- reloadData,
342
- component,
343
- });
65
+ entryContext,
66
+ screenContext,
67
+ searchContext,
68
+ screenData,
69
+ plugins,
70
+ };
344
71
 
345
- return <Component {...props} {...zappPipesDataProps} />;
72
+ return (
73
+ <ResolverSelector {...resolverProps}>
74
+ {(zappPipesDataProps) => (
75
+ <Component {...props} {...zappPipesDataProps} />
76
+ )}
77
+ </ResolverSelector>
78
+ );
346
79
  };
347
80
  }
@@ -0,0 +1,25 @@
1
+ // NullFeedResolver.tsx
2
+ import React, { useMemo } from "react";
3
+ import { ZappPipesDataProps } from "../types";
4
+
5
+ type NullFeedResolverProps = {
6
+ children: (dataProps: ZappPipesDataProps) => React.ReactNode;
7
+ };
8
+
9
+ export function NullFeedResolver({ children }: NullFeedResolverProps) {
10
+ const zappPipesDataProps = useMemo(
11
+ () => ({
12
+ zappPipesData: {
13
+ url: "",
14
+ loading: false,
15
+ data: null,
16
+ error: null,
17
+ },
18
+ reloadData: () => null,
19
+ loadNextData: undefined,
20
+ }),
21
+ []
22
+ );
23
+
24
+ return <>{children(zappPipesDataProps)}</>;
25
+ }
@@ -0,0 +1,87 @@
1
+ import React, { useEffect, useMemo, useReducer } from "react";
2
+ import { ComponentDataSourceContext, ZappPipesDataProps } from "../types";
3
+
4
+ const generateStaticUrl = (component: ZappUIComponent) => {
5
+ const { id, position } = component || {};
6
+
7
+ return `static://component?id=${id}&position=${position}`;
8
+ };
9
+
10
+ const reducer = (state, action) => {
11
+ switch (action.type) {
12
+ case "SET_DATA":
13
+ return { ...state, data: action.payload, loading: false };
14
+ case "SET_ERROR":
15
+ return { ...state, error: action.payload, loading: false };
16
+ default:
17
+ return state;
18
+ }
19
+ };
20
+
21
+ type StaticFeedResolverProps = ComponentDataSourceContext & {
22
+ children: (dataProps: ZappPipesDataProps) => React.ReactNode;
23
+ };
24
+
25
+ export function StaticFeedResolver({
26
+ children,
27
+ getStaticComponentFeed,
28
+ component,
29
+ componentIndex,
30
+ }: StaticFeedResolverProps) {
31
+ const url = generateStaticUrl(component);
32
+
33
+ const [{ loading, data, error }, dispatch] = useReducer(reducer, {
34
+ loading: true,
35
+ data: null,
36
+ error: null,
37
+ });
38
+
39
+ useEffect(() => {
40
+ const getData = async () => {
41
+ try {
42
+ const res = await getStaticComponentFeed({
43
+ index: componentIndex,
44
+ component,
45
+ });
46
+
47
+ dispatch({ type: "SET_DATA", payload: res });
48
+ } catch (err) {
49
+ dispatch({ type: "SET_ERROR", payload: err });
50
+ }
51
+ };
52
+
53
+ if (getStaticComponentFeed) {
54
+ getData();
55
+ }
56
+ }, [getStaticComponentFeed, component, componentIndex]);
57
+
58
+ const reloadData = async () => {
59
+ if (!getStaticComponentFeed) return Promise.resolve();
60
+
61
+ try {
62
+ const res = await getStaticComponentFeed({
63
+ index: componentIndex,
64
+ component,
65
+ });
66
+
67
+ dispatch({ type: "SET_DATA", payload: res });
68
+
69
+ return res;
70
+ } catch (err) {
71
+ dispatch({ type: "SET_ERROR", payload: err });
72
+
73
+ return Promise.reject(err);
74
+ }
75
+ };
76
+
77
+ const zappPipesDataProps = useMemo(
78
+ () => ({
79
+ zappPipesData: { url, loading, data, error },
80
+ reloadData,
81
+ loadNextData: undefined, // Static resolver doesn't support pagination
82
+ }),
83
+ [url, loading, data, error]
84
+ );
85
+
86
+ return <>{children(zappPipesDataProps)}</>;
87
+ }