@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4840257570 → 12.0.0-alpha.4885205607
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/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 +2 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +88 -112
- package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +20 -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/dataAdapter.ts +21 -7
- package/Components/MasterCell/index.tsx +5 -3
- package/Components/MasterCell/utils/__tests__/insertBetween.test.js +9 -0
- package/Components/MasterCell/utils/index.ts +32 -29
- package/Components/Navigator/StackNavigator.tsx +57 -0
- package/Components/Navigator/index.ts +1 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +5 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +6 -0
- package/Components/River/RefreshControl.tsx +2 -2
- 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/index.tsx +55 -58
- package/Components/Screen/navigationHandler.ts +5 -0
- package/Components/ScreenResolver/index.tsx +9 -12
- package/Components/Transitioner/Scene.tsx +32 -26
- 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 +26 -24
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +2 -14
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +56 -43
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +42 -32
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +104 -86
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +32 -4
- 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 +4 -4
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +7 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +32 -12
- 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/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/ScreenDataContext/index.tsx +20 -0
- package/Contexts/ZappPipesContext/ZappPipesEntryContext.ts +1 -1
- 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
|
@@ -3,14 +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
13
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
shouldNavBarDisplayMenu,
|
|
15
|
+
getNavBarProps,
|
|
16
|
+
getScreenId,
|
|
12
17
|
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
13
|
-
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
14
18
|
import {
|
|
15
19
|
useDimensions,
|
|
16
20
|
useRoute,
|
|
@@ -21,20 +25,16 @@ import {
|
|
|
21
25
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
22
26
|
import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
|
|
23
27
|
|
|
24
|
-
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
25
28
|
import { RouteManager } from "../RouteManager";
|
|
26
29
|
import { useScreenConfiguration } from "../River/useScreenConfiguration";
|
|
27
30
|
import { useScreenOrientationHandler } from "./orientationHandler";
|
|
28
31
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
: "screen_id" in screenData
|
|
36
|
-
? screenData.screen_id
|
|
37
|
-
: 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
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
function colorIsNotTransparent(color) {
|
|
@@ -45,9 +45,7 @@ function colorIsNotTransparent(color) {
|
|
|
45
45
|
R.replace("rgba(", "")
|
|
46
46
|
)(color);
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return alpha > 0;
|
|
48
|
+
return Number(layers?.[3]) > 0;
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
function isValidColor(string) {
|
|
@@ -67,9 +65,12 @@ export function Screen(_props: Props) {
|
|
|
67
65
|
// Gets the data for the current screen configuration
|
|
68
66
|
const currentScreenData = useCurrentScreenData();
|
|
69
67
|
const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
|
|
70
|
-
const insets = useSafeAreaInsets();
|
|
71
68
|
|
|
72
|
-
const {
|
|
69
|
+
const {
|
|
70
|
+
width: screenWidth,
|
|
71
|
+
height,
|
|
72
|
+
deviceInfo,
|
|
73
|
+
} = useDimensions("screen", {
|
|
73
74
|
fullDimensions: true,
|
|
74
75
|
});
|
|
75
76
|
|
|
@@ -81,30 +82,19 @@ export function Screen(_props: Props) {
|
|
|
81
82
|
|
|
82
83
|
const { title } = useNavbarState();
|
|
83
84
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (props) {
|
|
99
|
-
return {
|
|
100
|
-
...props,
|
|
101
|
-
id: pathname,
|
|
102
|
-
pathname: pathname,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return null;
|
|
107
|
-
}, [currentRiver, pathname]);
|
|
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]
|
|
97
|
+
);
|
|
108
98
|
|
|
109
99
|
const NavBar = React.useMemo(
|
|
110
100
|
() =>
|
|
@@ -126,16 +116,12 @@ export function Screen(_props: Props) {
|
|
|
126
116
|
|
|
127
117
|
const style = React.useMemo(
|
|
128
118
|
() => ({
|
|
129
|
-
|
|
119
|
+
...screenStyles,
|
|
130
120
|
backgroundColor: isValidColor(backgroundColor)
|
|
131
121
|
? backgroundColor
|
|
132
122
|
: theme.app_background_color,
|
|
133
|
-
paddingTop: 0,
|
|
134
|
-
// paddingBottom: insets.bottom, // Should be applied directly by UI plugin
|
|
135
|
-
// paddingLeft: insets.left, // Should be applied directly by UI plugin
|
|
136
|
-
// paddingRight: insets.right, // Should be applied directly by UI plugin
|
|
137
123
|
}),
|
|
138
|
-
[
|
|
124
|
+
[theme.app_background_color, backgroundColor]
|
|
139
125
|
);
|
|
140
126
|
|
|
141
127
|
const targetScreenData =
|
|
@@ -143,16 +129,27 @@ export function Screen(_props: Props) {
|
|
|
143
129
|
|
|
144
130
|
useScreenOrientationHandler({ screenData: targetScreenData });
|
|
145
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
|
+
|
|
146
145
|
return (
|
|
147
|
-
<
|
|
148
|
-
<
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
</View>
|
|
156
|
-
</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>
|
|
157
154
|
);
|
|
158
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}
|
|
@@ -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,41 @@ 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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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;
|
|
54
|
+
|
|
55
|
+
const dimensions = isAnimating
|
|
56
|
+
? {
|
|
57
|
+
height: "100%",
|
|
58
|
+
width: "100%",
|
|
59
|
+
}
|
|
60
|
+
: frame;
|
|
60
61
|
|
|
61
62
|
return (
|
|
62
63
|
<Animated.View
|
|
63
64
|
pointerEvents={pointerEvents}
|
|
64
|
-
style={[style, contentStyle,
|
|
65
|
+
style={[style, contentStyle, dimensions]}
|
|
65
66
|
>
|
|
66
|
-
<
|
|
67
|
-
{
|
|
68
|
-
|
|
67
|
+
<ScreenDataContext.Provider value={initialScreenData}>
|
|
68
|
+
<PathnameContext.Provider value={pathname}>
|
|
69
|
+
<ScreenContextProvider pathname={pathname}>
|
|
70
|
+
{children}
|
|
71
|
+
</ScreenContextProvider>
|
|
72
|
+
</PathnameContext.Provider>
|
|
73
|
+
</ScreenDataContext.Provider>
|
|
74
|
+
{isAnimating && <Animated.View style={overlayStyle} />}
|
|
69
75
|
</Animated.View>
|
|
70
76
|
);
|
|
71
77
|
}
|
|
@@ -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,
|
|
@@ -169,21 +166,23 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
169
166
|
|
|
170
167
|
transitionWithoutAnimation(resetState) {
|
|
171
168
|
const { scenes } = this.state;
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
169
|
+
const newScene = prepareScene(this.props.children);
|
|
170
|
+
const isLastSceneHook = scenes[scenes.length - 1].key.startsWith("/hook");
|
|
171
|
+
|
|
172
|
+
let newState;
|
|
173
|
+
|
|
174
|
+
if (resetState) {
|
|
175
|
+
newState = {
|
|
176
|
+
scenes: [newScene],
|
|
177
|
+
to: { index: 0 },
|
|
178
|
+
};
|
|
179
|
+
} else if (isLastSceneHook || scenes.length === 1) {
|
|
180
|
+
newState = { scenes: R.update(scenes.length - 1, newScene, scenes) };
|
|
181
|
+
} else {
|
|
182
|
+
newState = {
|
|
183
|
+
scenes: R.compose(R.tail, R.append(newScene))(scenes),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
187
186
|
|
|
188
187
|
this.setState(newState);
|
|
189
188
|
}
|
|
@@ -277,33 +276,25 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
277
276
|
// so only a single scene should be rendered,
|
|
278
277
|
// instead of dangerous nulls or duplicates.
|
|
279
278
|
renderSingleScene({ scenes, to }) {
|
|
280
|
-
const { contentStyle
|
|
281
|
-
const screenData =
|
|
282
|
-
|
|
283
|
-
const orientation = getScreenOrientation({
|
|
284
|
-
screenData,
|
|
285
|
-
layoutData,
|
|
286
|
-
});
|
|
279
|
+
const { contentStyle } = this.props;
|
|
280
|
+
const screenData = this.props.children.props.screenData;
|
|
281
|
+
const pathname = scenes[to.index].key;
|
|
287
282
|
|
|
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
283
|
return (
|
|
291
284
|
<View style={styles.container}>
|
|
292
|
-
{scenes[to.index] &&
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
</Scene>
|
|
306
|
-
)}
|
|
285
|
+
{scenes[to.index] && (
|
|
286
|
+
<Scene
|
|
287
|
+
{...{ style: to.style }}
|
|
288
|
+
pathname={pathname}
|
|
289
|
+
isActive={pathname === this.props.navigator.currentRoute}
|
|
290
|
+
contentStyle={contentStyle}
|
|
291
|
+
key={scenes[to.index].key}
|
|
292
|
+
screenUniqueId={scenes[to.index].screenUniqueId}
|
|
293
|
+
screenData={screenData}
|
|
294
|
+
>
|
|
295
|
+
{scenes[to.index].children}
|
|
296
|
+
</Scene>
|
|
297
|
+
)}
|
|
307
298
|
</View>
|
|
308
299
|
);
|
|
309
300
|
}
|
|
@@ -319,12 +310,14 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
319
310
|
<Scene
|
|
320
311
|
key={scenes[from.index].key}
|
|
321
312
|
pathname={scenes[from.index].key}
|
|
313
|
+
isActive={scenes[from.index].key === this.props.navigator.currentRoute}
|
|
322
314
|
style={from.style}
|
|
323
315
|
pointerEvents="none"
|
|
324
316
|
overlayStyle={from.overlayStyle}
|
|
325
317
|
animating={this.state.animating}
|
|
326
318
|
contentStyle={contentStyle}
|
|
327
319
|
screenUniqueId={scenes[from.index].screenUniqueId}
|
|
320
|
+
screenData={scenes[from.index].children.props.screenData}
|
|
328
321
|
>
|
|
329
322
|
{scenes[from.index].children}
|
|
330
323
|
</Scene>
|
|
@@ -333,12 +326,14 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
333
326
|
const toScene = scenes[to.index] && (
|
|
334
327
|
<Scene
|
|
335
328
|
pathname={scenes[to.index].key}
|
|
329
|
+
isActive={scenes[to.index].key === this.props.navigator.currentRoute}
|
|
336
330
|
key={scenes[to.index].key}
|
|
337
331
|
style={to.style}
|
|
338
332
|
overlayStyle={to.overlayStyle}
|
|
339
333
|
animating={this.state.animating}
|
|
340
334
|
contentStyle={contentStyle}
|
|
341
335
|
screenUniqueId={scenes[to.index].screenUniqueId}
|
|
336
|
+
screenData={this.props.children.props.screenData}
|
|
342
337
|
>
|
|
343
338
|
{scenes[to.index].children}
|
|
344
339
|
</Scene>
|
|
@@ -21,7 +21,11 @@ exports[`<Scene /> renders correctly 1`] = `
|
|
|
21
21
|
]
|
|
22
22
|
}
|
|
23
23
|
>
|
|
24
|
-
<ContextProvider
|
|
24
|
+
<ContextProvider>
|
|
25
|
+
<ContextProvider>
|
|
26
|
+
<ScreenContextProvider />
|
|
27
|
+
</ContextProvider>
|
|
28
|
+
</ContextProvider>
|
|
25
29
|
</ForwardRef(AnimatedComponentWrapper)>
|
|
26
30
|
`;
|
|
27
31
|
|
|
@@ -37,13 +41,17 @@ exports[`<Scene /> renders the overlay while animating 1`] = `
|
|
|
37
41
|
"paddingBottom": 49,
|
|
38
42
|
},
|
|
39
43
|
Object {
|
|
40
|
-
"height":
|
|
41
|
-
"width":
|
|
44
|
+
"height": "100%",
|
|
45
|
+
"width": "100%",
|
|
42
46
|
},
|
|
43
47
|
]
|
|
44
48
|
}
|
|
45
49
|
>
|
|
46
|
-
<ContextProvider
|
|
50
|
+
<ContextProvider>
|
|
51
|
+
<ContextProvider>
|
|
52
|
+
<ScreenContextProvider />
|
|
53
|
+
</ContextProvider>
|
|
54
|
+
</ContextProvider>
|
|
47
55
|
<ForwardRef(AnimatedComponentWrapper)
|
|
48
56
|
style={
|
|
49
57
|
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
|
};
|
|
@@ -508,6 +525,16 @@ export class LiveImage implements QuickBrickPlayer.SharedPlayerCallBacks {
|
|
|
508
525
|
LiveImageManager.instance.onLiveImageError(this, error);
|
|
509
526
|
};
|
|
510
527
|
|
|
528
|
+
onVideoError = (error: Error) => {
|
|
529
|
+
log_error(
|
|
530
|
+
`onVideoError: live-image, fail to play, switching back to image. error: ${
|
|
531
|
+
error?.message
|
|
532
|
+
}, ${playerInfo(this.player)}`
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
LiveImageManager.instance.onLiveImageError(this, error);
|
|
536
|
+
};
|
|
537
|
+
|
|
511
538
|
onVideoEnd = (_event) => {
|
|
512
539
|
log_info(
|
|
513
540
|
`onVideoEnd: live-image, video completed, switching back to image, ${playerInfo(
|