@applicaster/zapp-react-native-ui-components 12.0.0-alpha.3788876021 → 12.0.0-alpha.3823240084
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 +30 -9
- package/Components/Cell/CellWithFocusable.tsx +23 -9
- package/Components/Cell/TvOSCellComponent.tsx +3 -7
- package/Components/Focusable/Focusable.tsx +6 -1
- 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/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 -50
- package/Components/Layout/TV/__tests__/index.test.tsx +20 -75
- 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 +4 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +86 -116
- package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +57 -0
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +34 -1
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +14 -2
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +24 -9
- package/Components/MasterCell/DefaultComponents/index.ts +2 -0
- 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/dataAdapter.ts +21 -7
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
- package/Components/MasterCell/index.tsx +5 -3
- package/Components/MasterCell/utils/__tests__/insertBetween.test.js +9 -0
- package/Components/MasterCell/utils/index.ts +17 -30
- package/Components/MeasurmentsPortal/BasicMeasurementsPortal.tsx +11 -7
- package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +10 -1
- package/Components/Navigator/StackNavigator.tsx +57 -0
- package/Components/Navigator/index.ts +1 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +14 -6
- 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/RouteManager/index.tsx +2 -2
- 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 +3 -0
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +4 -0
- package/Components/Screen/index.tsx +62 -54
- package/Components/Screen/navigationHandler.ts +6 -3
- package/Components/ScreenResolver/index.tsx +9 -12
- package/Components/Transitioner/Scene.tsx +24 -25
- package/Components/Transitioner/Transitioner.tsx +38 -43
- 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 +52 -24
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +25 -28
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +2 -14
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +73 -48
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +55 -34
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +104 -86
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +44 -5
- package/Components/VideoModal/ModalAnimation/utils.ts +7 -4
- package/Components/VideoModal/PlayerDetails.tsx +3 -3
- package/Components/VideoModal/PlayerWrapper.tsx +67 -60
- package/Components/VideoModal/VideoModal.tsx +17 -17
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +7 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +80 -14
- package/Components/VideoModal/hooks/useModalSize.ts +10 -12
- package/Components/VideoModal/utils.ts +5 -2
- package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +31 -40
- package/Components/Viewport/ViewportTracker/index.tsx +1 -0
- package/Components/Viewport/utils.js +1 -1
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -3
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
- 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/events/index.ts +1 -0
- package/package.json +5 -5
- package/Components/Layout/TV/TransitionOverlay.tsx +0 -64
- /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
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { last } from "ramda";
|
|
3
|
+
import { View, StyleSheet } from "react-native";
|
|
4
|
+
import {
|
|
5
|
+
findMenuPlugin,
|
|
6
|
+
getNavigationProps,
|
|
7
|
+
getPathAttributes,
|
|
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 {
|
|
13
|
+
useNavbarState,
|
|
14
|
+
useScreenBackgroundColor,
|
|
15
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks/screen";
|
|
16
|
+
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
17
|
+
|
|
18
|
+
import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
|
|
19
|
+
import { ScreenResolver } from "../../ScreenResolver";
|
|
20
|
+
import { useInitialFocus, useRestoreFocus } from "./hooks";
|
|
21
|
+
import { isPlayerPlugin } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
22
|
+
|
|
23
|
+
const styles = StyleSheet.create({
|
|
24
|
+
container: {
|
|
25
|
+
position: "absolute",
|
|
26
|
+
top: 0,
|
|
27
|
+
left: 0,
|
|
28
|
+
right: 0,
|
|
29
|
+
bottom: 0,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
type Components = {
|
|
34
|
+
NavBar: React.ComponentType<any>;
|
|
35
|
+
Background: React.ComponentType<any>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type Props = {
|
|
39
|
+
route: string;
|
|
40
|
+
Components: Components;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const getActiveRiver = ({
|
|
44
|
+
screenId,
|
|
45
|
+
screenType,
|
|
46
|
+
routeState,
|
|
47
|
+
rivers,
|
|
48
|
+
fallbackActiveRiver,
|
|
49
|
+
}) => {
|
|
50
|
+
if (rivers[screenId]) {
|
|
51
|
+
if (screenType === "hooks") {
|
|
52
|
+
const navigations = routeState?.state?.entry?.payload?.navigations;
|
|
53
|
+
|
|
54
|
+
if (navigations) {
|
|
55
|
+
return routeState.state.entry.payload;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return routeState?.state?.screen;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// screenId is not presented into rivers, use fallback instead
|
|
63
|
+
return fallbackActiveRiver;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const getNavigations = ({
|
|
67
|
+
screenId,
|
|
68
|
+
screenType,
|
|
69
|
+
routeState,
|
|
70
|
+
rivers,
|
|
71
|
+
fallbackNavigations,
|
|
72
|
+
}) => {
|
|
73
|
+
if (rivers[screenId]) {
|
|
74
|
+
// river presents
|
|
75
|
+
if (screenType === "hooks") {
|
|
76
|
+
const navigations = routeState?.state?.entry?.payload?.navigations;
|
|
77
|
+
|
|
78
|
+
if (navigations) {
|
|
79
|
+
return navigations;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return routeState?.state?.screen?.navigations;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// screenId is not presented into rivers, use fallback instead
|
|
87
|
+
return fallbackNavigations;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const Screen = ({ route, Components }: Props) => {
|
|
91
|
+
if (isNilOrEmpty(route)) {
|
|
92
|
+
throw Error("Required props: route is missing");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const navigator = useNavigation();
|
|
96
|
+
const { plugins = [], rivers = [] } = usePickFromState(["plugins", "rivers"]);
|
|
97
|
+
|
|
98
|
+
const pathAttributes = getPathAttributes({ pathname: route });
|
|
99
|
+
const routeState = navigator.getStackForPathname(route);
|
|
100
|
+
|
|
101
|
+
const { screenType, screenId } = last(pathAttributes);
|
|
102
|
+
|
|
103
|
+
const backgroundColor = useScreenBackgroundColor(screenId);
|
|
104
|
+
|
|
105
|
+
useInitialFocus();
|
|
106
|
+
useRestoreFocus();
|
|
107
|
+
|
|
108
|
+
const activeRiver = getActiveRiver({
|
|
109
|
+
screenId,
|
|
110
|
+
screenType,
|
|
111
|
+
routeState,
|
|
112
|
+
rivers,
|
|
113
|
+
fallbackActiveRiver: navigator.activeRiver,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const navigationProps = getNavigationProps({
|
|
117
|
+
navigator: {
|
|
118
|
+
// @ts-ignore
|
|
119
|
+
activeRiver,
|
|
120
|
+
// @ts-ignore
|
|
121
|
+
screenTitle: routeState.state.entry?.title || routeState.screen?.name,
|
|
122
|
+
},
|
|
123
|
+
category: "menu",
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const navigations = getNavigations({
|
|
127
|
+
screenId,
|
|
128
|
+
screenType,
|
|
129
|
+
routeState,
|
|
130
|
+
rivers,
|
|
131
|
+
fallbackNavigations: navigator.activeRiver.navigations,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const menuPlugin = findMenuPlugin(navigations, plugins);
|
|
135
|
+
|
|
136
|
+
const NavBar = (Components.NavBar ||
|
|
137
|
+
menuPlugin.module) as React.ComponentType<any>;
|
|
138
|
+
|
|
139
|
+
const isPlayer = isPlayerPlugin(routeState);
|
|
140
|
+
|
|
141
|
+
const { visible: isNavBarVisible } = useNavbarState();
|
|
142
|
+
|
|
143
|
+
const screenData =
|
|
144
|
+
screenType === "hooks" || isPlayer
|
|
145
|
+
? routeState?.state?.entry
|
|
146
|
+
: routeState?.state?.screen;
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<View style={[styles.container, { backgroundColor }]}>
|
|
150
|
+
<NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
|
|
151
|
+
<NavBar
|
|
152
|
+
isVisible={isNavBarVisible}
|
|
153
|
+
menuPlugin={menuPlugin}
|
|
154
|
+
navigationProps={navigationProps}
|
|
155
|
+
/>
|
|
156
|
+
</NavBarContainer>
|
|
157
|
+
<ScreenResolver
|
|
158
|
+
screenType={screenType}
|
|
159
|
+
screenId={screenId}
|
|
160
|
+
screenData={screenData}
|
|
161
|
+
groupId={route}
|
|
162
|
+
/>
|
|
163
|
+
</View>
|
|
164
|
+
);
|
|
165
|
+
};
|
|
@@ -10,6 +10,8 @@ const mock_navBarVisibleFlag = true;
|
|
|
10
10
|
|
|
11
11
|
const mockIsNavBarVisible = jest.fn(() => mock_navBarVisibleFlag);
|
|
12
12
|
|
|
13
|
+
const mockIsOrientationCompatible = jest.fn(() => true);
|
|
14
|
+
|
|
13
15
|
jest.mock("react-native-safe-area-context", () => ({
|
|
14
16
|
useSafeAreaInsets: () => ({ top: 44 }),
|
|
15
17
|
}));
|
|
@@ -21,6 +23,7 @@ jest.mock("../../RouteManager", () => ({
|
|
|
21
23
|
jest.mock(
|
|
22
24
|
"@applicaster/zapp-react-native-utils/appUtils/orientationHelper",
|
|
23
25
|
() => ({
|
|
26
|
+
isOrientationCompatible: mockIsOrientationCompatible,
|
|
24
27
|
allowedOrientationsForScreen: jest.fn(),
|
|
25
28
|
getOrientation: jest.fn(),
|
|
26
29
|
getScreenOrientation: jest.fn(),
|
|
@@ -11,7 +11,9 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
|
|
|
11
11
|
}
|
|
12
12
|
>
|
|
13
13
|
<View
|
|
14
|
+
hasMenu={false}
|
|
14
15
|
id="/river/testId"
|
|
16
|
+
pathname="/river/testId"
|
|
15
17
|
selected="testId"
|
|
16
18
|
testID="navBar"
|
|
17
19
|
title=""
|
|
@@ -41,7 +43,9 @@ exports[`<Screen Component /> when the navbar should show renders correctly 1`]
|
|
|
41
43
|
}
|
|
42
44
|
>
|
|
43
45
|
<View
|
|
46
|
+
hasMenu={false}
|
|
44
47
|
id="/river/testId"
|
|
48
|
+
pathname="/river/testId"
|
|
45
49
|
selected="testId"
|
|
46
50
|
testID="navBar"
|
|
47
51
|
title=""
|
|
@@ -3,11 +3,18 @@ import React from "react";
|
|
|
3
3
|
import * as R from "ramda";
|
|
4
4
|
import { View } from "react-native";
|
|
5
5
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
6
|
+
import {
|
|
7
|
+
isOrientationCompatible,
|
|
8
|
+
useGetScreenOrientation,
|
|
9
|
+
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
6
10
|
|
|
7
11
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
8
12
|
import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
9
|
-
import {
|
|
10
|
-
|
|
13
|
+
import {
|
|
14
|
+
shouldNavBarDisplayMenu,
|
|
15
|
+
getNavBarProps,
|
|
16
|
+
getScreenId,
|
|
17
|
+
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
11
18
|
import {
|
|
12
19
|
useDimensions,
|
|
13
20
|
useRoute,
|
|
@@ -18,20 +25,16 @@ import {
|
|
|
18
25
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
19
26
|
import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
|
|
20
27
|
|
|
21
|
-
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
22
28
|
import { RouteManager } from "../RouteManager";
|
|
23
29
|
import { useScreenConfiguration } from "../River/useScreenConfiguration";
|
|
24
30
|
import { useScreenOrientationHandler } from "./orientationHandler";
|
|
25
31
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
: "screen_id" in screenData
|
|
33
|
-
? screenData.screen_id
|
|
34
|
-
: fallbackRiver.id;
|
|
32
|
+
const screenStyles = {
|
|
33
|
+
flex: 1,
|
|
34
|
+
paddingTop: 0,
|
|
35
|
+
// paddingBottom: insets.bottom, // Should be applied directly by UI plugin
|
|
36
|
+
// paddingLeft: insets.left, // Should be applied directly by UI plugin
|
|
37
|
+
// paddingRight: insets.right, // Should be applied directly by UI plugin
|
|
35
38
|
};
|
|
36
39
|
|
|
37
40
|
function colorIsNotTransparent(color) {
|
|
@@ -42,9 +45,7 @@ function colorIsNotTransparent(color) {
|
|
|
42
45
|
R.replace("rgba(", "")
|
|
43
46
|
)(color);
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return alpha > 0;
|
|
48
|
+
return Number(layers?.[3]) > 0;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
function isValidColor(string) {
|
|
@@ -52,11 +53,11 @@ function isValidColor(string) {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
type Props = {
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
pathname: unknown;
|
|
57
|
+
screenData: unknown;
|
|
57
58
|
};
|
|
58
59
|
|
|
59
|
-
export function Screen(
|
|
60
|
+
export function Screen(_props: Props) {
|
|
60
61
|
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
61
62
|
const navigation = useNavigation();
|
|
62
63
|
const { plugins } = usePickFromState(["plugins"]);
|
|
@@ -64,31 +65,35 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
64
65
|
// Gets the data for the current screen configuration
|
|
65
66
|
const currentScreenData = useCurrentScreenData();
|
|
66
67
|
const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
|
|
67
|
-
const insets = useSafeAreaInsets();
|
|
68
68
|
|
|
69
|
-
const {
|
|
69
|
+
const {
|
|
70
|
+
width: screenWidth,
|
|
71
|
+
height,
|
|
72
|
+
deviceInfo,
|
|
73
|
+
} = useDimensions("screen", {
|
|
70
74
|
fullDimensions: true,
|
|
71
75
|
});
|
|
72
76
|
|
|
73
|
-
const
|
|
77
|
+
const { screenData, pathname } = useRoute();
|
|
74
78
|
|
|
75
79
|
const currentRiver = useScreenData(
|
|
76
|
-
getScreenId(
|
|
80
|
+
getScreenId(screenData, navigation.activeRiver)
|
|
77
81
|
);
|
|
78
82
|
|
|
79
83
|
const { title } = useNavbarState();
|
|
80
84
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
const isTablet = deviceInfo?.isTablet;
|
|
86
|
+
|
|
87
|
+
const { appData } = usePickFromState(["appData"]);
|
|
88
|
+
const isTabletPortrait = appData?.isTabletPortrait;
|
|
89
|
+
|
|
90
|
+
const layoutData = { isTablet, isTabletPortrait, width: screenWidth, height };
|
|
91
|
+
|
|
92
|
+
const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins);
|
|
93
|
+
|
|
94
|
+
const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(
|
|
95
|
+
getNavBarProps(currentRiver, pathname, title),
|
|
96
|
+
[currentRiver, pathname]
|
|
92
97
|
);
|
|
93
98
|
|
|
94
99
|
const NavBar = React.useMemo(
|
|
@@ -97,12 +102,10 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
97
102
|
"nav_bar",
|
|
98
103
|
currentRiver,
|
|
99
104
|
plugins
|
|
100
|
-
) as React.ComponentType<MobileNavBarPluginProps>,
|
|
105
|
+
) as React.ComponentType<MobileNavBarPluginProps & { hasMenu: boolean }>,
|
|
101
106
|
[]
|
|
102
107
|
);
|
|
103
108
|
|
|
104
|
-
const { screenData, pathname } = routeData;
|
|
105
|
-
|
|
106
109
|
const offlinePlugin = getComponentModule({
|
|
107
110
|
plugins,
|
|
108
111
|
components: {},
|
|
@@ -113,16 +116,12 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
113
116
|
|
|
114
117
|
const style = React.useMemo(
|
|
115
118
|
() => ({
|
|
116
|
-
|
|
119
|
+
...screenStyles,
|
|
117
120
|
backgroundColor: isValidColor(backgroundColor)
|
|
118
121
|
? backgroundColor
|
|
119
122
|
: theme.app_background_color,
|
|
120
|
-
paddingTop: 0,
|
|
121
|
-
// paddingBottom: insets.bottom, // Should be applied directly by UI plugin
|
|
122
|
-
// paddingLeft: insets.left, // Should be applied directly by UI plugin
|
|
123
|
-
// paddingRight: insets.right, // Should be applied directly by UI plugin
|
|
124
123
|
}),
|
|
125
|
-
[
|
|
124
|
+
[theme.app_background_color, backgroundColor]
|
|
126
125
|
);
|
|
127
126
|
|
|
128
127
|
const targetScreenData =
|
|
@@ -130,18 +129,27 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
130
129
|
|
|
131
130
|
useScreenOrientationHandler({ screenData: targetScreenData });
|
|
132
131
|
|
|
132
|
+
const orientation = useGetScreenOrientation(targetScreenData);
|
|
133
|
+
|
|
134
|
+
// We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
|
|
135
|
+
// This saves unnecessary re-renders and user will not see distorted aspect screen.
|
|
136
|
+
if (
|
|
137
|
+
!isOrientationCompatible({
|
|
138
|
+
orientation,
|
|
139
|
+
layoutData,
|
|
140
|
+
})
|
|
141
|
+
) {
|
|
142
|
+
return <View style={style} />;
|
|
143
|
+
}
|
|
144
|
+
|
|
133
145
|
return (
|
|
134
|
-
<
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<RouteManager pathname={pathname} screenData={screenData} />
|
|
143
|
-
</OfflineFallbackScreen>
|
|
144
|
-
</View>
|
|
145
|
-
</ScreenContextProvider>
|
|
146
|
+
<View style={style}>
|
|
147
|
+
{navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
|
|
148
|
+
|
|
149
|
+
<OfflineFallbackScreen screenData={targetScreenData}>
|
|
150
|
+
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
151
|
+
<RouteManager pathname={pathname} screenData={screenData} />
|
|
152
|
+
</OfflineFallbackScreen>
|
|
153
|
+
</View>
|
|
146
154
|
);
|
|
147
155
|
}
|
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
* is similar to the navbar, except that it covers scenarios where only the navbar (and not)
|
|
6
6
|
* the menu, will be hidden
|
|
7
7
|
*
|
|
8
|
+
* - playable screens
|
|
9
|
+
* - qb_search_screen
|
|
10
|
+
* - screen hooks that specify showNavBar or presentFullScreen
|
|
11
|
+
* - screens or nested screens that have allow_screen_plugin_presentation set to true
|
|
12
|
+
*
|
|
8
13
|
* @param {String} route current route of the screen
|
|
9
14
|
* @param {Object} screenData payload associated with the currently presented screen
|
|
10
15
|
* @returns {Boolean}
|
|
@@ -21,9 +26,7 @@ export function isMenuVisible(route, screenData) {
|
|
|
21
26
|
if (screenData?.hookPlugin) {
|
|
22
27
|
const hookPlugin = screenData?.hookPlugin?.module;
|
|
23
28
|
|
|
24
|
-
return
|
|
25
|
-
hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true || false
|
|
26
|
-
);
|
|
29
|
+
return hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
if (
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import
|
|
3
|
-
import { useDispatch } from "react-redux";
|
|
2
|
+
import { path, prop } from "ramda";
|
|
4
3
|
import {
|
|
5
4
|
findPluginByType,
|
|
6
5
|
findPluginByIdentifier,
|
|
@@ -15,7 +14,6 @@ import { componentsLogger } from "../../Helpers/logger";
|
|
|
15
14
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
16
15
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
17
16
|
import { useScreenAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
|
|
18
|
-
import { setAppStateHasFinishedTransitioning } from "@applicaster/zapp-react-native-redux/appState";
|
|
19
17
|
|
|
20
18
|
const logger = componentsLogger.addSubsystem("ScreenResolver");
|
|
21
19
|
|
|
@@ -32,12 +30,13 @@ type Props = {
|
|
|
32
30
|
nextFocusLeft?: React.Ref<any>;
|
|
33
31
|
nextFocusUp?: React.Ref<any>;
|
|
34
32
|
};
|
|
33
|
+
groupId?: string;
|
|
35
34
|
};
|
|
36
35
|
|
|
37
36
|
export function ScreenResolverComponent(props: Props) {
|
|
38
37
|
useScreenAnalytics(props);
|
|
39
38
|
|
|
40
|
-
const { screenType, screenId, screenData } = props;
|
|
39
|
+
const { screenType, screenId, screenData, groupId } = props;
|
|
41
40
|
|
|
42
41
|
const { hookPlugin } = screenData || {};
|
|
43
42
|
|
|
@@ -53,11 +52,8 @@ export function ScreenResolverComponent(props: Props) {
|
|
|
53
52
|
|
|
54
53
|
const [, setScreenContext] = ZappPipesScreenContext.useZappPipesContext();
|
|
55
54
|
|
|
56
|
-
const dispatch = useDispatch();
|
|
57
|
-
|
|
58
55
|
React.useEffect(() => {
|
|
59
56
|
setScreenContext(rivers[screenId]);
|
|
60
|
-
dispatch(setAppStateHasFinishedTransitioning());
|
|
61
57
|
}, [screenId]);
|
|
62
58
|
|
|
63
59
|
const ScreenPlugin =
|
|
@@ -81,6 +77,7 @@ export function ScreenResolverComponent(props: Props) {
|
|
|
81
77
|
item={screenData}
|
|
82
78
|
mode={mode === "PIP" ? "PIP" : "FULLSCREEN"}
|
|
83
79
|
isModal={false}
|
|
80
|
+
groupId={groupId}
|
|
84
81
|
/>
|
|
85
82
|
);
|
|
86
83
|
}
|
|
@@ -98,14 +95,14 @@ export function ScreenResolverComponent(props: Props) {
|
|
|
98
95
|
}
|
|
99
96
|
|
|
100
97
|
const ScreenComponent =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
path(["module", "Component"], ScreenPlugin) ||
|
|
99
|
+
prop("module", ScreenPlugin) ||
|
|
100
|
+
prop("Component", ScreenPlugin) ||
|
|
104
101
|
ScreenPlugin;
|
|
105
102
|
|
|
106
103
|
const configuration =
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
prop("configuration", ScreenPlugin) ||
|
|
105
|
+
prop("__plugin_configuration", ScreenComponent);
|
|
109
106
|
|
|
110
107
|
if (ScreenComponent) {
|
|
111
108
|
return (
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
Animated,
|
|
4
|
-
useWindowDimensions,
|
|
5
|
-
ViewProps,
|
|
6
|
-
ViewStyle,
|
|
7
|
-
} from "react-native";
|
|
2
|
+
import { Animated, ViewProps, ViewStyle } from "react-native";
|
|
8
3
|
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
9
4
|
import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
5
|
+
import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
|
|
6
|
+
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
10
7
|
|
|
11
8
|
type Props = {
|
|
12
9
|
children: any;
|
|
@@ -16,6 +13,8 @@ type Props = {
|
|
|
16
13
|
animating: boolean;
|
|
17
14
|
contentStyle: ViewStyle;
|
|
18
15
|
pathname: string;
|
|
16
|
+
isActive: boolean;
|
|
17
|
+
screenData: NavigationScreenData;
|
|
19
18
|
};
|
|
20
19
|
|
|
21
20
|
/**
|
|
@@ -38,34 +37,34 @@ export function Scene({
|
|
|
38
37
|
animating,
|
|
39
38
|
contentStyle,
|
|
40
39
|
pathname,
|
|
40
|
+
isActive = false,
|
|
41
|
+
screenData,
|
|
41
42
|
}: Props) {
|
|
43
|
+
const [initialScreenData, setInitialScreenData] = React.useState(screenData);
|
|
44
|
+
|
|
45
|
+
React.useLayoutEffect(() => {
|
|
46
|
+
if (isActive) {
|
|
47
|
+
setInitialScreenData(screenData);
|
|
48
|
+
}
|
|
49
|
+
}, [screenData, isActive]);
|
|
50
|
+
|
|
42
51
|
const frame = useSafeAreaFrame();
|
|
43
|
-
const { height, width } = useWindowDimensions();
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
// Safe frame takes too long to update,
|
|
47
|
-
// so we can not rely on it there, and use height and width instead.
|
|
48
|
-
return (
|
|
49
|
-
<Animated.View
|
|
50
|
-
pointerEvents={pointerEvents}
|
|
51
|
-
style={[style, contentStyle, { height, width }]}
|
|
52
|
-
>
|
|
53
|
-
<PathnameContext.Provider value={pathname}>
|
|
54
|
-
{children}
|
|
55
|
-
</PathnameContext.Provider>
|
|
56
|
-
<Animated.View style={overlayStyle} />
|
|
57
|
-
</Animated.View>
|
|
58
|
-
);
|
|
59
|
-
}
|
|
53
|
+
const isAnimating = animating && overlayStyle;
|
|
60
54
|
|
|
61
55
|
return (
|
|
62
56
|
<Animated.View
|
|
63
57
|
pointerEvents={pointerEvents}
|
|
64
58
|
style={[style, contentStyle, frame]}
|
|
65
59
|
>
|
|
66
|
-
<
|
|
67
|
-
{
|
|
68
|
-
|
|
60
|
+
<ScreenDataContext.Provider value={initialScreenData}>
|
|
61
|
+
<PathnameContext.Provider value={pathname}>
|
|
62
|
+
<ScreenContextProvider pathname={pathname}>
|
|
63
|
+
{children}
|
|
64
|
+
</ScreenContextProvider>
|
|
65
|
+
</PathnameContext.Provider>
|
|
66
|
+
</ScreenDataContext.Provider>
|
|
67
|
+
{isAnimating && <Animated.View style={overlayStyle} />}
|
|
69
68
|
</Animated.View>
|
|
70
69
|
);
|
|
71
70
|
}
|