@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4337072244 → 12.0.0-alpha.4342066143
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 -5
- package/Components/Cell/CellWithFocusable.tsx +5 -17
- package/Components/FocusableGroup/index.tsx +0 -1
- package/Components/HandlePlayable/HandlePlayable.tsx +0 -3
- package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +2 -2
- package/Components/Layout/TV/TransitionOverlay.tsx +64 -0
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +50 -10
- package/Components/Layout/TV/__tests__/index.test.tsx +74 -18
- package/Components/Layout/TV/index.tsx +105 -43
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +80 -109
- package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +1 -4
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +1 -4
- package/Components/PlayerContainer/PlayerContainer.tsx +1 -3
- package/Components/River/ComponentsMap/ComponentsMap.tsx +6 -0
- package/Components/River/RefreshControl.tsx +2 -2
- package/Components/River/TV/River.tsx +23 -0
- package/Components/RouteManager/index.tsx +2 -2
- package/Components/ScreenResolver/index.tsx +1 -3
- package/Components/Transitioner/Scene.tsx +24 -19
- package/Components/Transitioner/Transitioner.tsx +9 -2
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +6 -2
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
- package/Components/VideoLive/LiveImageManager.ts +3 -0
- package/Components/VideoModal/PlayerDetails.tsx +3 -3
- package/Components/VideoModal/PlayerWrapper.tsx +69 -62
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +7 -0
- package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +31 -40
- package/Contexts/ScreenDataContext/index.ts +3 -0
- package/Contexts/ZappPipesContext/ZappPipesEntryContext.ts +1 -1
- package/package.json +5 -5
- package/Components/Screen/TV/hooks/index.ts +0 -3
- package/Components/Screen/TV/hooks/useInitialFocus.ts +0 -67
- package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
- package/Components/Screen/TV/index.web.tsx +0 -174
|
@@ -14,12 +14,13 @@ import { PlayerDetails } from "./PlayerDetails";
|
|
|
14
14
|
import { playerDimesionsHack } from "./utils";
|
|
15
15
|
import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
16
16
|
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
17
|
+
import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
|
|
17
18
|
|
|
18
19
|
import {
|
|
19
|
-
AnimationComponent,
|
|
20
|
-
ComponentAnimationType,
|
|
21
20
|
AnimatedScrollModal,
|
|
22
21
|
AnimatedVideoPlayerComponent,
|
|
22
|
+
AnimationComponent,
|
|
23
|
+
ComponentAnimationType,
|
|
23
24
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
24
25
|
|
|
25
26
|
type DimensionsT = {
|
|
@@ -96,7 +97,7 @@ const getEdges = (isTablet: boolean, isInlineModal: boolean) => {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
if (!isInlineModal && Platform.OS === "android") {
|
|
99
|
-
return [
|
|
100
|
+
return [];
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
return ["top"];
|
|
@@ -161,7 +162,7 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
161
162
|
width: isInlineModal && docked ? undefined : baseDimensions.width,
|
|
162
163
|
aspectRatio: !isInlineModal && !pip ? getScreenAspectRatio() : 16 / 9,
|
|
163
164
|
}),
|
|
164
|
-
[baseDimensions, isInlineModal, pip
|
|
165
|
+
[baseDimensions, isInlineModal, pip]
|
|
165
166
|
);
|
|
166
167
|
|
|
167
168
|
const containerDimensions: DimensionsT = React.useMemo(
|
|
@@ -180,65 +181,71 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
180
181
|
[containerDimensions, playerDimesionsHack]
|
|
181
182
|
);
|
|
182
183
|
|
|
184
|
+
const pathname = `${ROUTE_TYPES.VIDEO_MODAL}/${entry?.id}`;
|
|
185
|
+
|
|
183
186
|
return (
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
animationType={ComponentAnimationType.moveUpComponent}
|
|
210
|
-
style={isTabletLandscape ? defaultStyles.flex : undefined}
|
|
211
|
-
additionalData={{
|
|
212
|
-
useLayoutMeasure: isTabletLandscape,
|
|
213
|
-
disableAnimatedComponent: !isTabletLandscape,
|
|
214
|
-
resetAnimationValue: isTabletLandscape && docked,
|
|
215
|
-
}}
|
|
216
|
-
>
|
|
217
|
-
<AnimatedVideoPlayerComponent>
|
|
218
|
-
{children(childrenStyles)}
|
|
219
|
-
</AnimatedVideoPlayerComponent>
|
|
220
|
-
</AnimationComponent>
|
|
221
|
-
</View>
|
|
222
|
-
<AnimatedScrollModal>
|
|
223
|
-
{isInlineModal ? (
|
|
224
|
-
<AnimationComponent
|
|
225
|
-
animationType={ComponentAnimationType.componentFade}
|
|
226
|
-
style={defaultStyles.flex}
|
|
187
|
+
<ScreenContextProvider pathname={pathname}>
|
|
188
|
+
<PathnameContext.Provider value={pathname}>
|
|
189
|
+
<WrapperView
|
|
190
|
+
edges={getEdges(isTablet, isInlineModal) as readonly Edge[]}
|
|
191
|
+
style={[
|
|
192
|
+
safeAreaStyles(configuration, isTablet),
|
|
193
|
+
style,
|
|
194
|
+
playerDimesionsHack,
|
|
195
|
+
]}
|
|
196
|
+
>
|
|
197
|
+
<AnimationComponent
|
|
198
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
199
|
+
additionalData={{ saveArea: true }}
|
|
200
|
+
style={directionStyles(isTabletLandscape)}
|
|
201
|
+
>
|
|
202
|
+
<ScreenContextProvider pathname={pathname}>
|
|
203
|
+
<PathnameContext.Provider value={pathname}>
|
|
204
|
+
<View
|
|
205
|
+
testID={`${entry?.id}-player-container`}
|
|
206
|
+
style={[
|
|
207
|
+
defaultStyles.playerContainer,
|
|
208
|
+
containerDimensions,
|
|
209
|
+
containerStyle,
|
|
210
|
+
playerDimesionsHack,
|
|
211
|
+
]}
|
|
227
212
|
>
|
|
228
|
-
<
|
|
229
|
-
|
|
230
|
-
style={defaultStyles.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
213
|
+
<AnimationComponent
|
|
214
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
215
|
+
style={isTabletLandscape ? defaultStyles.flex : undefined}
|
|
216
|
+
additionalData={{
|
|
217
|
+
useLayoutMeasure: isTabletLandscape,
|
|
218
|
+
disableAnimatedComponent: !isTabletLandscape,
|
|
219
|
+
resetAnimationValue: isTabletLandscape && docked,
|
|
220
|
+
}}
|
|
221
|
+
>
|
|
222
|
+
<AnimatedVideoPlayerComponent>
|
|
223
|
+
{children(childrenStyles)}
|
|
224
|
+
</AnimatedVideoPlayerComponent>
|
|
225
|
+
</AnimationComponent>
|
|
226
|
+
</View>
|
|
227
|
+
<AnimatedScrollModal>
|
|
228
|
+
{isInlineModal ? (
|
|
229
|
+
<AnimationComponent
|
|
230
|
+
animationType={ComponentAnimationType.componentFade}
|
|
231
|
+
style={defaultStyles.flex}
|
|
232
|
+
>
|
|
233
|
+
<PlayerDetails
|
|
234
|
+
configuration={configuration}
|
|
235
|
+
style={defaultStyles.playerDetails}
|
|
236
|
+
entry={entry}
|
|
237
|
+
isTabletLandscape={isTabletLandscape}
|
|
238
|
+
/>
|
|
239
|
+
</AnimationComponent>
|
|
240
|
+
) : (
|
|
241
|
+
<View style={defaultStyles.playerDetails} />
|
|
242
|
+
)}
|
|
243
|
+
</AnimatedScrollModal>
|
|
244
|
+
</PathnameContext.Provider>
|
|
245
|
+
</ScreenContextProvider>
|
|
246
|
+
</AnimationComponent>
|
|
247
|
+
</WrapperView>
|
|
248
|
+
</PathnameContext.Provider>
|
|
249
|
+
</ScreenContextProvider>
|
|
243
250
|
);
|
|
244
251
|
};
|
|
@@ -25,6 +25,13 @@ jest.mock("react-native-gesture-handler");
|
|
|
25
25
|
|
|
26
26
|
jest.mock("../PlayerDetails", () => ({ PlayerDetails: View }));
|
|
27
27
|
|
|
28
|
+
jest.mock(
|
|
29
|
+
"@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext",
|
|
30
|
+
() => ({
|
|
31
|
+
useScreenContext: jest.fn().mockReturnValue({ screen: {}, entry: {} }),
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
|
|
28
35
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/device", () => ({
|
|
29
36
|
useIsTablet,
|
|
30
37
|
}));
|
|
@@ -6,23 +6,23 @@ import { callOnChildren } from "../utils";
|
|
|
6
6
|
|
|
7
7
|
export function ViewportTracker(props) {
|
|
8
8
|
const viewportEvents = useViewportEventsContext();
|
|
9
|
-
const { children } = props;
|
|
10
|
-
const [width, setWidth] = React.useState(0);
|
|
11
|
-
const [height, setHeight] = React.useState(0);
|
|
12
|
-
const [offsetX, setOffsetX] = React.useState(0);
|
|
13
|
-
const [offsetY, setOffsetY] = React.useState(0);
|
|
14
9
|
const [nodeHandle, setNodeHandle] = React.useState(null);
|
|
15
10
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
const childrenRef = React.useRef(props.children);
|
|
12
|
+
|
|
13
|
+
const dimensionsRef = React.useRef({ width: 0, height: 0 });
|
|
14
|
+
const offsetRef = React.useRef({ offsetX: 0, offsetY: 0 });
|
|
15
|
+
|
|
16
|
+
const assignRef = React.useCallback((ref) => {
|
|
17
|
+
childrenRef.current?.ref?.(ref);
|
|
18
|
+
setNodeHandle(findNodeHandle(ref));
|
|
19
|
+
}, []);
|
|
23
20
|
|
|
24
21
|
const onViewportChange = React.useCallback(
|
|
25
|
-
(
|
|
22
|
+
({
|
|
23
|
+
event = { ...dimensionsRef.current, ...offsetRef.current },
|
|
24
|
+
shouldMeasureLayout = true,
|
|
25
|
+
} = {}) => {
|
|
26
26
|
if (nodeHandle && event?.width > 0 && event?.height > 0) {
|
|
27
27
|
viewportEvents?.notify?.({
|
|
28
28
|
parentHandle: nodeHandle,
|
|
@@ -36,54 +36,45 @@ export function ViewportTracker(props) {
|
|
|
36
36
|
|
|
37
37
|
const onLayout = React.useCallback(
|
|
38
38
|
(event) => {
|
|
39
|
-
callOnChildren(
|
|
40
|
-
|
|
41
|
-
setHeight(event?.nativeEvent?.layout?.height);
|
|
39
|
+
callOnChildren(childrenRef.current, "onLayout", event);
|
|
40
|
+
dimensionsRef.current = event?.nativeEvent?.layout;
|
|
42
41
|
|
|
43
|
-
onViewportChange(
|
|
44
|
-
width: event?.nativeEvent?.layout?.width,
|
|
45
|
-
height: event?.nativeEvent?.layout?.height,
|
|
46
|
-
offsetX,
|
|
47
|
-
offsetY,
|
|
48
|
-
});
|
|
42
|
+
onViewportChange();
|
|
49
43
|
},
|
|
50
|
-
[
|
|
44
|
+
[onViewportChange]
|
|
51
45
|
);
|
|
52
46
|
|
|
53
47
|
const onContentSizeChange = React.useCallback(
|
|
54
48
|
(contentWidth, contentHeight) => {
|
|
55
49
|
callOnChildren(
|
|
56
|
-
|
|
50
|
+
childrenRef.current,
|
|
57
51
|
"onContentSizeChange",
|
|
58
52
|
contentWidth,
|
|
59
53
|
contentHeight
|
|
60
54
|
);
|
|
61
55
|
|
|
62
|
-
onViewportChange(
|
|
56
|
+
onViewportChange();
|
|
63
57
|
},
|
|
64
|
-
[onViewportChange
|
|
58
|
+
[onViewportChange]
|
|
65
59
|
);
|
|
66
60
|
|
|
67
61
|
const onScroll = React.useCallback(
|
|
68
62
|
(event) => {
|
|
69
|
-
callOnChildren(
|
|
70
|
-
|
|
71
|
-
setOffsetY(event?.nativeEvent?.contentOffset?.y);
|
|
63
|
+
callOnChildren(childrenRef.current, "onScroll", event);
|
|
64
|
+
offsetRef.current = event?.nativeEvent?.contentOffset;
|
|
72
65
|
|
|
73
|
-
onViewportChange(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
height,
|
|
77
|
-
offsetX: event?.nativeEvent?.contentOffset?.x,
|
|
78
|
-
offsetY: event?.nativeEvent?.contentOffset?.y,
|
|
79
|
-
},
|
|
80
|
-
false
|
|
81
|
-
);
|
|
66
|
+
onViewportChange({
|
|
67
|
+
shouldMeasureLayout: false,
|
|
68
|
+
});
|
|
82
69
|
},
|
|
83
|
-
[onViewportChange
|
|
70
|
+
[onViewportChange]
|
|
84
71
|
);
|
|
85
72
|
|
|
86
|
-
|
|
73
|
+
React.useEffect(() => {
|
|
74
|
+
childrenRef.current = props.children;
|
|
75
|
+
}, [props.children]);
|
|
76
|
+
|
|
77
|
+
return React.cloneElement(React.Children.only(props.children), {
|
|
87
78
|
ref: assignRef,
|
|
88
79
|
onLayout,
|
|
89
80
|
onContentSizeChange,
|
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.4342066143",
|
|
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.4342066143",
|
|
38
|
+
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4342066143",
|
|
39
|
+
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.4342066143",
|
|
40
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.4342066143",
|
|
41
41
|
"promise": "^8.3.0",
|
|
42
42
|
"react-router-native": "^5.1.2",
|
|
43
43
|
"url": "^0.11.0",
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
useNavigationPluginData,
|
|
4
|
-
useIsNavBarVisible,
|
|
5
|
-
useRoute,
|
|
6
|
-
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
7
|
-
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
8
|
-
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
9
|
-
|
|
10
|
-
type Return =
|
|
11
|
-
| {
|
|
12
|
-
onContent: true;
|
|
13
|
-
onMenu: false;
|
|
14
|
-
}
|
|
15
|
-
| {
|
|
16
|
-
onContent: false;
|
|
17
|
-
onMenu: true;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const getInitialFocus = (focusOnContent, isNavBarVisible): Return => {
|
|
21
|
-
if (focusOnContent) {
|
|
22
|
-
return {
|
|
23
|
-
onContent: true,
|
|
24
|
-
onMenu: false,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!focusOnContent && isNavBarVisible) {
|
|
29
|
-
// put focus on navbar
|
|
30
|
-
return {
|
|
31
|
-
onContent: false,
|
|
32
|
-
onMenu: true,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// we don't have navbar, put focus on content anyway
|
|
37
|
-
return {
|
|
38
|
-
onContent: true,
|
|
39
|
-
onMenu: false,
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const useInitialFocus = (): void => {
|
|
44
|
-
const navigationPluginData = useNavigationPluginData();
|
|
45
|
-
|
|
46
|
-
const focusOnContent = toBooleanWithDefaultFalse(
|
|
47
|
-
navigationPluginData?.rules?.focus_on_content
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
const isNavBarVisible = useIsNavBarVisible();
|
|
51
|
-
|
|
52
|
-
const { pathname: currentRoute } = useRoute();
|
|
53
|
-
|
|
54
|
-
React.useEffect(() => {
|
|
55
|
-
const initialFocus = getInitialFocus(focusOnContent, isNavBarVisible);
|
|
56
|
-
|
|
57
|
-
if (initialFocus.onContent) {
|
|
58
|
-
focusManager.setFocusOnContent(currentRoute);
|
|
59
|
-
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (initialFocus.onMenu) {
|
|
64
|
-
focusManager.setFocusOnMenu(currentRoute);
|
|
65
|
-
}
|
|
66
|
-
}, []);
|
|
67
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { isNil } from "ramda";
|
|
3
|
-
import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
4
|
-
import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
|
|
5
|
-
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
6
|
-
|
|
7
|
-
export const useRestoreFocus = (): void => {
|
|
8
|
-
const isScreenActive = useIsScreenActive();
|
|
9
|
-
const previousIsScreenActive = usePrevious(isScreenActive);
|
|
10
|
-
|
|
11
|
-
React.useEffect(() => {
|
|
12
|
-
if (isNil(previousIsScreenActive)) {
|
|
13
|
-
// it's initial mounting of the screen, do nothing here
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (!previousIsScreenActive && isScreenActive) {
|
|
18
|
-
// restore focus when we go back from next screen
|
|
19
|
-
focusManager.setInitialFocus();
|
|
20
|
-
}
|
|
21
|
-
}, [previousIsScreenActive, isScreenActive]);
|
|
22
|
-
};
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { last, pathOr } from "ramda";
|
|
3
|
-
import { View, StyleSheet } from "react-native";
|
|
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 { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
11
|
-
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
12
|
-
import { useScreenBackgroundColor } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
|
|
13
|
-
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
14
|
-
|
|
15
|
-
import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
|
|
16
|
-
import { ScreenResolver } from "../../ScreenResolver";
|
|
17
|
-
import { useInitialFocus, useRestoreFocus } from "./hooks";
|
|
18
|
-
|
|
19
|
-
const styles = StyleSheet.create({
|
|
20
|
-
container: {
|
|
21
|
-
position: "absolute",
|
|
22
|
-
top: 0,
|
|
23
|
-
left: 0,
|
|
24
|
-
right: 0,
|
|
25
|
-
bottom: 0,
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
type Components = {
|
|
30
|
-
NavBar: React.ComponentType<any>;
|
|
31
|
-
Background: React.ComponentType<any>;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
type Props = {
|
|
35
|
-
route: string;
|
|
36
|
-
Components: Components;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const isPlayer = (routeState): boolean => {
|
|
40
|
-
const pluginType = pathOr(
|
|
41
|
-
"unknown_plugin_type",
|
|
42
|
-
["state", "screen", "plugin_type"],
|
|
43
|
-
routeState
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
return pluginType === "player";
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const getActiveRiver = ({
|
|
50
|
-
screenId,
|
|
51
|
-
screenType,
|
|
52
|
-
routeState,
|
|
53
|
-
rivers,
|
|
54
|
-
fallbackActiveRiver,
|
|
55
|
-
}) => {
|
|
56
|
-
if (rivers[screenId]) {
|
|
57
|
-
if (screenType === "hooks") {
|
|
58
|
-
const navigations = routeState?.state?.entry?.payload?.navigations;
|
|
59
|
-
|
|
60
|
-
if (navigations) {
|
|
61
|
-
return routeState.state.entry.payload;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return routeState?.state?.screen;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// screenId is not presented into rivers, use fallback instead
|
|
69
|
-
return fallbackActiveRiver;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const getNavigations = ({
|
|
73
|
-
screenId,
|
|
74
|
-
screenType,
|
|
75
|
-
routeState,
|
|
76
|
-
rivers,
|
|
77
|
-
fallbackNavigations,
|
|
78
|
-
}) => {
|
|
79
|
-
if (rivers[screenId]) {
|
|
80
|
-
// river presents
|
|
81
|
-
if (screenType === "hooks") {
|
|
82
|
-
const navigations = routeState?.state?.entry?.payload?.navigations;
|
|
83
|
-
|
|
84
|
-
if (navigations) {
|
|
85
|
-
return navigations;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return routeState?.state?.screen?.navigations;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// screenId is not presented into rivers, use fallback instead
|
|
93
|
-
return fallbackNavigations;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
export const Screen = ({ route, Components }: Props) => {
|
|
97
|
-
if (isNilOrEmpty(route)) {
|
|
98
|
-
throw Error("Required props: route is missing");
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const navigator = useNavigation();
|
|
102
|
-
const { plugins = [], rivers = [] } = usePickFromState(["plugins", "rivers"]);
|
|
103
|
-
|
|
104
|
-
const pathAttributes = getPathAttributes({ pathname: route });
|
|
105
|
-
const routeState = navigator.getStackForPathname(route);
|
|
106
|
-
|
|
107
|
-
const { screenType, screenId } = last(pathAttributes);
|
|
108
|
-
|
|
109
|
-
const backgroundColor = useScreenBackgroundColor(screenId);
|
|
110
|
-
|
|
111
|
-
useInitialFocus();
|
|
112
|
-
useRestoreFocus();
|
|
113
|
-
|
|
114
|
-
const activeRiver = getActiveRiver({
|
|
115
|
-
screenId,
|
|
116
|
-
screenType,
|
|
117
|
-
routeState,
|
|
118
|
-
rivers,
|
|
119
|
-
fallbackActiveRiver: navigator.activeRiver,
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const navigationProps = getNavigationProps({
|
|
123
|
-
navigator: {
|
|
124
|
-
// @ts-ignore
|
|
125
|
-
activeRiver,
|
|
126
|
-
// @ts-ignore
|
|
127
|
-
screenTitle: routeState.state.entry?.title || routeState.screen?.name,
|
|
128
|
-
},
|
|
129
|
-
category: "menu",
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
const navigations = getNavigations({
|
|
133
|
-
screenId,
|
|
134
|
-
screenType,
|
|
135
|
-
routeState,
|
|
136
|
-
rivers,
|
|
137
|
-
fallbackNavigations: navigator.activeRiver.navigations,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const menuPlugin = resolveNavigationPlugin({
|
|
141
|
-
category: "menu",
|
|
142
|
-
navigations,
|
|
143
|
-
plugins,
|
|
144
|
-
}) as QuickBrickPlugin;
|
|
145
|
-
|
|
146
|
-
const NavBar = (Components.NavBar ||
|
|
147
|
-
menuPlugin.module) as React.ComponentType<any>;
|
|
148
|
-
|
|
149
|
-
const isNavBarVisible = !isPlayer(routeState);
|
|
150
|
-
|
|
151
|
-
const screenData =
|
|
152
|
-
screenType === "hooks"
|
|
153
|
-
? routeState?.state?.entry
|
|
154
|
-
: routeState?.state?.screen;
|
|
155
|
-
|
|
156
|
-
return (
|
|
157
|
-
<View style={[styles.container, { backgroundColor }]}>
|
|
158
|
-
<NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
|
|
159
|
-
<NavBar
|
|
160
|
-
groupId={route}
|
|
161
|
-
isVisible={isNavBarVisible}
|
|
162
|
-
menuPlugin={menuPlugin}
|
|
163
|
-
navigationProps={navigationProps}
|
|
164
|
-
/>
|
|
165
|
-
</NavBarContainer>
|
|
166
|
-
<ScreenResolver
|
|
167
|
-
screenType={screenType}
|
|
168
|
-
screenId={screenId}
|
|
169
|
-
screenData={screenData}
|
|
170
|
-
groupId={route}
|
|
171
|
-
/>
|
|
172
|
-
</View>
|
|
173
|
-
);
|
|
174
|
-
};
|