@applicaster/zapp-react-native-utils 14.0.0-alpha.3038031102 → 14.0.0-alpha.3140225604
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/appUtils/accessibilityManager/index.ts +9 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +547 -0
- package/configurationUtils/manifestKeyParser.ts +57 -32
- package/index.d.ts +3 -0
- package/navigationUtils/index.ts +4 -6
- package/package.json +2 -2
- package/playerUtils/index.ts +51 -0
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -3
- package/reactHooks/feed/useBatchLoading.ts +6 -8
- package/reactHooks/feed/useFeedLoader.tsx +8 -12
- package/reactHooks/feed/usePipesCacheReset.ts +2 -2
- package/reactHooks/layout/__tests__/index.test.tsx +1 -3
- package/reactHooks/layout/isTablet/index.ts +7 -3
- package/reactHooks/layout/useDimensions/__tests__/useDimensions.test.ts +36 -34
- package/reactHooks/layout/useDimensions/useDimensions.ts +3 -2
- package/reactHooks/layout/useLayoutVersion.ts +5 -5
- package/reactHooks/navigation/index.ts +7 -3
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +0 -4
- package/reactHooks/state/useRivers.ts +8 -7
- package/utils/index.ts +0 -1
- package/navigationUtils/__tests__/mapContentTypesToRivers.test.ts +0 -130
|
@@ -11,8 +11,11 @@ const currentPlatform = platformSelect({
|
|
|
11
11
|
android_tv: "android",
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// Do not change the order, focused_selected should be first
|
|
15
|
+
const states = ["focused_selected", "pressed", "focused", "selected"];
|
|
16
|
+
|
|
15
17
|
const platformSuffixes = ["ios", "tvos", "samsung", "lg", "android"];
|
|
18
|
+
type StateKey = (typeof states)[number] | "default";
|
|
16
19
|
|
|
17
20
|
export type GetAllSpecificStylesProps = {
|
|
18
21
|
componentName: string;
|
|
@@ -33,39 +36,47 @@ export const getAllSpecificStyles = ({
|
|
|
33
36
|
subComponentName,
|
|
34
37
|
outStyles,
|
|
35
38
|
}: GetAllSpecificStylesProps) => {
|
|
36
|
-
if (!outStyles)
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
+
if (!outStyles) throw new Error("outStyles is required");
|
|
40
|
+
if (!componentName) throw new Error("componentName is required");
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
const prefix =
|
|
43
|
+
subComponentName?.length > 0
|
|
44
|
+
? `${componentName}_style_${subComponentName}_`
|
|
45
|
+
: `${componentName}_style_`;
|
|
42
46
|
|
|
43
47
|
const defaultKey = "default";
|
|
44
48
|
|
|
45
|
-
if (!outStyles[defaultKey]) {
|
|
46
|
-
|
|
47
|
-
}
|
|
49
|
+
if (!outStyles[defaultKey]) outStyles[defaultKey] = {};
|
|
50
|
+
|
|
51
|
+
const tmpGenericDict: Record<StateKey, Record<string, any>> = {};
|
|
52
|
+
const tmpPlatformDict: Record<StateKey, Record<string, any>> = {};
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
const parseKey = (key: string, value: any) => {
|
|
50
55
|
if (!key.startsWith(prefix)) {
|
|
51
56
|
return;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
let styleName = key.slice(prefix.length);
|
|
60
|
+
if (!styleName || styleName.startsWith("_")) return;
|
|
55
61
|
|
|
56
|
-
const platform = platformSuffixes.find((
|
|
57
|
-
styleName.startsWith(
|
|
62
|
+
const platform = platformSuffixes.find((prefix) =>
|
|
63
|
+
styleName.startsWith(prefix)
|
|
58
64
|
);
|
|
59
65
|
|
|
66
|
+
let tmpDict = tmpGenericDict;
|
|
67
|
+
|
|
60
68
|
if (platform) {
|
|
61
69
|
if (currentPlatform !== platform) {
|
|
62
|
-
return;
|
|
70
|
+
return;
|
|
63
71
|
}
|
|
64
72
|
|
|
73
|
+
tmpDict = tmpPlatformDict;
|
|
65
74
|
styleName = styleName.slice(platform.length + 1);
|
|
66
75
|
}
|
|
67
76
|
|
|
68
|
-
let state =
|
|
77
|
+
let state = states.find((prefix) => styleName.startsWith(prefix)) as
|
|
78
|
+
| StateKey
|
|
79
|
+
| undefined;
|
|
69
80
|
|
|
70
81
|
if (state) {
|
|
71
82
|
styleName = styleName.slice(state.length + 1);
|
|
@@ -73,30 +84,44 @@ export const getAllSpecificStyles = ({
|
|
|
73
84
|
state = defaultKey;
|
|
74
85
|
}
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
if (!styleName) return;
|
|
77
88
|
|
|
78
|
-
|
|
89
|
+
const camelCaseKey = toCamelCase(styleName);
|
|
79
90
|
|
|
80
|
-
if (!
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
91
|
+
if (!tmpDict[state]) tmpDict[state] = {};
|
|
92
|
+
tmpDict[state][camelCaseKey] = value;
|
|
93
|
+
};
|
|
84
94
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
95
|
+
for (const [key, value] of Object.entries(configuration)) {
|
|
96
|
+
parseKey(key, value);
|
|
97
|
+
}
|
|
88
98
|
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
const allStates = Array.from(
|
|
100
|
+
new Set<StateKey>([
|
|
101
|
+
defaultKey,
|
|
102
|
+
...(Object.keys(tmpGenericDict) as StateKey[]),
|
|
103
|
+
...(Object.keys(tmpPlatformDict) as StateKey[]),
|
|
104
|
+
...(Object.keys(outStyles) as StateKey[]),
|
|
105
|
+
])
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
for (const state of allStates) {
|
|
109
|
+
outStyles[state] = Object.assign(
|
|
110
|
+
{},
|
|
111
|
+
outStyles[state] || {},
|
|
112
|
+
tmpGenericDict[state] || {},
|
|
113
|
+
tmpPlatformDict[state] || {}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
91
116
|
|
|
92
117
|
// Merge default styles with state specific styles
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (key === defaultKey) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
118
|
+
for (const state of Object.keys(outStyles)) {
|
|
119
|
+
if (state === defaultKey) continue;
|
|
98
120
|
|
|
99
|
-
|
|
100
|
-
|
|
121
|
+
outStyles[state] = Object.assign(
|
|
122
|
+
{},
|
|
123
|
+
outStyles[defaultKey],
|
|
124
|
+
outStyles[state]
|
|
125
|
+
);
|
|
101
126
|
}
|
|
102
127
|
};
|
package/index.d.ts
CHANGED
|
@@ -139,10 +139,13 @@ declare type AccessibilityState = {
|
|
|
139
139
|
};
|
|
140
140
|
|
|
141
141
|
declare type AccessibilityProps = {
|
|
142
|
+
accessible?: boolean;
|
|
142
143
|
accessibilityLabel?: string;
|
|
143
144
|
accessibilityHint?: string;
|
|
144
145
|
"aria-label"?: string;
|
|
145
146
|
"aria-description"?: string;
|
|
146
147
|
accessibilityRole?: string;
|
|
147
148
|
"aria-role"?: string;
|
|
149
|
+
role?: string;
|
|
150
|
+
tabindex?: number;
|
|
148
151
|
};
|
package/navigationUtils/index.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
isPlayable,
|
|
14
14
|
isV2River,
|
|
15
15
|
} from "./itemTypeMatchers";
|
|
16
|
-
import { RootState } from "@applicaster/zapp-react-native-redux/store";
|
|
17
16
|
|
|
18
17
|
type PathAttribute = {
|
|
19
18
|
screenType: string;
|
|
@@ -378,11 +377,10 @@ export const usesVideoModal = (
|
|
|
378
377
|
return targetScreenConfiguration?.styles?.use_video_modal;
|
|
379
378
|
};
|
|
380
379
|
|
|
381
|
-
export const mapContentTypesToRivers = (
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
380
|
+
export const mapContentTypesToRivers = ({
|
|
381
|
+
rivers,
|
|
382
|
+
contentTypes,
|
|
383
|
+
}): ZappContentTypesMapped | null => {
|
|
386
384
|
if (!contentTypes) {
|
|
387
385
|
return null;
|
|
388
386
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "14.0.0-alpha.
|
|
3
|
+
"version": "14.0.0-alpha.3140225604",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@applicaster/applicaster-types": "14.0.0-alpha.
|
|
30
|
+
"@applicaster/applicaster-types": "14.0.0-alpha.3140225604",
|
|
31
31
|
"buffer": "^5.2.1",
|
|
32
32
|
"camelize": "^1.0.0",
|
|
33
33
|
"dayjs": "^1.11.10",
|
package/playerUtils/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { isFilledArray } from "@applicaster/zapp-react-native-utils/arrayUtils";
|
|
|
5
5
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
6
6
|
|
|
7
7
|
import { getBoolFromConfigValue } from "../configurationUtils";
|
|
8
|
+
import { Dimensions } from "react-native";
|
|
8
9
|
|
|
9
10
|
export { getPlayerActionButtons } from "./getPlayerActionButtons";
|
|
10
11
|
|
|
@@ -97,3 +98,53 @@ export const isAudioItem = (item: Option<ZappEntry>) => {
|
|
|
97
98
|
export const isInlineTV = (screenData) => {
|
|
98
99
|
return isTV() && isFilledArray(screenData?.ui_components);
|
|
99
100
|
};
|
|
101
|
+
|
|
102
|
+
const isPercentage = (value: string | number): boolean => {
|
|
103
|
+
if (typeof value === "string") {
|
|
104
|
+
return value.includes("%");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return false;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const getPercentageOf = (percent: string, value: number) => {
|
|
111
|
+
const percentageValue = parseFloat(percent.replace("%", ""));
|
|
112
|
+
|
|
113
|
+
if (isNaN(percentageValue)) {
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return (value * percentageValue) / 100;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type DimensionsT = {
|
|
121
|
+
width: number | string;
|
|
122
|
+
height: number | string | undefined;
|
|
123
|
+
aspectRatio?: number;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const getTabletWidth = (
|
|
127
|
+
tablet_landscape_sidebar_width,
|
|
128
|
+
dimensions: DimensionsT
|
|
129
|
+
) => {
|
|
130
|
+
const { width: SCREEN_WIDTH } = Dimensions.get("screen");
|
|
131
|
+
|
|
132
|
+
const { width } = dimensions;
|
|
133
|
+
let widthValue = Number(width);
|
|
134
|
+
|
|
135
|
+
if (isPercentage(width)) {
|
|
136
|
+
widthValue = getPercentageOf(width.toString(), SCREEN_WIDTH);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const sidebarWidth = Number(tablet_landscape_sidebar_width?.replace("%", ""));
|
|
140
|
+
|
|
141
|
+
if (tablet_landscape_sidebar_width?.includes("%")) {
|
|
142
|
+
return widthValue * (1 - sidebarWidth / 100);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (Number.isNaN(sidebarWidth)) {
|
|
146
|
+
return widthValue * 0.65;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return widthValue - sidebarWidth;
|
|
150
|
+
};
|
|
@@ -21,9 +21,7 @@ jest.mock(
|
|
|
21
21
|
|
|
22
22
|
jest.useFakeTimers({ legacyFakeTimers: true });
|
|
23
23
|
|
|
24
|
-
jest.mock(
|
|
25
|
-
"@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation"
|
|
26
|
-
);
|
|
24
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
|
|
27
25
|
|
|
28
26
|
const mockStore = configureStore();
|
|
29
27
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { complement, compose, isNil, map, min, prop, take, uniq } from "ramda";
|
|
2
|
+
import { useDispatch } from "react-redux";
|
|
2
3
|
import * as React from "react";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
useAppDispatch,
|
|
6
|
-
useZappPipesFeed,
|
|
7
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
4
|
+
import { useZappPipesFeeds } from "@applicaster/zapp-react-native-redux/hooks";
|
|
5
|
+
import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
8
6
|
import { isNilOrEmpty } from "../../reactUtils/helpers";
|
|
9
7
|
import { ZappPipesSearchContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
|
|
10
8
|
import {
|
|
@@ -65,7 +63,7 @@ export const useBatchLoading = (
|
|
|
65
63
|
componentsToRender: { data?: ZappDataSource; component_type: string }[],
|
|
66
64
|
options: Options
|
|
67
65
|
) => {
|
|
68
|
-
const dispatch =
|
|
66
|
+
const dispatch = useDispatch();
|
|
69
67
|
const { screen: screenContext, entry: entryContext } = useScreenContext();
|
|
70
68
|
const [searchContext] = ZappPipesSearchContext.useZappPipesContext();
|
|
71
69
|
const [hasEverBeenReady, setHasEverBeenReady] = React.useState(false);
|
|
@@ -120,7 +118,7 @@ export const useBatchLoading = (
|
|
|
120
118
|
[]
|
|
121
119
|
);
|
|
122
120
|
|
|
123
|
-
const feeds =
|
|
121
|
+
const feeds = useZappPipesFeeds(feedUrls);
|
|
124
122
|
|
|
125
123
|
// dispatch loadPipesData for each feed that is not loaded
|
|
126
124
|
const runBatchLoading = React.useCallback(() => {
|
|
@@ -141,7 +139,7 @@ export const useBatchLoading = (
|
|
|
141
139
|
if (mappedFeedUrl) {
|
|
142
140
|
// 4. load data
|
|
143
141
|
return dispatch(
|
|
144
|
-
|
|
142
|
+
loadPipesData(mappedFeedUrl, { riverId: options.riverId })
|
|
145
143
|
);
|
|
146
144
|
}
|
|
147
145
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
+
import { useDispatch } from "react-redux";
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
useAppDispatch,
|
|
6
|
-
useZappPipesFeed,
|
|
7
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
4
|
+
import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
5
|
+
import { useZappPipesFeed } from "@applicaster/zapp-react-native-redux/hooks";
|
|
8
6
|
|
|
9
7
|
import { reactHooksLogger } from "../logger";
|
|
10
8
|
import { shouldDispatchData, useIsInitialRender } from "../utils";
|
|
@@ -51,7 +49,7 @@ export const useFeedLoader = ({
|
|
|
51
49
|
}, []);
|
|
52
50
|
|
|
53
51
|
const isInitialRender = useIsInitialRender();
|
|
54
|
-
const dispatch =
|
|
52
|
+
const dispatch = useDispatch();
|
|
55
53
|
const { screenData } = useRoute();
|
|
56
54
|
|
|
57
55
|
const callableFeedUrl = useInflatedUrl({ feedUrl, mapping });
|
|
@@ -66,7 +64,7 @@ export const useFeedLoader = ({
|
|
|
66
64
|
(silentRefresh = true, callback) => {
|
|
67
65
|
if (callableFeedUrl) {
|
|
68
66
|
dispatch(
|
|
69
|
-
|
|
67
|
+
loadPipesData(callableFeedUrl, {
|
|
70
68
|
clearCache: true,
|
|
71
69
|
silentRefresh,
|
|
72
70
|
callback,
|
|
@@ -84,7 +82,7 @@ export const useFeedLoader = ({
|
|
|
84
82
|
|
|
85
83
|
if (nextFeed) {
|
|
86
84
|
dispatch(
|
|
87
|
-
|
|
85
|
+
loadPipesData(nextFeed, {
|
|
88
86
|
silentRefresh: true,
|
|
89
87
|
parentFeed: callableFeedUrl,
|
|
90
88
|
riverId,
|
|
@@ -100,7 +98,7 @@ export const useFeedLoader = ({
|
|
|
100
98
|
) {
|
|
101
99
|
if (callableFeedUrl && !pipesOptions.skipLoading) {
|
|
102
100
|
dispatch(
|
|
103
|
-
|
|
101
|
+
loadPipesData(callableFeedUrl, {
|
|
104
102
|
...pipesOptions,
|
|
105
103
|
clearCache: true,
|
|
106
104
|
riverId,
|
|
@@ -133,9 +131,7 @@ export const useFeedLoader = ({
|
|
|
133
131
|
// Reload feed when feedUrl changes, unless skipLoading is true
|
|
134
132
|
useEffect(() => {
|
|
135
133
|
if (!isInitialRender && callableFeedUrl && !pipesOptions.skipLoading) {
|
|
136
|
-
dispatch(
|
|
137
|
-
ZappPipes.loadPipesData(callableFeedUrl, { ...pipesOptions, riverId })
|
|
138
|
-
);
|
|
134
|
+
dispatch(loadPipesData(callableFeedUrl, { ...pipesOptions, riverId }));
|
|
139
135
|
}
|
|
140
136
|
}, [callableFeedUrl]);
|
|
141
137
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { useDispatch } from "react-redux";
|
|
2
3
|
|
|
3
4
|
import { getDatasourceUrl } from "@applicaster/zapp-react-native-ui-components/Decorators/RiverFeedLoader/utils/getDatasourceUrl";
|
|
4
5
|
import { usePipesContexts } from "@applicaster/zapp-react-native-ui-components/Decorators/RiverFeedLoader/utils/usePipesContexts";
|
|
5
6
|
import { clearPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
6
7
|
|
|
7
8
|
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 { useAppDispatch } from "@applicaster/zapp-react-native-redux";
|
|
|
13
13
|
* @param {Array} riverComponents list of UI components
|
|
14
14
|
*/
|
|
15
15
|
export const usePipesCacheReset = (riverId, riverComponents) => {
|
|
16
|
-
const dispatch =
|
|
16
|
+
const dispatch = useDispatch();
|
|
17
17
|
const { screenData, pathname } = useRoute();
|
|
18
18
|
const pipesContexts = usePipesContexts(riverId, pathname);
|
|
19
19
|
|
|
@@ -42,17 +42,15 @@ jest.mock("react-native-safe-area-context", () => ({
|
|
|
42
42
|
}));
|
|
43
43
|
|
|
44
44
|
jest.mock("../../../reactUtils", () => ({
|
|
45
|
-
...jest.requireActual("../../../reactUtils"),
|
|
46
45
|
platformSelect: jest.fn((specs) => specs[platform] || specs.default),
|
|
47
46
|
isTV: jest.fn(() => mock_tv_flag),
|
|
48
47
|
}));
|
|
49
48
|
|
|
50
49
|
jest.mock("../../navigation", () => ({
|
|
50
|
+
useNavigation: () => null,
|
|
51
51
|
useIsScreenActive: () => true,
|
|
52
52
|
}));
|
|
53
53
|
|
|
54
|
-
jest.mock("../../navigation/useNavigation");
|
|
55
|
-
|
|
56
54
|
const { Dimensions } = require("react-native");
|
|
57
55
|
const { useDimensions } = require("..");
|
|
58
56
|
|
|
@@ -1,5 +1,11 @@
|
|
|
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
|
|
@@ -13,9 +19,7 @@ export const isTablet = (
|
|
|
13
19
|
if (Platform?.OS === "ios") {
|
|
14
20
|
return Platform?.isPad;
|
|
15
21
|
} else if (Platform?.OS === "android") {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return initialProps?.is_tablet;
|
|
22
|
+
return isAndroidTablet();
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
const { width } = dimensions || {};
|
|
@@ -1,48 +1,46 @@
|
|
|
1
1
|
import { renderHook } from "@testing-library/react-hooks";
|
|
2
2
|
import { Dimensions, StatusBar } from "react-native";
|
|
3
|
-
import { useDimensions } from "../useDimensions";
|
|
4
|
-
import { usePickFromState } from "@applicaster/zapp-react-native-redux";
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
const mockUsePickFromState = jest.fn();
|
|
5
|
+
const mockUseIsScreenActive = jest.fn();
|
|
6
|
+
const mockGetInitialDimensions = jest.fn();
|
|
7
|
+
const mockGetDeviceInfo = jest.fn();
|
|
7
8
|
|
|
8
|
-
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
});
|
|
9
|
+
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
10
|
+
...(jest.requireActual("@applicaster/zapp-react-native-redux/hooks") as {}),
|
|
11
|
+
usePickFromState: mockUsePickFromState,
|
|
12
|
+
}));
|
|
14
13
|
|
|
15
|
-
jest.mock(
|
|
16
|
-
|
|
17
|
-
() => ({
|
|
18
|
-
useIsScreenActive: jest.fn().mockReturnValue(true),
|
|
19
|
-
})
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
jest.doMock("../helpers", () => ({
|
|
23
|
-
getInitialDimensions: jest
|
|
24
|
-
.fn()
|
|
25
|
-
.mockReturnValue({ width: 100, height: 200, scale: 1, fontScale: 1 }),
|
|
14
|
+
jest.mock("../../../navigation", () => ({
|
|
15
|
+
useIsScreenActive: mockUseIsScreenActive,
|
|
26
16
|
}));
|
|
27
17
|
|
|
28
|
-
jest.mock("
|
|
29
|
-
|
|
18
|
+
jest.mock("../helpers", () => ({
|
|
19
|
+
getInitialDimensions: mockGetInitialDimensions,
|
|
30
20
|
}));
|
|
31
21
|
|
|
32
|
-
|
|
22
|
+
jest.mock("../../getDeviceInfo", () => ({
|
|
23
|
+
getDeviceInfo: mockGetDeviceInfo,
|
|
24
|
+
}));
|
|
33
25
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Dimensions.addEventListener = jest.fn().mockReturnValue({
|
|
37
|
-
remove: jest.fn(),
|
|
38
|
-
});
|
|
26
|
+
const { useDimensions } = require("../useDimensions");
|
|
39
27
|
|
|
40
28
|
describe("useDimensions", () => {
|
|
29
|
+
const mockDimensions = { width: 100, height: 200, scale: 1, fontScale: 1 };
|
|
41
30
|
const mockAppData = { someData: "test" };
|
|
42
31
|
|
|
43
32
|
beforeEach(() => {
|
|
44
|
-
|
|
45
|
-
|
|
33
|
+
jest.clearAllMocks();
|
|
34
|
+
Dimensions.get = jest.fn().mockReturnValue(mockDimensions);
|
|
35
|
+
|
|
36
|
+
Dimensions.addEventListener = jest.fn().mockReturnValue({
|
|
37
|
+
remove: jest.fn(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
mockUsePickFromState.mockReturnValue({ appData: mockAppData });
|
|
41
|
+
mockUseIsScreenActive.mockReturnValue(true);
|
|
42
|
+
mockGetInitialDimensions.mockReturnValue(mockDimensions);
|
|
43
|
+
mockGetDeviceInfo.mockReturnValue({ deviceInfo: "testDeviceInfo" });
|
|
46
44
|
});
|
|
47
45
|
|
|
48
46
|
it("returns correct initial dimensions", () => {
|
|
@@ -50,9 +48,12 @@ describe("useDimensions", () => {
|
|
|
50
48
|
useDimensions("window", { fullDimensions: false })
|
|
51
49
|
);
|
|
52
50
|
|
|
53
|
-
expect(result.current).
|
|
51
|
+
expect(result.current).toEqual({
|
|
52
|
+
...mockDimensions,
|
|
54
53
|
statusBarHeight: StatusBar.currentHeight,
|
|
55
54
|
});
|
|
55
|
+
|
|
56
|
+
expect(mockGetInitialDimensions).toHaveBeenCalledWith("window");
|
|
56
57
|
});
|
|
57
58
|
|
|
58
59
|
it("calls handler on mount", () => {
|
|
@@ -69,7 +70,7 @@ describe("useDimensions", () => {
|
|
|
69
70
|
useDimensions("window", { fullDimensions: false })
|
|
70
71
|
);
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
mockUseIsScreenActive.mockReturnValue(false);
|
|
73
74
|
rerender();
|
|
74
75
|
|
|
75
76
|
expect(Dimensions.addEventListener).toHaveBeenCalledWith(
|
|
@@ -83,7 +84,8 @@ describe("useDimensions", () => {
|
|
|
83
84
|
useDimensions("window", { fullDimensions: true })
|
|
84
85
|
);
|
|
85
86
|
|
|
86
|
-
expect(result.current).
|
|
87
|
+
expect(result.current).toEqual({
|
|
88
|
+
...mockDimensions,
|
|
87
89
|
scale: 1,
|
|
88
90
|
fontScale: 1,
|
|
89
91
|
statusBarHeight: StatusBar.currentHeight,
|
|
@@ -96,7 +98,7 @@ describe("useDimensions", () => {
|
|
|
96
98
|
);
|
|
97
99
|
|
|
98
100
|
expect(result.current.height).toBe(
|
|
99
|
-
mockDimensions.height -
|
|
101
|
+
mockDimensions.height - StatusBar.currentHeight ?? 0
|
|
100
102
|
);
|
|
101
103
|
});
|
|
102
104
|
|
|
@@ -10,7 +10,7 @@ import { isTV } from "../../../reactUtils";
|
|
|
10
10
|
import { Options, UseDimensions } from "../types";
|
|
11
11
|
import { getDeviceInfo } from "../getDeviceInfo";
|
|
12
12
|
import { getInitialDimensions } from "./helpers";
|
|
13
|
-
import { useIsScreenActive } from "../../navigation
|
|
13
|
+
import { useIsScreenActive } from "../../navigation";
|
|
14
14
|
|
|
15
15
|
function compensateForScaleIfNeeded(context) {
|
|
16
16
|
return function () {
|
|
@@ -24,6 +24,8 @@ const applyScaleToDimensions = R.unless(R.propEq("scale", 1), (dimensions) => ({
|
|
|
24
24
|
scale: 1,
|
|
25
25
|
}));
|
|
26
26
|
|
|
27
|
+
const statusBarHeight = StatusBar?.currentHeight;
|
|
28
|
+
|
|
27
29
|
/**
|
|
28
30
|
* Returns React-native Dimensions object and updates it on any dimension change
|
|
29
31
|
* @param {('screen'|'window')} [context=window] - Dimensions context passed to Dimensions.get method
|
|
@@ -35,7 +37,6 @@ export const useDimensions: UseDimensions = (
|
|
|
35
37
|
context = "window",
|
|
36
38
|
fullDimensions = { fullDimensions: false, updateForInactiveScreens: true }
|
|
37
39
|
) => {
|
|
38
|
-
const statusBarHeight = StatusBar?.currentHeight;
|
|
39
40
|
const isActive = useIsScreenActive();
|
|
40
41
|
const { appData } = usePickFromState(["appData"]);
|
|
41
42
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-redeclare */
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
selectLayoutVersion,
|
|
5
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
2
|
+
import { useSelector } from "react-redux";
|
|
3
|
+
import * as R from "ramda";
|
|
6
4
|
|
|
7
5
|
export function useLayoutVersion(): ZappLayoutVersions;
|
|
8
6
|
|
|
@@ -25,7 +23,9 @@ export function useLayoutVersion({
|
|
|
25
23
|
isV2?: boolean;
|
|
26
24
|
isV1?: boolean;
|
|
27
25
|
} = {}): boolean | ZappLayoutVersions {
|
|
28
|
-
const layoutVersion =
|
|
26
|
+
const layoutVersion = useSelector<any, ZappLayoutVersions>(
|
|
27
|
+
R.path(["appData", "layoutVersion"])
|
|
28
|
+
);
|
|
29
29
|
|
|
30
30
|
if (isV2) {
|
|
31
31
|
return layoutVersion === "v2";
|
|
@@ -14,7 +14,7 @@ import { HOOKS_EVENTS } from "../../appUtils/HooksManager/constants";
|
|
|
14
14
|
import { getRiverFromRoute, getTargetRoute } from "../../navigationUtils";
|
|
15
15
|
import { useConnectionInfo } from "../connection";
|
|
16
16
|
|
|
17
|
-
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
17
|
+
import { isTV, isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
18
18
|
import { useNavbarState } from "../screen";
|
|
19
19
|
|
|
20
20
|
export { useNavigation } from "./useNavigation";
|
|
@@ -127,10 +127,14 @@ export function isNavBarVisible(
|
|
|
127
127
|
|
|
128
128
|
export const useBackHandler = (cb: () => boolean) => {
|
|
129
129
|
useEffect(() => {
|
|
130
|
-
|
|
130
|
+
if (!isWeb()) {
|
|
131
|
+
BackHandler.addEventListener("hardwareBackPress", cb);
|
|
132
|
+
}
|
|
131
133
|
|
|
132
134
|
return () => {
|
|
133
|
-
|
|
135
|
+
if (!isWeb()) {
|
|
136
|
+
BackHandler.removeEventListener("hardwareBackPress", cb);
|
|
137
|
+
}
|
|
134
138
|
};
|
|
135
139
|
}, [cb]);
|
|
136
140
|
};
|
|
@@ -14,10 +14,6 @@ jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
|
|
|
14
14
|
|
|
15
15
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
|
|
16
16
|
|
|
17
|
-
jest.mock(
|
|
18
|
-
"@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation"
|
|
19
|
-
);
|
|
20
|
-
|
|
21
17
|
const { useCellResolver } = require("../useCellResolver");
|
|
22
18
|
|
|
23
19
|
describe("cellResolver", () => {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useAppSelector,
|
|
3
|
-
selectRivers,
|
|
4
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
1
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const riversSelector = ["rivers"];
|
|
4
|
+
|
|
5
|
+
export const useRivers = () => {
|
|
6
|
+
const { rivers } = usePickFromState(riversSelector as any);
|
|
7
|
+
|
|
8
|
+
return rivers;
|
|
9
|
+
};
|