@applicaster/zapp-react-native-utils 12.0.0-alpha.7725319213 → 12.0.0-alpha.8121552272
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 +16 -8
- package/analyticsUtils/__tests__/analyticsManager.test.js +75 -73
- package/analyticsUtils/helpers/hooks.ts +1 -1
- package/appUtils/HooksManager/index.js +3 -1
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +12 -3
- package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +1 -1
- package/appUtils/keyCodes/__tests__/keyCodes.test.js +80 -85
- package/appUtils/keyCodes/keys.web.js +1 -0
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +53 -0
- package/appUtils/playerManager/conts.ts +5 -0
- package/appUtils/playerManager/player.ts +47 -6
- package/appUtils/playerManager/playerFactory.ts +12 -10
- package/appUtils/playerManager/playerNative.ts +28 -0
- package/appUtils/playerManager/usePlayerState.tsx +13 -1
- package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +50 -0
- package/cellUtils/__tests__/cellUtils.test.ts +59 -0
- package/cellUtils/__tests__/fixtures.ts +13 -0
- package/cellUtils/index.ts +33 -2
- package/focusManager/index.ts +1 -1
- package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +2 -2
- package/functionUtils/__tests__/functionUtils.test.js +244 -248
- package/localizationUtils/__tests__/localizationUtils.test.ts +17 -13
- package/localizationUtils/index.ts +6 -3
- package/logger/index.ts +1 -1
- package/manifestUtils/defaultManifestConfigurations/generalContent.js +6 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +10 -1
- package/manifestUtils/index.js +5 -1
- package/manifestUtils/secondaryImage/index.js +18 -15
- package/modalState/index.ts +57 -0
- package/navigationUtils/index.ts +56 -7
- package/package.json +3 -2
- package/playerUtils/configurationGenerator.ts +11 -1
- package/pluginUtils/index.ts +2 -2
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +2 -0
- package/reactHooks/autoscrolling/__tests__/{useTrackedView.test.ts → useTrackedView.test.tsx} +18 -1
- package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -9
- package/reactHooks/index.ts +2 -0
- package/reactHooks/layout/__tests__/{index.test.js → index.test.tsx} +66 -59
- package/reactHooks/layout/getDeviceInfo/index.ts +4 -2
- package/reactHooks/layout/types/index.ts +2 -0
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +11 -16
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +12 -14
- package/reactHooks/layout/useDimensions/useDimensions.ts +13 -7
- package/reactHooks/navigation/__mocks__/index.ts +2 -0
- package/reactHooks/navigation/__mocks__/useNavigation.ts +4 -0
- package/reactHooks/navigation/__tests__/index.test.tsx +234 -78
- package/reactHooks/navigation/index.ts +251 -85
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +3 -1
- package/reactHooks/screen/__mocks__/useScreenContext.ts +3 -1
- package/reactHooks/screen/index.ts +2 -0
- package/reactHooks/screen/useScreenContext.ts +1 -1
- package/reactHooks/screen/useScreenData.ts +1 -1
- package/reactHooks/state/useRivers.ts +3 -1
- package/reactHooks/useListenEventBusEvent.ts +1 -4
- package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +10 -9
- package/riverComponetsMeasurementProvider/index.tsx +2 -2
- package/screenState/index.ts +8 -0
- package/testUtils/index.tsx +15 -2
|
@@ -41,6 +41,14 @@ function getPlayerConfiguration({ platform }) {
|
|
|
41
41
|
label_tooltip:
|
|
42
42
|
"Enable if you want to have adaptive background gradient based on audio background image.",
|
|
43
43
|
},
|
|
44
|
+
{
|
|
45
|
+
key: "audio_player_background_image_query",
|
|
46
|
+
label: "Audio Player Image Query",
|
|
47
|
+
initial_value: "",
|
|
48
|
+
type: "text_input",
|
|
49
|
+
label_tooltip:
|
|
50
|
+
"Set the query params which control the size of the image e.g width, height. This will help to optimize the loading time, when magic background is enabled.",
|
|
51
|
+
},
|
|
44
52
|
],
|
|
45
53
|
};
|
|
46
54
|
|
|
@@ -1655,7 +1663,8 @@ function getPlayerConfiguration({ platform }) {
|
|
|
1655
1663
|
platform.includes("lg") ||
|
|
1656
1664
|
platform.includes("samsung") ||
|
|
1657
1665
|
platform.includes("android_tv") ||
|
|
1658
|
-
platform.includes("amazon")
|
|
1666
|
+
platform.includes("amazon") ||
|
|
1667
|
+
platform.includes("vizio")
|
|
1659
1668
|
) {
|
|
1660
1669
|
styles.fields.push(
|
|
1661
1670
|
// Captions Menu
|
package/manifestUtils/index.js
CHANGED
|
@@ -22,7 +22,11 @@ const {
|
|
|
22
22
|
const { buttonKey } = require("./buttons");
|
|
23
23
|
const { tvBadges } = require("./tvBadges");
|
|
24
24
|
const { mobileProgressBar, tvProgressBar } = require("./progressBar");
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
secondaryImage,
|
|
28
|
+
getUpdatedSecondaryImageKeys,
|
|
29
|
+
} = require("./secondaryImage");
|
|
26
30
|
|
|
27
31
|
module.exports = {
|
|
28
32
|
fontKey,
|
|
@@ -132,29 +132,32 @@ function secondaryImage({
|
|
|
132
132
|
|
|
133
133
|
const POSITION_OVER_IMAGE = toSnakeCase(position_over_image);
|
|
134
134
|
|
|
135
|
-
const getUpdatedSecondaryImageKeys = (secondaryImageManifest) =>
|
|
136
|
-
|
|
135
|
+
const getUpdatedSecondaryImageKeys = (secondaryImageManifest) =>
|
|
136
|
+
secondaryImageManifest.fields.reduce((acc, item) => {
|
|
137
|
+
const key = item.key;
|
|
137
138
|
|
|
138
|
-
|
|
139
|
+
const conditionalFields = (item.conditional_fields || []).map(
|
|
140
|
+
(field) => field.key
|
|
141
|
+
);
|
|
139
142
|
|
|
140
|
-
|
|
141
|
-
|
|
143
|
+
const updatedConditionalFields = conditionalFields.reduce((acc, field) => {
|
|
144
|
+
const updatedKey = field.replace("secondary_image_", "nested_image_");
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
...acc,
|
|
148
|
+
[updatedKey]: field,
|
|
149
|
+
};
|
|
150
|
+
}, {});
|
|
151
|
+
|
|
152
|
+
const updatedKey = key.replace("secondary_image_", "nested_image_");
|
|
142
153
|
|
|
143
154
|
return {
|
|
144
155
|
...acc,
|
|
145
|
-
|
|
156
|
+
...updatedConditionalFields,
|
|
157
|
+
[updatedKey]: key,
|
|
146
158
|
};
|
|
147
159
|
}, {});
|
|
148
160
|
|
|
149
|
-
const updatedKey = key.replace("secondary_image_", "nested_image_");
|
|
150
|
-
|
|
151
|
-
return {
|
|
152
|
-
...acc,
|
|
153
|
-
...updatedConditionalFields,
|
|
154
|
-
[updatedKey]: key,
|
|
155
|
-
};
|
|
156
|
-
}, {});
|
|
157
|
-
|
|
158
161
|
module.exports = {
|
|
159
162
|
secondaryImage,
|
|
160
163
|
getUpdatedSecondaryImageKeys,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { create } from "zustand";
|
|
2
|
+
|
|
3
|
+
interface ModalState {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
screen: any;
|
|
6
|
+
options: Record<string, unknown>;
|
|
7
|
+
props: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface ModalStore {
|
|
11
|
+
modalState: ModalState;
|
|
12
|
+
setModalState: (newState: Partial<ModalState>) => void;
|
|
13
|
+
openModal: (
|
|
14
|
+
item: any,
|
|
15
|
+
options?: Record<string, unknown>,
|
|
16
|
+
props?: Record<string, unknown>
|
|
17
|
+
) => void;
|
|
18
|
+
dismissModal: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const initialModalState: ModalState = {
|
|
22
|
+
visible: false,
|
|
23
|
+
screen: null,
|
|
24
|
+
options: {},
|
|
25
|
+
props: {},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const useModalStore = create<ModalStore>((set) => ({
|
|
29
|
+
modalState: initialModalState,
|
|
30
|
+
setModalState: (newState) =>
|
|
31
|
+
set((state) => ({
|
|
32
|
+
modalState: { ...state.modalState, ...newState },
|
|
33
|
+
})),
|
|
34
|
+
openModal: ({
|
|
35
|
+
item,
|
|
36
|
+
options = {},
|
|
37
|
+
props = { screenData: {} },
|
|
38
|
+
}: OpenModalArg) =>
|
|
39
|
+
set({
|
|
40
|
+
modalState: {
|
|
41
|
+
visible: true,
|
|
42
|
+
screen: item,
|
|
43
|
+
options: {
|
|
44
|
+
animated: true,
|
|
45
|
+
animationType: "slide",
|
|
46
|
+
onShow: () => {},
|
|
47
|
+
presentationStyle: "overFullScreen",
|
|
48
|
+
transparent: true,
|
|
49
|
+
...options,
|
|
50
|
+
onDismiss: () => set({ modalState: initialModalState }),
|
|
51
|
+
onRequestClose: () => set({ modalState: initialModalState }),
|
|
52
|
+
},
|
|
53
|
+
props,
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
dismissModal: () => set(() => ({ modalState: initialModalState })),
|
|
57
|
+
}));
|
package/navigationUtils/index.ts
CHANGED
|
@@ -93,19 +93,68 @@ export function resolveNavigationPlugin({
|
|
|
93
93
|
* @param {Object} navigator to look for navigation props
|
|
94
94
|
* @param {String} category to look for in screen navigations
|
|
95
95
|
* @returns {Object} props
|
|
96
|
+
* @deprecated use getNavigationPropsV2 instead
|
|
96
97
|
*/
|
|
97
98
|
export function getNavigationProps({
|
|
98
|
-
navigator
|
|
99
|
+
navigator,
|
|
99
100
|
title = "",
|
|
100
101
|
category,
|
|
101
102
|
}: {
|
|
102
103
|
navigator: QuickBrickAppNavigator;
|
|
103
104
|
title: string;
|
|
104
105
|
category: string;
|
|
105
|
-
}):
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
}): {
|
|
107
|
+
selected: string;
|
|
108
|
+
title: string;
|
|
109
|
+
home: boolean;
|
|
110
|
+
styles: unknown;
|
|
111
|
+
assets: ZappNavBarAssets;
|
|
112
|
+
rules: ZappNavBarRules;
|
|
113
|
+
nav_items: NavBarItem[];
|
|
114
|
+
} | null {
|
|
115
|
+
const { activeRiver } = navigator;
|
|
116
|
+
const { navigations, id: selected, home } = activeRiver; // use useRiver hook instead
|
|
117
|
+
|
|
118
|
+
const navigation: ZappNavigation = R.find(
|
|
119
|
+
R.propEq("category", category),
|
|
120
|
+
navigations
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
if (!navigation) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const { styles, assets, nav_items, rules } = navigation;
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
selected,
|
|
131
|
+
title,
|
|
132
|
+
home,
|
|
133
|
+
styles,
|
|
134
|
+
assets: assets as ZappNavBarAssets,
|
|
135
|
+
nav_items: nav_items as any as NavBarItem[],
|
|
136
|
+
rules: rules as any as ZappNavBarRules,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function getNavigationPropsV2({
|
|
141
|
+
currentRiver,
|
|
142
|
+
title = "",
|
|
143
|
+
category,
|
|
144
|
+
}: {
|
|
145
|
+
currentRiver: ZappRiver;
|
|
146
|
+
title: string;
|
|
147
|
+
category: string;
|
|
148
|
+
}): {
|
|
149
|
+
selected: string;
|
|
150
|
+
title: string;
|
|
151
|
+
home: boolean;
|
|
152
|
+
styles: unknown;
|
|
153
|
+
assets: ZappNavBarAssets;
|
|
154
|
+
rules: ZappNavBarRules;
|
|
155
|
+
nav_items: NavBarItem[];
|
|
156
|
+
} | null {
|
|
157
|
+
const { navigations, id: selected, home } = currentRiver; // use useRiver hook instead
|
|
109
158
|
const navigation = R.find(R.propEq("category", category), navigations);
|
|
110
159
|
|
|
111
160
|
if (!navigation) {
|
|
@@ -170,7 +219,7 @@ export function getScreenIdForContentType(payload, contentTypes) {
|
|
|
170
219
|
export function getItemTargetId(
|
|
171
220
|
item: ZappEntry | ZappRiver,
|
|
172
221
|
screenType?: string, // todo: creat screen types enum
|
|
173
|
-
contentTypes?: ZappContentTypes,
|
|
222
|
+
contentTypes?: ZappContentTypes | null,
|
|
174
223
|
rivers?: Record<string, ZappRiver>
|
|
175
224
|
) {
|
|
176
225
|
// Pipes v2 resolution
|
|
@@ -217,7 +266,7 @@ export function getTargetRoute(
|
|
|
217
266
|
layoutVersion = undefined,
|
|
218
267
|
rivers = {},
|
|
219
268
|
}: {
|
|
220
|
-
contentTypes?: ZappContentTypes;
|
|
269
|
+
contentTypes?: ZappContentTypes | null;
|
|
221
270
|
layoutVersion?: Maybe<ZappLayoutVersions>;
|
|
222
271
|
rivers?: Record<string, ZappRiver>;
|
|
223
272
|
} = {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.8121552272",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "12.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "12.0.0-alpha.8121552272",
|
|
32
32
|
"buffer": "^5.2.1",
|
|
33
33
|
"camelize": "^1.0.0",
|
|
34
34
|
"create-react-context": "^0.2.3",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"immer": "*",
|
|
45
45
|
"react": "17.0.2",
|
|
46
46
|
"react-native": "0.68.6",
|
|
47
|
+
"validate-color": "*",
|
|
47
48
|
"zustand": "*"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
@@ -22,6 +22,7 @@ function getDevice(platform) {
|
|
|
22
22
|
case "android_tv_for_quickbrick":
|
|
23
23
|
case "lg_tv":
|
|
24
24
|
case "samsung_tv":
|
|
25
|
+
case "vizio":
|
|
25
26
|
case "web":
|
|
26
27
|
return "tv";
|
|
27
28
|
}
|
|
@@ -46,6 +47,14 @@ function getPlayerConfiguration({ platform }) {
|
|
|
46
47
|
label_tooltip:
|
|
47
48
|
"Enable if you want to have adaptive background gradient based on audio background image.",
|
|
48
49
|
},
|
|
50
|
+
{
|
|
51
|
+
key: "audio_player_background_image_query",
|
|
52
|
+
label: "Audio Player Image Query",
|
|
53
|
+
initial_value: "",
|
|
54
|
+
type: "text_input",
|
|
55
|
+
label_tooltip:
|
|
56
|
+
"Set the query params which control the size of the image e.g width, height. This will help to optimize the loading time, when magic background is enabled.",
|
|
57
|
+
},
|
|
49
58
|
],
|
|
50
59
|
};
|
|
51
60
|
|
|
@@ -1651,7 +1660,8 @@ function getPlayerConfiguration({ platform }) {
|
|
|
1651
1660
|
platform.includes("lg") ||
|
|
1652
1661
|
platform.includes("samsung") ||
|
|
1653
1662
|
platform.includes("android_tv") ||
|
|
1654
|
-
platform.includes("amazon")
|
|
1663
|
+
platform.includes("amazon") ||
|
|
1664
|
+
platform.includes("vizio")
|
|
1655
1665
|
) {
|
|
1656
1666
|
styles.fields.push(
|
|
1657
1667
|
// Captions Menu for TV
|
package/pluginUtils/index.ts
CHANGED
|
@@ -20,14 +20,14 @@ type Plugin = {
|
|
|
20
20
|
* returns the component module for a specific type
|
|
21
21
|
* Will look in components first, then in plugins
|
|
22
22
|
*/
|
|
23
|
-
function getComponentModule({
|
|
23
|
+
export function getComponentModule({
|
|
24
24
|
componentType,
|
|
25
25
|
components,
|
|
26
26
|
plugins,
|
|
27
27
|
}: {
|
|
28
28
|
componentType: string;
|
|
29
29
|
components: ComponentsMap;
|
|
30
|
-
plugins: Plugin[];
|
|
30
|
+
plugins: Plugin[] | QuickBrickPlugin[];
|
|
31
31
|
}) {
|
|
32
32
|
const component = R.compose(
|
|
33
33
|
R.prop(R.__, components),
|
package/reactHooks/autoscrolling/__tests__/{useTrackedView.test.ts → useTrackedView.test.tsx}
RENAMED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
1
3
|
import { act, renderHook } from "@testing-library/react-hooks";
|
|
4
|
+
import { Provider } from "react-redux";
|
|
5
|
+
import configureStore from "redux-mock-store";
|
|
2
6
|
|
|
3
7
|
const mockUpdateComponentsPositions = jest.fn();
|
|
4
8
|
|
|
@@ -17,11 +21,24 @@ jest.mock(
|
|
|
17
21
|
|
|
18
22
|
jest.useFakeTimers();
|
|
19
23
|
|
|
24
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
|
|
25
|
+
|
|
26
|
+
const mockStore = configureStore();
|
|
27
|
+
|
|
28
|
+
const store = mockStore({ appData: {} });
|
|
29
|
+
|
|
30
|
+
const Wrapper = ({ children }: { children: React.ReactChild }) => (
|
|
31
|
+
/* @ts-ignore */
|
|
32
|
+
<Provider store={store}>{children}</Provider>
|
|
33
|
+
);
|
|
34
|
+
|
|
20
35
|
const { useTrackedView } = require("../useTrackedView");
|
|
21
36
|
|
|
22
37
|
describe("useTrackCurrentAutoScrollingElement", () => {
|
|
23
38
|
it("should update position for selected component", async () => {
|
|
24
|
-
const { result } = renderHook(() => useTrackedView("123")
|
|
39
|
+
const { result } = renderHook(() => useTrackedView("123"), {
|
|
40
|
+
wrapper: Wrapper,
|
|
41
|
+
});
|
|
25
42
|
|
|
26
43
|
// Fast-forward until all timers have been executed
|
|
27
44
|
jest.advanceTimersByTime(3000);
|
|
@@ -5,27 +5,34 @@ type Return = (index: number) => void;
|
|
|
5
5
|
|
|
6
6
|
type Predicate = (
|
|
7
7
|
entry: ZappUIComponentProps["zappPipesData"]["data"]["entry"],
|
|
8
|
-
index: number
|
|
8
|
+
index: number,
|
|
9
|
+
numberOfColumns: number
|
|
9
10
|
) => boolean;
|
|
10
11
|
|
|
11
12
|
type Props = {
|
|
12
13
|
ifNeeded: Predicate;
|
|
13
14
|
loadNextData: () => void;
|
|
14
15
|
entry: ZappUIComponentProps["zappPipesData"]["data"]["entry"];
|
|
16
|
+
numberOfColumns?: number;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
const handleLoadNextPage =
|
|
18
20
|
(
|
|
19
|
-
ifNeeded: (
|
|
21
|
+
ifNeeded: (
|
|
22
|
+
entry: ZappEntry[],
|
|
23
|
+
index: number,
|
|
24
|
+
numberOfColumns?: number
|
|
25
|
+
) => boolean,
|
|
20
26
|
loadNextData: () => void,
|
|
21
|
-
entry: ZappEntry[]
|
|
27
|
+
entry: ZappEntry[],
|
|
28
|
+
numberOfColumns
|
|
22
29
|
) =>
|
|
23
30
|
(index: number) => {
|
|
24
31
|
/**
|
|
25
32
|
* Lazy-Loading, invoke nextLoadData if we reach the end of the List
|
|
26
33
|
*/
|
|
27
34
|
|
|
28
|
-
if (ifNeeded(entry, index)) {
|
|
35
|
+
if (ifNeeded(entry, index, numberOfColumns)) {
|
|
29
36
|
loadNextData();
|
|
30
37
|
}
|
|
31
38
|
};
|
|
@@ -34,10 +41,10 @@ export const useLoadNextPageIfNeeded = ({
|
|
|
34
41
|
ifNeeded,
|
|
35
42
|
loadNextData = noop,
|
|
36
43
|
entry,
|
|
44
|
+
numberOfColumns = 0,
|
|
37
45
|
}: Props): Return => {
|
|
38
|
-
return React.useCallback(
|
|
39
|
-
ifNeeded,
|
|
40
|
-
loadNextData,
|
|
41
|
-
|
|
42
|
-
]);
|
|
46
|
+
return React.useCallback(
|
|
47
|
+
handleLoadNextPage(ifNeeded, loadNextData, entry, numberOfColumns),
|
|
48
|
+
[ifNeeded, loadNextData, entry, numberOfColumns]
|
|
49
|
+
);
|
|
43
50
|
};
|
package/reactHooks/index.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
1
3
|
import { cleanup, renderHook } from "@testing-library/react-hooks";
|
|
4
|
+
import { Provider } from "react-redux";
|
|
5
|
+
import configureStore from "redux-mock-store";
|
|
6
|
+
|
|
7
|
+
import * as ReactNative from "react-native";
|
|
2
8
|
|
|
3
9
|
const mocked_return_value = (tv) => ({
|
|
4
10
|
screen: tv
|
|
@@ -10,41 +16,31 @@ const mocked_return_value = (tv) => ({
|
|
|
10
16
|
const platform = "android";
|
|
11
17
|
let tv_flag = false;
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
ReactNative.Dimensions.get = jest.fn(
|
|
20
|
+
(context) => mocked_return_value(tv_flag)[context]
|
|
21
|
+
);
|
|
16
22
|
|
|
17
23
|
const mockRemoveFn = jest.fn();
|
|
18
24
|
|
|
19
|
-
jest.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const Dims = {
|
|
23
|
-
get: jest.fn((context) => mocked_return_value(tv_flag)[context]),
|
|
24
|
-
addEventListener: jest.fn().mockReturnValue({
|
|
25
|
-
remove: mockRemoveFn,
|
|
26
|
-
}),
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const QuickBrickCommunicationModule = {
|
|
30
|
-
initialProps: {
|
|
31
|
-
is_tablet: false,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
...RNMock,
|
|
37
|
-
Dimensions: Dims,
|
|
38
|
-
Platform: {
|
|
39
|
-
OS: platform,
|
|
40
|
-
},
|
|
41
|
-
NativeModules: {
|
|
42
|
-
...RNMock.NativeModules,
|
|
43
|
-
QuickBrickCommunicationModule,
|
|
44
|
-
},
|
|
45
|
-
};
|
|
25
|
+
ReactNative.Dimensions.addEventListener = jest.fn().mockReturnValue({
|
|
26
|
+
remove: mockRemoveFn,
|
|
46
27
|
});
|
|
47
28
|
|
|
29
|
+
ReactNative.Platform.OS = platform;
|
|
30
|
+
|
|
31
|
+
const QuickBrickCommunicationModule = {
|
|
32
|
+
initialProps: {
|
|
33
|
+
is_tablet: false,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
ReactNative.NativeModules.QuickBrickCommunicationModule =
|
|
38
|
+
QuickBrickCommunicationModule;
|
|
39
|
+
|
|
40
|
+
jest.mock("react-native-safe-area-context", () => ({
|
|
41
|
+
useSafeAreaInsets: () => ({ top: 50 }),
|
|
42
|
+
}));
|
|
43
|
+
|
|
48
44
|
jest.mock("../../../reactUtils", () => ({
|
|
49
45
|
platformSelect: jest.fn((specs) => specs[platform] || specs.default),
|
|
50
46
|
isTV: jest.fn(() => tv_flag),
|
|
@@ -52,22 +48,47 @@ jest.mock("../../../reactUtils", () => ({
|
|
|
52
48
|
|
|
53
49
|
jest.mock("../../navigation", () => ({
|
|
54
50
|
useNavigation: () => null,
|
|
51
|
+
useIsScreenActive: () => true,
|
|
55
52
|
}));
|
|
56
53
|
|
|
57
54
|
const { Dimensions } = require("react-native");
|
|
58
|
-
const { useDimensions } = require("
|
|
55
|
+
const { useDimensions } = require("..");
|
|
56
|
+
|
|
57
|
+
const mockStore = configureStore();
|
|
58
|
+
|
|
59
|
+
const getWrapper = () => {
|
|
60
|
+
const store = mockStore({ appData: {} });
|
|
61
|
+
|
|
62
|
+
const Wrapper = ({ children }: { children: React.ReactChild }) => (
|
|
63
|
+
/* @ts-ignore */
|
|
64
|
+
<Provider store={store}>{children}</Provider>
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return Wrapper;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const testHook = (context, params?) => {
|
|
71
|
+
const wrapper = getWrapper();
|
|
72
|
+
|
|
73
|
+
const {
|
|
74
|
+
result,
|
|
75
|
+
result: { current: dimensions },
|
|
76
|
+
} = renderHook(() => useDimensions(context, params), {
|
|
77
|
+
wrapper,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return { result, dimensions };
|
|
81
|
+
};
|
|
59
82
|
|
|
60
83
|
describe("useDimensions", () => {
|
|
61
84
|
it("renders", () => {
|
|
62
|
-
const { result } =
|
|
63
|
-
useDimensions("window", { fullDimensions: true })
|
|
64
|
-
);
|
|
85
|
+
const { result } = testHook("window", { fullDimensions: true });
|
|
65
86
|
|
|
66
87
|
expect(result).toBeDefined();
|
|
67
88
|
});
|
|
68
89
|
|
|
69
90
|
it("sets event listener", () => {
|
|
70
|
-
|
|
91
|
+
testHook("window", { fullDimensions: true });
|
|
71
92
|
|
|
72
93
|
expect(Dimensions.addEventListener).toBeCalledWith(
|
|
73
94
|
"change",
|
|
@@ -76,16 +97,14 @@ describe("useDimensions", () => {
|
|
|
76
97
|
});
|
|
77
98
|
|
|
78
99
|
it("removes event listener", () => {
|
|
79
|
-
|
|
100
|
+
testHook("window", { fullDimensions: true });
|
|
80
101
|
cleanup();
|
|
81
102
|
|
|
82
103
|
expect(mockRemoveFn).toBeCalled();
|
|
83
104
|
});
|
|
84
105
|
|
|
85
106
|
it("Returns full dimensions object", () => {
|
|
86
|
-
const {
|
|
87
|
-
result: { current: dimensions },
|
|
88
|
-
} = renderHook(() => useDimensions("window", { fullDimensions: true }));
|
|
107
|
+
const { dimensions } = testHook("window", { fullDimensions: true });
|
|
89
108
|
|
|
90
109
|
expect(dimensions).toHaveProperty("height");
|
|
91
110
|
expect(dimensions).toHaveProperty("width");
|
|
@@ -94,20 +113,17 @@ describe("useDimensions", () => {
|
|
|
94
113
|
});
|
|
95
114
|
|
|
96
115
|
it("Returns shorthand dimensions object", () => {
|
|
97
|
-
const {
|
|
98
|
-
result: { current: dimensions },
|
|
99
|
-
} = renderHook(() => useDimensions("window"));
|
|
116
|
+
const { dimensions } = testHook("window");
|
|
100
117
|
|
|
101
118
|
expect(dimensions).toHaveProperty("height");
|
|
102
119
|
expect(dimensions).toHaveProperty("width");
|
|
103
120
|
});
|
|
104
121
|
|
|
105
122
|
it("Returns the device info object", () => {
|
|
106
|
-
const {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
);
|
|
123
|
+
const { dimensions } = testHook("window", {
|
|
124
|
+
fullDimensions: true,
|
|
125
|
+
deviceInfo: true,
|
|
126
|
+
});
|
|
111
127
|
|
|
112
128
|
expect(dimensions).toHaveProperty("height");
|
|
113
129
|
expect(dimensions).toHaveProperty("width");
|
|
@@ -120,10 +136,7 @@ describe("useDimensions", () => {
|
|
|
120
136
|
it("applies the scale on TV, and screen context", () => {
|
|
121
137
|
tv_flag = true;
|
|
122
138
|
const { screen } = mocked_return_value(tv_flag);
|
|
123
|
-
|
|
124
|
-
const {
|
|
125
|
-
result: { current: dimensions },
|
|
126
|
-
} = renderHook(() => useDimensions("screen"));
|
|
139
|
+
const { dimensions } = testHook("screen");
|
|
127
140
|
|
|
128
141
|
expect(dimensions).toHaveProperty("height", screen.height * screen.scale);
|
|
129
142
|
expect(dimensions).toHaveProperty("width", screen.width * screen.scale);
|
|
@@ -135,10 +148,7 @@ describe("useDimensions", () => {
|
|
|
135
148
|
it("doesn't apply the scale on mobile with screen context", () => {
|
|
136
149
|
tv_flag = false;
|
|
137
150
|
const { screen } = mocked_return_value(tv_flag);
|
|
138
|
-
|
|
139
|
-
const {
|
|
140
|
-
result: { current: dimensions },
|
|
141
|
-
} = renderHook(() => useDimensions("screen"));
|
|
151
|
+
const { dimensions } = testHook("screen");
|
|
142
152
|
|
|
143
153
|
expect(dimensions).toHaveProperty("height", screen.height);
|
|
144
154
|
expect(dimensions).toHaveProperty("width", screen.width);
|
|
@@ -148,10 +158,7 @@ describe("useDimensions", () => {
|
|
|
148
158
|
it("doesn't apply the scale on TV with window context", () => {
|
|
149
159
|
tv_flag = true;
|
|
150
160
|
const { window } = mocked_return_value(tv_flag);
|
|
151
|
-
|
|
152
|
-
const {
|
|
153
|
-
result: { current: dimensions },
|
|
154
|
-
} = renderHook(() => useDimensions("window"));
|
|
161
|
+
const { dimensions } = testHook("window");
|
|
155
162
|
|
|
156
163
|
expect(dimensions).toHaveProperty("height", window.height);
|
|
157
164
|
expect(dimensions).toHaveProperty("width", window.width);
|
|
@@ -3,13 +3,15 @@ import { isTablet } from "../isTablet";
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns an object with additional device info that can be used to determine if tablet
|
|
5
5
|
* @param {Number} dimensions - Dimensions object passed to the function
|
|
6
|
+
* @param {Object} appData - application data object passed to the function
|
|
6
7
|
* @returns {DeviceInfo} deviceInfo - returns an object with scale, isTablet, and orientation
|
|
7
8
|
*/
|
|
8
|
-
export const getDeviceInfo = (dimensions) => {
|
|
9
|
+
export const getDeviceInfo = (dimensions, appData) => {
|
|
9
10
|
const scale = dimensions?.scale;
|
|
10
11
|
const isLandscape = dimensions?.width > dimensions?.height;
|
|
11
12
|
const orientation = isLandscape ? "landscape" : "portrait";
|
|
12
13
|
const tablet = isTablet(dimensions, orientation) || false;
|
|
14
|
+
const isTabletLandscape = tablet && !appData?.isTabletPortrait;
|
|
13
15
|
|
|
14
|
-
return { scale, isTablet: tablet, orientation };
|
|
16
|
+
return { scale, isTablet: tablet, orientation, isTabletLandscape };
|
|
15
17
|
};
|
|
@@ -2,6 +2,7 @@ type DeviceInfo = {
|
|
|
2
2
|
isTablet: boolean;
|
|
3
3
|
scale: number;
|
|
4
4
|
orientation: string;
|
|
5
|
+
isTabletLandscape: boolean;
|
|
5
6
|
};
|
|
6
7
|
|
|
7
8
|
type RNDimensions = {
|
|
@@ -20,6 +21,7 @@ export type Options = {
|
|
|
20
21
|
excludeStatusBar?: boolean;
|
|
21
22
|
rounded?: boolean;
|
|
22
23
|
deviceInfo?: boolean;
|
|
24
|
+
updateForInactiveScreens?: boolean;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
export type Context = "window" | "screen";
|