@applicaster/zapp-react-native-utils 15.0.0-alpha.2239032089 → 15.0.0-alpha.2292107474
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 +3 -6
- package/actionsExecutor/feedDecorator.ts +6 -6
- package/adsUtils/index.ts +2 -2
- package/analyticsUtils/AnalyticPlayerListener.ts +5 -2
- package/analyticsUtils/README.md +1 -1
- package/appUtils/HooksManager/index.ts +10 -10
- package/appUtils/accessibilityManager/__tests__/utils.test.ts +360 -0
- package/appUtils/accessibilityManager/const.ts +4 -0
- package/appUtils/accessibilityManager/hooks.ts +20 -13
- package/appUtils/accessibilityManager/index.ts +28 -1
- package/appUtils/accessibilityManager/utils.ts +59 -8
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +1 -0
- package/appUtils/focusManager/index.ios.ts +27 -6
- package/appUtils/focusManagerAux/utils/index.ios.ts +19 -1
- package/appUtils/focusManagerAux/utils/index.ts +19 -1
- package/appUtils/focusManagerAux/utils/utils.ios.ts +200 -32
- package/appUtils/keyCodes/keys/keys.web.ts +1 -4
- package/appUtils/orientationHelper.ts +2 -4
- package/appUtils/platform/platformUtils.ts +117 -18
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +94 -4
- package/appUtils/playerManager/OverlayObserver/utils.ts +32 -20
- package/appUtils/playerManager/conts.ts +21 -0
- package/appUtils/playerManager/player.ts +4 -0
- package/appUtils/playerManager/playerNative.ts +29 -16
- package/appUtils/playerManager/usePlayerState.tsx +14 -2
- package/arrayUtils/__tests__/allTruthy.test.ts +24 -0
- package/arrayUtils/__tests__/anyThruthy.test.ts +24 -0
- package/arrayUtils/index.ts +5 -0
- package/cellUtils/index.ts +32 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
- package/focusManager/aux/index.ts +1 -1
- package/manifestUtils/defaultManifestConfigurations/player.js +96 -11
- package/manifestUtils/keys.js +21 -0
- package/manifestUtils/sharedConfiguration/screenPicker/utils.js +1 -0
- package/manifestUtils/tvAction/container/index.js +1 -1
- package/navigationUtils/index.ts +19 -16
- package/package.json +4 -4
- package/playerUtils/usePlayerTTS.ts +8 -3
- package/pluginUtils/index.ts +4 -0
- package/reactHooks/advertising/index.ts +2 -2
- package/reactHooks/debugging/__tests__/index.test.js +4 -4
- package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
- package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +3 -0
- package/reactHooks/feed/__tests__/{useInflatedUrl.test.ts → useInflatedUrl.test.tsx} +62 -7
- package/reactHooks/feed/useBatchLoading.ts +7 -1
- package/reactHooks/feed/useEntryScreenId.ts +2 -2
- package/reactHooks/feed/useFeedLoader.tsx +0 -9
- package/reactHooks/feed/useInflatedUrl.ts +57 -37
- package/reactHooks/feed/usePipesCacheReset.ts +3 -1
- package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +13 -16
- package/reactHooks/layout/index.ts +1 -1
- package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
- package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
- package/reactHooks/navigation/index.ts +11 -6
- package/reactHooks/navigation/useRoute.ts +8 -6
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
- package/reactHooks/resolvers/useCellResolver.ts +6 -2
- package/reactHooks/resolvers/useComponentResolver.ts +8 -2
- package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +11 -3
- package/reactHooks/screen/useTargetScreenData.ts +4 -2
- package/reactHooks/state/useRivers.ts +1 -1
- package/reactHooks/usePluginConfiguration.ts +2 -2
- package/searchUtils/const.ts +7 -0
- package/searchUtils/index.ts +3 -0
- package/stringUtils/index.ts +1 -1
- package/testUtils/index.tsx +30 -21
- package/utils/__tests__/mapAccum.test.ts +73 -0
- package/utils/__tests__/mergeRight.test.ts +48 -0
- package/utils/__tests__/selectors.test.ts +124 -0
- package/utils/index.ts +19 -0
- package/utils/mapAccum.ts +23 -0
- package/utils/mergeRight.ts +5 -0
- package/utils/path.ts +6 -3
- package/utils/pathOr.ts +5 -1
- package/utils/selectors.ts +46 -0
- package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +128 -38
- package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +26 -10
- package/zappFrameworkUtils/HookCallback/useCallbackActions.ts +6 -9
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
getInflatedDataSourceUrl,
|
|
7
|
+
getSearchContext,
|
|
8
|
+
useGetUrlInflater,
|
|
9
|
+
} from "../useInflatedUrl";
|
|
10
|
+
|
|
11
|
+
import { reactHooksLogger } from "../../logger";
|
|
12
|
+
|
|
13
|
+
jest.mock("../../navigation", () => ({
|
|
14
|
+
useRoute: () => ({ pathname: "/mock/path" }),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
// mock contexts hooks
|
|
18
|
+
jest.mock("@applicaster/zapp-react-native-ui-components/Contexts", () => ({
|
|
19
|
+
ZappPipesEntryContext: {
|
|
20
|
+
useZappPipesContext: () => [
|
|
21
|
+
{ id: "entry-1", extensions: { showId: "A123" } },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
ZappPipesSearchContext: {
|
|
25
|
+
useZappPipesContext: () => ["user%20query"],
|
|
26
|
+
},
|
|
27
|
+
ZappPipesScreenContext: {
|
|
28
|
+
useZappPipesContext: () => [{ id: "screen-1" }],
|
|
29
|
+
},
|
|
30
|
+
}));
|
|
31
|
+
|
|
1
32
|
jest.mock("../../logger", () => ({
|
|
2
33
|
reactHooksLogger: {
|
|
3
34
|
warning: jest.fn(),
|
|
@@ -5,13 +36,6 @@ jest.mock("../../logger", () => ({
|
|
|
5
36
|
},
|
|
6
37
|
}));
|
|
7
38
|
|
|
8
|
-
const {
|
|
9
|
-
getInflatedDataSourceUrl,
|
|
10
|
-
getSearchContext,
|
|
11
|
-
} = require("../useInflatedUrl");
|
|
12
|
-
|
|
13
|
-
const { reactHooksLogger } = require("../../logger");
|
|
14
|
-
|
|
15
39
|
let mockStore;
|
|
16
40
|
|
|
17
41
|
describe("getInflatedDataSourceUrl", () => {
|
|
@@ -188,3 +212,34 @@ describe("getSearchContext", () => {
|
|
|
188
212
|
expect(result).toHaveProperty(mapping.queryParam.property, searchContext);
|
|
189
213
|
});
|
|
190
214
|
});
|
|
215
|
+
|
|
216
|
+
describe("useGetUrlInflater", () => {
|
|
217
|
+
const { renderHook } = require("@testing-library/react-hooks");
|
|
218
|
+
|
|
219
|
+
it("returns original url when mapping is not provided", () => {
|
|
220
|
+
const { result } = renderHook(() => useGetUrlInflater(), {
|
|
221
|
+
wrapper: WrappedWithProviders,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const src = "https://foo.com/feed";
|
|
225
|
+
expect(result.current(src)).toBe(src);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it("inflates url using entry/search/screen contexts when mapping provided", () => {
|
|
229
|
+
const { result } = renderHook(() => useGetUrlInflater(), {
|
|
230
|
+
wrapper: ({ children }) => (
|
|
231
|
+
<WrappedWithProviders>{children}</WrappedWithProviders>
|
|
232
|
+
),
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const source = "https://foo.com/shows/{{showId}}?q={{q}}";
|
|
236
|
+
|
|
237
|
+
const mapping = {
|
|
238
|
+
showId: { source: "entry", property: "extensions.showId" },
|
|
239
|
+
q: { source: "search", property: "q" },
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const url = result.current(source, mapping);
|
|
243
|
+
expect(url).toBe("https://foo.com/shows/A123?q=user%20query");
|
|
244
|
+
});
|
|
245
|
+
});
|
|
@@ -151,7 +151,13 @@ export const useBatchLoading = (
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
});
|
|
154
|
-
}, [
|
|
154
|
+
}, [
|
|
155
|
+
batchComponents,
|
|
156
|
+
feeds,
|
|
157
|
+
getUrl,
|
|
158
|
+
loadPipesDataDispatcher,
|
|
159
|
+
options.riverId,
|
|
160
|
+
]);
|
|
155
161
|
|
|
156
162
|
React.useEffect(() => {
|
|
157
163
|
runBatchLoading();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useContentTypes } from "@applicaster/zapp-react-native-redux";
|
|
2
2
|
|
|
3
3
|
export const useEntryScreenId = (entry?: ZappEntry): string | undefined => {
|
|
4
|
-
const
|
|
4
|
+
const contentTypes = useContentTypes();
|
|
5
5
|
|
|
6
6
|
if (!entry) {
|
|
7
7
|
return;
|
|
@@ -37,15 +37,6 @@ export const useFeedLoader = ({
|
|
|
37
37
|
mapping,
|
|
38
38
|
pipesOptions = {},
|
|
39
39
|
}: Props): FeedLoaderResponse => {
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
if (!feedUrl) {
|
|
42
|
-
logger.warning({
|
|
43
|
-
message: "Required parameter feedUrl is missing",
|
|
44
|
-
data: { feedUrl },
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}, []);
|
|
48
|
-
|
|
49
40
|
const isInitialRender = useIsInitialRender();
|
|
50
41
|
|
|
51
42
|
const callableFeedUrl = useInflatedUrl({ feedUrl, mapping });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useMemo } from "react";
|
|
1
|
+
import { useCallback, useMemo, useRef } from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -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
|
|
@@ -164,7 +169,7 @@ const encodeIfNeeded: (string) => string = R.tryCatch(
|
|
|
164
169
|
|
|
165
170
|
export function getSearchContext(
|
|
166
171
|
searchContext: string,
|
|
167
|
-
mapping: ZappTypeMapping
|
|
172
|
+
mapping: Nullable<ZappTypeMapping>
|
|
168
173
|
) {
|
|
169
174
|
if (!mapping) {
|
|
170
175
|
return {};
|
|
@@ -178,6 +183,45 @@ export function getSearchContext(
|
|
|
178
183
|
return { [property]: encodeIfNeeded(searchContext) };
|
|
179
184
|
}
|
|
180
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Hook returns a function that replace placeholders with context values
|
|
188
|
+
* @returns function that inflates urls based on contexts
|
|
189
|
+
*/
|
|
190
|
+
export const useGetUrlInflater = () => {
|
|
191
|
+
const { pathname } = useRoute();
|
|
192
|
+
|
|
193
|
+
const [entryContext] = ZappPipesEntryContext.useZappPipesContext(pathname);
|
|
194
|
+
const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
|
|
195
|
+
const [screenContext] = ZappPipesScreenContext.useZappPipesContext();
|
|
196
|
+
|
|
197
|
+
const entryContextRef = useRef(entryContext);
|
|
198
|
+
entryContextRef.current = entryContext;
|
|
199
|
+
|
|
200
|
+
const screenContextRef = useRef(screenContext);
|
|
201
|
+
screenContextRef.current = screenContext;
|
|
202
|
+
|
|
203
|
+
const searchContextRef = useRef(searchContext);
|
|
204
|
+
searchContextRef.current = searchContext;
|
|
205
|
+
|
|
206
|
+
return useCallback(
|
|
207
|
+
(
|
|
208
|
+
feedUrl: Nullable<string>,
|
|
209
|
+
mapping?: Nullable<ZappTypeMapping>
|
|
210
|
+
): Nullable<string> => {
|
|
211
|
+
return getInflatedDataSourceUrl({
|
|
212
|
+
source: feedUrl,
|
|
213
|
+
contexts: {
|
|
214
|
+
entry: entryContextRef.current,
|
|
215
|
+
screen: screenContextRef.current,
|
|
216
|
+
search: getSearchContext(searchContextRef.current, mapping),
|
|
217
|
+
},
|
|
218
|
+
mapping,
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
[]
|
|
222
|
+
);
|
|
223
|
+
};
|
|
224
|
+
|
|
181
225
|
export function useInflatedUrl({
|
|
182
226
|
feedUrl,
|
|
183
227
|
mapping,
|
|
@@ -185,36 +229,12 @@ export function useInflatedUrl({
|
|
|
185
229
|
feedUrl?: string;
|
|
186
230
|
mapping?: ZappTypeMapping;
|
|
187
231
|
}) {
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
const [entryContext] = ZappPipesEntryContext.useZappPipesContext(pathname);
|
|
191
|
-
const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
|
|
192
|
-
const [screenContext] = ZappPipesScreenContext.useZappPipesContext();
|
|
232
|
+
const urlInflater = useGetUrlInflater();
|
|
193
233
|
|
|
194
234
|
const url = useMemo(
|
|
195
|
-
() =>
|
|
196
|
-
|
|
197
|
-
? getInflatedDataSourceUrl({
|
|
198
|
-
source: feedUrl,
|
|
199
|
-
contexts: {
|
|
200
|
-
entry: entryContext,
|
|
201
|
-
screen: screenContext,
|
|
202
|
-
search: getSearchContext(searchContext, mapping),
|
|
203
|
-
},
|
|
204
|
-
mapping,
|
|
205
|
-
})
|
|
206
|
-
: feedUrl,
|
|
207
|
-
[feedUrl, mapping]
|
|
235
|
+
() => urlInflater(feedUrl, mapping),
|
|
236
|
+
[urlInflater, feedUrl, mapping]
|
|
208
237
|
);
|
|
209
238
|
|
|
210
|
-
if (!feedUrl) {
|
|
211
|
-
logger.warning({
|
|
212
|
-
message: "Required parameter feedUrl is missing",
|
|
213
|
-
data: { feedUrl },
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
239
|
return url;
|
|
220
240
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
2
2
|
import React from "react";
|
|
3
3
|
|
|
4
|
-
type Return = (index: number) => void;
|
|
5
|
-
|
|
6
4
|
type Predicate = (
|
|
7
|
-
|
|
5
|
+
entryLength: number,
|
|
8
6
|
index: number,
|
|
9
7
|
numberOfColumns: number
|
|
10
8
|
) => boolean;
|
|
@@ -12,19 +10,15 @@ type Predicate = (
|
|
|
12
10
|
type Props = {
|
|
13
11
|
ifNeeded: Predicate;
|
|
14
12
|
loadNextData: () => void;
|
|
15
|
-
|
|
13
|
+
entryLength: number;
|
|
16
14
|
numberOfColumns?: number;
|
|
17
15
|
};
|
|
18
16
|
|
|
19
17
|
const handleLoadNextPage =
|
|
20
18
|
(
|
|
21
|
-
ifNeeded:
|
|
22
|
-
entry: ZappEntry[],
|
|
23
|
-
index: number,
|
|
24
|
-
numberOfColumns?: number
|
|
25
|
-
) => boolean,
|
|
19
|
+
ifNeeded: Predicate,
|
|
26
20
|
loadNextData: () => void,
|
|
27
|
-
|
|
21
|
+
entryLength: number,
|
|
28
22
|
numberOfColumns
|
|
29
23
|
) =>
|
|
30
24
|
(index: number) => {
|
|
@@ -32,7 +26,7 @@ const handleLoadNextPage =
|
|
|
32
26
|
* Lazy-Loading, invoke nextLoadData if we reach the end of the List
|
|
33
27
|
*/
|
|
34
28
|
|
|
35
|
-
if (ifNeeded(
|
|
29
|
+
if (ifNeeded(entryLength, index, numberOfColumns)) {
|
|
36
30
|
loadNextData();
|
|
37
31
|
}
|
|
38
32
|
};
|
|
@@ -40,11 +34,14 @@ const handleLoadNextPage =
|
|
|
40
34
|
export const useLoadNextPageIfNeeded = ({
|
|
41
35
|
ifNeeded,
|
|
42
36
|
loadNextData = noop,
|
|
43
|
-
|
|
37
|
+
entryLength,
|
|
44
38
|
numberOfColumns = 0,
|
|
45
|
-
}: Props)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
}: Props) => {
|
|
40
|
+
const memoFn = React.useMemo(
|
|
41
|
+
() =>
|
|
42
|
+
handleLoadNextPage(ifNeeded, loadNextData, entryLength, numberOfColumns),
|
|
43
|
+
[ifNeeded, loadNextData, entryLength, numberOfColumns]
|
|
49
44
|
);
|
|
45
|
+
|
|
46
|
+
return memoFn;
|
|
50
47
|
};
|
package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx}
RENAMED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { renderHook } from "@testing-library/react-native";
|
|
2
3
|
import { Dimensions, StatusBar } from "react-native";
|
|
3
4
|
import { useDimensions } from "../useDimensions";
|
|
4
|
-
import { usePickFromState } from "@applicaster/zapp-react-native-redux";
|
|
5
5
|
|
|
6
6
|
import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive";
|
|
7
|
-
|
|
8
|
-
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => {
|
|
9
|
-
return {
|
|
10
|
-
...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
|
|
11
|
-
usePickFromState: jest.fn(),
|
|
12
|
-
};
|
|
13
|
-
});
|
|
7
|
+
import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
14
8
|
|
|
15
9
|
jest.mock(
|
|
16
10
|
"@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
|
|
@@ -42,12 +36,22 @@ describe("useDimensions", () => {
|
|
|
42
36
|
|
|
43
37
|
beforeEach(() => {
|
|
44
38
|
StatusBar.currentHeight = 20;
|
|
45
|
-
(usePickFromState as jest.Mock).mockReturnValue({ appData: mockAppData });
|
|
46
39
|
});
|
|
47
40
|
|
|
48
41
|
it("returns correct initial dimensions", () => {
|
|
49
|
-
const { result } = renderHook(
|
|
50
|
-
useDimensions("window", { fullDimensions: false })
|
|
42
|
+
const { result } = renderHook(
|
|
43
|
+
() => useDimensions("window", { fullDimensions: false }),
|
|
44
|
+
{
|
|
45
|
+
wrapper: ({ children }) => (
|
|
46
|
+
<WrappedWithProviders
|
|
47
|
+
store={{
|
|
48
|
+
appData: mockAppData,
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{children}
|
|
52
|
+
</WrappedWithProviders>
|
|
53
|
+
),
|
|
54
|
+
}
|
|
51
55
|
);
|
|
52
56
|
|
|
53
57
|
expect(result.current).toMatchObject({
|
|
@@ -56,7 +60,17 @@ describe("useDimensions", () => {
|
|
|
56
60
|
});
|
|
57
61
|
|
|
58
62
|
it("calls handler on mount", () => {
|
|
59
|
-
renderHook(() => useDimensions("window", { fullDimensions: false })
|
|
63
|
+
renderHook(() => useDimensions("window", { fullDimensions: false }), {
|
|
64
|
+
wrapper: ({ children }) => (
|
|
65
|
+
<WrappedWithProviders
|
|
66
|
+
store={{
|
|
67
|
+
appData: mockAppData,
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
{children}
|
|
71
|
+
</WrappedWithProviders>
|
|
72
|
+
),
|
|
73
|
+
});
|
|
60
74
|
|
|
61
75
|
expect(Dimensions.addEventListener).toHaveBeenCalledWith(
|
|
62
76
|
"change",
|
|
@@ -65,12 +79,23 @@ describe("useDimensions", () => {
|
|
|
65
79
|
});
|
|
66
80
|
|
|
67
81
|
it("calls handler on isActive change", () => {
|
|
68
|
-
const { rerender } = renderHook(
|
|
69
|
-
useDimensions("window", { fullDimensions: false })
|
|
82
|
+
const { rerender } = renderHook(
|
|
83
|
+
() => useDimensions("window", { fullDimensions: false }),
|
|
84
|
+
{
|
|
85
|
+
wrapper: ({ children }) => (
|
|
86
|
+
<WrappedWithProviders
|
|
87
|
+
store={{
|
|
88
|
+
appData: mockAppData,
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
{children}
|
|
92
|
+
</WrappedWithProviders>
|
|
93
|
+
),
|
|
94
|
+
}
|
|
70
95
|
);
|
|
71
96
|
|
|
72
97
|
(useIsScreenActive as jest.Mock).mockReturnValue(false);
|
|
73
|
-
rerender();
|
|
98
|
+
rerender({});
|
|
74
99
|
|
|
75
100
|
expect(Dimensions.addEventListener).toHaveBeenCalledWith(
|
|
76
101
|
"change",
|
|
@@ -79,8 +104,19 @@ describe("useDimensions", () => {
|
|
|
79
104
|
});
|
|
80
105
|
|
|
81
106
|
it("handles fullDimensions option", () => {
|
|
82
|
-
const { result } = renderHook(
|
|
83
|
-
useDimensions("window", { fullDimensions: true })
|
|
107
|
+
const { result } = renderHook(
|
|
108
|
+
() => useDimensions("window", { fullDimensions: true }),
|
|
109
|
+
{
|
|
110
|
+
wrapper: ({ children }) => (
|
|
111
|
+
<WrappedWithProviders
|
|
112
|
+
store={{
|
|
113
|
+
appData: mockAppData,
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
{children}
|
|
117
|
+
</WrappedWithProviders>
|
|
118
|
+
),
|
|
119
|
+
}
|
|
84
120
|
);
|
|
85
121
|
|
|
86
122
|
expect(result.current).toMatchObject({
|
|
@@ -91,8 +127,19 @@ describe("useDimensions", () => {
|
|
|
91
127
|
});
|
|
92
128
|
|
|
93
129
|
it("handles excludeStatusBar option", () => {
|
|
94
|
-
const { result } = renderHook(
|
|
95
|
-
useDimensions("window", { excludeStatusBar: true })
|
|
130
|
+
const { result } = renderHook(
|
|
131
|
+
() => useDimensions("window", { excludeStatusBar: true }),
|
|
132
|
+
{
|
|
133
|
+
wrapper: ({ children }) => (
|
|
134
|
+
<WrappedWithProviders
|
|
135
|
+
store={{
|
|
136
|
+
appData: mockAppData,
|
|
137
|
+
}}
|
|
138
|
+
>
|
|
139
|
+
{children}
|
|
140
|
+
</WrappedWithProviders>
|
|
141
|
+
),
|
|
142
|
+
}
|
|
96
143
|
);
|
|
97
144
|
|
|
98
145
|
expect(result.current.height).toBe(
|
|
@@ -101,8 +148,19 @@ describe("useDimensions", () => {
|
|
|
101
148
|
});
|
|
102
149
|
|
|
103
150
|
it("handles rounded option", () => {
|
|
104
|
-
const { result } = renderHook(
|
|
105
|
-
useDimensions("window", { rounded: true })
|
|
151
|
+
const { result } = renderHook(
|
|
152
|
+
() => useDimensions("window", { rounded: true }),
|
|
153
|
+
{
|
|
154
|
+
wrapper: ({ children }) => (
|
|
155
|
+
<WrappedWithProviders
|
|
156
|
+
store={{
|
|
157
|
+
appData: mockAppData,
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
{children}
|
|
161
|
+
</WrappedWithProviders>
|
|
162
|
+
),
|
|
163
|
+
}
|
|
106
164
|
);
|
|
107
165
|
|
|
108
166
|
expect(result.current.width).toBe(Math.ceil(mockDimensions.width));
|
|
@@ -110,8 +168,19 @@ describe("useDimensions", () => {
|
|
|
110
168
|
});
|
|
111
169
|
|
|
112
170
|
it("handles deviceInfo option", () => {
|
|
113
|
-
const { result } = renderHook(
|
|
114
|
-
useDimensions("window", { deviceInfo: true })
|
|
171
|
+
const { result } = renderHook(
|
|
172
|
+
() => useDimensions("window", { deviceInfo: true }),
|
|
173
|
+
{
|
|
174
|
+
wrapper: ({ children }) => (
|
|
175
|
+
<WrappedWithProviders
|
|
176
|
+
store={{
|
|
177
|
+
appData: mockAppData,
|
|
178
|
+
}}
|
|
179
|
+
>
|
|
180
|
+
{children}
|
|
181
|
+
</WrappedWithProviders>
|
|
182
|
+
),
|
|
183
|
+
}
|
|
115
184
|
);
|
|
116
185
|
|
|
117
186
|
expect(result.current.deviceInfo).toMatchObject({
|
|
@@ -121,7 +190,18 @@ describe("useDimensions", () => {
|
|
|
121
190
|
|
|
122
191
|
it("logs deprecation warning when fullDimensions is boolean", () => {
|
|
123
192
|
const consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation();
|
|
124
|
-
|
|
193
|
+
|
|
194
|
+
renderHook(() => useDimensions("window", true), {
|
|
195
|
+
wrapper: ({ children }) => (
|
|
196
|
+
<WrappedWithProviders
|
|
197
|
+
store={{
|
|
198
|
+
appData: mockAppData,
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
{children}
|
|
202
|
+
</WrappedWithProviders>
|
|
203
|
+
),
|
|
204
|
+
});
|
|
125
205
|
|
|
126
206
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
127
207
|
"Deprecation Warning\nSecond argument is now the options object. {fullDimensions: boolean, ...}"
|
|
@@ -3,7 +3,7 @@ import { useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
|
3
3
|
import * as R from "ramda";
|
|
4
4
|
|
|
5
5
|
import { Dimensions, Platform, StatusBar } from "react-native";
|
|
6
|
-
import {
|
|
6
|
+
import { useAppData } from "@applicaster/zapp-react-native-redux/hooks";
|
|
7
7
|
|
|
8
8
|
import { isTV } from "../../../reactUtils";
|
|
9
9
|
|
|
@@ -37,7 +37,7 @@ export const useDimensions: UseDimensions = (
|
|
|
37
37
|
) => {
|
|
38
38
|
const statusBarHeight = StatusBar?.currentHeight;
|
|
39
39
|
const isActive = useIsScreenActive();
|
|
40
|
-
const
|
|
40
|
+
const appData = useAppData();
|
|
41
41
|
|
|
42
42
|
if (typeof fullDimensions === "boolean") {
|
|
43
43
|
// eslint-disable-next-line no-console
|
|
@@ -3,7 +3,7 @@ import { BackHandler } from "react-native";
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
useContentTypes,
|
|
6
|
-
|
|
6
|
+
usePlugins,
|
|
7
7
|
} from "@applicaster/zapp-react-native-redux/hooks";
|
|
8
8
|
import { HooksManager } from "@applicaster/zapp-react-native-utils/appUtils/HooksManager";
|
|
9
9
|
|
|
@@ -16,6 +16,8 @@ import { useConnectionInfo } from "../connection";
|
|
|
16
16
|
|
|
17
17
|
import { isTV, isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
18
18
|
import { useNavbarState } from "../screen";
|
|
19
|
+
import { useRivers } from "../state";
|
|
20
|
+
import { useLayoutVersion } from "../layout";
|
|
19
21
|
|
|
20
22
|
export { useNavigation } from "./useNavigation";
|
|
21
23
|
|
|
@@ -86,6 +88,10 @@ export function isNavBarVisible(
|
|
|
86
88
|
if (route.startsWith("/hooks/")) {
|
|
87
89
|
const module = screenData?.module;
|
|
88
90
|
|
|
91
|
+
if (module === undefined) {
|
|
92
|
+
return showNavBar;
|
|
93
|
+
}
|
|
94
|
+
|
|
89
95
|
if (module?.presentFullScreen) {
|
|
90
96
|
return false;
|
|
91
97
|
}
|
|
@@ -164,11 +170,10 @@ export const useZappHooksForEntry = (
|
|
|
164
170
|
setIsRunningInBackground,
|
|
165
171
|
}: HookModalContextT = useContext(ZappHookModalContext.ReactContext);
|
|
166
172
|
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
} = usePickFromState(["appData", "rivers", "plugins"]);
|
|
173
|
+
const plugins = usePlugins();
|
|
174
|
+
const rivers = useRivers();
|
|
175
|
+
|
|
176
|
+
const layoutVersion = useLayoutVersion();
|
|
172
177
|
|
|
173
178
|
const contentTypes = useContentTypes();
|
|
174
179
|
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
import { useContext } from "react";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
useContentTypes,
|
|
8
|
+
usePlugins,
|
|
9
|
+
} from "@applicaster/zapp-react-native-redux/hooks";
|
|
7
10
|
|
|
8
11
|
import { legacyScreenData } from "@applicaster/quick-brick-core/App/NavigationProvider/utils";
|
|
9
12
|
|
|
@@ -14,6 +17,7 @@ import { useNavigation } from "./useNavigation";
|
|
|
14
17
|
import { useModalStoreState } from "../../modalState";
|
|
15
18
|
import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
|
|
16
19
|
import { usePathname } from "./usePathname";
|
|
20
|
+
import { useRivers } from "../state";
|
|
17
21
|
|
|
18
22
|
// starts with modal/
|
|
19
23
|
const isModalPathname = (pathname: string) => /^modal\//.test(pathname);
|
|
@@ -42,11 +46,9 @@ export const useRoute = (
|
|
|
42
46
|
? legacyScreenData(screenContext)
|
|
43
47
|
: screenContext;
|
|
44
48
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"contentTypes",
|
|
49
|
-
]);
|
|
49
|
+
const plugins = usePlugins();
|
|
50
|
+
const rivers = useRivers();
|
|
51
|
+
const contentTypes = useContentTypes();
|
|
50
52
|
|
|
51
53
|
const modalState = useModalStoreState();
|
|
52
54
|
|
|
@@ -147,17 +147,34 @@ export class TVSeekController
|
|
|
147
147
|
|
|
148
148
|
let targetPos = currentPos;
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
150
|
+
const isLive = this.playerController.isLive();
|
|
151
|
+
|
|
152
|
+
if (isLive) {
|
|
153
|
+
if (this.currentSeekType === SEEK_TYPE.REWIND) {
|
|
154
|
+
targetPos = Math.min(
|
|
155
|
+
currentPos + offset,
|
|
156
|
+
this.playerController.getSeekableDuration()
|
|
157
|
+
);
|
|
158
|
+
} else if (this.currentSeekType === SEEK_TYPE.FORWARD) {
|
|
159
|
+
targetPos = Math.max(0, currentPos - offset);
|
|
160
|
+
} else {
|
|
161
|
+
log_warning(
|
|
162
|
+
`TVSeekController: handleDelayedSeek - invalid seek type: ${this.currentSeekType}`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
157
165
|
} else {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
166
|
+
if (this.currentSeekType === SEEK_TYPE.FORWARD) {
|
|
167
|
+
targetPos = Math.min(
|
|
168
|
+
currentPos + offset,
|
|
169
|
+
this.playerController.getSeekableDuration()
|
|
170
|
+
);
|
|
171
|
+
} else if (this.currentSeekType === SEEK_TYPE.REWIND) {
|
|
172
|
+
targetPos = Math.max(0, currentPos - offset);
|
|
173
|
+
} else {
|
|
174
|
+
log_warning(
|
|
175
|
+
`TVSeekController: handleDelayedSeek - invalid seek type: ${this.currentSeekType}`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
161
178
|
}
|
|
162
179
|
|
|
163
180
|
log_debug(
|