@applicaster/zapp-react-native-ui-components 14.0.0-alpha.2175196485 → 14.0.0-alpha.2292190333
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.
- package/Components/AudioPlayer/mobile/Layout.tsx +1 -1
- package/Components/AudioPlayer/tv/helpers.tsx +10 -3
- package/Components/BaseFocusable/index.tsx +23 -12
- package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
- package/Components/Cell/index.js +1 -1
- package/Components/ComponentResolver/index.ts +1 -1
- package/Components/FeedLoader/FeedLoader.tsx +6 -15
- package/Components/FeedLoader/FeedLoaderHOC.tsx +21 -0
- package/Components/FeedLoader/index.js +2 -8
- package/Components/Focusable/FocusableiOS.tsx +1 -1
- package/Components/Focusable/Touchable.tsx +6 -3
- package/Components/Focusable/index.android.tsx +11 -4
- package/Components/Focusable/index.tsx +1 -1
- package/Components/FocusableList/FocusableItem.tsx +22 -3
- package/Components/FocusableList/FocusableListItemWrapper.tsx +2 -1
- package/Components/FocusableList/index.tsx +14 -7
- package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +13 -10
- package/Components/Layout/TV/LayoutBackground.tsx +1 -1
- package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -0
- package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +10 -10
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +18 -18
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/index.test.tsx +10 -10
- package/Components/MasterCell/utils/behaviorProvider.ts +82 -14
- package/Components/MasterCell/utils/index.ts +11 -5
- package/Components/OfflineHandler/__tests__/index.test.tsx +26 -35
- package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
- package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
- package/Components/PlayerContainer/index.ts +1 -1
- package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +378 -0
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
- package/Components/River/RefreshControl.tsx +11 -17
- package/Components/River/TV/River.tsx +2 -17
- package/Components/River/TV/index.tsx +3 -1
- package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
- package/Components/River/TV/withRiverDataLoader.tsx +17 -0
- package/Components/River/__tests__/river.test.js +12 -26
- package/Components/River/index.tsx +1 -1
- package/Components/Screen/__tests__/Screen.test.tsx +28 -29
- package/Components/Tabs/Tabs.tsx +2 -3
- package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +3 -9
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +24 -8
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
- package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
- package/Contexts/ScreenContext/index.tsx +46 -6
- package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
- package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +221 -209
- package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +14 -16
- package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -20
- package/Decorators/RiverFeedLoader/index.tsx +22 -4
- package/Decorators/RiverFeedLoader/utils/index.ts +0 -18
- package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
- package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
- package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
- package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
- package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
- package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
- package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
- package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
- package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
- package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
- package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +266 -0
- package/Decorators/ZappPipesDataConnector/types.ts +29 -0
- package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
- package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +136 -0
- package/events/index.ts +1 -0
- package/package.json +5 -6
- package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
|
@@ -1,25 +1,12 @@
|
|
|
1
1
|
/// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
/// <reference types="@applicaster/zapp-react-native-ui-components" />
|
|
3
|
-
import 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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
});
|
|
65
|
+
entryContext,
|
|
66
|
+
screenContext,
|
|
67
|
+
searchContext,
|
|
68
|
+
screenData,
|
|
69
|
+
plugins,
|
|
70
|
+
};
|
|
344
71
|
|
|
345
|
-
return
|
|
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
|
+
}
|