@applicaster/zapp-react-native-ui-components 12.0.0-alpha.3631152042 → 12.0.0-alpha.4433422595
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 +1 -1
- package/Components/Cell/Cell.tsx +5 -1
- package/Components/FocusableGroup/index.tsx +1 -0
- package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +2 -2
- package/Components/Layout/TV/index.tsx +116 -25
- package/Components/PlayerContainer/PlayerContainer.tsx +1 -7
- package/Components/Screen/TV/index.web.tsx +88 -0
- package/Components/Screen/index.tsx +1 -1
- package/package.json +5 -5
|
@@ -73,7 +73,7 @@ export class BaseFocusable<
|
|
|
73
73
|
getId(props?: { id: string; groupId: string }) {
|
|
74
74
|
const { id, groupId = null } = props || this.props;
|
|
75
75
|
|
|
76
|
-
return groupId ?
|
|
76
|
+
return groupId ? `groupId:${groupId}___${id}` : id;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
getRect() {
|
package/Components/Cell/Cell.tsx
CHANGED
|
@@ -207,7 +207,11 @@ export class CellComponent extends React.Component<Props> {
|
|
|
207
207
|
|
|
208
208
|
const { id } = item;
|
|
209
209
|
|
|
210
|
-
const focusableId = R.join("-", [
|
|
210
|
+
const focusableId = R.join("-", [
|
|
211
|
+
`componentId:${component?.id}`,
|
|
212
|
+
`id:${id}`,
|
|
213
|
+
`index:${index}`,
|
|
214
|
+
]);
|
|
211
215
|
|
|
212
216
|
const handleFocus = (focusable, mouse) => {
|
|
213
217
|
const focusFn = onFocus || noop;
|
|
@@ -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,11 +1,15 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
+
import { View, StyleSheet } from "react-native";
|
|
3
4
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
4
5
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
5
6
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
7
|
+
import { useNavbarState } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
|
|
8
|
+
import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
6
9
|
|
|
7
10
|
import {
|
|
8
11
|
getNavigationProps,
|
|
12
|
+
getPathAttributes,
|
|
9
13
|
resolveNavigationPlugin,
|
|
10
14
|
routeIsPlayerScreen,
|
|
11
15
|
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
@@ -17,9 +21,23 @@ import { ScreenContainer } from "./ScreenContainer";
|
|
|
17
21
|
import { TransitionOverlay } from "./TransitionOverlay";
|
|
18
22
|
|
|
19
23
|
import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
|
|
20
|
-
import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
21
24
|
import { PathnameContext } from "../../../Contexts/PathnameContext";
|
|
22
|
-
|
|
25
|
+
|
|
26
|
+
import { FocusableGroup } from "../../FocusableGroup";
|
|
27
|
+
import { Screen } from "../../Screen/TV/index.web";
|
|
28
|
+
|
|
29
|
+
const styles = StyleSheet.create({
|
|
30
|
+
container: {
|
|
31
|
+
position: "absolute",
|
|
32
|
+
width: 1920,
|
|
33
|
+
height: 1080,
|
|
34
|
+
backgroundColor: "black",
|
|
35
|
+
// opacity: 0.5,
|
|
36
|
+
|
|
37
|
+
borderWidth: 4,
|
|
38
|
+
borderColor: "magenta",
|
|
39
|
+
},
|
|
40
|
+
});
|
|
23
41
|
|
|
24
42
|
type Components = {
|
|
25
43
|
NavBar: React.ComponentType<any>;
|
|
@@ -27,16 +45,65 @@ type Components = {
|
|
|
27
45
|
};
|
|
28
46
|
|
|
29
47
|
type ComponentsExtraProps = {
|
|
30
|
-
Background?: Record<string, any>;
|
|
31
48
|
NavBar?: Record<string, any>;
|
|
49
|
+
Background?: Record<string, any>;
|
|
32
50
|
};
|
|
33
51
|
|
|
34
52
|
type Props = {
|
|
35
53
|
Components: Components;
|
|
36
|
-
|
|
37
|
-
|
|
54
|
+
componentsExtraProps?: ComponentsExtraProps;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const StackNavigator = ({ Components }: Props) => {
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
const { mainStack, currentRoute } = useNavigation();
|
|
60
|
+
|
|
61
|
+
console.log("DEBUG", { mainStack });
|
|
62
|
+
|
|
63
|
+
const renderScreen = ({ route, action, key, state }) => {
|
|
64
|
+
const pathAttributes = getPathAttributes({ pathname: route });
|
|
65
|
+
|
|
66
|
+
if (R.isEmpty(pathAttributes)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log("SCENE:", { route, state, key, action });
|
|
71
|
+
|
|
72
|
+
const id = `${route}`;
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<FocusableGroup
|
|
76
|
+
id={id}
|
|
77
|
+
preferredFocus={route === currentRoute}
|
|
78
|
+
excludeFromFocusSearching
|
|
79
|
+
key={id}
|
|
80
|
+
>
|
|
81
|
+
<View style={styles.container}>
|
|
82
|
+
<PathnameContext.Provider value={route}>
|
|
83
|
+
<Screen route={route} Components={Components} />
|
|
84
|
+
</PathnameContext.Provider>
|
|
85
|
+
</View>
|
|
86
|
+
</FocusableGroup>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return mainStack.map(renderScreen);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const TransitionerTV = ({ componentsExtraProps, Components }: Props) => {
|
|
94
|
+
return (
|
|
95
|
+
<>
|
|
96
|
+
<ScreenLayoutContextProvider>
|
|
97
|
+
<StackNavigator
|
|
98
|
+
componentsExtraProps={componentsExtraProps}
|
|
99
|
+
Components={Components}
|
|
100
|
+
/>
|
|
101
|
+
</ScreenLayoutContextProvider>
|
|
102
|
+
</>
|
|
103
|
+
);
|
|
38
104
|
};
|
|
39
105
|
|
|
106
|
+
// @ts-ignore
|
|
40
107
|
const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
41
108
|
const navigator = useNavigation();
|
|
42
109
|
const theme = useTheme();
|
|
@@ -97,33 +164,57 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
|
97
164
|
return null;
|
|
98
165
|
}
|
|
99
166
|
|
|
167
|
+
console.log("DEBUG", "TV Layout");
|
|
168
|
+
|
|
100
169
|
return (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
170
|
+
// @ts-ignore
|
|
171
|
+
<TransitionerTV
|
|
172
|
+
componentsExtraProps={ComponentsExtraProps}
|
|
173
|
+
Components={Components}
|
|
174
|
+
>
|
|
175
|
+
<LayoutContainer>
|
|
176
|
+
<ScreenLayoutContextProvider>
|
|
177
|
+
<Components.Background
|
|
178
|
+
backgroundColor={backgroundColor}
|
|
179
|
+
backgroundImageUrl={backgroundImageUrl}
|
|
180
|
+
{...R.omit(["ref"])(ComponentsExtraProps?.Background)}
|
|
181
|
+
>
|
|
182
|
+
{!isTVOS ? navBarContainer : null}
|
|
183
|
+
{navBarReady ? (
|
|
184
|
+
/**
|
|
111
185
|
Need to re-mount this component on each navigation event
|
|
112
186
|
It's a hack to work around the fact that we don't support
|
|
113
187
|
correct screen rendering in our navigator (shared currentRoute state)
|
|
114
188
|
**/
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
189
|
+
<PathnameContext.Provider value={navigator.currentRoute}>
|
|
190
|
+
<ScreenContainer>{children}</ScreenContainer>
|
|
191
|
+
</PathnameContext.Provider>
|
|
192
|
+
) : null}
|
|
193
|
+
{/** Render NavBarContainer over ScreenContainer to let tvOS native
|
|
120
194
|
focus manager works correctly to focus nav bar items first **/}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
195
|
+
{isTVOS ? navBarContainer : null}
|
|
196
|
+
<TransitionOverlay />
|
|
197
|
+
</Components.Background>
|
|
198
|
+
</ScreenLayoutContextProvider>
|
|
199
|
+
</LayoutContainer>
|
|
200
|
+
</TransitionerTV>
|
|
126
201
|
);
|
|
127
202
|
};
|
|
128
203
|
|
|
129
204
|
export default Layout;
|
|
205
|
+
|
|
206
|
+
/// Transitioner:
|
|
207
|
+
/*
|
|
208
|
+
Component: Transitioner
|
|
209
|
+
Responsibilities:
|
|
210
|
+
- Transitione between screens.
|
|
211
|
+
Tehere is no transition on Tv so no need for transitioner.
|
|
212
|
+
|
|
213
|
+
Component: StackNavigator
|
|
214
|
+
Responsibilities:
|
|
215
|
+
- Render the screens in the stack.
|
|
216
|
+
- Render the NavBar? I guess navbar should be part of the screen
|
|
217
|
+
- Render the screen.
|
|
218
|
+
|
|
219
|
+
Q
|
|
220
|
+
*/
|
|
@@ -145,13 +145,7 @@ const renderApplePlayer = ({
|
|
|
145
145
|
}) => {
|
|
146
146
|
const { title, summary } = item || {};
|
|
147
147
|
|
|
148
|
-
if (!
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// TODO: Check if it is not breaking default player logic on tvos
|
|
153
|
-
// Also if needs to add on tvos brightcove player for QB player
|
|
154
|
-
if (player.supportsNativeControls()) {
|
|
148
|
+
if (!isAppleTV() || !player) {
|
|
155
149
|
return null;
|
|
156
150
|
}
|
|
157
151
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { last, pathOr } from "ramda";
|
|
3
|
+
import { ScreenResolver } from "../../ScreenResolver";
|
|
4
|
+
import {
|
|
5
|
+
getNavigationProps,
|
|
6
|
+
getPathAttributes,
|
|
7
|
+
resolveNavigationPlugin,
|
|
8
|
+
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
9
|
+
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
10
|
+
import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
|
|
11
|
+
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
12
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
13
|
+
|
|
14
|
+
type Components = {
|
|
15
|
+
NavBar: React.ComponentType<any>;
|
|
16
|
+
Background: React.ComponentType<any>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type Props = {
|
|
20
|
+
route: string;
|
|
21
|
+
Components: Components;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const isPlayer = (routeState): boolean => {
|
|
25
|
+
const pluginType = pathOr(
|
|
26
|
+
"unknown_plugin_type",
|
|
27
|
+
["state", "screen", "plugin_type"],
|
|
28
|
+
routeState
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return pluginType === "player";
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Screen = (props: Props) => {
|
|
35
|
+
if (!props.route) {
|
|
36
|
+
throw new Error("Required props route is missing");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const { getStackForPathname } = useNavigation();
|
|
40
|
+
const { plugins = [] } = usePickFromState(["plugins"]);
|
|
41
|
+
|
|
42
|
+
const pathAttributes = getPathAttributes({ pathname: props.route });
|
|
43
|
+
const routeState = getStackForPathname(props.route);
|
|
44
|
+
|
|
45
|
+
console.log("debug_2", "Screen", { routeState, route: props.route });
|
|
46
|
+
|
|
47
|
+
const { screenType, screenId } = last(pathAttributes);
|
|
48
|
+
|
|
49
|
+
const navigationProps = getNavigationProps({
|
|
50
|
+
navigator: {
|
|
51
|
+
activeRiver: routeState.state.screen,
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
screenTitle: routeState.state.entry?.title || routeState.screen?.name,
|
|
54
|
+
},
|
|
55
|
+
category: "menu",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const menuPlugin = resolveNavigationPlugin({
|
|
59
|
+
category: "menu",
|
|
60
|
+
navigations: routeState.state.screen?.navigations,
|
|
61
|
+
plugins,
|
|
62
|
+
}) as QuickBrickPlugin;
|
|
63
|
+
|
|
64
|
+
const NavBar = (props.Components.NavBar ||
|
|
65
|
+
menuPlugin.module) as React.ComponentType<any>;
|
|
66
|
+
|
|
67
|
+
const isNavBarVisible = !isPlayer(routeState);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<>
|
|
71
|
+
<NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
|
|
72
|
+
<NavBar
|
|
73
|
+
groupId={props.route}
|
|
74
|
+
isVisible={isNavBarVisible}
|
|
75
|
+
menuPlugin={menuPlugin}
|
|
76
|
+
navigationProps={navigationProps}
|
|
77
|
+
// Maybe activeRiver?
|
|
78
|
+
/>
|
|
79
|
+
</NavBarContainer>
|
|
80
|
+
<ScreenResolver
|
|
81
|
+
screenType={screenType}
|
|
82
|
+
screenId={screenId}
|
|
83
|
+
screenData={routeState?.state?.screen}
|
|
84
|
+
groupId={props.route}
|
|
85
|
+
/>
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
@@ -137,7 +137,7 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
137
137
|
{...{ ...(navBarProps as MobileNavBarPluginProps), id: pathname }}
|
|
138
138
|
/>
|
|
139
139
|
|
|
140
|
-
<OfflineFallbackScreen screenData={
|
|
140
|
+
<OfflineFallbackScreen screenData={targetScreenData}>
|
|
141
141
|
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
142
142
|
<RouteManager pathname={pathname} screenData={screenData} />
|
|
143
143
|
</OfflineFallbackScreen>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.4433422595",
|
|
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": "12.0.0-alpha.
|
|
38
|
-
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.
|
|
39
|
-
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.
|
|
40
|
-
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.
|
|
37
|
+
"@applicaster/applicaster-types": "12.0.0-alpha.4433422595",
|
|
38
|
+
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4433422595",
|
|
39
|
+
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.4433422595",
|
|
40
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.4433422595",
|
|
41
41
|
"promise": "^8.3.0",
|
|
42
42
|
"react-router-native": "^5.1.2",
|
|
43
43
|
"url": "^0.11.0",
|