@applicaster/zapp-react-native-utils 14.0.0-rc.9 → 14.0.0-rc.90
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/actionsExecutor/ActionExecutorContext.tsx +60 -84
- package/actionsExecutor/ScreenActions.ts +164 -0
- package/actionsExecutor/StorageActions.ts +110 -0
- package/actionsExecutor/feedDecorator.ts +171 -0
- package/actionsExecutor/screenResolver.ts +11 -0
- package/analyticsUtils/AnalyticPlayerListener.ts +5 -2
- package/analyticsUtils/AnalyticsEvents/helper.ts +81 -0
- package/analyticsUtils/AnalyticsEvents/sendHeaderClickEvent.ts +1 -1
- package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -1
- package/analyticsUtils/AnalyticsEvents/sendOnClickEvent.ts +14 -4
- package/analyticsUtils/__tests__/analyticsUtils.test.js +3 -0
- package/analyticsUtils/events.ts +8 -0
- package/analyticsUtils/index.tsx +3 -4
- package/analyticsUtils/manager.ts +1 -1
- package/analyticsUtils/playerAnalyticsTracker.ts +2 -1
- package/appUtils/HooksManager/Hook.ts +4 -4
- package/appUtils/HooksManager/index.ts +11 -1
- package/appUtils/accessibilityManager/const.ts +13 -0
- package/appUtils/accessibilityManager/hooks.ts +35 -1
- package/appUtils/accessibilityManager/index.ts +154 -30
- package/appUtils/accessibilityManager/utils.ts +24 -0
- package/appUtils/contextKeysManager/contextResolver.ts +42 -1
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +8 -0
- package/appUtils/focusManager/__tests__/focusManager.test.js +1 -1
- package/appUtils/focusManager/events.ts +2 -0
- package/appUtils/focusManager/index.ios.ts +27 -0
- package/appUtils/focusManager/index.ts +86 -11
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +1 -1
- package/appUtils/focusManagerAux/utils/index.ts +112 -3
- package/appUtils/focusManagerAux/utils/utils.ios.ts +35 -0
- package/appUtils/platform/platformUtils.ts +33 -3
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +91 -16
- package/appUtils/playerManager/OverlayObserver/utils.ts +32 -20
- package/appUtils/playerManager/conts.ts +21 -0
- package/appUtils/playerManager/useChapterMarker.tsx +0 -1
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +16 -0
- package/arrayUtils/__tests__/allTruthy.test.ts +24 -0
- package/arrayUtils/__tests__/anyThruthy.test.ts +24 -0
- package/arrayUtils/__tests__/isEmptyArray.test.ts +63 -0
- package/arrayUtils/__tests__/isFilledArray.test.ts +1 -1
- package/arrayUtils/index.ts +13 -3
- package/audioPlayerUtils/__tests__/getArtworkImage.test.ts +144 -0
- package/audioPlayerUtils/__tests__/getBackgroundImage.test.ts +72 -0
- package/audioPlayerUtils/__tests__/getImageFromEntry.test.ts +110 -0
- package/audioPlayerUtils/assets/index.ts +2 -0
- package/audioPlayerUtils/index.ts +242 -0
- package/componentsUtils/__tests__/isTabsScreen.test.ts +38 -0
- package/componentsUtils/index.ts +4 -1
- package/conf/player/__tests__/selectors.test.ts +34 -0
- package/conf/player/selectors.ts +10 -0
- package/configurationUtils/__tests__/configurationUtils.test.js +0 -31
- package/configurationUtils/__tests__/getMediaItems.test.ts +65 -0
- package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +34 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +546 -0
- package/configurationUtils/index.ts +64 -35
- package/configurationUtils/manifestKeyParser.ts +57 -32
- package/focusManager/FocusManager.ts +104 -20
- package/focusManager/Tree.ts +25 -21
- package/focusManager/__tests__/FocusManager.test.ts +50 -8
- package/focusManager/aux/index.ts +98 -0
- package/focusManager/utils.ts +12 -6
- package/index.d.ts +1 -10
- package/manifestUtils/_internals/getDefaultConfiguration.js +28 -0
- package/manifestUtils/{_internals.js → _internals/index.js} +2 -25
- package/manifestUtils/createConfig.js +4 -1
- package/manifestUtils/defaultManifestConfigurations/player.js +2764 -1539
- package/manifestUtils/index.js +4 -0
- package/manifestUtils/keys.js +33 -0
- package/manifestUtils/progressBar/__tests__/mobileProgressBar.test.js +0 -30
- package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +6 -0
- package/navigationUtils/__tests__/mapContentTypesToRivers.test.ts +130 -0
- package/navigationUtils/index.ts +26 -21
- package/package.json +2 -3
- package/playerUtils/PlayerTTS/PlayerTTS.ts +359 -0
- package/playerUtils/PlayerTTS/index.ts +1 -0
- package/playerUtils/__tests__/configurationUtils.test.ts +1 -65
- package/playerUtils/__tests__/getPlayerActionButtons.test.ts +54 -0
- package/playerUtils/_internals/__tests__/utils.test.ts +71 -0
- package/playerUtils/_internals/index.ts +1 -0
- package/playerUtils/_internals/utils.ts +31 -0
- package/playerUtils/configurationUtils.ts +0 -44
- package/playerUtils/getPlayerActionButtons.ts +17 -0
- package/playerUtils/index.ts +53 -0
- package/playerUtils/usePlayerTTS.ts +21 -0
- package/playerUtils/useValidatePlayerConfig.tsx +22 -19
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +15 -14
- package/reactHooks/cell-click/__tests__/index.test.js +3 -0
- package/reactHooks/cell-click/index.ts +8 -1
- package/reactHooks/debugging/__tests__/index.test.js +0 -1
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +47 -90
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +71 -31
- package/reactHooks/feed/index.ts +2 -0
- package/reactHooks/feed/useBatchLoading.ts +17 -10
- package/reactHooks/feed/useFeedLoader.tsx +36 -43
- package/reactHooks/feed/useInflatedUrl.ts +23 -29
- package/reactHooks/feed/useLoadPipesDataDispatch.ts +63 -0
- package/reactHooks/feed/usePipesCacheReset.ts +3 -3
- package/reactHooks/flatList/useSequentialRenderItem.tsx +3 -3
- package/reactHooks/layout/__tests__/index.test.tsx +3 -1
- package/reactHooks/layout/index.ts +1 -1
- package/reactHooks/layout/isTablet/index.ts +12 -5
- package/reactHooks/layout/useDimensions/__tests__/useDimensions.test.ts +34 -36
- package/reactHooks/layout/useDimensions/useDimensions.ts +2 -3
- package/reactHooks/layout/useLayoutVersion.ts +5 -5
- package/reactHooks/navigation/index.ts +7 -5
- package/reactHooks/navigation/useIsScreenActive.ts +9 -5
- package/reactHooks/navigation/useRoute.ts +7 -2
- package/reactHooks/navigation/useScreenStateStore.ts +8 -0
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +4 -0
- package/reactHooks/screen/useScreenContext.ts +1 -1
- package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +2 -1
- package/reactHooks/state/index.ts +1 -1
- package/reactHooks/state/useHomeRiver.ts +4 -2
- package/reactHooks/state/useRivers.ts +7 -8
- package/riverComponetsMeasurementProvider/index.tsx +1 -1
- package/screenPickerUtils/index.ts +13 -0
- package/services/js2native.ts +1 -0
- package/storage/ScreenSingleValueProvider.ts +204 -0
- package/storage/ScreenStateMultiSelectProvider.ts +293 -0
- package/storage/StorageMultiSelectProvider.ts +192 -0
- package/storage/StorageSingleSelectProvider.ts +108 -0
- package/testUtils/index.tsx +7 -8
- package/time/BackgroundTimer.ts +6 -4
- package/utils/__tests__/endsWith.test.ts +30 -0
- package/utils/__tests__/find.test.ts +36 -0
- package/utils/__tests__/mapAccum.test.ts +73 -0
- package/utils/__tests__/omit.test.ts +19 -0
- package/utils/__tests__/path.test.ts +33 -0
- package/utils/__tests__/pathOr.test.ts +37 -0
- package/utils/__tests__/startsWith.test.ts +30 -0
- package/utils/__tests__/take.test.ts +40 -0
- package/utils/endsWith.ts +9 -0
- package/utils/find.ts +3 -0
- package/utils/index.ts +38 -1
- package/utils/mapAccum.ts +23 -0
- package/utils/omit.ts +5 -0
- package/utils/path.ts +5 -0
- package/utils/pathOr.ts +5 -0
- package/utils/startsWith.ts +9 -0
- package/utils/take.ts +5 -0
- package/playerUtils/configurationGenerator.ts +0 -2572
|
@@ -2,15 +2,12 @@ import { renderHook } from "@testing-library/react-hooks";
|
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
import * as zappPipesModule from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
4
4
|
import * as reactReduxModules from "react-redux";
|
|
5
|
-
import { Provider } from "react-redux";
|
|
6
5
|
import * as React from "react";
|
|
7
|
-
import configureStore from "redux-mock-store";
|
|
8
|
-
import thunk from "redux-thunk";
|
|
9
6
|
import * as useRouteHook from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute";
|
|
10
7
|
import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
|
|
11
8
|
import { useFeedLoader } from "../useFeedLoader";
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
import { WrappedWithProviders } from "../../../testUtils";
|
|
10
|
+
import { ScreenStateResolver } from "../../../appUtils/contextKeysManager/contextResolver";
|
|
14
11
|
|
|
15
12
|
jest.useFakeTimers({ legacyFakeTimers: true });
|
|
16
13
|
|
|
@@ -55,13 +52,15 @@ const mockZappPipesData = {
|
|
|
55
52
|
|
|
56
53
|
describe("useFeedLoader", () => {
|
|
57
54
|
describe("with cached feed url", () => {
|
|
58
|
-
const store =
|
|
55
|
+
const store = {
|
|
59
56
|
plugins: [],
|
|
60
57
|
zappPipes: { "test://testfakeurl": mockZappPipesData },
|
|
61
|
-
}
|
|
58
|
+
};
|
|
62
59
|
|
|
63
|
-
const wrapper: React.FC<any> = ({ children }) => (
|
|
64
|
-
<
|
|
60
|
+
const wrapper: React.FC<any> = ({ children, ...props }) => (
|
|
61
|
+
<WrappedWithProviders store={props.store || store}>
|
|
62
|
+
{children}
|
|
63
|
+
</WrappedWithProviders>
|
|
65
64
|
);
|
|
66
65
|
|
|
67
66
|
it("returns cached feed", () => {
|
|
@@ -110,8 +109,10 @@ describe("useFeedLoader", () => {
|
|
|
110
109
|
describe("without cached feeds", () => {
|
|
111
110
|
const feedUrl = "test://testfakeurl2";
|
|
112
111
|
|
|
113
|
-
const wrapper: React.FC<any> = ({ children,
|
|
114
|
-
<
|
|
112
|
+
const wrapper: React.FC<any> = ({ children, ...props }) => (
|
|
113
|
+
<WrappedWithProviders store={props.store}>
|
|
114
|
+
{children}
|
|
115
|
+
</WrappedWithProviders>
|
|
115
116
|
);
|
|
116
117
|
|
|
117
118
|
it("It loads data for new url and returns it", () => {
|
|
@@ -123,10 +124,10 @@ describe("useFeedLoader", () => {
|
|
|
123
124
|
.spyOn(zappPipesModule, "loadPipesData")
|
|
124
125
|
.mockImplementation(jest.fn());
|
|
125
126
|
|
|
126
|
-
const initialStore =
|
|
127
|
+
const initialStore = {
|
|
127
128
|
plugins: [],
|
|
128
129
|
zappPipes: { "test://testfakeurl": "foobar" },
|
|
129
|
-
}
|
|
130
|
+
};
|
|
130
131
|
|
|
131
132
|
const { result, rerender } = renderHook(
|
|
132
133
|
() => useFeedLoader({ feedUrl: "test://testfakeurl2" }),
|
|
@@ -135,15 +136,19 @@ describe("useFeedLoader", () => {
|
|
|
135
136
|
|
|
136
137
|
expect(result.current.data).toBeNull();
|
|
137
138
|
|
|
138
|
-
expect(loadPipesDataSpy).
|
|
139
|
+
expect(loadPipesDataSpy).toHaveBeenCalledWith(feedUrl, {
|
|
139
140
|
clearCache: true,
|
|
140
141
|
riverId: undefined,
|
|
142
|
+
callback: expect.any(Function),
|
|
143
|
+
resolvers: {
|
|
144
|
+
screen: expect.any(ScreenStateResolver),
|
|
145
|
+
},
|
|
141
146
|
});
|
|
142
147
|
|
|
143
|
-
const store2 =
|
|
148
|
+
const store2 = {
|
|
144
149
|
plugins: [],
|
|
145
150
|
zappPipes: { "test://testfakeurl2": mockZappPipesData },
|
|
146
|
-
}
|
|
151
|
+
};
|
|
147
152
|
|
|
148
153
|
rerender({ store: store2 });
|
|
149
154
|
|
|
@@ -164,10 +169,10 @@ describe("useFeedLoader", () => {
|
|
|
164
169
|
.spyOn(reactReduxModules, "useDispatch")
|
|
165
170
|
.mockImplementation(() => jest.fn());
|
|
166
171
|
|
|
167
|
-
const initialStore =
|
|
172
|
+
const initialStore = {
|
|
168
173
|
plugins: [],
|
|
169
174
|
zappPipes: { "test://testfakeurl": "foobar" },
|
|
170
|
-
}
|
|
175
|
+
};
|
|
171
176
|
|
|
172
177
|
const { result, rerender } = renderHook(
|
|
173
178
|
() => useFeedLoader({ feedUrl: "test://testfakeurl2" }),
|
|
@@ -176,15 +181,22 @@ describe("useFeedLoader", () => {
|
|
|
176
181
|
|
|
177
182
|
expect(result.current.data).toBeNull();
|
|
178
183
|
|
|
179
|
-
expect(loadPipesDataSpy).
|
|
184
|
+
expect(loadPipesDataSpy.mock.calls[0][0]).toBe(feedUrl);
|
|
185
|
+
|
|
186
|
+
expect(loadPipesDataSpy.mock.calls[0][1]).toMatchObject({
|
|
180
187
|
clearCache: true,
|
|
181
188
|
riverId: undefined,
|
|
189
|
+
resolvers: {
|
|
190
|
+
screen: {
|
|
191
|
+
screenStateStore: expect.any(Function),
|
|
192
|
+
},
|
|
193
|
+
},
|
|
182
194
|
});
|
|
183
195
|
|
|
184
|
-
const store2 =
|
|
196
|
+
const store2 = {
|
|
185
197
|
plugins: [],
|
|
186
198
|
zappPipes: { "test://testfakeurl2": mockZappPipesData },
|
|
187
|
-
}
|
|
199
|
+
};
|
|
188
200
|
|
|
189
201
|
rerender({ store: store2 });
|
|
190
202
|
|
|
@@ -197,8 +209,10 @@ describe("useFeedLoader", () => {
|
|
|
197
209
|
const feedUrl = "test://testfakeurl";
|
|
198
210
|
const feedUrlWithNext = "test://withnexttestfakeurl";
|
|
199
211
|
|
|
200
|
-
const wrapper: React.FC<any> = ({ children,
|
|
201
|
-
<
|
|
212
|
+
const wrapper: React.FC<any> = ({ children, ...props }) => (
|
|
213
|
+
<WrappedWithProviders store={props.store || {}}>
|
|
214
|
+
{children}
|
|
215
|
+
</WrappedWithProviders>
|
|
202
216
|
);
|
|
203
217
|
|
|
204
218
|
describe("reloadData", () => {
|
|
@@ -211,10 +225,10 @@ describe("useFeedLoader", () => {
|
|
|
211
225
|
.spyOn(reactReduxModules, "useDispatch")
|
|
212
226
|
.mockImplementation(() => jest.fn());
|
|
213
227
|
|
|
214
|
-
const initialStore =
|
|
228
|
+
const initialStore = {
|
|
215
229
|
plugins: [],
|
|
216
230
|
zappPipes: { [feedUrl]: "foobar" },
|
|
217
|
-
}
|
|
231
|
+
};
|
|
218
232
|
|
|
219
233
|
const { result } = renderHook(() => useFeedLoader({ feedUrl }), {
|
|
220
234
|
wrapper,
|
|
@@ -223,11 +237,24 @@ describe("useFeedLoader", () => {
|
|
|
223
237
|
|
|
224
238
|
const { reloadData } = result.current;
|
|
225
239
|
|
|
226
|
-
reloadData();
|
|
240
|
+
reloadData?.();
|
|
241
|
+
|
|
242
|
+
expect(loadPipesDataSpy).toHaveBeenCalled();
|
|
243
|
+
|
|
244
|
+
expect(
|
|
245
|
+
loadPipesDataSpy.mock.calls[loadPipesDataSpy.mock.calls.length - 1][0]
|
|
246
|
+
).toBe(feedUrl);
|
|
227
247
|
|
|
228
|
-
expect(
|
|
248
|
+
expect(
|
|
249
|
+
loadPipesDataSpy.mock.calls[loadPipesDataSpy.mock.calls.length - 1][1]
|
|
250
|
+
).toMatchObject({
|
|
229
251
|
clearCache: true,
|
|
230
252
|
silentRefresh: true,
|
|
253
|
+
resolvers: {
|
|
254
|
+
screen: {
|
|
255
|
+
screenStateStore: expect.any(Function),
|
|
256
|
+
},
|
|
257
|
+
},
|
|
231
258
|
});
|
|
232
259
|
|
|
233
260
|
loadPipesDataSpy.mockRestore();
|
|
@@ -247,10 +274,10 @@ describe("useFeedLoader", () => {
|
|
|
247
274
|
.spyOn(reactReduxModules, "useDispatch")
|
|
248
275
|
.mockImplementation(() => jest.fn());
|
|
249
276
|
|
|
250
|
-
const initialStore =
|
|
277
|
+
const initialStore = {
|
|
251
278
|
plugins: [],
|
|
252
279
|
zappPipes: { [feedUrlWithNext]: { data: { next: nextUrl } } },
|
|
253
|
-
}
|
|
280
|
+
};
|
|
254
281
|
|
|
255
282
|
const { result } = renderHook(
|
|
256
283
|
() => useFeedLoader({ feedUrl: feedUrlWithNext }),
|
|
@@ -262,11 +289,24 @@ describe("useFeedLoader", () => {
|
|
|
262
289
|
|
|
263
290
|
const { loadNext } = result.current;
|
|
264
291
|
|
|
265
|
-
loadNext();
|
|
292
|
+
loadNext?.();
|
|
293
|
+
|
|
294
|
+
expect(loadPipesDataSpy).toHaveBeenCalled();
|
|
295
|
+
|
|
296
|
+
expect(
|
|
297
|
+
loadPipesDataSpy.mock.calls[loadPipesDataSpy.mock.calls.length - 1][0]
|
|
298
|
+
).toBe(nextUrl);
|
|
266
299
|
|
|
267
|
-
expect(
|
|
300
|
+
expect(
|
|
301
|
+
loadPipesDataSpy.mock.calls[loadPipesDataSpy.mock.calls.length - 1][1]
|
|
302
|
+
).toMatchObject({
|
|
268
303
|
parentFeed: feedUrlWithNext,
|
|
269
304
|
silentRefresh: true,
|
|
305
|
+
resolvers: {
|
|
306
|
+
screen: {
|
|
307
|
+
screenStateStore: expect.any(Function),
|
|
308
|
+
},
|
|
309
|
+
},
|
|
270
310
|
});
|
|
271
311
|
|
|
272
312
|
loadPipesDataSpy.mockRestore();
|
package/reactHooks/feed/index.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { complement, compose, isNil, map, min, prop, take, uniq } from "ramda";
|
|
2
|
-
import { useDispatch } from "react-redux";
|
|
3
2
|
import * as React from "react";
|
|
4
|
-
import {
|
|
5
|
-
import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
3
|
+
import { useZappPipesFeed } from "@applicaster/zapp-react-native-redux";
|
|
6
4
|
import { isNilOrEmpty } from "../../reactUtils/helpers";
|
|
7
5
|
import { ZappPipesSearchContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
|
|
8
6
|
import {
|
|
9
7
|
getInflatedDataSourceUrl,
|
|
10
8
|
getSearchContext,
|
|
9
|
+
useLoadPipesDataDispatch,
|
|
11
10
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
11
|
import { isGallery } from "@applicaster/zapp-react-native-utils/componentsUtils";
|
|
13
|
-
import { useScreenContext } from "../screen
|
|
12
|
+
import { useScreenContext } from "../screen";
|
|
14
13
|
|
|
15
14
|
type Options = {
|
|
16
15
|
initialBatchSize?: number;
|
|
@@ -63,7 +62,6 @@ export const useBatchLoading = (
|
|
|
63
62
|
componentsToRender: { data?: ZappDataSource; component_type: string }[],
|
|
64
63
|
options: Options
|
|
65
64
|
) => {
|
|
66
|
-
const dispatch = useDispatch();
|
|
67
65
|
const { screen: screenContext, entry: entryContext } = useScreenContext();
|
|
68
66
|
const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
|
|
69
67
|
const [hasEverBeenReady, setHasEverBeenReady] = React.useState(false);
|
|
@@ -118,7 +116,9 @@ export const useBatchLoading = (
|
|
|
118
116
|
[]
|
|
119
117
|
);
|
|
120
118
|
|
|
121
|
-
const feeds =
|
|
119
|
+
const feeds = useZappPipesFeed(feedUrls);
|
|
120
|
+
|
|
121
|
+
const loadPipesDataDispatcher = useLoadPipesDataDispatch();
|
|
122
122
|
|
|
123
123
|
// dispatch loadPipesData for each feed that is not loaded
|
|
124
124
|
const runBatchLoading = React.useCallback(() => {
|
|
@@ -138,17 +138,24 @@ export const useBatchLoading = (
|
|
|
138
138
|
|
|
139
139
|
if (mappedFeedUrl) {
|
|
140
140
|
// 4. load data
|
|
141
|
-
return
|
|
142
|
-
|
|
141
|
+
return loadPipesDataDispatcher(
|
|
142
|
+
mappedFeedUrl,
|
|
143
|
+
{
|
|
144
|
+
riverId: options.riverId,
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
withResolvers: true,
|
|
148
|
+
withScreenRouteMapping: true,
|
|
149
|
+
}
|
|
143
150
|
);
|
|
144
151
|
}
|
|
145
152
|
}
|
|
146
153
|
});
|
|
147
|
-
}, [feedUrls]);
|
|
154
|
+
}, [feedUrls, feeds, loadPipesDataDispatcher]);
|
|
148
155
|
|
|
149
156
|
React.useEffect(() => {
|
|
150
157
|
runBatchLoading();
|
|
151
|
-
}, []);
|
|
158
|
+
}, [runBatchLoading]); // Adding runBatchLoading as a dependency to ensure that it reloads feeds when clearPipesData is called
|
|
152
159
|
|
|
153
160
|
React.useEffect(() => {
|
|
154
161
|
// check if all feeds are ready and set hasEverBeenReady to true
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
-
import { useDispatch } from "react-redux";
|
|
3
2
|
|
|
4
|
-
import {
|
|
5
|
-
import { useZappPipesFeed } from "@applicaster/zapp-react-native-redux/hooks";
|
|
3
|
+
import { useZappPipesFeed } from "@applicaster/zapp-react-native-redux";
|
|
6
4
|
|
|
7
5
|
import { reactHooksLogger } from "../logger";
|
|
8
6
|
import { shouldDispatchData, useIsInitialRender } from "../utils";
|
|
9
7
|
import { useInflatedUrl } from "./useInflatedUrl";
|
|
10
|
-
import {
|
|
8
|
+
import { useLoadPipesDataDispatch } from "./useLoadPipesDataDispatch";
|
|
11
9
|
|
|
12
10
|
const logger = reactHooksLogger.addSubsystem("useFeedLoader");
|
|
13
11
|
|
|
@@ -39,39 +37,27 @@ export const useFeedLoader = ({
|
|
|
39
37
|
mapping,
|
|
40
38
|
pipesOptions = {},
|
|
41
39
|
}: Props): FeedLoaderResponse => {
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
if (!feedUrl) {
|
|
44
|
-
logger.warning({
|
|
45
|
-
message: "Required parameter feedUrl is missing",
|
|
46
|
-
data: { feedUrl },
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
40
|
const isInitialRender = useIsInitialRender();
|
|
52
|
-
const dispatch = useDispatch();
|
|
53
|
-
const { screenData } = useRoute();
|
|
54
41
|
|
|
55
42
|
const callableFeedUrl = useInflatedUrl({ feedUrl, mapping });
|
|
56
43
|
|
|
57
44
|
const currentFeed = useZappPipesFeed(callableFeedUrl);
|
|
58
45
|
|
|
59
|
-
const
|
|
60
|
-
(screenData as LegacyNavigationScreenData)?.targetScreen?.id ??
|
|
61
|
-
screenData?.id;
|
|
46
|
+
const loadPipesDataDispatcher = useLoadPipesDataDispatch();
|
|
62
47
|
|
|
63
48
|
const reloadData = React.useCallback<ReloadDataFunction>(
|
|
64
49
|
(silentRefresh = true, callback) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
50
|
+
loadPipesDataDispatcher(
|
|
51
|
+
callableFeedUrl,
|
|
52
|
+
{
|
|
53
|
+
clearCache: true,
|
|
54
|
+
silentRefresh,
|
|
55
|
+
callback,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
withResolvers: true,
|
|
59
|
+
}
|
|
60
|
+
);
|
|
75
61
|
},
|
|
76
62
|
[callableFeedUrl]
|
|
77
63
|
);
|
|
@@ -80,15 +66,16 @@ export const useFeedLoader = ({
|
|
|
80
66
|
if (callableFeedUrl) {
|
|
81
67
|
const nextFeed = currentFeed?.data?.next;
|
|
82
68
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
69
|
+
loadPipesDataDispatcher(
|
|
70
|
+
nextFeed,
|
|
71
|
+
{
|
|
72
|
+
silentRefresh: true,
|
|
73
|
+
parentFeed: callableFeedUrl,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
withResolvers: true,
|
|
77
|
+
}
|
|
78
|
+
);
|
|
92
79
|
}
|
|
93
80
|
}, [callableFeedUrl, currentFeed?.data?.next]);
|
|
94
81
|
|
|
@@ -97,12 +84,16 @@ export const useFeedLoader = ({
|
|
|
97
84
|
shouldDispatchData(callableFeedUrl, currentFeed, pipesOptions.clearCache)
|
|
98
85
|
) {
|
|
99
86
|
if (callableFeedUrl && !pipesOptions.skipLoading) {
|
|
100
|
-
|
|
101
|
-
|
|
87
|
+
loadPipesDataDispatcher(
|
|
88
|
+
callableFeedUrl,
|
|
89
|
+
{
|
|
102
90
|
...pipesOptions,
|
|
103
91
|
clearCache: true,
|
|
104
|
-
|
|
105
|
-
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
withResolvers: true,
|
|
95
|
+
withScreenRouteMapping: true,
|
|
96
|
+
}
|
|
106
97
|
);
|
|
107
98
|
} else if (!callableFeedUrl) {
|
|
108
99
|
logger.info({
|
|
@@ -131,9 +122,11 @@ export const useFeedLoader = ({
|
|
|
131
122
|
// Reload feed when feedUrl changes, unless skipLoading is true
|
|
132
123
|
useEffect(() => {
|
|
133
124
|
if (!isInitialRender && callableFeedUrl && !pipesOptions.skipLoading) {
|
|
134
|
-
|
|
125
|
+
loadPipesDataDispatcher(callableFeedUrl, pipesOptions, {
|
|
126
|
+
withResolvers: true,
|
|
127
|
+
});
|
|
135
128
|
}
|
|
136
|
-
}, [callableFeedUrl]);
|
|
129
|
+
}, [callableFeedUrl, isInitialRender, pipesOptions.skipLoading]);
|
|
137
130
|
|
|
138
131
|
return React.useMemo(() => {
|
|
139
132
|
if (!callableFeedUrl || !feedUrl) {
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from "@applicaster/zapp-pipes-v2-client";
|
|
19
19
|
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
20
20
|
import { ENDPOINT_TAGS } from "../../types";
|
|
21
|
+
import { isNilOrEmpty } from "../../reactUtils/helpers";
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* will match any occurrence in a string of one or more word characters
|
|
@@ -75,15 +76,19 @@ export const getInflatedDataSourceUrl: GetInflatedDataSourceUrl = ({
|
|
|
75
76
|
* https://foo.com/shows/A1234
|
|
76
77
|
*/
|
|
77
78
|
|
|
78
|
-
if (!
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
if (!isNilOrEmpty(mapping)) {
|
|
80
|
+
if (!source) {
|
|
81
|
+
if (__DEV__) {
|
|
82
|
+
// eslint-disable-next-line no-console
|
|
83
|
+
throw new Error(
|
|
84
|
+
"getInflatedDataSourceUrl: source is empty while mapping is provided"
|
|
85
|
+
);
|
|
86
|
+
}
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
return source || null;
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
// Hack because in tv we expect to get key names instead of values from the fake entry
|
|
@@ -193,28 +198,17 @@ export function useInflatedUrl({
|
|
|
193
198
|
|
|
194
199
|
const url = useMemo(
|
|
195
200
|
() =>
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
: feedUrl,
|
|
207
|
-
[feedUrl, mapping]
|
|
201
|
+
getInflatedDataSourceUrl({
|
|
202
|
+
source: feedUrl,
|
|
203
|
+
contexts: {
|
|
204
|
+
entry: entryContext,
|
|
205
|
+
screen: screenContext,
|
|
206
|
+
search: getSearchContext(searchContext, mapping),
|
|
207
|
+
},
|
|
208
|
+
mapping,
|
|
209
|
+
}),
|
|
210
|
+
[entryContext, feedUrl, mapping, screenContext, searchContext]
|
|
208
211
|
);
|
|
209
212
|
|
|
210
|
-
if (!feedUrl) {
|
|
211
|
-
logger.warning({
|
|
212
|
-
message: "Required parameter feedUrl is missing",
|
|
213
|
-
data: { feedUrl },
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
213
|
return url;
|
|
220
214
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useAppDispatch,
|
|
3
|
+
ZappPipes,
|
|
4
|
+
} from "@applicaster/zapp-react-native-redux";
|
|
5
|
+
import { applyScreenRouteDefaults } from "@applicaster/zapp-react-native-redux/ZappPipes/feedProcessor";
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { useScreenResolvers } from "../../actionsExecutor/screenResolver";
|
|
8
|
+
import { useRoute } from "../navigation";
|
|
9
|
+
import { useScreenStateStore } from "../navigation/useScreenStateStore";
|
|
10
|
+
|
|
11
|
+
export const useLoadPipesDataDispatch = () => {
|
|
12
|
+
const screenStateStore = useScreenStateStore();
|
|
13
|
+
const resolvers = useScreenResolvers();
|
|
14
|
+
const dispatch = useAppDispatch();
|
|
15
|
+
|
|
16
|
+
const { pathname, screenData } = useRoute();
|
|
17
|
+
|
|
18
|
+
const riverId =
|
|
19
|
+
(screenData as LegacyNavigationScreenData)?.targetScreen?.id ??
|
|
20
|
+
screenData?.id;
|
|
21
|
+
|
|
22
|
+
const onLoadCB = (options) => (data, _err) => {
|
|
23
|
+
options?.callback?.();
|
|
24
|
+
|
|
25
|
+
if (data) {
|
|
26
|
+
applyScreenRouteDefaults(data, screenStateStore, pathname);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return React.useCallback(
|
|
31
|
+
(
|
|
32
|
+
url: string,
|
|
33
|
+
options: {
|
|
34
|
+
callback?: (data: unknown, error?: Error | null | undefined) => void;
|
|
35
|
+
riverId?: string;
|
|
36
|
+
clearCache?: boolean;
|
|
37
|
+
silentRefresh?: boolean;
|
|
38
|
+
parentFeed?: string;
|
|
39
|
+
} = {},
|
|
40
|
+
{
|
|
41
|
+
withResolvers = false,
|
|
42
|
+
withScreenRouteMapping = false,
|
|
43
|
+
}: {
|
|
44
|
+
withResolvers?: boolean;
|
|
45
|
+
withScreenRouteMapping?: boolean;
|
|
46
|
+
} = {}
|
|
47
|
+
) => {
|
|
48
|
+
if (url) {
|
|
49
|
+
dispatch(
|
|
50
|
+
ZappPipes.loadPipesData(url, {
|
|
51
|
+
riverId,
|
|
52
|
+
resolvers: withResolvers ? resolvers : undefined,
|
|
53
|
+
...options,
|
|
54
|
+
callback: withScreenRouteMapping
|
|
55
|
+
? onLoadCB(options)
|
|
56
|
+
: options?.callback,
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
[]
|
|
62
|
+
);
|
|
63
|
+
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { useDispatch } from "react-redux";
|
|
3
2
|
|
|
4
3
|
import { getDatasourceUrl } from "@applicaster/zapp-react-native-ui-components/Decorators/RiverFeedLoader/utils/getDatasourceUrl";
|
|
5
4
|
import { usePipesContexts } from "@applicaster/zapp-react-native-ui-components/Decorators/RiverFeedLoader/utils/usePipesContexts";
|
|
6
5
|
import { clearPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
7
6
|
|
|
8
|
-
import { useRoute } from "../navigation
|
|
7
|
+
import { useRoute } from "../navigation";
|
|
8
|
+
import { useAppDispatch } from "@applicaster/zapp-react-native-redux";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* reset river components cache when screen is unmounted
|
|
@@ -13,7 +13,7 @@ import { useRoute } from "../navigation/useRoute";
|
|
|
13
13
|
* @param {Array} riverComponents list of UI components
|
|
14
14
|
*/
|
|
15
15
|
export const usePipesCacheReset = (riverId, riverComponents) => {
|
|
16
|
-
const dispatch =
|
|
16
|
+
const dispatch = useAppDispatch();
|
|
17
17
|
const { screenData, pathname } = useRoute();
|
|
18
18
|
const pipesContexts = usePipesContexts(riverId, pathname);
|
|
19
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import { View } from "react-native";
|
|
3
|
+
import { View, ViewStyle } from "react-native";
|
|
4
4
|
|
|
5
5
|
import { platformSelect } from "../../reactUtils";
|
|
6
6
|
|
|
@@ -49,13 +49,13 @@ export const useSequentialRenderItem = (data: Data) => {
|
|
|
49
49
|
const readyToDisplay =
|
|
50
50
|
index === 0 ? true : arePreviousComponentsReady(index);
|
|
51
51
|
|
|
52
|
-
const displayStyle = {
|
|
52
|
+
const displayStyle: ViewStyle = {
|
|
53
53
|
display: readyToDisplay ? "flex" : "none",
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
const readyStyle = {
|
|
57
57
|
visibility: readyToDisplay ? "visible" : "hidden",
|
|
58
|
-
};
|
|
58
|
+
} as ViewStyle;
|
|
59
59
|
|
|
60
60
|
const style = platformSelect({
|
|
61
61
|
tvos: readyStyle,
|
|
@@ -42,15 +42,17 @@ jest.mock("react-native-safe-area-context", () => ({
|
|
|
42
42
|
}));
|
|
43
43
|
|
|
44
44
|
jest.mock("../../../reactUtils", () => ({
|
|
45
|
+
...jest.requireActual("../../../reactUtils"),
|
|
45
46
|
platformSelect: jest.fn((specs) => specs[platform] || specs.default),
|
|
46
47
|
isTV: jest.fn(() => mock_tv_flag),
|
|
47
48
|
}));
|
|
48
49
|
|
|
49
50
|
jest.mock("../../navigation", () => ({
|
|
50
|
-
useNavigation: () => null,
|
|
51
51
|
useIsScreenActive: () => true,
|
|
52
52
|
}));
|
|
53
53
|
|
|
54
|
+
jest.mock("../../navigation/useNavigation");
|
|
55
|
+
|
|
54
56
|
const { Dimensions } = require("react-native");
|
|
55
57
|
const { useDimensions } = require("..");
|
|
56
58
|
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { NativeModules, Platform } from "react-native";
|
|
2
2
|
|
|
3
|
+
export const isAndroidTablet = () => {
|
|
4
|
+
const { initialProps } = NativeModules.QuickBrickCommunicationModule;
|
|
5
|
+
|
|
6
|
+
return initialProps?.is_tablet;
|
|
7
|
+
};
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
10
|
* Determines wether the given device is a tablet based on dimensions, orientation, and platform
|
|
5
11
|
* @param {Object} dimensions - Dimensions object passed to the function
|
|
6
12
|
* @param {String} orientation - Orientation enum passed to the function
|
|
7
13
|
* @returns {Boolean} isTablet - returns whether the given device is a tablet
|
|
8
14
|
*/
|
|
9
|
-
export const isTablet = (
|
|
15
|
+
export const isTablet = (
|
|
16
|
+
dimensions?: { width: number; height: number },
|
|
17
|
+
orientation?: string
|
|
18
|
+
) => {
|
|
10
19
|
if (Platform?.OS === "ios") {
|
|
11
20
|
return Platform?.isPad;
|
|
12
21
|
} else if (Platform?.OS === "android") {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return initialProps?.is_tablet;
|
|
22
|
+
return isAndroidTablet();
|
|
16
23
|
}
|
|
17
24
|
|
|
18
|
-
const { width } = dimensions;
|
|
25
|
+
const { width } = dimensions || {};
|
|
19
26
|
|
|
20
27
|
if (width < 600) return false;
|
|
21
28
|
if (width >= 600 && width < 840) return orientation === "portrait";
|