@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4433422595 → 12.0.0-alpha.4462655310
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 +2 -2
- package/Components/Cell/Cell.tsx +5 -9
- package/Components/Cell/CellWithFocusable.tsx +17 -5
- 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/__tests__/__snapshots__/index.test.tsx.snap +10 -50
- package/Components/Layout/TV/__tests__/index.test.tsx +19 -75
- package/Components/Layout/TV/index.tsx +26 -116
- 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/Image/Image.ios.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +14 -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/tv/ButtonContainerView/index.android.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +4 -1
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -3
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
- package/Components/MasterCell/utils/index.ts +33 -35
- package/Components/MeasurmentsPortal/BasicMeasurementsPortal.tsx +11 -7
- package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +10 -1
- package/Components/Navigator/StackNavigator.tsx +48 -0
- package/Components/Navigator/index.ts +1 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +23 -3
- 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 +6 -0
- 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 +119 -28
- 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 +64 -25
- package/Components/ScreenResolver/index.tsx +3 -1
- package/Components/Transitioner/Scene.tsx +24 -19
- package/Components/Transitioner/Transitioner.tsx +21 -28
- 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 +18 -1
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +20 -5
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +0 -5
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +78 -0
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +352 -0
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +158 -0
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +461 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +154 -0
- package/Components/VideoModal/ModalAnimation/index.ts +15 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +299 -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 +151 -119
- 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/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/VideoModal/hooks/usePosition.ts +0 -50
- /package/Contexts/{index.js → index.ts} +0 -0
|
@@ -1,15 +1,30 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
import { last, pathOr } from "ramda";
|
|
3
|
-
import {
|
|
3
|
+
import { View, StyleSheet } from "react-native";
|
|
4
4
|
import {
|
|
5
5
|
getNavigationProps,
|
|
6
6
|
getPathAttributes,
|
|
7
7
|
resolveNavigationPlugin,
|
|
8
8
|
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
9
9
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
10
|
-
import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
|
|
11
10
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
12
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
|
+
});
|
|
13
28
|
|
|
14
29
|
type Components = {
|
|
15
30
|
NavBar: React.ComponentType<any>;
|
|
@@ -21,68 +36,144 @@ type Props = {
|
|
|
21
36
|
Components: Components;
|
|
22
37
|
};
|
|
23
38
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
39
|
+
const getPluginType = pathOr("unknown_plugin_type", [
|
|
40
|
+
"state",
|
|
41
|
+
"screen",
|
|
42
|
+
"plugin_type",
|
|
43
|
+
]);
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
const isPlayerPlugin = (routeState): boolean =>
|
|
46
|
+
getPluginType(routeState) === "player";
|
|
47
|
+
|
|
48
|
+
const isLoginPlugin = (routeState): boolean =>
|
|
49
|
+
getPluginType(routeState) === "login";
|
|
50
|
+
|
|
51
|
+
const getActiveRiver = ({
|
|
52
|
+
screenId,
|
|
53
|
+
screenType,
|
|
54
|
+
routeState,
|
|
55
|
+
rivers,
|
|
56
|
+
fallbackActiveRiver,
|
|
57
|
+
}) => {
|
|
58
|
+
if (rivers[screenId]) {
|
|
59
|
+
if (screenType === "hooks") {
|
|
60
|
+
const navigations = routeState?.state?.entry?.payload?.navigations;
|
|
61
|
+
|
|
62
|
+
if (navigations) {
|
|
63
|
+
return routeState.state.entry.payload;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return routeState?.state?.screen;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// screenId is not presented into rivers, use fallback instead
|
|
71
|
+
return fallbackActiveRiver;
|
|
32
72
|
};
|
|
33
73
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
74
|
+
const getNavigations = ({
|
|
75
|
+
screenId,
|
|
76
|
+
screenType,
|
|
77
|
+
routeState,
|
|
78
|
+
rivers,
|
|
79
|
+
fallbackNavigations,
|
|
80
|
+
}) => {
|
|
81
|
+
if (rivers[screenId]) {
|
|
82
|
+
// river presents
|
|
83
|
+
if (screenType === "hooks") {
|
|
84
|
+
const navigations = routeState?.state?.entry?.payload?.navigations;
|
|
85
|
+
|
|
86
|
+
if (navigations) {
|
|
87
|
+
return navigations;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return routeState?.state?.screen?.navigations;
|
|
37
92
|
}
|
|
38
93
|
|
|
39
|
-
|
|
40
|
-
|
|
94
|
+
// screenId is not presented into rivers, use fallback instead
|
|
95
|
+
return fallbackNavigations;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const Screen = ({ route, Components }: Props) => {
|
|
99
|
+
if (isNilOrEmpty(route)) {
|
|
100
|
+
throw Error("Required props: route is missing");
|
|
101
|
+
}
|
|
41
102
|
|
|
42
|
-
const
|
|
43
|
-
const
|
|
103
|
+
const navigator = useNavigation();
|
|
104
|
+
const { plugins = [], rivers = [] } = usePickFromState(["plugins", "rivers"]);
|
|
44
105
|
|
|
45
|
-
|
|
106
|
+
const pathAttributes = getPathAttributes({ pathname: route });
|
|
107
|
+
const routeState = navigator.getStackForPathname(route);
|
|
46
108
|
|
|
47
109
|
const { screenType, screenId } = last(pathAttributes);
|
|
48
110
|
|
|
111
|
+
const backgroundColor = useScreenBackgroundColor(screenId);
|
|
112
|
+
|
|
113
|
+
useInitialFocus();
|
|
114
|
+
useRestoreFocus();
|
|
115
|
+
|
|
116
|
+
const activeRiver = getActiveRiver({
|
|
117
|
+
screenId,
|
|
118
|
+
screenType,
|
|
119
|
+
routeState,
|
|
120
|
+
rivers,
|
|
121
|
+
fallbackActiveRiver: navigator.activeRiver,
|
|
122
|
+
});
|
|
123
|
+
|
|
49
124
|
const navigationProps = getNavigationProps({
|
|
50
125
|
navigator: {
|
|
51
|
-
|
|
126
|
+
// @ts-ignore
|
|
127
|
+
activeRiver,
|
|
52
128
|
// @ts-ignore
|
|
53
129
|
screenTitle: routeState.state.entry?.title || routeState.screen?.name,
|
|
54
130
|
},
|
|
55
131
|
category: "menu",
|
|
56
132
|
});
|
|
57
133
|
|
|
134
|
+
const navigations = getNavigations({
|
|
135
|
+
screenId,
|
|
136
|
+
screenType,
|
|
137
|
+
routeState,
|
|
138
|
+
rivers,
|
|
139
|
+
fallbackNavigations: navigator.activeRiver.navigations,
|
|
140
|
+
});
|
|
141
|
+
|
|
58
142
|
const menuPlugin = resolveNavigationPlugin({
|
|
59
143
|
category: "menu",
|
|
60
|
-
navigations
|
|
144
|
+
navigations,
|
|
61
145
|
plugins,
|
|
62
146
|
}) as QuickBrickPlugin;
|
|
63
147
|
|
|
64
|
-
const NavBar = (
|
|
148
|
+
const NavBar = (Components.NavBar ||
|
|
65
149
|
menuPlugin.module) as React.ComponentType<any>;
|
|
66
150
|
|
|
67
|
-
const
|
|
151
|
+
const isPlayer = isPlayerPlugin(routeState);
|
|
152
|
+
const isLogin = isLoginPlugin(routeState);
|
|
153
|
+
|
|
154
|
+
const isNavBarVisible = !isPlayer && !isLogin;
|
|
155
|
+
|
|
156
|
+
const screenData =
|
|
157
|
+
screenType === "hooks" || isPlayer
|
|
158
|
+
? routeState?.state?.entry
|
|
159
|
+
: routeState?.state?.screen;
|
|
68
160
|
|
|
69
161
|
return (
|
|
70
|
-
|
|
162
|
+
<View style={[styles.container, { backgroundColor }]}>
|
|
71
163
|
<NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
|
|
72
164
|
<NavBar
|
|
73
|
-
groupId={
|
|
165
|
+
groupId={route}
|
|
74
166
|
isVisible={isNavBarVisible}
|
|
75
167
|
menuPlugin={menuPlugin}
|
|
76
168
|
navigationProps={navigationProps}
|
|
77
|
-
// Maybe activeRiver?
|
|
78
169
|
/>
|
|
79
170
|
</NavBarContainer>
|
|
80
171
|
<ScreenResolver
|
|
81
172
|
screenType={screenType}
|
|
82
173
|
screenId={screenId}
|
|
83
|
-
screenData={
|
|
84
|
-
groupId={
|
|
174
|
+
screenData={screenData}
|
|
175
|
+
groupId={route}
|
|
85
176
|
/>
|
|
86
|
-
|
|
177
|
+
</View>
|
|
87
178
|
);
|
|
88
179
|
};
|
|
@@ -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,10 +3,17 @@ 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 {
|
|
13
|
+
import {
|
|
14
|
+
getNavigationPropsV2,
|
|
15
|
+
resolveNavigationPlugin,
|
|
16
|
+
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
10
17
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
11
18
|
import {
|
|
12
19
|
useDimensions,
|
|
@@ -52,11 +59,11 @@ function isValidColor(string) {
|
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
type Props = {
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
pathname: unknown;
|
|
63
|
+
screenData: unknown;
|
|
57
64
|
};
|
|
58
65
|
|
|
59
|
-
export function Screen(
|
|
66
|
+
export function Screen(_props: Props) {
|
|
60
67
|
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
61
68
|
const navigation = useNavigation();
|
|
62
69
|
const { plugins } = usePickFromState(["plugins"]);
|
|
@@ -66,30 +73,53 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
66
73
|
const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
|
|
67
74
|
const insets = useSafeAreaInsets();
|
|
68
75
|
|
|
69
|
-
const {
|
|
76
|
+
const {
|
|
77
|
+
width: screenWidth,
|
|
78
|
+
height,
|
|
79
|
+
deviceInfo,
|
|
80
|
+
} = useDimensions("screen", {
|
|
70
81
|
fullDimensions: true,
|
|
71
82
|
});
|
|
72
83
|
|
|
73
|
-
const
|
|
84
|
+
const { screenData, pathname } = useRoute();
|
|
74
85
|
|
|
75
86
|
const currentRiver = useScreenData(
|
|
76
|
-
getScreenId(
|
|
87
|
+
getScreenId(screenData, navigation.activeRiver)
|
|
77
88
|
);
|
|
78
89
|
|
|
79
90
|
const { title } = useNavbarState();
|
|
80
91
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
const isTablet = deviceInfo?.isTablet;
|
|
93
|
+
|
|
94
|
+
const { appData } = usePickFromState(["appData"]);
|
|
95
|
+
const isTabletPortrait = appData?.isTabletPortrait;
|
|
96
|
+
|
|
97
|
+
const layoutData = { isTablet, isTabletPortrait, width: screenWidth, height };
|
|
98
|
+
|
|
99
|
+
const hasMenu =
|
|
100
|
+
resolveNavigationPlugin({
|
|
101
|
+
category: "menu",
|
|
102
|
+
navigations: currentRiver.navigations,
|
|
103
|
+
plugins,
|
|
104
|
+
})?.identifier === "quick_brick_side_menu";
|
|
105
|
+
|
|
106
|
+
const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(() => {
|
|
107
|
+
const props = getNavigationPropsV2({
|
|
108
|
+
currentRiver,
|
|
109
|
+
title,
|
|
110
|
+
category: "nav_bar",
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (props) {
|
|
114
|
+
return {
|
|
115
|
+
...props,
|
|
116
|
+
id: pathname,
|
|
117
|
+
pathname: pathname,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return null;
|
|
122
|
+
}, [currentRiver, pathname]);
|
|
93
123
|
|
|
94
124
|
const NavBar = React.useMemo(
|
|
95
125
|
() =>
|
|
@@ -97,12 +127,10 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
97
127
|
"nav_bar",
|
|
98
128
|
currentRiver,
|
|
99
129
|
plugins
|
|
100
|
-
) as React.ComponentType<MobileNavBarPluginProps>,
|
|
130
|
+
) as React.ComponentType<MobileNavBarPluginProps & { hasMenu: boolean }>,
|
|
101
131
|
[]
|
|
102
132
|
);
|
|
103
133
|
|
|
104
|
-
const { screenData, pathname } = routeData;
|
|
105
|
-
|
|
106
134
|
const offlinePlugin = getComponentModule({
|
|
107
135
|
plugins,
|
|
108
136
|
components: {},
|
|
@@ -130,12 +158,23 @@ export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
|
130
158
|
|
|
131
159
|
useScreenOrientationHandler({ screenData: targetScreenData });
|
|
132
160
|
|
|
161
|
+
const orientation = useGetScreenOrientation(targetScreenData);
|
|
162
|
+
|
|
163
|
+
// We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
|
|
164
|
+
// This saves unnecessary re-renders and user will not see distorted aspect screen.
|
|
165
|
+
if (
|
|
166
|
+
!isOrientationCompatible({
|
|
167
|
+
orientation,
|
|
168
|
+
layoutData,
|
|
169
|
+
})
|
|
170
|
+
) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
133
174
|
return (
|
|
134
175
|
<ScreenContextProvider pathname={pathname}>
|
|
135
176
|
<View style={style}>
|
|
136
|
-
<NavBar
|
|
137
|
-
{...{ ...(navBarProps as MobileNavBarPluginProps), id: pathname }}
|
|
138
|
-
/>
|
|
177
|
+
{navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
|
|
139
178
|
|
|
140
179
|
<OfflineFallbackScreen screenData={targetScreenData}>
|
|
141
180
|
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
@@ -32,12 +32,13 @@ type Props = {
|
|
|
32
32
|
nextFocusLeft?: React.Ref<any>;
|
|
33
33
|
nextFocusUp?: React.Ref<any>;
|
|
34
34
|
};
|
|
35
|
+
groupId?: string;
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
export function ScreenResolverComponent(props: Props) {
|
|
38
39
|
useScreenAnalytics(props);
|
|
39
40
|
|
|
40
|
-
const { screenType, screenId, screenData } = props;
|
|
41
|
+
const { screenType, screenId, screenData, groupId } = props;
|
|
41
42
|
|
|
42
43
|
const { hookPlugin } = screenData || {};
|
|
43
44
|
|
|
@@ -81,6 +82,7 @@ export function ScreenResolverComponent(props: Props) {
|
|
|
81
82
|
item={screenData}
|
|
82
83
|
mode={mode === "PIP" ? "PIP" : "FULLSCREEN"}
|
|
83
84
|
isModal={false}
|
|
85
|
+
groupId={groupId}
|
|
84
86
|
/>
|
|
85
87
|
);
|
|
86
88
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from "react-native";
|
|
8
8
|
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
9
9
|
import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
10
|
+
import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
|
|
10
11
|
|
|
11
12
|
type Props = {
|
|
12
13
|
children: any;
|
|
@@ -16,6 +17,8 @@ type Props = {
|
|
|
16
17
|
animating: boolean;
|
|
17
18
|
contentStyle: ViewStyle;
|
|
18
19
|
pathname: string;
|
|
20
|
+
isActive: boolean;
|
|
21
|
+
screenData: NavigationScreenData;
|
|
19
22
|
};
|
|
20
23
|
|
|
21
24
|
/**
|
|
@@ -38,34 +41,36 @@ export function Scene({
|
|
|
38
41
|
animating,
|
|
39
42
|
contentStyle,
|
|
40
43
|
pathname,
|
|
44
|
+
isActive = false,
|
|
45
|
+
screenData,
|
|
41
46
|
}: Props) {
|
|
47
|
+
const [initialScreenData, setInitialScreenData] = React.useState(screenData);
|
|
48
|
+
|
|
49
|
+
React.useLayoutEffect(() => {
|
|
50
|
+
if (isActive) {
|
|
51
|
+
setInitialScreenData(screenData);
|
|
52
|
+
}
|
|
53
|
+
}, [screenData, isActive]);
|
|
54
|
+
|
|
42
55
|
const frame = useSafeAreaFrame();
|
|
43
56
|
const { height, width } = useWindowDimensions();
|
|
44
57
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
}
|
|
58
|
+
// Safe frame takes too long to update,
|
|
59
|
+
// so we can not rely on it there, and use height and width instead.
|
|
60
|
+
const isAnimating = animating && overlayStyle;
|
|
61
|
+
const dimensions = isAnimating ? { height, width } : frame;
|
|
60
62
|
|
|
61
63
|
return (
|
|
62
64
|
<Animated.View
|
|
63
65
|
pointerEvents={pointerEvents}
|
|
64
|
-
style={[style, contentStyle,
|
|
66
|
+
style={[style, contentStyle, dimensions]}
|
|
65
67
|
>
|
|
66
|
-
<
|
|
67
|
-
{
|
|
68
|
-
|
|
68
|
+
<ScreenDataContext.Provider value={initialScreenData}>
|
|
69
|
+
<PathnameContext.Provider value={pathname}>
|
|
70
|
+
{children}
|
|
71
|
+
</PathnameContext.Provider>
|
|
72
|
+
</ScreenDataContext.Provider>
|
|
73
|
+
{isAnimating && <Animated.View style={overlayStyle} />}
|
|
69
74
|
</Animated.View>
|
|
70
75
|
);
|
|
71
76
|
}
|
|
@@ -4,10 +4,7 @@ import * as R from "ramda";
|
|
|
4
4
|
|
|
5
5
|
import { AnimationManager } from "./AnimationManager";
|
|
6
6
|
import { Scene } from "./Scene";
|
|
7
|
-
|
|
8
|
-
getScreenOrientation,
|
|
9
|
-
isOrientationCompatible,
|
|
10
|
-
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
7
|
+
|
|
11
8
|
import {
|
|
12
9
|
getSceneByRoute,
|
|
13
10
|
shouldSkipAnimationForPreviousWebViewScene,
|
|
@@ -277,33 +274,25 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
277
274
|
// so only a single scene should be rendered,
|
|
278
275
|
// instead of dangerous nulls or duplicates.
|
|
279
276
|
renderSingleScene({ scenes, to }) {
|
|
280
|
-
const { contentStyle
|
|
281
|
-
const screenData =
|
|
282
|
-
|
|
283
|
-
const orientation = getScreenOrientation({
|
|
284
|
-
screenData,
|
|
285
|
-
layoutData,
|
|
286
|
-
});
|
|
277
|
+
const { contentStyle } = this.props;
|
|
278
|
+
const screenData = this.props.children.props.screenData;
|
|
279
|
+
const pathname = scenes[to.index].key;
|
|
287
280
|
|
|
288
|
-
// We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
|
|
289
|
-
// This saves unnecessary re-renders and user will not see distorted aspect screen.
|
|
290
281
|
return (
|
|
291
282
|
<View style={styles.container}>
|
|
292
|
-
{scenes[to.index] &&
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
</Scene>
|
|
306
|
-
)}
|
|
283
|
+
{scenes[to.index] && (
|
|
284
|
+
<Scene
|
|
285
|
+
{...{ style: to.style }}
|
|
286
|
+
pathname={pathname}
|
|
287
|
+
isActive={pathname === this.props.navigator.currentRoute}
|
|
288
|
+
contentStyle={contentStyle}
|
|
289
|
+
key={scenes[to.index].key}
|
|
290
|
+
screenUniqueId={scenes[to.index].screenUniqueId}
|
|
291
|
+
screenData={screenData}
|
|
292
|
+
>
|
|
293
|
+
{scenes[to.index].children}
|
|
294
|
+
</Scene>
|
|
295
|
+
)}
|
|
307
296
|
</View>
|
|
308
297
|
);
|
|
309
298
|
}
|
|
@@ -319,12 +308,14 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
319
308
|
<Scene
|
|
320
309
|
key={scenes[from.index].key}
|
|
321
310
|
pathname={scenes[from.index].key}
|
|
311
|
+
isActive={scenes[from.index].key === this.props.navigator.currentRoute}
|
|
322
312
|
style={from.style}
|
|
323
313
|
pointerEvents="none"
|
|
324
314
|
overlayStyle={from.overlayStyle}
|
|
325
315
|
animating={this.state.animating}
|
|
326
316
|
contentStyle={contentStyle}
|
|
327
317
|
screenUniqueId={scenes[from.index].screenUniqueId}
|
|
318
|
+
screenData={scenes[from.index].children.props.screenData}
|
|
328
319
|
>
|
|
329
320
|
{scenes[from.index].children}
|
|
330
321
|
</Scene>
|
|
@@ -333,12 +324,14 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
333
324
|
const toScene = scenes[to.index] && (
|
|
334
325
|
<Scene
|
|
335
326
|
pathname={scenes[to.index].key}
|
|
327
|
+
isActive={scenes[to.index].key === this.props.navigator.currentRoute}
|
|
336
328
|
key={scenes[to.index].key}
|
|
337
329
|
style={to.style}
|
|
338
330
|
overlayStyle={to.overlayStyle}
|
|
339
331
|
animating={this.state.animating}
|
|
340
332
|
contentStyle={contentStyle}
|
|
341
333
|
screenUniqueId={scenes[to.index].screenUniqueId}
|
|
334
|
+
screenData={this.props.children.props.screenData}
|
|
342
335
|
>
|
|
343
336
|
{scenes[to.index].children}
|
|
344
337
|
</Scene>
|
|
@@ -21,7 +21,9 @@ exports[`<Scene /> renders correctly 1`] = `
|
|
|
21
21
|
]
|
|
22
22
|
}
|
|
23
23
|
>
|
|
24
|
-
<ContextProvider
|
|
24
|
+
<ContextProvider>
|
|
25
|
+
<ContextProvider />
|
|
26
|
+
</ContextProvider>
|
|
25
27
|
</ForwardRef(AnimatedComponentWrapper)>
|
|
26
28
|
`;
|
|
27
29
|
|
|
@@ -43,7 +45,9 @@ exports[`<Scene /> renders the overlay while animating 1`] = `
|
|
|
43
45
|
]
|
|
44
46
|
}
|
|
45
47
|
>
|
|
46
|
-
<ContextProvider
|
|
48
|
+
<ContextProvider>
|
|
49
|
+
<ContextProvider />
|
|
50
|
+
</ContextProvider>
|
|
47
51
|
<ForwardRef(AnimatedComponentWrapper)
|
|
48
52
|
style={
|
|
49
53
|
Object {
|
|
@@ -10,7 +10,11 @@ import { Component } from "react";
|
|
|
10
10
|
|
|
11
11
|
const { log_debug, log_info, log_error } = loggerLiveImageManager;
|
|
12
12
|
|
|
13
|
-
export type LiveImageManagerEvent =
|
|
13
|
+
export type LiveImageManagerEvent =
|
|
14
|
+
| "onEnd"
|
|
15
|
+
| "onStart"
|
|
16
|
+
| "onError"
|
|
17
|
+
| "onDestroy";
|
|
14
18
|
|
|
15
19
|
export type LiveImageManagerListenerData = {
|
|
16
20
|
id: string;
|
|
@@ -102,6 +106,16 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
this.items = this.items.filter((i) => i !== item);
|
|
109
|
+
|
|
110
|
+
this.invokeListenersUpdate({
|
|
111
|
+
callbackName: "onDestroy",
|
|
112
|
+
event: {
|
|
113
|
+
item,
|
|
114
|
+
playerId: this.currentlyPlaying?.playerId,
|
|
115
|
+
primaryPlayerId: this.primaryPlayer?.playerId,
|
|
116
|
+
entry: item.getPlayer().getEntry(),
|
|
117
|
+
},
|
|
118
|
+
});
|
|
105
119
|
};
|
|
106
120
|
|
|
107
121
|
public onViewportEnter = (item: LiveImage) => {
|
|
@@ -351,6 +365,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
351
365
|
item,
|
|
352
366
|
playerId: this.currentlyPlaying?.playerId,
|
|
353
367
|
primaryPlayerId: this.primaryPlayer?.playerId,
|
|
368
|
+
entry: item.getPlayer().getEntry(),
|
|
354
369
|
},
|
|
355
370
|
});
|
|
356
371
|
};
|
|
@@ -385,6 +400,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
385
400
|
item,
|
|
386
401
|
playerId: this.currentlyPlaying?.playerId,
|
|
387
402
|
primaryPlayerId: this.primaryPlayer?.playerId,
|
|
403
|
+
entry: item.getPlayer().getEntry(),
|
|
388
404
|
},
|
|
389
405
|
});
|
|
390
406
|
};
|
|
@@ -419,6 +435,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
419
435
|
error,
|
|
420
436
|
playerId: currentItem?.playerId,
|
|
421
437
|
primaryPlayerId: currentItem?.playerId,
|
|
438
|
+
entry: item.getPlayer().getEntry(),
|
|
422
439
|
},
|
|
423
440
|
});
|
|
424
441
|
};
|