@applicaster/zapp-react-native-ui-components 13.0.0-alpha.3592913150 → 13.0.0-alpha.3640541630
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.ios.ts +1 -1
- package/Components/BaseFocusable/index.tsx +1 -1
- package/Components/Cell/Cell.tsx +7 -4
- package/Components/Cell/TvOSCellComponent.tsx +22 -20
- package/Components/Cell/index.js +1 -3
- package/Components/Focusable/FocusableTvOS.tsx +1 -5
- package/Components/Focusable/Touchable.tsx +19 -20
- package/Components/FocusableList/index.tsx +9 -25
- package/Components/FocusableScrollView/index.tsx +12 -39
- package/Components/Layout/TV/NavBarContainer.tsx +7 -8
- package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -11
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
- package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/utils/index.ts +1 -1
- package/Components/ModalComponent/Header/index.tsx +3 -3
- package/Components/River/ComponentsMap/ComponentsMap.tsx +39 -65
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
- package/Components/River/RiverFooter.tsx +39 -9
- package/Components/River/RiverItem.tsx +37 -2
- package/Components/River/TV/index.tsx +1 -6
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +148 -31
- package/Components/River/__tests__/componentsMap.test.js +17 -5
- package/Components/Screen/hooks.ts +56 -0
- package/Components/Screen/index.tsx +13 -39
- package/Components/Tabs/Tab.tsx +6 -6
- package/Components/TextInputTv/index.tsx +2 -2
- package/Components/Transitioner/AnimationManager.js +8 -8
- package/Components/Transitioner/Scene.tsx +52 -23
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +59 -43
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
- package/Components/Transitioner/index.js +8 -4
- package/Components/VideoLive/LiveImageManager.ts +27 -1
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +29 -21
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +51 -1
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +0 -5
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +7 -6
- package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
- package/Components/VideoModal/OpaqueLayer.tsx +33 -0
- package/Components/VideoModal/PlayerWrapper.tsx +16 -35
- package/Components/VideoModal/VideoModal.tsx +14 -23
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +0 -90
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
- package/Components/VideoModal/hooks/index.ts +7 -0
- package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
- package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
- package/Components/VideoModal/hooks/utils/index.ts +33 -0
- package/Components/VideoModal/utils.ts +1 -1
- package/Contexts/ScreenContext/index.tsx +3 -2
- package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
- package/Decorators/ZappPipesDataConnector/index.tsx +31 -1
- package/package.json +5 -5
- package/Contexts/ComponentsMapOffsetContext/index.tsx +0 -46
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
3
|
-
import { cleanup } from "@testing-library/react-native";
|
|
2
|
+
import { cleanup, render } from "@testing-library/react-native";
|
|
4
3
|
import { Provider } from "react-redux";
|
|
5
4
|
import configureStore from "redux-mock-store";
|
|
6
5
|
|
|
@@ -81,6 +80,13 @@ const mockScreenData = {
|
|
|
81
80
|
id: "A1234",
|
|
82
81
|
};
|
|
83
82
|
|
|
83
|
+
jest.mock("@applicaster/zapp-react-native-redux/AppStore", () => ({
|
|
84
|
+
appStore: {
|
|
85
|
+
get: jest.fn((prop) => mockStore[prop]),
|
|
86
|
+
getState: jest.fn(),
|
|
87
|
+
},
|
|
88
|
+
}));
|
|
89
|
+
|
|
84
90
|
jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
|
|
85
91
|
useIsRTL: jest.fn(() => mock_rtl_flag),
|
|
86
92
|
}));
|
|
@@ -153,7 +159,13 @@ const plugins = [];
|
|
|
153
159
|
const navigation = {};
|
|
154
160
|
|
|
155
161
|
const props = { components, cellStyles, riverComponents, navigation };
|
|
156
|
-
|
|
162
|
+
|
|
163
|
+
const store = mockStore({
|
|
164
|
+
components,
|
|
165
|
+
cellStyles,
|
|
166
|
+
plugins,
|
|
167
|
+
getState: jest.fn(),
|
|
168
|
+
});
|
|
157
169
|
|
|
158
170
|
jest.useFakeTimers();
|
|
159
171
|
|
|
@@ -170,12 +182,12 @@ describe("componentsMap", () => {
|
|
|
170
182
|
.spyOn(themeUtils, "useTheme")
|
|
171
183
|
.mockImplementation(() => () => theme);
|
|
172
184
|
|
|
173
|
-
const
|
|
185
|
+
const { toJSON } = render(
|
|
174
186
|
<Provider store={store}>
|
|
175
187
|
<ComponentsMap {...props} />
|
|
176
188
|
</Provider>
|
|
177
189
|
);
|
|
178
190
|
|
|
179
|
-
expect(
|
|
191
|
+
expect(toJSON()).toMatchSnapshot();
|
|
180
192
|
});
|
|
181
193
|
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
2
|
+
import {
|
|
3
|
+
useGetScreenOrientation,
|
|
4
|
+
isOrientationCompatible,
|
|
5
|
+
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
6
|
+
import {
|
|
7
|
+
useCurrentScreenData,
|
|
8
|
+
useDimensions,
|
|
9
|
+
useRoute,
|
|
10
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
11
|
+
import { useMemo, useEffect, useState } from "react";
|
|
12
|
+
|
|
13
|
+
export const useWaitForValidOrientation = () => {
|
|
14
|
+
const {
|
|
15
|
+
width: screenWidth,
|
|
16
|
+
height,
|
|
17
|
+
deviceInfo,
|
|
18
|
+
} = useDimensions("screen", {
|
|
19
|
+
fullDimensions: true,
|
|
20
|
+
updateForInactiveScreens: false,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const currentScreenData = useCurrentScreenData();
|
|
24
|
+
|
|
25
|
+
const { screenData } = useRoute();
|
|
26
|
+
|
|
27
|
+
const [readyState, setReadyState] = useState(false);
|
|
28
|
+
|
|
29
|
+
const isTablet = deviceInfo?.isTablet;
|
|
30
|
+
|
|
31
|
+
const { appData } = usePickFromState(["appData"]);
|
|
32
|
+
const isTabletPortrait = appData?.isTabletPortrait;
|
|
33
|
+
|
|
34
|
+
const layoutData = useMemo(
|
|
35
|
+
() => ({ isTablet, isTabletPortrait, width: screenWidth, height }),
|
|
36
|
+
[isTablet, isTabletPortrait, screenWidth, height]
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const targetScreenData =
|
|
40
|
+
currentScreenData || (screenData as any)?.targetScreen || screenData;
|
|
41
|
+
|
|
42
|
+
const orientation = useGetScreenOrientation(targetScreenData);
|
|
43
|
+
|
|
44
|
+
const isReadyForDisplay = isOrientationCompatible({
|
|
45
|
+
orientation,
|
|
46
|
+
layoutData,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (isReadyForDisplay && !readyState) {
|
|
51
|
+
setReadyState(true);
|
|
52
|
+
}
|
|
53
|
+
}, [readyState, orientation, layoutData]);
|
|
54
|
+
|
|
55
|
+
return readyState;
|
|
56
|
+
};
|
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { View } from "react-native";
|
|
4
4
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
5
|
-
import {
|
|
6
|
-
isOrientationCompatible,
|
|
7
|
-
useGetScreenOrientation,
|
|
8
|
-
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
9
5
|
|
|
10
6
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
11
7
|
import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
@@ -15,7 +11,6 @@ import {
|
|
|
15
11
|
getScreenId,
|
|
16
12
|
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
17
13
|
import {
|
|
18
|
-
useDimensions,
|
|
19
14
|
useRoute,
|
|
20
15
|
useCurrentScreenData,
|
|
21
16
|
useNavbarState,
|
|
@@ -27,6 +22,7 @@ import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/Ap
|
|
|
27
22
|
import { RouteManager } from "../RouteManager";
|
|
28
23
|
import { useScreenConfiguration } from "../River/useScreenConfiguration";
|
|
29
24
|
import { isValidColor } from "./utils";
|
|
25
|
+
import { useWaitForValidOrientation } from "./hooks";
|
|
30
26
|
|
|
31
27
|
const screenStyles = {
|
|
32
28
|
flex: 1,
|
|
@@ -50,14 +46,6 @@ export function Screen(_props: Props) {
|
|
|
50
46
|
const currentScreenData = useCurrentScreenData();
|
|
51
47
|
const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
|
|
52
48
|
|
|
53
|
-
const {
|
|
54
|
-
width: screenWidth,
|
|
55
|
-
height,
|
|
56
|
-
deviceInfo,
|
|
57
|
-
} = useDimensions("screen", {
|
|
58
|
-
fullDimensions: true,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
49
|
const { screenData, pathname } = useRoute();
|
|
62
50
|
|
|
63
51
|
const currentRiver = useScreenData(
|
|
@@ -66,13 +54,6 @@ export function Screen(_props: Props) {
|
|
|
66
54
|
|
|
67
55
|
const { title } = useNavbarState();
|
|
68
56
|
|
|
69
|
-
const isTablet = deviceInfo?.isTablet;
|
|
70
|
-
|
|
71
|
-
const { appData } = usePickFromState(["appData"]);
|
|
72
|
-
const isTabletPortrait = appData?.isTabletPortrait;
|
|
73
|
-
|
|
74
|
-
const layoutData = { isTablet, isTabletPortrait, width: screenWidth, height };
|
|
75
|
-
|
|
76
57
|
const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins);
|
|
77
58
|
|
|
78
59
|
const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(
|
|
@@ -108,30 +89,23 @@ export function Screen(_props: Props) {
|
|
|
108
89
|
[theme.app_background_color, backgroundColor]
|
|
109
90
|
);
|
|
110
91
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const orientation = useGetScreenOrientation(targetScreenData);
|
|
92
|
+
// Set ready state when screen is rotated to desired orientation
|
|
93
|
+
const isReady = useWaitForValidOrientation();
|
|
115
94
|
|
|
116
95
|
// We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
|
|
117
96
|
// This saves unnecessary re-renders and user will not see distorted aspect screen.
|
|
118
|
-
if (
|
|
119
|
-
!isOrientationCompatible({
|
|
120
|
-
orientation,
|
|
121
|
-
layoutData,
|
|
122
|
-
})
|
|
123
|
-
) {
|
|
124
|
-
return <View style={style} />;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
97
|
return (
|
|
128
98
|
<View style={style}>
|
|
129
|
-
{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
99
|
+
{isReady ? (
|
|
100
|
+
<>
|
|
101
|
+
{navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
|
|
102
|
+
|
|
103
|
+
<OfflineFallbackScreen>
|
|
104
|
+
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
105
|
+
<RouteManager pathname={pathname} screenData={screenData} />
|
|
106
|
+
</OfflineFallbackScreen>
|
|
107
|
+
</>
|
|
108
|
+
) : null}
|
|
135
109
|
</View>
|
|
136
110
|
);
|
|
137
111
|
}
|
package/Components/Tabs/Tab.tsx
CHANGED
|
@@ -69,8 +69,8 @@ const getStyles = (configuration, selected, focused) => {
|
|
|
69
69
|
? tab_cell_background_color_selected_active
|
|
70
70
|
: tab_cell_background_color_selected_default
|
|
71
71
|
: focused
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
? tab_cell_background_color_active
|
|
73
|
+
: tab_cell_background_color_default,
|
|
74
74
|
justifyContent: "center",
|
|
75
75
|
alignItems: "center",
|
|
76
76
|
position: "relative",
|
|
@@ -85,8 +85,8 @@ const getStyles = (configuration, selected, focused) => {
|
|
|
85
85
|
? tab_cell_border_color_active_focused
|
|
86
86
|
: tab_cell_border_color_active
|
|
87
87
|
: focused
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
? tab_cell_border_color_default_focused
|
|
89
|
+
: tab_cell_border_color_default,
|
|
90
90
|
},
|
|
91
91
|
label: {
|
|
92
92
|
fontFamily: text_label_font_family,
|
|
@@ -98,8 +98,8 @@ const getStyles = (configuration, selected, focused) => {
|
|
|
98
98
|
? text_label_selected_active_font_color
|
|
99
99
|
: text_label_selected_default_font_color
|
|
100
100
|
: focused
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
? text_label_active_font_color
|
|
102
|
+
: text_label_default_font_color,
|
|
103
103
|
},
|
|
104
104
|
underline: {
|
|
105
105
|
position: "absolute",
|
|
@@ -3,19 +3,19 @@ import { Animated } from "react-native";
|
|
|
3
3
|
import { NAV_ACTION_PUSH, NAV_ACTION_BACK } from "./Transitioner";
|
|
4
4
|
|
|
5
5
|
type TransitionConfig = {
|
|
6
|
-
duration: number
|
|
7
|
-
easing: any
|
|
6
|
+
duration: number;
|
|
7
|
+
easing: any;
|
|
8
8
|
from: {
|
|
9
|
-
style: any
|
|
10
|
-
}
|
|
9
|
+
style: any;
|
|
10
|
+
};
|
|
11
11
|
to: {
|
|
12
|
-
style: any
|
|
13
|
-
}
|
|
12
|
+
style: any;
|
|
13
|
+
};
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
type Props = {
|
|
17
|
-
transitionConfig: TransitionConfig
|
|
18
|
-
contentStyle: { [string]: any }
|
|
17
|
+
transitionConfig: TransitionConfig;
|
|
18
|
+
contentStyle: { [string]: any };
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { equals } from "ramda";
|
|
2
3
|
import { Animated, ViewProps, ViewStyle } from "react-native";
|
|
3
4
|
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
4
5
|
|
|
@@ -8,6 +9,11 @@ import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
|
8
9
|
import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
|
|
9
10
|
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
10
11
|
|
|
12
|
+
const fullWidthDimensions = {
|
|
13
|
+
height: "100%",
|
|
14
|
+
width: "100%",
|
|
15
|
+
};
|
|
16
|
+
|
|
11
17
|
type Props = {
|
|
12
18
|
children: any;
|
|
13
19
|
style: any;
|
|
@@ -20,6 +26,47 @@ type Props = {
|
|
|
20
26
|
screenData: NavigationScreenData;
|
|
21
27
|
};
|
|
22
28
|
|
|
29
|
+
export function CurrentScreenContextProvider({
|
|
30
|
+
children,
|
|
31
|
+
...props
|
|
32
|
+
}: {
|
|
33
|
+
children: any;
|
|
34
|
+
pathname: string;
|
|
35
|
+
isActive: boolean;
|
|
36
|
+
screenData: NavigationScreenData;
|
|
37
|
+
}) {
|
|
38
|
+
const { pathname, isActive = false, screenData } = props;
|
|
39
|
+
|
|
40
|
+
const [initialScreenData, setInitialScreenData] = React.useState(screenData);
|
|
41
|
+
|
|
42
|
+
React.useLayoutEffect(() => {
|
|
43
|
+
const screenDataChanged = !equals(initialScreenData, screenData);
|
|
44
|
+
|
|
45
|
+
if (isActive && screenDataChanged) {
|
|
46
|
+
setInitialScreenData(screenData);
|
|
47
|
+
}
|
|
48
|
+
}, [initialScreenData, screenData, isActive]);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<ScreenDataContext.Provider value={initialScreenData}>
|
|
52
|
+
<PathnameContext.Provider value={pathname}>
|
|
53
|
+
<ScreenContextProvider pathname={pathname}>
|
|
54
|
+
{children}
|
|
55
|
+
</ScreenContextProvider>
|
|
56
|
+
</PathnameContext.Provider>
|
|
57
|
+
</ScreenDataContext.Provider>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const withCurrentScreenContext = (Component) =>
|
|
62
|
+
function SceneComponent(props: Props) {
|
|
63
|
+
return (
|
|
64
|
+
<CurrentScreenContextProvider {...props}>
|
|
65
|
+
<Component {...props} />
|
|
66
|
+
</CurrentScreenContextProvider>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
23
70
|
/**
|
|
24
71
|
* Animated View container for any purpose.
|
|
25
72
|
* Renders given children with given style object.
|
|
@@ -32,53 +79,35 @@ type Props = {
|
|
|
32
79
|
* @param contentStyle
|
|
33
80
|
* @param screenUniqueId
|
|
34
81
|
*/
|
|
35
|
-
|
|
82
|
+
function SceneComponent({
|
|
36
83
|
children,
|
|
37
84
|
style,
|
|
38
85
|
pointerEvents = "auto",
|
|
39
86
|
overlayStyle,
|
|
40
87
|
animating,
|
|
41
88
|
contentStyle,
|
|
42
|
-
pathname,
|
|
43
89
|
isActive = false,
|
|
44
90
|
screenData,
|
|
45
91
|
}: Props) {
|
|
46
|
-
const [initialScreenData, setInitialScreenData] = React.useState(screenData);
|
|
47
|
-
|
|
48
92
|
useScreenOrientationHandler({
|
|
49
93
|
screenData,
|
|
50
94
|
isActive,
|
|
51
95
|
});
|
|
52
96
|
|
|
53
|
-
React.useLayoutEffect(() => {
|
|
54
|
-
if (isActive) {
|
|
55
|
-
setInitialScreenData(screenData);
|
|
56
|
-
}
|
|
57
|
-
}, [screenData, isActive]);
|
|
58
|
-
|
|
59
97
|
const frame = useSafeAreaFrame();
|
|
60
98
|
const isAnimating = animating && overlayStyle;
|
|
61
99
|
|
|
62
|
-
const dimensions = isAnimating
|
|
63
|
-
? {
|
|
64
|
-
width: "100%",
|
|
65
|
-
height: "100%",
|
|
66
|
-
}
|
|
67
|
-
: frame;
|
|
100
|
+
const dimensions = isAnimating ? fullWidthDimensions : frame;
|
|
68
101
|
|
|
69
102
|
return (
|
|
70
103
|
<Animated.View
|
|
71
104
|
pointerEvents={pointerEvents}
|
|
72
105
|
style={[style, contentStyle, dimensions]}
|
|
73
106
|
>
|
|
74
|
-
|
|
75
|
-
<PathnameContext.Provider value={pathname}>
|
|
76
|
-
<ScreenContextProvider pathname={pathname}>
|
|
77
|
-
{children}
|
|
78
|
-
</ScreenContextProvider>
|
|
79
|
-
</PathnameContext.Provider>
|
|
80
|
-
</ScreenDataContext.Provider>
|
|
107
|
+
{children}
|
|
81
108
|
{isAnimating && <Animated.View style={overlayStyle} />}
|
|
82
109
|
</Animated.View>
|
|
83
110
|
);
|
|
84
111
|
}
|
|
112
|
+
|
|
113
|
+
export const Scene = withCurrentScreenContext(SceneComponent);
|
|
@@ -1,63 +1,79 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`<Scene /> renders correctly 1`] = `
|
|
4
|
-
<
|
|
5
|
-
|
|
4
|
+
<CurrentScreenContextProvider
|
|
5
|
+
contentStyle={
|
|
6
|
+
{
|
|
7
|
+
"paddingBottom": 49,
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
overlayStyle={
|
|
11
|
+
{
|
|
12
|
+
"opacity": 1,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
6
15
|
style={
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
{
|
|
17
|
+
"flex": 1,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
>
|
|
21
|
+
<SceneComponent
|
|
22
|
+
contentStyle={
|
|
11
23
|
{
|
|
12
24
|
"paddingBottom": 49,
|
|
13
|
-
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
overlayStyle={
|
|
14
28
|
{
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<ContextProvider>
|
|
26
|
-
<ScreenContextProvider />
|
|
27
|
-
</ContextProvider>
|
|
28
|
-
</ContextProvider>
|
|
29
|
-
</ForwardRef(AnimatedComponentWrapper)>
|
|
29
|
+
"opacity": 1,
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
style={
|
|
33
|
+
{
|
|
34
|
+
"flex": 1,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/>
|
|
38
|
+
</CurrentScreenContextProvider>
|
|
30
39
|
`;
|
|
31
40
|
|
|
32
41
|
exports[`<Scene /> renders the overlay while animating 1`] = `
|
|
33
|
-
<
|
|
34
|
-
|
|
42
|
+
<CurrentScreenContextProvider
|
|
43
|
+
animating={true}
|
|
44
|
+
contentStyle={
|
|
45
|
+
{
|
|
46
|
+
"paddingBottom": 49,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
overlayStyle={
|
|
50
|
+
{
|
|
51
|
+
"opacity": 1,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
35
54
|
style={
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
55
|
+
{
|
|
56
|
+
"flex": 1,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
>
|
|
60
|
+
<SceneComponent
|
|
61
|
+
animating={true}
|
|
62
|
+
contentStyle={
|
|
40
63
|
{
|
|
41
64
|
"paddingBottom": 49,
|
|
42
|
-
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
overlayStyle={
|
|
43
68
|
{
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
>
|
|
50
|
-
<ContextProvider>
|
|
51
|
-
<ContextProvider>
|
|
52
|
-
<ScreenContextProvider />
|
|
53
|
-
</ContextProvider>
|
|
54
|
-
</ContextProvider>
|
|
55
|
-
<ForwardRef(AnimatedComponentWrapper)
|
|
69
|
+
"opacity": 1,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
56
72
|
style={
|
|
57
73
|
{
|
|
58
|
-
"
|
|
74
|
+
"flex": 1,
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
77
|
/>
|
|
62
|
-
</
|
|
78
|
+
</CurrentScreenContextProvider>
|
|
63
79
|
`;
|
|
@@ -9,7 +9,7 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
>
|
|
12
|
-
<
|
|
12
|
+
<SceneComponent
|
|
13
13
|
isActive={true}
|
|
14
14
|
screenUniqueId="mocked-uuid"
|
|
15
15
|
style={{}}
|
|
@@ -23,6 +23,6 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
|
|
|
23
23
|
children
|
|
24
24
|
</Text>
|
|
25
25
|
</View>
|
|
26
|
-
</
|
|
26
|
+
</SceneComponent>
|
|
27
27
|
</View>
|
|
28
28
|
`;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { useWindowDimensions } from "react-native";
|
|
3
2
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
4
3
|
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
|
|
5
4
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
@@ -7,10 +6,15 @@ import { TransitionerComponent } from "./Transitioner";
|
|
|
7
6
|
|
|
8
7
|
export const Transitioner = (props) => {
|
|
9
8
|
const navigator = useNavigation();
|
|
10
|
-
const { height, width } = useWindowDimensions();
|
|
11
9
|
|
|
12
|
-
const
|
|
13
|
-
|
|
10
|
+
const {
|
|
11
|
+
width,
|
|
12
|
+
height,
|
|
13
|
+
deviceInfo: { isTablet },
|
|
14
|
+
} = useDimensions("window", {
|
|
15
|
+
updateForInactiveScreens: false,
|
|
16
|
+
deviceInfo: true,
|
|
17
|
+
});
|
|
14
18
|
|
|
15
19
|
const { appData } = usePickFromState(["appData"]);
|
|
16
20
|
const isTabletPortrait = appData?.isTabletPortrait;
|
|
@@ -8,6 +8,8 @@ import { loggerLiveImageManager } from "./loggerHelper";
|
|
|
8
8
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
9
9
|
import { Component } from "react";
|
|
10
10
|
|
|
11
|
+
const TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION = 500; // ms
|
|
12
|
+
|
|
11
13
|
const { log_debug, log_info, log_error } = loggerLiveImageManager;
|
|
12
14
|
|
|
13
15
|
export type LiveImageManagerEvent =
|
|
@@ -62,6 +64,9 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
62
64
|
protected currentlyPlaying: LiveImage | null = null;
|
|
63
65
|
protected primaryPlayer: Player | null = null;
|
|
64
66
|
|
|
67
|
+
private checkPlayerPositionTimeout: ReturnType<typeof setTimeout> | null =
|
|
68
|
+
null;
|
|
69
|
+
|
|
65
70
|
protected listeners: Record<
|
|
66
71
|
string,
|
|
67
72
|
Record<LiveImageManagerEvent, (event?: Record<string, any>) => void>
|
|
@@ -118,6 +123,11 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
118
123
|
});
|
|
119
124
|
};
|
|
120
125
|
|
|
126
|
+
private cancelCheckPlayerPositionTimeout = () => {
|
|
127
|
+
clearTimeout(this.checkPlayerPositionTimeout);
|
|
128
|
+
this.checkPlayerPositionTimeout = null;
|
|
129
|
+
};
|
|
130
|
+
|
|
121
131
|
public onViewportEnter = (item: LiveImage) => {
|
|
122
132
|
log_debug(
|
|
123
133
|
`onViewportEnter: live-image ${playerInfo(
|
|
@@ -125,7 +135,21 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
125
135
|
)}, primary ${playerInfo(this.primaryPlayer)}`
|
|
126
136
|
);
|
|
127
137
|
|
|
128
|
-
|
|
138
|
+
if (!isTV()) {
|
|
139
|
+
// mobile only
|
|
140
|
+
// we have to delay running checkPlayerPosition, because sometimes on fast scrolling we get wrong order onEnter, then onLeave.
|
|
141
|
+
// which could cause select wrong item to play
|
|
142
|
+
|
|
143
|
+
this.cancelCheckPlayerPositionTimeout();
|
|
144
|
+
|
|
145
|
+
this.checkPlayerPositionTimeout = setTimeout(() => {
|
|
146
|
+
this.cancelCheckPlayerPositionTimeout();
|
|
147
|
+
|
|
148
|
+
this.checkPlayerPosition(item);
|
|
149
|
+
}, TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION);
|
|
150
|
+
} else {
|
|
151
|
+
this.checkPlayerPosition(item);
|
|
152
|
+
}
|
|
129
153
|
};
|
|
130
154
|
|
|
131
155
|
public onViewportLeave = (item: LiveImage) => {
|
|
@@ -246,6 +270,8 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
246
270
|
};
|
|
247
271
|
|
|
248
272
|
public checkPlayerPosition = (item: LiveImage) => {
|
|
273
|
+
this.cancelCheckPlayerPositionTimeout();
|
|
274
|
+
|
|
249
275
|
log_debug(
|
|
250
276
|
`checkPlayerPosition: live-image playerId: ${playerInfo(
|
|
251
277
|
item.player
|