@applicaster/zapp-react-native-ui-components 13.0.0-alpha.8532113155 → 13.0.0-alpha.9103242840
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Components/BaseFocusable/index.ios.ts +1 -1
- package/Components/BaseFocusable/index.tsx +1 -1
- package/Components/Cell/Cell.tsx +4 -7
- package/Components/Cell/CellWithFocusable.tsx +59 -43
- package/Components/Cell/TvOSCellComponent.tsx +20 -22
- package/Components/Cell/__tests__/CellWIthFocusable.test.js +6 -13
- package/Components/Cell/index.js +3 -1
- package/Components/Focusable/FocusableTvOS.tsx +5 -1
- package/Components/Focusable/Touchable.tsx +20 -19
- package/Components/FocusableList/index.tsx +26 -9
- package/Components/FocusableScrollView/index.tsx +39 -12
- package/Components/Layout/TV/NavBarContainer.tsx +8 -7
- package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +1 -1
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +1 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -4
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -5
- package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
- package/Components/MasterCell/utils/index.ts +1 -1
- package/Components/ModalComponent/Header/index.tsx +3 -3
- package/Components/River/ComponentsMap/ComponentsMap.tsx +65 -39
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +51 -78
- package/Components/River/RiverFooter.tsx +9 -39
- package/Components/River/RiverItem.tsx +2 -37
- package/Components/River/TV/index.tsx +6 -1
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +31 -100
- package/Components/River/__tests__/componentsMap.test.js +5 -17
- package/Components/Screen/index.tsx +39 -13
- package/Components/Tabs/Tab.tsx +6 -6
- package/Components/TextInputTv/index.tsx +2 -2
- package/Components/Transitioner/AnimationManager.js +8 -8
- package/Components/Transitioner/Scene.tsx +23 -52
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +43 -59
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
- package/Components/Transitioner/index.js +4 -8
- package/Components/VideoLive/LiveImageManager.ts +1 -27
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +21 -29
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +1 -51
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -0
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +6 -7
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +3 -2
- package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
- package/Components/VideoModal/PlayerWrapper.tsx +35 -16
- package/Components/VideoModal/VideoModal.tsx +23 -14
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +90 -0
- package/Components/VideoModal/hooks/utils/index.ts +0 -33
- package/Components/VideoModal/utils.ts +1 -1
- package/Contexts/ComponentsMapOffsetContext/index.tsx +46 -0
- package/Contexts/ScreenContext/index.tsx +2 -3
- package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
- package/Decorators/ZappPipesDataConnector/index.tsx +1 -31
- package/package.json +5 -5
- package/Components/Cell/CellWithFocusable.ios.tsx +0 -126
- package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +0 -66
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +0 -93
- package/Components/Screen/hooks.ts +0 -56
- package/Components/VideoModal/OpaqueLayer.tsx +0 -33
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +0 -89
- package/Components/VideoModal/hooks/index.ts +0 -7
- package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +0 -49
- package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +0 -91
|
@@ -99,9 +99,8 @@ export function ScreenContextProvider({
|
|
|
99
99
|
const isNested = useNestedNavigationContext();
|
|
100
100
|
const currentScreenScreenData = useCurrentScreenData();
|
|
101
101
|
|
|
102
|
-
const screenNavBarStateRef =
|
|
103
|
-
null
|
|
104
|
-
);
|
|
102
|
+
const screenNavBarStateRef =
|
|
103
|
+
useRef<null | ReturnType<typeof createStore>>(null);
|
|
105
104
|
|
|
106
105
|
const getScreenNavBarState = useCallback(() => {
|
|
107
106
|
if (screenNavBarStateRef.current !== null) {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
/// <reference types="@applicaster/zapp-react-native-ui-components" />
|
|
3
3
|
import React, { useEffect, useMemo } from "react";
|
|
4
|
-
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
|
|
5
|
-
|
|
6
4
|
import * as R from "ramda";
|
|
7
5
|
import { Platform } from "react-native";
|
|
8
6
|
import Url from "url";
|
|
9
|
-
|
|
7
|
+
|
|
10
8
|
import { favoritesListener } from "@applicaster/zapp-react-native-bridge/Favorites";
|
|
11
9
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
12
10
|
import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
@@ -21,12 +19,6 @@ import { ZappPipesSearchContext } from "@applicaster/zapp-react-native-ui-compon
|
|
|
21
19
|
import { useScreenContext } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
|
|
22
20
|
|
|
23
21
|
import { isVerticalListOrGrid } from "./utils";
|
|
24
|
-
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
25
|
-
import {
|
|
26
|
-
findEndpointForURL,
|
|
27
|
-
HTTP_METHODS,
|
|
28
|
-
} from "@applicaster/zapp-pipes-v2-client";
|
|
29
|
-
import { getNamespaceAndKey } from "@applicaster/zapp-react-native-utils/appUtils/contextKeysManager/utils";
|
|
30
22
|
|
|
31
23
|
type Props = {
|
|
32
24
|
component: ZappUIComponent;
|
|
@@ -299,28 +291,6 @@ export function zappPipesDataConnector(
|
|
|
299
291
|
if (addListener) {
|
|
300
292
|
return addListener(reloadData);
|
|
301
293
|
}
|
|
302
|
-
} else {
|
|
303
|
-
const pipesEndpoints = appStore.get("pipesEndpoints");
|
|
304
|
-
|
|
305
|
-
const endpointURL = findEndpointForURL(
|
|
306
|
-
dataSourceUrl,
|
|
307
|
-
pipesEndpoints,
|
|
308
|
-
HTTP_METHODS.GET
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
const endpoint = pipesEndpoints?.[endpointURL];
|
|
312
|
-
|
|
313
|
-
if (endpoint?.tags?.includes(ENDPOINT_TAGS.observe_storage)) {
|
|
314
|
-
const subscriptions: (() => void)[] = endpoint.context_obj.map(
|
|
315
|
-
(data: Record<string, any>) => {
|
|
316
|
-
const { namespace, key } = getNamespaceAndKey(data.key);
|
|
317
|
-
|
|
318
|
-
return localStorage.addListener({ key, namespace }, reloadData);
|
|
319
|
-
}
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
return () => subscriptions.forEach((listener) => listener());
|
|
323
|
-
}
|
|
324
294
|
}
|
|
325
295
|
}, [dataSourceUrl, reloadData]);
|
|
326
296
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
3
|
+
"version": "13.0.0-alpha.9103242840",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"redux-mock-store": "^1.5.3"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@applicaster/applicaster-types": "13.0.0-alpha.
|
|
38
|
-
"@applicaster/zapp-react-native-bridge": "13.0.0-alpha.
|
|
39
|
-
"@applicaster/zapp-react-native-redux": "13.0.0-alpha.
|
|
40
|
-
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.
|
|
37
|
+
"@applicaster/applicaster-types": "13.0.0-alpha.9103242840",
|
|
38
|
+
"@applicaster/zapp-react-native-bridge": "13.0.0-alpha.9103242840",
|
|
39
|
+
"@applicaster/zapp-react-native-redux": "13.0.0-alpha.9103242840",
|
|
40
|
+
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.9103242840",
|
|
41
41
|
"promise": "^8.3.0",
|
|
42
42
|
"react-router-native": "^5.1.2",
|
|
43
43
|
"url": "^0.11.0",
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/** TODO: Remove this file when tvos FocusableGroup
|
|
2
|
-
* behaviour is aligned to the web one
|
|
3
|
-
* FocusableGroup should only send onFocus and onBlur events when
|
|
4
|
-
* Focus enters and leaves the Focusables inside the branch
|
|
5
|
-
*/
|
|
6
|
-
import * as React from "react";
|
|
7
|
-
|
|
8
|
-
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
9
|
-
import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events";
|
|
10
|
-
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
11
|
-
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
12
|
-
|
|
13
|
-
import { isAppleTV } from "../../Helpers/Platform";
|
|
14
|
-
import { useCellState } from "../MasterCell/utils";
|
|
15
|
-
|
|
16
|
-
const useCellFocusedState = (
|
|
17
|
-
skipFocusManagerRegistration: boolean,
|
|
18
|
-
groupId: string,
|
|
19
|
-
id: string
|
|
20
|
-
) => {
|
|
21
|
-
const [currentCellFocused, setCurrentCellFocused] = React.useState(false);
|
|
22
|
-
|
|
23
|
-
React.useEffect(() => {
|
|
24
|
-
const isGroupItemFocused = () => {
|
|
25
|
-
if (!skipFocusManagerRegistration) {
|
|
26
|
-
const isFocused = focusManager.isGroupItemFocused(groupId, id);
|
|
27
|
-
setCurrentCellFocused(isFocused);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const handler = () => {
|
|
32
|
-
// tvOS hack for properly checking focus
|
|
33
|
-
if (isAppleTV()) {
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
isGroupItemFocused();
|
|
36
|
-
}, 0);
|
|
37
|
-
} else {
|
|
38
|
-
isGroupItemFocused();
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
focusManager.on(FOCUS_EVENTS.FOCUS, handler);
|
|
43
|
-
|
|
44
|
-
return () => {
|
|
45
|
-
focusManager.removeHandler(FOCUS_EVENTS.FOCUS, handler);
|
|
46
|
-
};
|
|
47
|
-
}, [groupId, skipFocusManagerRegistration]);
|
|
48
|
-
|
|
49
|
-
return currentCellFocused;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
type Props = {
|
|
53
|
-
item: ZappEntry;
|
|
54
|
-
CellRenderer: React.FunctionComponent<any>;
|
|
55
|
-
id: string;
|
|
56
|
-
groupId: string;
|
|
57
|
-
onFocus: Function;
|
|
58
|
-
index: number;
|
|
59
|
-
scrollTo: Function;
|
|
60
|
-
preferredFocus?: boolean;
|
|
61
|
-
skipFocusManagerRegistration?: boolean;
|
|
62
|
-
isFocusable?: boolean;
|
|
63
|
-
behavior: Behavior;
|
|
64
|
-
focused?: boolean;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export function CellWithFocusable(props: Props) {
|
|
68
|
-
const {
|
|
69
|
-
index,
|
|
70
|
-
item,
|
|
71
|
-
CellRenderer,
|
|
72
|
-
id,
|
|
73
|
-
groupId,
|
|
74
|
-
onFocus,
|
|
75
|
-
scrollTo = noop,
|
|
76
|
-
preferredFocus,
|
|
77
|
-
skipFocusManagerRegistration,
|
|
78
|
-
isFocusable,
|
|
79
|
-
behavior,
|
|
80
|
-
focused,
|
|
81
|
-
} = props;
|
|
82
|
-
|
|
83
|
-
const isFocused = useCellFocusedState(
|
|
84
|
-
skipFocusManagerRegistration,
|
|
85
|
-
groupId,
|
|
86
|
-
id
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
const state = useCellState({
|
|
90
|
-
id: item.id,
|
|
91
|
-
behavior,
|
|
92
|
-
focused: isFocused || toBooleanWithDefaultFalse(focused),
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
const [focusedButtonId, setFocusedButtonId] = React.useState(undefined);
|
|
96
|
-
|
|
97
|
-
// for horizontal scrolling
|
|
98
|
-
React.useEffect(() => {
|
|
99
|
-
if (focusedButtonId) {
|
|
100
|
-
scrollTo(index);
|
|
101
|
-
}
|
|
102
|
-
}, [focusedButtonId]);
|
|
103
|
-
|
|
104
|
-
const handleToggleFocus = (value) => {
|
|
105
|
-
setFocusedButtonId(value.focusedButtonId);
|
|
106
|
-
|
|
107
|
-
if (value.focusable) {
|
|
108
|
-
onFocus(value.focusable, value.mouse);
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<CellRenderer
|
|
114
|
-
item={item}
|
|
115
|
-
groupId={groupId}
|
|
116
|
-
onToggleFocus={handleToggleFocus}
|
|
117
|
-
state={state}
|
|
118
|
-
prefixId={id}
|
|
119
|
-
focusedButtonId={focusedButtonId}
|
|
120
|
-
preferredFocus={preferredFocus}
|
|
121
|
-
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
122
|
-
isFocusable={isFocusable}
|
|
123
|
-
focused={focused}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}
|
package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BorderContainerView,
|
|
3
|
-
getBorderPadding, // Export for testing (using a double underscore prefix is a common convention)
|
|
4
|
-
} from "../index";
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
import { render } from "@testing-library/react-native";
|
|
7
|
-
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
8
|
-
import { View } from "react-native";
|
|
9
|
-
|
|
10
|
-
jest.mock("@applicaster/zapp-react-native-utils/numberUtils", () => ({
|
|
11
|
-
toNumberWithDefaultZero: jest.fn((value) => Number(value) || 0),
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
describe("BorderContainerView", () => {
|
|
15
|
-
describe("getBorderPadding", () => {
|
|
16
|
-
it("returns 0 for inside", () => {
|
|
17
|
-
expect(getBorderPadding("inside", 10)).toBe(0);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("returns borderWidth / 2 for center", () => {
|
|
21
|
-
expect(getBorderPadding("center", 10)).toBe(5);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("returns borderWidth for outside", () => {
|
|
25
|
-
expect(getBorderPadding("outside", 10)).toBe(10);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("returns borderWidth for invalid position", () => {
|
|
29
|
-
// @ts-ignore
|
|
30
|
-
expect(getBorderPadding("other_value", 10)).toBe(10);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("Border component renders null if no borderPosition", () => {
|
|
35
|
-
const style = { borderWidth: 5, borderRadius: 10, borderColor: "red" };
|
|
36
|
-
|
|
37
|
-
const padding = {
|
|
38
|
-
paddingTop: 2,
|
|
39
|
-
paddingRight: 3,
|
|
40
|
-
paddingBottom: 4,
|
|
41
|
-
paddingLeft: 5,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const borderPosition = null;
|
|
45
|
-
|
|
46
|
-
const { queryByTestId } = render(
|
|
47
|
-
<BorderContainerView
|
|
48
|
-
style={style}
|
|
49
|
-
testID="border-container"
|
|
50
|
-
borderPosition={borderPosition}
|
|
51
|
-
borderPaddingTop={toNumberWithDefaultZero(padding.paddingTop)}
|
|
52
|
-
borderPaddingRight={toNumberWithDefaultZero(padding.paddingRight)}
|
|
53
|
-
borderPaddingBottom={toNumberWithDefaultZero(padding.paddingBottom)}
|
|
54
|
-
borderPaddingLeft={toNumberWithDefaultZero(padding.paddingLeft)}
|
|
55
|
-
>
|
|
56
|
-
<View testID="child" />
|
|
57
|
-
</BorderContainerView>
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const children = queryByTestId("border-container").children;
|
|
61
|
-
|
|
62
|
-
expect(children[1].props.testID).toBe("child");
|
|
63
|
-
|
|
64
|
-
expect(children[0].children.length).toBe(0);
|
|
65
|
-
});
|
|
66
|
-
});
|
package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { ImageBorderContainer } from "../index";
|
|
2
|
-
import { getImageContainerMarginStyles } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
3
|
-
|
|
4
|
-
const mockValue = (key) => {
|
|
5
|
-
const values = {
|
|
6
|
-
cell_padding_top: 1,
|
|
7
|
-
cell_padding_left: 2,
|
|
8
|
-
cell_padding_right: 3,
|
|
9
|
-
cell_padding_bottom: 4,
|
|
10
|
-
image_border_size: 5,
|
|
11
|
-
image_focused_border_color: "red",
|
|
12
|
-
image_selected_border_color: "blue",
|
|
13
|
-
image_focused_selected_border_color: "green",
|
|
14
|
-
image_border_color: "black",
|
|
15
|
-
image_corner_radius: 10,
|
|
16
|
-
image_border_position: "outside",
|
|
17
|
-
image_border_padding_top: 6,
|
|
18
|
-
image_border_padding_right: 7,
|
|
19
|
-
image_border_padding_bottom: 8,
|
|
20
|
-
image_border_padding_left: 9,
|
|
21
|
-
image_margin_top: 11,
|
|
22
|
-
image_margin_left: 12,
|
|
23
|
-
image_margin_right: 13,
|
|
24
|
-
image_margin_bottom: 14,
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
return values[key] || 0;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
describe("ImageBorderContainer", () => {
|
|
31
|
-
it("calculates style properties correctly", () => {
|
|
32
|
-
const marginStyles = getImageContainerMarginStyles({ value: mockValue });
|
|
33
|
-
|
|
34
|
-
expect(marginStyles.marginTop).toBe(11);
|
|
35
|
-
expect(marginStyles.marginLeft).toBe(12);
|
|
36
|
-
expect(marginStyles.marginRight).toBe(13);
|
|
37
|
-
expect(marginStyles.marginBottom).toBe(14);
|
|
38
|
-
|
|
39
|
-
const props = {
|
|
40
|
-
value: mockValue,
|
|
41
|
-
state: "default",
|
|
42
|
-
imageStyles: {},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const result = ImageBorderContainer(props);
|
|
46
|
-
|
|
47
|
-
expect(result.style.marginTop).toBe(12); // 11 + 1
|
|
48
|
-
expect(result.style.marginLeft).toBe(14); // 12 + 2
|
|
49
|
-
expect(result.style.marginRight).toBe(16); // 13 + 3
|
|
50
|
-
expect(result.style.marginBottom).toBe(18); // 14 + 4
|
|
51
|
-
expect(result.style.borderWidth).toBe(5);
|
|
52
|
-
expect(result.style.borderColor).toBe("black");
|
|
53
|
-
expect(result.style.borderRadius).toBe(10);
|
|
54
|
-
expect(result.additionalProps.borderPosition).toBe("outside");
|
|
55
|
-
expect(result.additionalProps.borderPaddingTop).toBe(6);
|
|
56
|
-
expect(result.additionalProps.borderPaddingRight).toBe(7);
|
|
57
|
-
expect(result.additionalProps.borderPaddingBottom).toBe(8);
|
|
58
|
-
expect(result.additionalProps.borderPaddingLeft).toBe(9);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("handles focused state correctly", () => {
|
|
62
|
-
const props = {
|
|
63
|
-
value: mockValue,
|
|
64
|
-
state: "focused",
|
|
65
|
-
imageStyles: {},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const result = ImageBorderContainer(props);
|
|
69
|
-
expect(result.style.borderColor).toBe("red");
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("handles selected state correctly", () => {
|
|
73
|
-
const props = {
|
|
74
|
-
value: mockValue,
|
|
75
|
-
state: "selected",
|
|
76
|
-
imageStyles: {},
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const result = ImageBorderContainer(props);
|
|
80
|
-
expect(result.style.borderColor).toBe("blue");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("handles focused and selected state correctly", () => {
|
|
84
|
-
const props = {
|
|
85
|
-
value: mockValue,
|
|
86
|
-
state: "focused_selected",
|
|
87
|
-
imageStyles: {},
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const result = ImageBorderContainer(props);
|
|
91
|
-
expect(result.style.borderColor).toBe("green");
|
|
92
|
-
});
|
|
93
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
2
|
-
import {
|
|
3
|
-
useGetScreenOrientation,
|
|
4
|
-
isOrientationCompatible,
|
|
5
|
-
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
6
|
-
import {
|
|
7
|
-
useCurrentScreenData,
|
|
8
|
-
useDimensions,
|
|
9
|
-
useRoute,
|
|
10
|
-
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
11
|
-
import { useMemo, useEffect, useState } from "react";
|
|
12
|
-
|
|
13
|
-
export const useWaitForValidOrientation = () => {
|
|
14
|
-
const {
|
|
15
|
-
width: screenWidth,
|
|
16
|
-
height,
|
|
17
|
-
deviceInfo,
|
|
18
|
-
} = useDimensions("screen", {
|
|
19
|
-
fullDimensions: true,
|
|
20
|
-
updateForInactiveScreens: false,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const currentScreenData = useCurrentScreenData();
|
|
24
|
-
|
|
25
|
-
const { screenData } = useRoute();
|
|
26
|
-
|
|
27
|
-
const [readyState, setReadyState] = useState(false);
|
|
28
|
-
|
|
29
|
-
const isTablet = deviceInfo?.isTablet;
|
|
30
|
-
|
|
31
|
-
const { appData } = usePickFromState(["appData"]);
|
|
32
|
-
const isTabletPortrait = appData?.isTabletPortrait;
|
|
33
|
-
|
|
34
|
-
const layoutData = useMemo(
|
|
35
|
-
() => ({ isTablet, isTabletPortrait, width: screenWidth, height }),
|
|
36
|
-
[isTablet, isTabletPortrait, screenWidth, height]
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const targetScreenData =
|
|
40
|
-
currentScreenData || (screenData as any)?.targetScreen || screenData;
|
|
41
|
-
|
|
42
|
-
const orientation = useGetScreenOrientation(targetScreenData);
|
|
43
|
-
|
|
44
|
-
const isReadyForDisplay = isOrientationCompatible({
|
|
45
|
-
orientation,
|
|
46
|
-
layoutData,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
if (isReadyForDisplay && !readyState) {
|
|
51
|
-
setReadyState(true);
|
|
52
|
-
}
|
|
53
|
-
}, [readyState, orientation, layoutData]);
|
|
54
|
-
|
|
55
|
-
return readyState;
|
|
56
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { StyleSheet, View } from "react-native";
|
|
3
|
-
|
|
4
|
-
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
5
|
-
|
|
6
|
-
import { Spinner } from "../Spinner";
|
|
7
|
-
|
|
8
|
-
const styles = StyleSheet.create({
|
|
9
|
-
container: {
|
|
10
|
-
...StyleSheet.absoluteFillObject,
|
|
11
|
-
alignItems: "center",
|
|
12
|
-
justifyContent: "center",
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export const OpaqueLayer = () => {
|
|
17
|
-
const theme = useTheme();
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<View
|
|
21
|
-
style={[
|
|
22
|
-
styles.container,
|
|
23
|
-
{
|
|
24
|
-
// we assume that it's non-transparent and we could show spinner always until it will be covered by player
|
|
25
|
-
// this spinner hides all content under modal
|
|
26
|
-
backgroundColor: theme?.app_background_color,
|
|
27
|
-
},
|
|
28
|
-
]}
|
|
29
|
-
>
|
|
30
|
-
<Spinner />
|
|
31
|
-
</View>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { renderHook } from "@testing-library/react-hooks";
|
|
2
|
-
import { useDelayedPlayerDetails } from "../useDelayedPlayerDetails";
|
|
3
|
-
import { withTimeout$ } from "@applicaster/zapp-react-native-utils/idleUtils";
|
|
4
|
-
import { showDetails } from "../utils";
|
|
5
|
-
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
6
|
-
|
|
7
|
-
jest.mock("@applicaster/zapp-react-native-utils/idleUtils", () => ({
|
|
8
|
-
withTimeout$: jest.fn(),
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
jest.mock("../utils", () => ({
|
|
12
|
-
showDetails: jest.fn(),
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
|
|
16
|
-
useIsTablet: jest.fn(),
|
|
17
|
-
}));
|
|
18
|
-
|
|
19
|
-
describe("useDelayedPlayerDetails", () => {
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
jest.clearAllMocks();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("should return false initially", () => {
|
|
25
|
-
(withTimeout$ as jest.Mock).mockReturnValue({
|
|
26
|
-
subscribe: jest.fn().mockReturnValue({ unsubscribe: jest.fn() }),
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const { result } = renderHook(() =>
|
|
30
|
-
useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
expect(result.current).toBe(false);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("should return true if showDetails returns true", () => {
|
|
37
|
-
(withTimeout$ as jest.Mock).mockReturnValue({
|
|
38
|
-
subscribe: (callback) => {
|
|
39
|
-
callback.next();
|
|
40
|
-
|
|
41
|
-
return { unsubscribe: jest.fn() };
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
(showDetails as jest.Mock).mockReturnValue(true);
|
|
46
|
-
(useIsTablet as jest.Mock).mockReturnValue(false);
|
|
47
|
-
|
|
48
|
-
const { result } = renderHook(() =>
|
|
49
|
-
useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
expect(result.current).toBe(true);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should return false if showDetails returns false", () => {
|
|
56
|
-
(withTimeout$ as jest.Mock).mockReturnValue({
|
|
57
|
-
subscribe: (callback) => {
|
|
58
|
-
callback.next();
|
|
59
|
-
|
|
60
|
-
return { unsubscribe: jest.fn() };
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
(showDetails as jest.Mock).mockReturnValue(false);
|
|
65
|
-
(useIsTablet as jest.Mock).mockReturnValue(false);
|
|
66
|
-
|
|
67
|
-
const { result } = renderHook(() =>
|
|
68
|
-
useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
expect(result.current).toBe(false);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("should unsubscribe on unmount", () => {
|
|
75
|
-
const unsubscribeMock = jest.fn();
|
|
76
|
-
|
|
77
|
-
(withTimeout$ as jest.Mock).mockReturnValue({
|
|
78
|
-
subscribe: jest.fn().mockReturnValue({ unsubscribe: unsubscribeMock }),
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const { unmount } = renderHook(() =>
|
|
82
|
-
useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
unmount();
|
|
86
|
-
|
|
87
|
-
expect(unsubscribeMock).toHaveBeenCalled();
|
|
88
|
-
});
|
|
89
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
3
|
-
import { withTimeout$ } from "@applicaster/zapp-react-native-utils/idleUtils";
|
|
4
|
-
|
|
5
|
-
import { showDetails } from "./utils";
|
|
6
|
-
|
|
7
|
-
const TIMEOUT = 100; // ms
|
|
8
|
-
|
|
9
|
-
type Props = { isInline: boolean; isDocked: boolean; isPip: boolean };
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Custom hook to determine whether to show player details with a delay.
|
|
13
|
-
*
|
|
14
|
-
* @param {Object} params - The parameters object.
|
|
15
|
-
* @param {boolean} params.isInline - Indicates if the player is inline.
|
|
16
|
-
* @param {boolean} params.isDocked - Indicates if the player is docked.
|
|
17
|
-
* @param {boolean} params.isPip - Indicates if the player is in PIP mode.
|
|
18
|
-
* @returns {boolean} - Returns true if player details should be shown, otherwise false.
|
|
19
|
-
*/
|
|
20
|
-
export const useDelayedPlayerDetails = ({
|
|
21
|
-
isInline,
|
|
22
|
-
isDocked,
|
|
23
|
-
isPip,
|
|
24
|
-
}: Props): boolean => {
|
|
25
|
-
const [shouldShowDetails, setShouldShowDetails] = React.useState(false);
|
|
26
|
-
|
|
27
|
-
const isTablet = useIsTablet();
|
|
28
|
-
|
|
29
|
-
React.useEffect(() => {
|
|
30
|
-
const subscription = withTimeout$(TIMEOUT).subscribe({
|
|
31
|
-
next: () => {
|
|
32
|
-
setShouldShowDetails(() => {
|
|
33
|
-
return showDetails({
|
|
34
|
-
isMobile: !isTablet,
|
|
35
|
-
isInline,
|
|
36
|
-
isDocked,
|
|
37
|
-
isPip,
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
return () => {
|
|
44
|
-
subscription.unsubscribe();
|
|
45
|
-
};
|
|
46
|
-
}, [isDocked, isTablet, isInline, isPip]);
|
|
47
|
-
|
|
48
|
-
return shouldShowDetails;
|
|
49
|
-
};
|