@applicaster/zapp-react-native-ui-components 12.0.0-alpha.3977160850 → 12.0.0-alpha.4043183114
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.tsx +3 -3
- package/Components/Cell/Cell.tsx +16 -15
- package/Components/Cell/CellWithFocusable.tsx +40 -19
- package/Components/Cell/TvOSCellComponent.tsx +8 -13
- package/Components/ErrorScreen/index.tsx +1 -1
- package/Components/Focusable/Focusable.tsx +6 -1
- package/Components/FocusableCell/index.tsx +7 -7
- package/Components/FocusableGroup/index.tsx +11 -2
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +13 -6
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +1 -1
- package/Components/HandlePlayable/HandlePlayable.tsx +3 -0
- package/Components/HookRenderer/index.tsx +1 -3
- package/Components/Image/Image.android.tsx +3 -25
- package/Components/Image/Image.tsx +18 -2
- package/Components/Image/utils/index.ts +39 -0
- package/Components/Layout/TV/ScreenContainer.tsx +79 -5
- package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +2 -2
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +38 -28
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +25 -13
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +10 -10
- package/Components/Layout/TV/__tests__/index.test.tsx +20 -87
- package/Components/Layout/TV/index.tsx +14 -67
- package/Components/Layout/TV/index.web.tsx +33 -0
- package/Components/Layout/index.tsx +15 -11
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -0
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +88 -112
- package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +9 -26
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +37 -2
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +14 -2
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +24 -9
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +10 -2
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -3
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
- package/Components/MasterCell/utils/__tests__/insertBetween.test.js +9 -0
- package/Components/MasterCell/utils/index.ts +35 -37
- package/Components/MeasurmentsPortal/BasicMeasurementsPortal.tsx +11 -7
- package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +10 -1
- package/Components/NativeFocusables/{index.js → index.ts} +4 -2
- package/Components/Navigator/StackNavigator.tsx +57 -0
- package/Components/Navigator/index.ts +1 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +66 -31
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
- package/Components/PlayerImageBackground/index.tsx +34 -8
- package/Components/River/ComponentsMap/ComponentsMap.tsx +92 -22
- package/Components/River/RefreshControl.tsx +55 -1
- package/Components/River/TV/River.tsx +0 -23
- package/Components/River/__tests__/componentsMap.test.js +7 -0
- package/Components/Screen/TV/hooks/index.ts +3 -0
- package/Components/Screen/TV/hooks/useInitialFocus.ts +70 -0
- package/Components/Screen/TV/hooks/useRestoreFocus.ts +22 -0
- package/Components/Screen/TV/index.web.tsx +165 -0
- package/Components/Screen/__tests__/Screen.test.tsx +8 -1
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +14 -0
- package/Components/Screen/index.tsx +65 -48
- package/Components/Screen/navigationHandler.ts +5 -0
- package/Components/ScreenResolver/index.tsx +3 -1
- package/Components/Tabs/TV/styles.ts +1 -1
- package/Components/Transitioner/Scene.tsx +32 -26
- package/Components/Transitioner/Transitioner.tsx +21 -28
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +12 -4
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
- package/Components/VideoLive/LiveImageManager.ts +28 -1
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +31 -28
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +45 -3
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +18 -28
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +66 -0
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +355 -0
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +161 -0
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +456 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +182 -0
- package/Components/VideoModal/ModalAnimation/index.ts +15 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +302 -0
- package/Components/VideoModal/PlayerDetails.tsx +3 -3
- package/Components/VideoModal/PlayerWrapper.tsx +77 -47
- package/Components/VideoModal/VideoModal.tsx +23 -40
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +13 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +266 -166
- package/Components/VideoModal/hooks/useModalSize.ts +10 -12
- package/Components/VideoModal/utils.ts +8 -5
- package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +31 -40
- package/Components/Viewport/ViewportTracker/index.tsx +1 -0
- package/Components/Viewport/utils.js +1 -1
- package/Contexts/FocusableGroupContext/FocusableGroupContext.ts +3 -0
- package/Contexts/FocusableGroupContext/FocusableGroupContextProvider.tsx +16 -0
- package/Contexts/FocusableGroupContext/__tests__/FocusableGroupContextProvider.test.tsx +22 -0
- package/Contexts/FocusableGroupContext/__tests__/withFocusableContext.test.tsx +26 -0
- package/Contexts/FocusableGroupContext/index.ts +7 -0
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +17 -0
- package/Contexts/MenuToggleContext/{index.js → index.ts} +16 -0
- package/Contexts/ScreenContext/__tests__/__snapshots__/index.test.tsx.snap +3 -0
- package/Contexts/ScreenContext/__tests__/index.test.tsx +27 -0
- package/Contexts/ScreenContext/index.tsx +94 -25
- package/Contexts/ScreenDataContext/index.tsx +20 -0
- package/Contexts/ZappPipesContext/ZappPipesEntryContext.ts +1 -1
- package/Decorators/Analytics/{index.js → index.tsx} +11 -11
- package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
- package/README.md +1 -13
- package/events/index.ts +1 -0
- package/package.json +5 -5
- package/Components/Layout/TV/TransitionOverlay.tsx +0 -64
- package/Components/VideoModal/hooks/usePosition.ts +0 -50
- /package/Components/FocusableGroup/{index.android.js → index.android.ts} +0 -0
- /package/Components/FocusableGroup/{index.ios.js → index.ios.ts} +0 -0
- /package/Contexts/{index.js → index.ts} +0 -0
|
@@ -5,13 +5,30 @@ import * as R from "ramda";
|
|
|
5
5
|
import { ScreenLayoutContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenLayoutContext";
|
|
6
6
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
7
7
|
import { ifEmptyUseFallback } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
useCurrentScreenData,
|
|
10
|
+
useNavbarState,
|
|
11
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks/screen";
|
|
9
12
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
10
13
|
|
|
11
14
|
import { useScreenConfiguration } from "../../River/useScreenConfiguration";
|
|
12
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
findMenuPlugin,
|
|
17
|
+
getNavigationProps,
|
|
18
|
+
routeIsPlayerScreen,
|
|
19
|
+
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
20
|
+
import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
21
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
22
|
+
import { NavBarContainer } from "./NavBarContainer";
|
|
23
|
+
|
|
24
|
+
type ComponentsExtraProps = {
|
|
25
|
+
Background?: Record<string, any>;
|
|
26
|
+
NavBar?: Record<string, any>;
|
|
27
|
+
};
|
|
13
28
|
|
|
14
29
|
type Props = {
|
|
30
|
+
ComponentsExtraProps?: ComponentsExtraProps;
|
|
31
|
+
NavBar: React.ComponentType<any>;
|
|
15
32
|
children: React.ReactNode;
|
|
16
33
|
};
|
|
17
34
|
|
|
@@ -30,9 +47,13 @@ const styles = StyleSheet.create({
|
|
|
30
47
|
container: { flex: 1, height: "100%", width: "100%" },
|
|
31
48
|
});
|
|
32
49
|
|
|
50
|
+
const isTVOS = isApplePlatform();
|
|
51
|
+
|
|
33
52
|
// eslint-disable-next-line react/display-name
|
|
34
53
|
export const ScreenContainer = React.memo(function ScreenContainer({
|
|
35
54
|
children,
|
|
55
|
+
ComponentsExtraProps,
|
|
56
|
+
NavBar,
|
|
36
57
|
}: Props) {
|
|
37
58
|
const { screenMarginBottom } = React.useContext(ScreenLayoutContext);
|
|
38
59
|
const { currentRoute, screenData } = useNavigation();
|
|
@@ -80,9 +101,62 @@ export const ScreenContainer = React.memo(function ScreenContainer({
|
|
|
80
101
|
[themeStyles]
|
|
81
102
|
);
|
|
82
103
|
|
|
104
|
+
const navigator = useNavigation();
|
|
105
|
+
const { activeRiver } = navigator;
|
|
106
|
+
const { title, visible } = useNavbarState();
|
|
107
|
+
|
|
108
|
+
const { plugins = [] } = usePickFromState([
|
|
109
|
+
"appState",
|
|
110
|
+
"remoteConfigurations",
|
|
111
|
+
"plugins",
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
const navigationProps = getNavigationProps({
|
|
115
|
+
navigator,
|
|
116
|
+
title,
|
|
117
|
+
category: "menu",
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const menuPlugin = React.useMemo(
|
|
121
|
+
() => findMenuPlugin(activeRiver?.navigations, plugins),
|
|
122
|
+
[activeRiver?.navigations]
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const NavBarComponent = React.useMemo(
|
|
126
|
+
() => NavBar || (menuPlugin.module as React.ComponentType<any>),
|
|
127
|
+
[]
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const [navBarReady, setNavBarReady] = React.useState(false);
|
|
131
|
+
|
|
132
|
+
const navBarContainer = (
|
|
133
|
+
<NavBarContainer isVisible={visible} onReady={setNavBarReady}>
|
|
134
|
+
<NavBarComponent
|
|
135
|
+
ref={ComponentsExtraProps?.NavBar?.ref}
|
|
136
|
+
isVisible={visible}
|
|
137
|
+
menuPlugin={menuPlugin}
|
|
138
|
+
navigationProps={navigationProps}
|
|
139
|
+
{...R.omit(["ref"])(ComponentsExtraProps?.NavBar)}
|
|
140
|
+
/>
|
|
141
|
+
</NavBarContainer>
|
|
142
|
+
);
|
|
143
|
+
|
|
83
144
|
return (
|
|
84
|
-
|
|
85
|
-
{
|
|
86
|
-
|
|
145
|
+
<>
|
|
146
|
+
{!isTVOS ? navBarContainer : null}
|
|
147
|
+
{navBarReady ? (
|
|
148
|
+
/**
|
|
149
|
+
Need to re-mount this component on each navigation event
|
|
150
|
+
It's a hack to work around the fact that we don't support
|
|
151
|
+
correct screen rendering in our navigator (shared currentRoute state)
|
|
152
|
+
**/
|
|
153
|
+
<View testID="screen-container" style={viewStyles}>
|
|
154
|
+
{children}
|
|
155
|
+
</View>
|
|
156
|
+
) : null}
|
|
157
|
+
{/** Render NavBarContainer over ScreenContainer to let tvOS native
|
|
158
|
+
focus manager works correctly to focus nav bar items first **/}
|
|
159
|
+
{isTVOS ? navBarContainer : null}
|
|
160
|
+
</>
|
|
87
161
|
);
|
|
88
162
|
});
|
|
@@ -60,7 +60,7 @@ export function ScreenLayoutContextProvider(props: {
|
|
|
60
60
|
initialState
|
|
61
61
|
);
|
|
62
62
|
|
|
63
|
-
const
|
|
63
|
+
const screenLayoutValue = React.useMemo(
|
|
64
64
|
() => ({
|
|
65
65
|
...screenLayout,
|
|
66
66
|
setScreenLayout,
|
|
@@ -69,7 +69,7 @@ export function ScreenLayoutContextProvider(props: {
|
|
|
69
69
|
);
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
|
-
<ScreenLayoutContext.Provider value={
|
|
72
|
+
<ScreenLayoutContext.Provider value={screenLayoutValue}>
|
|
73
73
|
{props.children}
|
|
74
74
|
</ScreenLayoutContext.Provider>
|
|
75
75
|
);
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { render } from "@testing-library/react-native";
|
|
3
|
+
import { render, waitFor } from "@testing-library/react-native";
|
|
4
|
+
import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
4
5
|
|
|
5
6
|
import { ScreenLayoutContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenLayoutContext";
|
|
6
7
|
|
|
7
8
|
const navigator_mock = {
|
|
8
9
|
currentRoute: "/river/A1234",
|
|
9
10
|
screenData: {},
|
|
11
|
+
activeRiver: {
|
|
12
|
+
navigations: {},
|
|
13
|
+
id: "A1234",
|
|
14
|
+
home: false,
|
|
15
|
+
},
|
|
10
16
|
};
|
|
11
17
|
|
|
18
|
+
jest.mock("@applicaster/zapp-react-native-utils/navigationUtils", () => ({
|
|
19
|
+
...jest.requireActual<any>(
|
|
20
|
+
"@applicaster/zapp-react-native-utils/navigationUtils"
|
|
21
|
+
),
|
|
22
|
+
findMenuPlugin: () => ({}),
|
|
23
|
+
}));
|
|
24
|
+
|
|
12
25
|
jest.mock("@applicaster/quick-brick-core/App/ActionSetters", () => ({
|
|
13
26
|
useRiverInitialState: () => ({}),
|
|
14
27
|
}));
|
|
@@ -17,13 +30,13 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
|
17
30
|
useNavigation: () => navigator_mock,
|
|
18
31
|
}));
|
|
19
32
|
|
|
20
|
-
jest.mock("../../../River/useScreenConfiguration
|
|
33
|
+
jest.mock("../../../River/useScreenConfiguration", () => ({
|
|
21
34
|
useScreenConfiguration: () => ({}),
|
|
22
35
|
}));
|
|
23
36
|
|
|
24
|
-
jest.mock(
|
|
25
|
-
useCurrentScreenData
|
|
26
|
-
|
|
37
|
+
jest.mock(
|
|
38
|
+
"@applicaster/zapp-react-native-utils/reactHooks/screen/useCurrentScreenData"
|
|
39
|
+
);
|
|
27
40
|
|
|
28
41
|
jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
|
|
29
42
|
useTheme: () => ({}),
|
|
@@ -44,42 +57,39 @@ describe("ScreenContainer", () => {
|
|
|
44
57
|
const setScreenLayout = () => {};
|
|
45
58
|
|
|
46
59
|
const wrapper = ({ children }) => (
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
60
|
+
<WrappedWithProviders>
|
|
61
|
+
<ScreenLayoutContext.Provider
|
|
62
|
+
value={{ ...screenLayout, setScreenLayout }}
|
|
63
|
+
>
|
|
64
|
+
<ScreenContainer NavBar={View}>{children}</ScreenContainer>
|
|
65
|
+
</ScreenLayoutContext.Provider>
|
|
66
|
+
</WrappedWithProviders>
|
|
50
67
|
);
|
|
51
68
|
|
|
52
69
|
const TestComp = () => <View testID="test-component" />;
|
|
53
70
|
|
|
54
71
|
it("renders", () => {
|
|
55
|
-
const { toJSON } = render(
|
|
56
|
-
<ScreenContainer>
|
|
57
|
-
<TestComp />
|
|
58
|
-
</ScreenContainer>,
|
|
59
|
-
{ wrapper }
|
|
60
|
-
);
|
|
72
|
+
const { toJSON } = render(<TestComp />, { wrapper });
|
|
61
73
|
|
|
62
74
|
expect(toJSON()).toMatchSnapshot();
|
|
63
75
|
});
|
|
64
76
|
|
|
65
|
-
it("renders passed component", () => {
|
|
66
|
-
const { getByTestId } = render(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
);
|
|
77
|
+
it("renders passed component", async () => {
|
|
78
|
+
const { getByTestId } = render(<TestComp />, { wrapper });
|
|
79
|
+
|
|
80
|
+
await waitFor(() => {
|
|
81
|
+
return expect(getByTestId("screen-container")).toBeDefined();
|
|
82
|
+
});
|
|
72
83
|
|
|
73
84
|
expect(getByTestId("test-component")).toBeDefined();
|
|
74
85
|
});
|
|
75
86
|
|
|
76
|
-
it("sets margins provided by the theme", () => {
|
|
77
|
-
const { getByTestId } = render(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
87
|
+
it("sets margins provided by the theme", async () => {
|
|
88
|
+
const { getByTestId } = render(<TestComp />, { wrapper });
|
|
89
|
+
|
|
90
|
+
await waitFor(() => {
|
|
91
|
+
return expect(getByTestId("screen-container")).toBeDefined();
|
|
92
|
+
});
|
|
83
93
|
|
|
84
94
|
const screen = getByTestId("screen-container");
|
|
85
95
|
expect(screen.props.style).toMatchSnapshot();
|
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`ScreenContainer renders 1`] = `
|
|
4
|
-
<
|
|
4
|
+
<RNCSafeAreaProvider
|
|
5
|
+
onInsetsChange={[Function]}
|
|
5
6
|
style={
|
|
6
7
|
Array [
|
|
7
8
|
Object {
|
|
8
9
|
"flex": 1,
|
|
9
|
-
"height": "100%",
|
|
10
|
-
"width": "100%",
|
|
11
|
-
},
|
|
12
|
-
Object {
|
|
13
|
-
"backgroundColor": "transparent",
|
|
14
|
-
"marginBottom": 10,
|
|
15
|
-
"paddingBottom": 0,
|
|
16
|
-
"paddingTop": 0,
|
|
17
10
|
},
|
|
11
|
+
undefined,
|
|
18
12
|
]
|
|
19
13
|
}
|
|
20
|
-
testID="screen-container"
|
|
21
14
|
>
|
|
22
15
|
<View
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
style={
|
|
17
|
+
Array [
|
|
18
|
+
Object {
|
|
19
|
+
"position": "absolute",
|
|
20
|
+
"top": 0,
|
|
21
|
+
"width": 1920,
|
|
22
|
+
"zIndex": 10,
|
|
23
|
+
},
|
|
24
|
+
Object {
|
|
25
|
+
"maxHeight": 10,
|
|
26
|
+
},
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
testID="nav-bar-container"
|
|
30
|
+
>
|
|
31
|
+
<View
|
|
32
|
+
isVisible={true}
|
|
33
|
+
menuPlugin={Object {}}
|
|
34
|
+
navigationProps={null}
|
|
35
|
+
/>
|
|
36
|
+
</View>
|
|
37
|
+
</RNCSafeAreaProvider>
|
|
26
38
|
`;
|
|
27
39
|
|
|
28
40
|
exports[`ScreenContainer sets margins provided by the theme 1`] = `
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`Layout TV renders 1`] = `
|
|
4
4
|
<View
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"height": 1080,
|
|
9
|
-
"width": 1920,
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
testID="layout-container"
|
|
5
|
+
excludeFromFocusSearching={true}
|
|
6
|
+
id="/river/A1234"
|
|
7
|
+
preferredFocus={true}
|
|
13
8
|
>
|
|
14
9
|
<View
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
Components={
|
|
11
|
+
Object {
|
|
12
|
+
"Background": [Function],
|
|
13
|
+
"NavBar": [Function],
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
route="/river/A1234"
|
|
17
17
|
/>
|
|
18
18
|
</View>
|
|
19
19
|
`;
|
|
@@ -1,91 +1,49 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import
|
|
2
|
+
import { omit } from "ramda";
|
|
3
3
|
import { View } from "react-native";
|
|
4
4
|
import { render } from "@testing-library/react-native";
|
|
5
5
|
import { Provider } from "react-redux";
|
|
6
|
-
import { createStore } from "redux";
|
|
7
6
|
import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
|
|
7
|
+
import configureStore from "redux-mock-store";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
const withoutChildren = omit(["children"]);
|
|
10
10
|
|
|
11
|
-
jest.mock("
|
|
12
|
-
|
|
11
|
+
jest.mock("../../../Screen/TV/index.web", () => ({
|
|
12
|
+
Screen: View,
|
|
13
13
|
}));
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
useCurrentScreenData: jest.fn(() => ({
|
|
17
|
-
navigations: [
|
|
18
|
-
{
|
|
19
|
-
category: "menu",
|
|
20
|
-
navigation_type: "menu",
|
|
21
|
-
styles: {
|
|
22
|
-
hide_secondary_level_menu: false,
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
})),
|
|
27
|
-
}));
|
|
28
|
-
|
|
29
|
-
const Layout = require("..").default;
|
|
30
|
-
|
|
31
|
-
const ResolvedMenuPlug = () => <View testID="resolved-menu-plug" />;
|
|
15
|
+
const Layout = require("../index.web").default;
|
|
32
16
|
|
|
33
|
-
const
|
|
34
|
-
{
|
|
35
|
-
module: ResolvedMenuPlug,
|
|
36
|
-
type: "menu",
|
|
37
|
-
name: "resolved-menu-plug",
|
|
38
|
-
},
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
const bgImage = "http://applicaster.com";
|
|
42
|
-
const isNavBarVisible = true;
|
|
43
|
-
|
|
44
|
-
const store = createStore(() => ({
|
|
17
|
+
const mockStore = configureStore()({
|
|
45
18
|
appState: { appReady: true },
|
|
46
|
-
|
|
47
|
-
plugins,
|
|
48
|
-
}));
|
|
19
|
+
});
|
|
49
20
|
|
|
50
21
|
describe("Layout TV", () => {
|
|
51
|
-
const themes = {
|
|
52
|
-
myTheme: { screen_margin_top: 10, screen_margin_bottom: 10 },
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const selectedThemeId = "myTheme";
|
|
56
|
-
|
|
57
22
|
const navigator = {
|
|
58
|
-
activeRiver: {
|
|
59
|
-
navigations: [{ category: "menu", navigation_type: "menu" }],
|
|
60
|
-
},
|
|
61
|
-
canGoBack: () => false,
|
|
62
23
|
currentRoute: "/river/A1234",
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
24
|
+
canGoBack: jest.fn(),
|
|
25
|
+
mainStack: [
|
|
26
|
+
{
|
|
27
|
+
route: "/river/A1234",
|
|
28
|
+
state: { screen: {} },
|
|
29
|
+
},
|
|
30
|
+
],
|
|
67
31
|
};
|
|
68
32
|
|
|
69
33
|
const wrapper = ({ children }) => (
|
|
70
|
-
<Provider store={
|
|
34
|
+
<Provider store={mockStore}>
|
|
71
35
|
<NavigationContext.Provider value={navigator}>
|
|
72
|
-
|
|
73
|
-
{children}
|
|
74
|
-
</ThemeContext.Provider>
|
|
36
|
+
{children}
|
|
75
37
|
</NavigationContext.Provider>
|
|
76
38
|
</Provider>
|
|
77
39
|
);
|
|
78
40
|
|
|
79
|
-
const Screen = (props) => (
|
|
80
|
-
<View testID="screen-component" {...R.omit(["children"])(props)} />
|
|
81
|
-
);
|
|
82
|
-
|
|
83
41
|
const NavBar = (props) => (
|
|
84
|
-
<View testID="nav-bar-component" {...
|
|
42
|
+
<View testID="nav-bar-component" {...withoutChildren(props)} />
|
|
85
43
|
);
|
|
86
44
|
|
|
87
45
|
const Background = (props: Record<any, any>) => (
|
|
88
|
-
<View testID="background-component" {...
|
|
46
|
+
<View testID="background-component" {...withoutChildren(props)}>
|
|
89
47
|
{props.children}
|
|
90
48
|
</View>
|
|
91
49
|
);
|
|
@@ -96,33 +54,8 @@ describe("Layout TV", () => {
|
|
|
96
54
|
};
|
|
97
55
|
|
|
98
56
|
it("renders", () => {
|
|
99
|
-
const { toJSON } = render(
|
|
100
|
-
<Layout Components={Components}>
|
|
101
|
-
<Screen />
|
|
102
|
-
</Layout>,
|
|
103
|
-
{ wrapper }
|
|
104
|
-
);
|
|
57
|
+
const { toJSON } = render(<Layout Components={Components} />, { wrapper });
|
|
105
58
|
|
|
106
59
|
expect(toJSON()).toMatchSnapshot();
|
|
107
60
|
});
|
|
108
|
-
|
|
109
|
-
describe("props passed to background component", () => {
|
|
110
|
-
it("passes correct props", () => {
|
|
111
|
-
const { getByTestId } = render(
|
|
112
|
-
<Layout
|
|
113
|
-
Components={Components}
|
|
114
|
-
ComponentsExtraProps={{
|
|
115
|
-
Background: { testProp: true },
|
|
116
|
-
}}
|
|
117
|
-
>
|
|
118
|
-
<Screen />
|
|
119
|
-
</Layout>,
|
|
120
|
-
{ wrapper }
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
const bgComponent = getByTestId("background-component");
|
|
124
|
-
expect(bgComponent.props.backgroundImageUrl).toBe(bgImage);
|
|
125
|
-
expect(bgComponent.props.testProp).toBe(true);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
61
|
});
|
|
@@ -4,22 +4,14 @@ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
|
4
4
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
5
5
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
getNavigationProps,
|
|
9
|
-
resolveNavigationPlugin,
|
|
10
|
-
routeIsPlayerScreen,
|
|
11
|
-
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
12
|
-
|
|
13
7
|
import { getBackgroundImageUrl } from "../utils";
|
|
14
8
|
import { LayoutContainer } from "./LayoutContainer";
|
|
15
|
-
import { NavBarContainer } from "./NavBarContainer";
|
|
16
9
|
import { ScreenContainer } from "./ScreenContainer";
|
|
17
|
-
import { TransitionOverlay } from "./TransitionOverlay";
|
|
18
10
|
|
|
19
11
|
import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
|
|
20
|
-
import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
21
12
|
import { PathnameContext } from "../../../Contexts/PathnameContext";
|
|
22
|
-
import {
|
|
13
|
+
import { ScreenDataContext } from "../../../Contexts/ScreenDataContext";
|
|
14
|
+
import { ScreenContextProvider } from "../../../Contexts/ScreenContext";
|
|
23
15
|
|
|
24
16
|
type Components = {
|
|
25
17
|
NavBar: React.ComponentType<any>;
|
|
@@ -40,20 +32,9 @@ type Props = {
|
|
|
40
32
|
const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
41
33
|
const navigator = useNavigation();
|
|
42
34
|
const theme = useTheme();
|
|
43
|
-
const { title, visible } = useNavbarState();
|
|
44
|
-
const { activeRiver, currentRoute } = navigator;
|
|
45
|
-
|
|
46
|
-
const {
|
|
47
|
-
appState: { appReady = false } = {},
|
|
48
|
-
remoteConfigurations,
|
|
49
|
-
plugins = [],
|
|
50
|
-
} = usePickFromState(["appState", "remoteConfigurations", "plugins"]);
|
|
51
35
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
title,
|
|
55
|
-
category: "menu",
|
|
56
|
-
});
|
|
36
|
+
const { appState: { appReady = false } = {}, remoteConfigurations } =
|
|
37
|
+
usePickFromState(["appState", "remoteConfigurations", "plugins"]);
|
|
57
38
|
|
|
58
39
|
const backgroundColor = React.useMemo(() => theme.app_background_color, []);
|
|
59
40
|
|
|
@@ -62,37 +43,6 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
|
62
43
|
[remoteConfigurations]
|
|
63
44
|
);
|
|
64
45
|
|
|
65
|
-
const menuPlugin = React.useMemo(
|
|
66
|
-
() =>
|
|
67
|
-
resolveNavigationPlugin({
|
|
68
|
-
category: "menu",
|
|
69
|
-
navigations: activeRiver?.navigations,
|
|
70
|
-
plugins,
|
|
71
|
-
}) as QuickBrickPlugin,
|
|
72
|
-
[]
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
const NavBar = React.useMemo(
|
|
76
|
-
() => Components.NavBar || (menuPlugin.module as React.ComponentType<any>),
|
|
77
|
-
[]
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
const [navBarReady, setNavBarReady] = React.useState(false);
|
|
81
|
-
|
|
82
|
-
const navBarContainer = (
|
|
83
|
-
<NavBarContainer isVisible={visible} onReady={setNavBarReady}>
|
|
84
|
-
<NavBar
|
|
85
|
-
ref={ComponentsExtraProps?.NavBar?.ref}
|
|
86
|
-
isVisible={visible && !routeIsPlayerScreen(currentRoute)}
|
|
87
|
-
menuPlugin={menuPlugin}
|
|
88
|
-
navigationProps={navigationProps}
|
|
89
|
-
{...R.omit(["ref"])(ComponentsExtraProps?.NavBar)}
|
|
90
|
-
/>
|
|
91
|
-
</NavBarContainer>
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const isTVOS = isApplePlatform();
|
|
95
|
-
|
|
96
46
|
if (!appReady) {
|
|
97
47
|
return null;
|
|
98
48
|
}
|
|
@@ -105,21 +55,18 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
|
105
55
|
backgroundImageUrl={backgroundImageUrl}
|
|
106
56
|
{...R.omit(["ref"])(ComponentsExtraProps?.Background)}
|
|
107
57
|
>
|
|
108
|
-
{
|
|
109
|
-
{navBarReady ? (
|
|
110
|
-
/**
|
|
111
|
-
Need to re-mount this component on each navigation event
|
|
112
|
-
It's a hack to work around the fact that we don't support
|
|
113
|
-
correct screen rendering in our navigator (shared currentRoute state)
|
|
114
|
-
**/
|
|
58
|
+
<ScreenDataContext.Provider value={navigator.data}>
|
|
115
59
|
<PathnameContext.Provider value={navigator.currentRoute}>
|
|
116
|
-
<
|
|
60
|
+
<ScreenContextProvider pathname={navigator.currentRoute}>
|
|
61
|
+
<ScreenContainer
|
|
62
|
+
ComponentsExtraProps={ComponentsExtraProps}
|
|
63
|
+
NavBar={Components.NavBar}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</ScreenContainer>
|
|
67
|
+
</ScreenContextProvider>
|
|
117
68
|
</PathnameContext.Provider>
|
|
118
|
-
|
|
119
|
-
{/** Render NavBarContainer over ScreenContainer to let tvOS native
|
|
120
|
-
focus manager works correctly to focus nav bar items first **/}
|
|
121
|
-
{!isTVOS ? navBarContainer : null}
|
|
122
|
-
<TransitionOverlay />
|
|
69
|
+
</ScreenDataContext.Provider>
|
|
123
70
|
</Components.Background>
|
|
124
71
|
</ScreenLayoutContextProvider>
|
|
125
72
|
</LayoutContainer>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { pathOr } from "ramda";
|
|
3
|
+
|
|
4
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
5
|
+
|
|
6
|
+
import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
|
|
7
|
+
import { StackNavigator } from "../../Navigator";
|
|
8
|
+
|
|
9
|
+
type Components = {
|
|
10
|
+
NavBar: React.ComponentType<any>;
|
|
11
|
+
Background: React.ComponentType<any>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
Components: Components;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const Layout = ({ Components }: Props) => {
|
|
19
|
+
const { appState } = usePickFromState(["appState"]);
|
|
20
|
+
const appReady = pathOr(false, ["appReady"], appState);
|
|
21
|
+
|
|
22
|
+
if (!appReady) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<ScreenLayoutContextProvider>
|
|
28
|
+
<StackNavigator Components={Components} />
|
|
29
|
+
</ScreenLayoutContextProvider>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default Layout;
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
isTV,
|
|
4
|
+
platformSelect,
|
|
5
|
+
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
6
|
|
|
6
7
|
import Mobile from "./Mobile";
|
|
7
|
-
import TV from "./TV";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import TVWeb from "./TV/index.web";
|
|
10
|
+
import TVDefault from "./TV/index";
|
|
11
|
+
|
|
12
|
+
const TV = platformSelect({
|
|
13
|
+
samsung_tv: TVWeb,
|
|
14
|
+
lg_tv: TVWeb,
|
|
15
|
+
web: TVWeb,
|
|
16
|
+
default: TVDefault,
|
|
17
|
+
});
|
|
11
18
|
|
|
19
|
+
export default function Layout(props) {
|
|
12
20
|
if (isTV()) {
|
|
13
|
-
return
|
|
14
|
-
<ScreenContextProvider pathname={pathname}>
|
|
15
|
-
<TV {...props} />
|
|
16
|
-
</ScreenContextProvider>
|
|
17
|
-
);
|
|
21
|
+
return <TV {...props} />;
|
|
18
22
|
} else {
|
|
19
23
|
return <Mobile {...props} />;
|
|
20
24
|
}
|
|
@@ -25,6 +25,7 @@ type Props = {
|
|
|
25
25
|
testID?: string;
|
|
26
26
|
accessibilityLabel?: string;
|
|
27
27
|
cellUUID?: string;
|
|
28
|
+
extraProps?: Record<string, any>;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
function isStringAsset(asset) {
|
|
@@ -108,6 +109,7 @@ export function ActionButton(props: Props) {
|
|
|
108
109
|
flavour={flavour}
|
|
109
110
|
asset={getAssetValue(asset, flavour)}
|
|
110
111
|
cellUUID={cellUUID}
|
|
112
|
+
{...(props?.extraProps ?? {})}
|
|
111
113
|
/>
|
|
112
114
|
)}
|
|
113
115
|
</TouchableOpacity>
|