@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4195481103 → 12.0.0-alpha.4220424021
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/Cell/Cell.tsx +21 -5
- package/Components/FreezeWithCallback/Freeze.tsx +31 -0
- package/Components/FreezeWithCallback/LICENSE +21 -0
- package/Components/FreezeWithCallback/Suspender.tsx +17 -0
- package/Components/FreezeWithCallback/__tests__/index.test.tsx +170 -0
- package/Components/FreezeWithCallback/index.tsx +3 -0
- package/Components/Layout/TV/ScreenContainer.tsx +3 -8
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -7
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +20 -0
- package/Components/MasterCell/DefaultComponents/index.ts +2 -0
- package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
- package/Components/MasterCell/dataAdapter.ts +21 -7
- package/Components/MasterCell/index.tsx +5 -3
- package/Components/PlayerContainer/PlayerContainer.tsx +2 -5
- package/Components/Screen/TV/hooks/index.ts +0 -2
- package/Components/Screen/TV/index.web.tsx +34 -25
- package/Components/Screen/__tests__/Screen.test.tsx +0 -49
- package/Components/Screen/index.tsx +27 -76
- package/Components/Screen/navigationHandler.ts +6 -3
- package/Components/Screen/orientationHandler.ts +18 -7
- package/Components/Screen/utils.ts +16 -0
- package/Components/ScreenResolver/index.tsx +6 -11
- package/Components/Transitioner/Scene.tsx +20 -12
- package/Components/Transitioner/Transitioner.tsx +26 -21
- package/Components/Transitioner/__tests__/Scene.test.js +7 -0
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +8 -4
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
- 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 +31 -7
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +9 -2
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +23 -5
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +28 -8
- package/Components/VideoModal/ModalAnimation/utils.ts +1 -0
- package/Components/VideoModal/PlayerWrapper.tsx +1 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +48 -2
- package/Components/VideoModal/hooks/useModalSize.ts +10 -12
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -3
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
- package/package.json +5 -5
- package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { last } from "ramda";
|
|
3
|
-
import {
|
|
3
|
+
import { StyleSheet, View } from "react-native";
|
|
4
4
|
import {
|
|
5
|
+
findMenuPlugin,
|
|
5
6
|
getNavigationProps,
|
|
6
7
|
getPathAttributes,
|
|
7
|
-
resolveNavigationPlugin,
|
|
8
8
|
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
useIsScreenActive,
|
|
11
|
+
useNavigation,
|
|
12
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
10
13
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
11
14
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
12
15
|
import {
|
|
@@ -17,8 +20,10 @@ import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/he
|
|
|
17
20
|
|
|
18
21
|
import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
|
|
19
22
|
import { ScreenResolver } from "../../ScreenResolver";
|
|
20
|
-
import { useInitialFocus
|
|
23
|
+
import { useInitialFocus } from "./hooks";
|
|
21
24
|
import { isPlayerPlugin } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
25
|
+
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
26
|
+
import { FreezeWithCallback } from "../../FreezeWithCallback";
|
|
22
27
|
|
|
23
28
|
const styles = StyleSheet.create({
|
|
24
29
|
container: {
|
|
@@ -103,7 +108,6 @@ export const Screen = ({ route, Components }: Props) => {
|
|
|
103
108
|
const backgroundColor = useScreenBackgroundColor(screenId);
|
|
104
109
|
|
|
105
110
|
useInitialFocus();
|
|
106
|
-
useRestoreFocus();
|
|
107
111
|
|
|
108
112
|
const activeRiver = getActiveRiver({
|
|
109
113
|
screenId,
|
|
@@ -131,11 +135,7 @@ export const Screen = ({ route, Components }: Props) => {
|
|
|
131
135
|
fallbackNavigations: navigator.activeRiver.navigations,
|
|
132
136
|
});
|
|
133
137
|
|
|
134
|
-
const menuPlugin =
|
|
135
|
-
category: "menu",
|
|
136
|
-
navigations,
|
|
137
|
-
plugins,
|
|
138
|
-
}) as QuickBrickPlugin;
|
|
138
|
+
const menuPlugin = findMenuPlugin(navigations, plugins);
|
|
139
139
|
|
|
140
140
|
const NavBar = (Components.NavBar ||
|
|
141
141
|
menuPlugin.module) as React.ComponentType<any>;
|
|
@@ -149,21 +149,30 @@ export const Screen = ({ route, Components }: Props) => {
|
|
|
149
149
|
? routeState?.state?.entry
|
|
150
150
|
: routeState?.state?.screen;
|
|
151
151
|
|
|
152
|
+
const isScreenActive = useIsScreenActive();
|
|
153
|
+
|
|
152
154
|
return (
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
<FreezeWithCallback
|
|
156
|
+
freeze={!isScreenActive}
|
|
157
|
+
onRelease={() => {
|
|
158
|
+
focusManager.setInitialFocus();
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
<View style={[styles.container, { backgroundColor }]}>
|
|
162
|
+
<NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
|
|
163
|
+
<NavBar
|
|
164
|
+
isVisible={isNavBarVisible}
|
|
165
|
+
menuPlugin={menuPlugin}
|
|
166
|
+
navigationProps={navigationProps}
|
|
167
|
+
/>
|
|
168
|
+
</NavBarContainer>
|
|
169
|
+
<ScreenResolver
|
|
170
|
+
screenType={screenType}
|
|
171
|
+
screenId={screenId}
|
|
172
|
+
screenData={screenData}
|
|
173
|
+
groupId={route}
|
|
159
174
|
/>
|
|
160
|
-
</
|
|
161
|
-
|
|
162
|
-
screenType={screenType}
|
|
163
|
-
screenId={screenId}
|
|
164
|
-
screenData={screenData}
|
|
165
|
-
groupId={route}
|
|
166
|
-
/>
|
|
167
|
-
</View>
|
|
175
|
+
</View>
|
|
176
|
+
</FreezeWithCallback>
|
|
168
177
|
);
|
|
169
178
|
};
|
|
@@ -99,14 +99,6 @@ jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
|
99
99
|
}),
|
|
100
100
|
}));
|
|
101
101
|
|
|
102
|
-
const {
|
|
103
|
-
ORIENTATIONS,
|
|
104
|
-
} = require("@applicaster/zapp-react-native-utils/appUtils/orientationHelper");
|
|
105
|
-
|
|
106
|
-
const {
|
|
107
|
-
useCurrentScreenData,
|
|
108
|
-
} = require("@applicaster/zapp-react-native-utils/reactHooks/screen");
|
|
109
|
-
|
|
110
102
|
const {
|
|
111
103
|
allowedOrientationsForScreen,
|
|
112
104
|
getOrientation,
|
|
@@ -158,45 +150,4 @@ describe("<Screen Component />", () => {
|
|
|
158
150
|
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
159
151
|
});
|
|
160
152
|
});
|
|
161
|
-
|
|
162
|
-
it("invokes the orientation hook when the route changes", () => {
|
|
163
|
-
act(() => {
|
|
164
|
-
wrapper = create(<Screen {...screenProps} />);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// @ts-ignore
|
|
168
|
-
useCurrentScreenData.mockReturnValue({
|
|
169
|
-
id: "player-testId",
|
|
170
|
-
general: { screen_orientation: ORIENTATIONS.landscapeSensor },
|
|
171
|
-
plugin_type: "player",
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
act(() => {
|
|
175
|
-
wrapper.update(
|
|
176
|
-
<Screen
|
|
177
|
-
{...screenProps}
|
|
178
|
-
pathname="/playable"
|
|
179
|
-
screenData={{
|
|
180
|
-
id: "player-testId",
|
|
181
|
-
general: { screen_orientation: ORIENTATIONS.landscapeSensor },
|
|
182
|
-
plugin_type: "player",
|
|
183
|
-
}}
|
|
184
|
-
/>
|
|
185
|
-
);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
useCurrentScreenData.mockReturnValue({
|
|
189
|
-
id: "player-testId",
|
|
190
|
-
general: { screen_orientation: ORIENTATIONS.landscapeSensor },
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
act(() => {
|
|
194
|
-
wrapper.update(<Screen {...screenProps} />);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
expect(allowedOrientationsForScreen).toHaveBeenNthCalledWith(
|
|
198
|
-
1,
|
|
199
|
-
ORIENTATIONS.landscapeSensor
|
|
200
|
-
);
|
|
201
|
-
});
|
|
202
153
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
import React from "react";
|
|
3
|
-
import * as R from "ramda";
|
|
4
3
|
import { View } from "react-native";
|
|
5
4
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
6
5
|
import {
|
|
@@ -11,10 +10,10 @@ import {
|
|
|
11
10
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
12
11
|
import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
13
12
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
shouldNavBarDisplayMenu,
|
|
14
|
+
getNavBarProps,
|
|
15
|
+
getScreenId,
|
|
16
16
|
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
17
|
-
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
18
17
|
import {
|
|
19
18
|
useDimensions,
|
|
20
19
|
useRoute,
|
|
@@ -25,39 +24,18 @@ import {
|
|
|
25
24
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
26
25
|
import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
|
|
27
26
|
|
|
28
|
-
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
29
27
|
import { RouteManager } from "../RouteManager";
|
|
30
28
|
import { useScreenConfiguration } from "../River/useScreenConfiguration";
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
: "screen_id" in screenData
|
|
40
|
-
? screenData.screen_id
|
|
41
|
-
: fallbackRiver.id;
|
|
29
|
+
import { isValidColor } from "./utils";
|
|
30
|
+
|
|
31
|
+
const screenStyles = {
|
|
32
|
+
flex: 1,
|
|
33
|
+
paddingTop: 0,
|
|
34
|
+
// paddingBottom: insets.bottom, // Should be applied directly by UI plugin
|
|
35
|
+
// paddingLeft: insets.left, // Should be applied directly by UI plugin
|
|
36
|
+
// paddingRight: insets.right, // Should be applied directly by UI plugin
|
|
42
37
|
};
|
|
43
38
|
|
|
44
|
-
function colorIsNotTransparent(color) {
|
|
45
|
-
const layers = R.compose(
|
|
46
|
-
R.map(R.trim),
|
|
47
|
-
R.split(","),
|
|
48
|
-
R.replace(")", ""),
|
|
49
|
-
R.replace("rgba(", "")
|
|
50
|
-
)(color);
|
|
51
|
-
|
|
52
|
-
const alpha = Number(layers?.[3]);
|
|
53
|
-
|
|
54
|
-
return alpha > 0;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function isValidColor(string) {
|
|
58
|
-
return string && string !== "transparent" && colorIsNotTransparent(string);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
39
|
type Props = {
|
|
62
40
|
pathname: unknown;
|
|
63
41
|
screenData: unknown;
|
|
@@ -71,7 +49,6 @@ export function Screen(_props: Props) {
|
|
|
71
49
|
// Gets the data for the current screen configuration
|
|
72
50
|
const currentScreenData = useCurrentScreenData();
|
|
73
51
|
const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
|
|
74
|
-
const insets = useSafeAreaInsets();
|
|
75
52
|
|
|
76
53
|
const {
|
|
77
54
|
width: screenWidth,
|
|
@@ -96,30 +73,12 @@ export function Screen(_props: Props) {
|
|
|
96
73
|
|
|
97
74
|
const layoutData = { isTablet, isTabletPortrait, width: screenWidth, height };
|
|
98
75
|
|
|
99
|
-
const hasMenu =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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]);
|
|
76
|
+
const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins);
|
|
77
|
+
|
|
78
|
+
const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(
|
|
79
|
+
getNavBarProps(currentRiver, pathname, title),
|
|
80
|
+
[currentRiver, pathname]
|
|
81
|
+
);
|
|
123
82
|
|
|
124
83
|
const NavBar = React.useMemo(
|
|
125
84
|
() =>
|
|
@@ -141,23 +100,17 @@ export function Screen(_props: Props) {
|
|
|
141
100
|
|
|
142
101
|
const style = React.useMemo(
|
|
143
102
|
() => ({
|
|
144
|
-
|
|
103
|
+
...screenStyles,
|
|
145
104
|
backgroundColor: isValidColor(backgroundColor)
|
|
146
105
|
? backgroundColor
|
|
147
106
|
: theme.app_background_color,
|
|
148
|
-
paddingTop: 0,
|
|
149
|
-
// paddingBottom: insets.bottom, // Should be applied directly by UI plugin
|
|
150
|
-
// paddingLeft: insets.left, // Should be applied directly by UI plugin
|
|
151
|
-
// paddingRight: insets.right, // Should be applied directly by UI plugin
|
|
152
107
|
}),
|
|
153
|
-
[
|
|
108
|
+
[theme.app_background_color, backgroundColor]
|
|
154
109
|
);
|
|
155
110
|
|
|
156
111
|
const targetScreenData =
|
|
157
112
|
currentScreenData || (screenData as any)?.targetScreen || screenData;
|
|
158
113
|
|
|
159
|
-
useScreenOrientationHandler({ screenData: targetScreenData });
|
|
160
|
-
|
|
161
114
|
const orientation = useGetScreenOrientation(targetScreenData);
|
|
162
115
|
|
|
163
116
|
// We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
|
|
@@ -172,15 +125,13 @@ export function Screen(_props: Props) {
|
|
|
172
125
|
}
|
|
173
126
|
|
|
174
127
|
return (
|
|
175
|
-
<
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
</View>
|
|
184
|
-
</ScreenContextProvider>
|
|
128
|
+
<View style={style}>
|
|
129
|
+
{navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
|
|
130
|
+
|
|
131
|
+
<OfflineFallbackScreen screenData={targetScreenData}>
|
|
132
|
+
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
133
|
+
<RouteManager pathname={pathname} screenData={screenData} />
|
|
134
|
+
</OfflineFallbackScreen>
|
|
135
|
+
</View>
|
|
185
136
|
);
|
|
186
137
|
}
|
|
@@ -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,14 +1,16 @@
|
|
|
1
1
|
import React, { useLayoutEffect } from "react";
|
|
2
|
+
|
|
2
3
|
import {
|
|
3
4
|
allowedOrientationsForScreen,
|
|
4
5
|
ORIENTATIONS,
|
|
5
6
|
getOrientation,
|
|
6
7
|
useGetScreenOrientation,
|
|
7
8
|
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
8
|
-
|
|
9
|
+
import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
|
|
9
10
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
10
11
|
import { findPluginByType } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
11
12
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
13
|
+
|
|
12
14
|
import { ZappHookModalContext } from "../../Contexts";
|
|
13
15
|
import { HookModalContextT } from "../../Contexts/ZappHookModalContext";
|
|
14
16
|
|
|
@@ -79,14 +81,23 @@ export function useNewOrientationForScreenData({
|
|
|
79
81
|
screenOrientation;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
screenData
|
|
84
|
-
|
|
84
|
+
type Props = {
|
|
85
|
+
screenData: {
|
|
86
|
+
screen: {};
|
|
87
|
+
};
|
|
88
|
+
isActive: boolean;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export function useScreenOrientationHandler({ screenData, isActive }: Props) {
|
|
85
92
|
const { isHooksExecutionInProgress } = React.useContext<HookModalContextT>(
|
|
86
93
|
ZappHookModalContext.ReactContext
|
|
87
94
|
);
|
|
88
95
|
|
|
89
|
-
const
|
|
96
|
+
const prevIsActive = usePrevious(isActive);
|
|
97
|
+
|
|
98
|
+
const newOrientation = useNewOrientationForScreenData({
|
|
99
|
+
screenData: screenData.screen,
|
|
100
|
+
});
|
|
90
101
|
|
|
91
102
|
useLayoutEffect(() => {
|
|
92
103
|
// Null means screen does not have orientation preference, so we can skip rotate
|
|
@@ -100,12 +111,12 @@ export function useScreenOrientationHandler({
|
|
|
100
111
|
return;
|
|
101
112
|
}
|
|
102
113
|
|
|
103
|
-
if (newOrientation !== current) {
|
|
114
|
+
if (!prevIsActive && isActive && newOrientation !== current) {
|
|
104
115
|
current = newOrientation;
|
|
105
116
|
|
|
106
117
|
setOrientation(newOrientation);
|
|
107
118
|
}
|
|
108
|
-
}, [newOrientation, isHooksExecutionInProgress]);
|
|
119
|
+
}, [newOrientation, isHooksExecutionInProgress, prevIsActive, isActive]);
|
|
109
120
|
}
|
|
110
121
|
|
|
111
122
|
export function useOrientationHandler({ screenData }: OrientationHookArgs) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { map, split, replace, compose, trim } from "ramda";
|
|
2
|
+
|
|
3
|
+
function colorIsNotTransparent(color) {
|
|
4
|
+
const layers = compose(
|
|
5
|
+
map(trim),
|
|
6
|
+
split(","),
|
|
7
|
+
replace(")", ""),
|
|
8
|
+
replace("rgba(", "")
|
|
9
|
+
)(color);
|
|
10
|
+
|
|
11
|
+
return Number(layers?.[3]) > 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function isValidColor(string) {
|
|
15
|
+
return string && string !== "transparent" && colorIsNotTransparent(string);
|
|
16
|
+
}
|
|
@@ -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
|
|
|
@@ -54,11 +52,8 @@ export function ScreenResolverComponent(props: Props) {
|
|
|
54
52
|
|
|
55
53
|
const [, setScreenContext] = ZappPipesScreenContext.useZappPipesContext();
|
|
56
54
|
|
|
57
|
-
const dispatch = useDispatch();
|
|
58
|
-
|
|
59
55
|
React.useEffect(() => {
|
|
60
56
|
setScreenContext(rivers[screenId]);
|
|
61
|
-
dispatch(setAppStateHasFinishedTransitioning());
|
|
62
57
|
}, [screenId]);
|
|
63
58
|
|
|
64
59
|
const ScreenPlugin =
|
|
@@ -100,14 +95,14 @@ export function ScreenResolverComponent(props: Props) {
|
|
|
100
95
|
}
|
|
101
96
|
|
|
102
97
|
const ScreenComponent =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
path(["module", "Component"], ScreenPlugin) ||
|
|
99
|
+
prop("module", ScreenPlugin) ||
|
|
100
|
+
prop("Component", ScreenPlugin) ||
|
|
106
101
|
ScreenPlugin;
|
|
107
102
|
|
|
108
103
|
const configuration =
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
prop("configuration", ScreenPlugin) ||
|
|
105
|
+
prop("__plugin_configuration", ScreenComponent);
|
|
111
106
|
|
|
112
107
|
if (ScreenComponent) {
|
|
113
108
|
return (
|
|
@@ -1,13 +1,12 @@
|
|
|
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";
|
|
4
|
+
|
|
5
|
+
import { useScreenOrientationHandler } from "@applicaster/zapp-react-native-ui-components/Components/Screen/orientationHandler";
|
|
6
|
+
|
|
9
7
|
import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
10
8
|
import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
|
|
9
|
+
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
11
10
|
|
|
12
11
|
type Props = {
|
|
13
12
|
children: any;
|
|
@@ -46,6 +45,11 @@ export function Scene({
|
|
|
46
45
|
}: Props) {
|
|
47
46
|
const [initialScreenData, setInitialScreenData] = React.useState(screenData);
|
|
48
47
|
|
|
48
|
+
useScreenOrientationHandler({
|
|
49
|
+
screenData,
|
|
50
|
+
isActive,
|
|
51
|
+
});
|
|
52
|
+
|
|
49
53
|
React.useLayoutEffect(() => {
|
|
50
54
|
if (isActive) {
|
|
51
55
|
setInitialScreenData(screenData);
|
|
@@ -53,12 +57,14 @@ export function Scene({
|
|
|
53
57
|
}, [screenData, isActive]);
|
|
54
58
|
|
|
55
59
|
const frame = useSafeAreaFrame();
|
|
56
|
-
const { height, width } = useWindowDimensions();
|
|
57
|
-
|
|
58
|
-
// Safe frame takes too long to update,
|
|
59
|
-
// so we can not rely on it there, and use height and width instead.
|
|
60
60
|
const isAnimating = animating && overlayStyle;
|
|
61
|
-
|
|
61
|
+
|
|
62
|
+
const dimensions = isAnimating
|
|
63
|
+
? {
|
|
64
|
+
width: "100%",
|
|
65
|
+
height: "100%",
|
|
66
|
+
}
|
|
67
|
+
: frame;
|
|
62
68
|
|
|
63
69
|
return (
|
|
64
70
|
<Animated.View
|
|
@@ -67,7 +73,9 @@ export function Scene({
|
|
|
67
73
|
>
|
|
68
74
|
<ScreenDataContext.Provider value={initialScreenData}>
|
|
69
75
|
<PathnameContext.Provider value={pathname}>
|
|
70
|
-
{
|
|
76
|
+
<ScreenContextProvider pathname={pathname}>
|
|
77
|
+
{children}
|
|
78
|
+
</ScreenContextProvider>
|
|
71
79
|
</PathnameContext.Provider>
|
|
72
80
|
</ScreenDataContext.Provider>
|
|
73
81
|
{isAnimating && <Animated.View style={overlayStyle} />}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import
|
|
3
|
+
import { update, compose, tail, append, take, identity } from "ramda";
|
|
4
4
|
|
|
5
5
|
import { AnimationManager } from "./AnimationManager";
|
|
6
6
|
import { Scene } from "./Scene";
|
|
@@ -46,7 +46,7 @@ function prepareScene(children) {
|
|
|
46
46
|
*/
|
|
47
47
|
function scenesForBackTransition(props: SceneProps, { scenes }) {
|
|
48
48
|
return scenes.length > 1
|
|
49
|
-
?
|
|
49
|
+
? identity(scenes)
|
|
50
50
|
: [prepareScene(props.children), scenes[0]];
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -110,7 +110,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
110
110
|
pushTransitionStart() {
|
|
111
111
|
this.setState(
|
|
112
112
|
{
|
|
113
|
-
scenes:
|
|
113
|
+
scenes: append(prepareScene(this.props.children), this.state.scenes),
|
|
114
114
|
...this.animationManager.stateForAction(this.state, NAV_ACTION_PUSH),
|
|
115
115
|
},
|
|
116
116
|
() => {
|
|
@@ -166,21 +166,23 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
166
166
|
|
|
167
167
|
transitionWithoutAnimation(resetState) {
|
|
168
168
|
const { scenes } = this.state;
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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: update(scenes.length - 1, newScene, scenes) };
|
|
181
|
+
} else {
|
|
182
|
+
newState = {
|
|
183
|
+
scenes: compose(tail, append(newScene))(scenes),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
184
186
|
|
|
185
187
|
this.setState(newState);
|
|
186
188
|
}
|
|
@@ -223,7 +225,10 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
223
225
|
this.shouldSkipAnimationForRoute(previousRoute) ||
|
|
224
226
|
this.shouldSkipAnimationForRoute(currentRoute)
|
|
225
227
|
) {
|
|
226
|
-
|
|
228
|
+
// we are going back, in this case we need to have only one scene using resetState
|
|
229
|
+
const resetState = isGoingBack ? true : undefined;
|
|
230
|
+
|
|
231
|
+
return this.transitionWithoutAnimation(resetState);
|
|
227
232
|
}
|
|
228
233
|
|
|
229
234
|
switch (this.props.navigator.previousAction) {
|
|
@@ -266,7 +271,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
266
271
|
backTransitionEnd(stepsBack) {
|
|
267
272
|
this.setState({
|
|
268
273
|
animating: false,
|
|
269
|
-
scenes:
|
|
274
|
+
scenes: take(this.state.scenes.length - stepsBack, this.state.scenes),
|
|
270
275
|
});
|
|
271
276
|
}
|
|
272
277
|
|
|
@@ -282,7 +287,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
282
287
|
<View style={styles.container}>
|
|
283
288
|
{scenes[to.index] && (
|
|
284
289
|
<Scene
|
|
285
|
-
{...{ style: to
|
|
290
|
+
{...{ style: to?.style || {} }}
|
|
286
291
|
pathname={pathname}
|
|
287
292
|
isActive={pathname === this.props.navigator.currentRoute}
|
|
288
293
|
contentStyle={contentStyle}
|
|
@@ -16,6 +16,13 @@ jest.mock("react-native-safe-area-context", () => ({
|
|
|
16
16
|
})),
|
|
17
17
|
}));
|
|
18
18
|
|
|
19
|
+
jest.mock(
|
|
20
|
+
"@applicaster/zapp-react-native-ui-components/Components/Screen/orientationHandler",
|
|
21
|
+
() => ({
|
|
22
|
+
useScreenOrientationHandler: jest.fn(),
|
|
23
|
+
})
|
|
24
|
+
);
|
|
25
|
+
|
|
19
26
|
const { Scene } = require("../Scene");
|
|
20
27
|
|
|
21
28
|
const wrapper = shallow(
|
|
@@ -22,7 +22,9 @@ exports[`<Scene /> renders correctly 1`] = `
|
|
|
22
22
|
}
|
|
23
23
|
>
|
|
24
24
|
<ContextProvider>
|
|
25
|
-
<ContextProvider
|
|
25
|
+
<ContextProvider>
|
|
26
|
+
<ScreenContextProvider />
|
|
27
|
+
</ContextProvider>
|
|
26
28
|
</ContextProvider>
|
|
27
29
|
</ForwardRef(AnimatedComponentWrapper)>
|
|
28
30
|
`;
|
|
@@ -39,14 +41,16 @@ exports[`<Scene /> renders the overlay while animating 1`] = `
|
|
|
39
41
|
"paddingBottom": 49,
|
|
40
42
|
},
|
|
41
43
|
Object {
|
|
42
|
-
"height":
|
|
43
|
-
"width":
|
|
44
|
+
"height": "100%",
|
|
45
|
+
"width": "100%",
|
|
44
46
|
},
|
|
45
47
|
]
|
|
46
48
|
}
|
|
47
49
|
>
|
|
48
50
|
<ContextProvider>
|
|
49
|
-
<ContextProvider
|
|
51
|
+
<ContextProvider>
|
|
52
|
+
<ScreenContextProvider />
|
|
53
|
+
</ContextProvider>
|
|
50
54
|
</ContextProvider>
|
|
51
55
|
<ForwardRef(AnimatedComponentWrapper)
|
|
52
56
|
style={
|