@applicaster/zapp-react-native-ui-components 13.0.0-alpha.9946926334 → 13.0.0-rc.100
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/AppContainer/__tests__/AppContainer.test.js +4 -6
- package/Components/AudioPlayer/AudioPlayer.tsx +7 -0
- package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +54 -111
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +36 -20
- package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
- package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
- package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
- package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
- package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
- package/Components/AudioPlayer/__tests__/title.test.js +3 -5
- package/Components/AudioPlayer/helpers.tsx +1 -0
- package/Components/BaseFocusable/index.ios.ts +1 -1
- package/Components/BaseFocusable/index.tsx +2 -3
- package/Components/Cell/Cell.tsx +11 -16
- package/Components/Cell/CellWithFocusable.tsx +50 -59
- package/Components/Cell/CellWrapper.tsx +18 -0
- package/Components/Cell/TvOSCellComponent.tsx +20 -26
- package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
- package/Components/Cell/index.js +3 -1
- package/Components/Cell/styles.ts +17 -0
- package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +46 -48
- package/Components/CellRendererResolver/index.ts +2 -1
- package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
- package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
- package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
- package/Components/ErrorScreen/index.tsx +14 -6
- package/Components/Focusable/Focusable.tsx +1 -0
- package/Components/Focusable/FocusableTvOS.tsx +6 -2
- package/Components/Focusable/Touchable.tsx +19 -20
- package/Components/Focusable/index.android.tsx +10 -3
- package/Components/FocusableCell/index.tsx +1 -1
- package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
- package/Components/FocusableGroup/index.tsx +0 -3
- package/Components/FocusableList/index.tsx +26 -10
- package/Components/FocusableScrollView/index.tsx +43 -13
- package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
- package/Components/Layout/TV/LayoutBackground.tsx +28 -0
- package/Components/Layout/TV/NavBarContainer.tsx +19 -23
- package/Components/Layout/TV/ScreenContainer.tsx +8 -2
- package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
- package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
- package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
- package/Components/Layout/TV/index.tsx +6 -20
- package/Components/Layout/TV/index.web.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
- 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 +10 -15
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
- package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
- package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
- package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
- package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +0 -229
- package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
- package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
- package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +2 -2
- package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
- package/Components/MasterCell/utils/index.ts +9 -135
- package/Components/ModalComponent/BottomSheetModalContent.tsx +45 -19
- package/Components/ModalComponent/Button/Item.tsx +6 -5
- package/Components/ModalComponent/Button/assets.ts +1 -1
- package/Components/ModalComponent/Button/index.tsx +30 -43
- package/Components/ModalComponent/Header/index.tsx +3 -3
- package/Components/ModalComponent/utils.ts +55 -7
- package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
- package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
- package/Components/OfflineHandler/utils/index.ts +1 -1
- package/Components/PlayerContainer/PlayerContainer.tsx +43 -21
- package/Components/PlayerContainer/PlayerContainerContext.tsx +9 -0
- package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
- package/Components/PlayerImageBackground/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +42 -65
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
- package/Components/River/RiverFooter.tsx +39 -9
- package/Components/River/RiverItem.tsx +39 -3
- package/Components/River/TV/index.tsx +6 -1
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +100 -31
- package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
- package/Components/River/__tests__/componentsMap.test.js +17 -5
- package/Components/River/__tests__/river.test.js +75 -40
- package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +11 -4
- package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
- package/Components/RouteManager/__tests__/testId.test.js +8 -6
- package/Components/Screen/TV/index.web.tsx +5 -6
- package/Components/Screen/hooks.ts +53 -0
- package/Components/Screen/index.tsx +16 -42
- package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
- package/Components/Tabs/Tab.tsx +11 -9
- package/Components/TextInputTv/index.tsx +4 -3
- package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
- package/Components/TrackedView/index.tsx +1 -0
- package/Components/Transitioner/AnimationManager.js +15 -15
- package/Components/Transitioner/Scene.tsx +53 -24
- package/Components/Transitioner/Transitioner.tsx +3 -3
- package/Components/Transitioner/__tests__/Scene.test.js +25 -14
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +9 -49
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
- package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
- package/Components/Transitioner/index.js +8 -4
- package/Components/VideoLive/LiveImageManager.ts +27 -1
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +36 -24
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +51 -1
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -5
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +51 -31
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +8 -4
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +48 -22
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +12 -6
- package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
- package/Components/VideoModal/ModalAnimation/const.ts +5 -0
- package/Components/VideoModal/ModalAnimation/index.ts +2 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +38 -2
- package/Components/VideoModal/OpaqueLayer.tsx +33 -0
- package/Components/VideoModal/PlayerDetails.tsx +18 -10
- package/Components/VideoModal/PlayerWrapper.tsx +43 -39
- package/Components/VideoModal/VideoModal.tsx +17 -11
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
- 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 +4 -5
- package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
- package/Components/Viewport/__tests__/utils.test.js +5 -4
- package/Components/ZappUIComponent/Placeholder.tsx +3 -1
- package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
- package/Components/ZappUIComponent/index.tsx +4 -17
- package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
- package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
- package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
- package/Contexts/HeaderOffsetContext/index.tsx +4 -6
- package/Contexts/ScreenContext/index.tsx +6 -12
- package/Contexts/ScreenLayoutContext/index.tsx +5 -3
- package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
- package/Decorators/Navigator/index.tsx +1 -1
- package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
- package/Decorators/RiverResolver/index.tsx +6 -8
- package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
- package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
- package/Decorators/ZappPipesDataConnector/index.tsx +6 -2
- package/package.json +7 -11
- package/tsconfig.json +2 -3
- package/.babelrc +0 -8
- package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
- package/Components/Cell/CellStyles/Hero/index.js +0 -111
- package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
- package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
- package/Components/Cell/CellStyles/colors.js +0 -40
- package/Components/Cell/CellStyles/index.js +0 -15
- package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
- package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
- package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
- package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
- package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
- package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
|
@@ -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
|
-
|
|
76
|
-
<ScreenContextProvider pathname={pathname}>
|
|
77
|
-
{children}
|
|
78
|
-
</ScreenContextProvider>
|
|
79
|
-
</PathnameContext.Provider>
|
|
80
|
-
</ScreenDataContext.Provider>
|
|
81
|
-
{isAnimating && <Animated.View style={overlayStyle} />}
|
|
107
|
+
{children}
|
|
108
|
+
{isAnimating ? <Animated.View style={overlayStyle} /> : null}
|
|
82
109
|
</Animated.View>
|
|
83
110
|
);
|
|
84
111
|
}
|
|
112
|
+
|
|
113
|
+
export const Scene = withCurrentScreenContext(SceneComponent);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { append, compose, identity, isNil, tail, take, update } from "ramda";
|
|
4
4
|
|
|
5
5
|
import { AnimationManager } from "./AnimationManager";
|
|
6
6
|
import { Scene } from "./Scene";
|
|
@@ -289,7 +289,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
289
289
|
|
|
290
290
|
return (
|
|
291
291
|
<View style={styles.container}>
|
|
292
|
-
{scenes[to.index]
|
|
292
|
+
{scenes[to.index] ? (
|
|
293
293
|
<Scene
|
|
294
294
|
{...{ style: to?.style || {} }}
|
|
295
295
|
pathname={pathname}
|
|
@@ -301,7 +301,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
301
301
|
>
|
|
302
302
|
{scenes[to.index].children}
|
|
303
303
|
</Scene>
|
|
304
|
-
)}
|
|
304
|
+
) : null}
|
|
305
305
|
</View>
|
|
306
306
|
);
|
|
307
307
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { render } from "@testing-library/react-native";
|
|
3
|
+
|
|
4
|
+
import { Scene } from "../Scene";
|
|
4
5
|
|
|
5
6
|
const overlayStyle = { opacity: 1 };
|
|
6
7
|
const contentStyle = { paddingBottom: 49 };
|
|
@@ -23,28 +24,38 @@ jest.mock(
|
|
|
23
24
|
})
|
|
24
25
|
);
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
jest.mock("../../../Contexts/PathnameContext", () => ({
|
|
28
|
+
PathnameContext: jest.requireActual("react").createContext({ pathname: "" }),
|
|
29
|
+
}));
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
);
|
|
31
|
+
jest.mock("../../../Contexts/ScreenDataContext", () => ({
|
|
32
|
+
ScreenDataContext: jest.requireActual("react").createContext({}),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
jest.mock("../../../Contexts/ScreenContext", () => ({
|
|
36
|
+
ScreenContextProvider: jest.requireActual("react-native").View,
|
|
37
|
+
}));
|
|
35
38
|
|
|
36
39
|
describe("<Scene />", () => {
|
|
40
|
+
const wrapper = render(
|
|
41
|
+
<Scene
|
|
42
|
+
style={style}
|
|
43
|
+
overlayStyle={overlayStyle}
|
|
44
|
+
contentStyle={contentStyle}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
|
|
37
48
|
it("renders correctly", () => {
|
|
38
|
-
expect(
|
|
49
|
+
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
39
50
|
});
|
|
40
51
|
|
|
41
52
|
// skipped - this isn't a very useful test, and it doesn't work as it used to on the new version of RN
|
|
42
53
|
it.skip("renders children surrounded by AnimatedComponent", () => {
|
|
43
|
-
expect(
|
|
54
|
+
expect(wrapper.toJSON()).toEqual("AnimatedComponent");
|
|
44
55
|
});
|
|
45
56
|
|
|
46
57
|
it("renders the overlay while animating", () => {
|
|
47
|
-
const wrapperWithOverlay =
|
|
58
|
+
const wrapperWithOverlay = render(
|
|
48
59
|
<Scene
|
|
49
60
|
style={style}
|
|
50
61
|
overlayStyle={overlayStyle}
|
|
@@ -53,6 +64,6 @@ describe("<Scene />", () => {
|
|
|
53
64
|
/>
|
|
54
65
|
);
|
|
55
66
|
|
|
56
|
-
expect(
|
|
67
|
+
expect(wrapperWithOverlay.toJSON).toMatchSnapshot();
|
|
57
68
|
});
|
|
58
69
|
});
|
|
@@ -1,63 +1,23 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`<Scene /> renders correctly 1`] = `
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
<View>
|
|
5
|
+
<View
|
|
6
|
+
collapsable={false}
|
|
7
|
+
pointerEvents="auto"
|
|
8
|
+
style={
|
|
8
9
|
{
|
|
9
10
|
"flex": 1,
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"paddingBottom": 49,
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
11
|
"fontScale": 2,
|
|
16
12
|
"height": 1334,
|
|
13
|
+
"paddingBottom": 49,
|
|
17
14
|
"scale": 2,
|
|
18
15
|
"statusBarHeight": null,
|
|
19
16
|
"width": 750,
|
|
20
|
-
},
|
|
21
|
-
]
|
|
22
|
-
}
|
|
23
|
-
>
|
|
24
|
-
<ContextProvider>
|
|
25
|
-
<ContextProvider>
|
|
26
|
-
<ScreenContextProvider />
|
|
27
|
-
</ContextProvider>
|
|
28
|
-
</ContextProvider>
|
|
29
|
-
</ForwardRef(AnimatedComponentWrapper)>
|
|
30
|
-
`;
|
|
31
|
-
|
|
32
|
-
exports[`<Scene /> renders the overlay while animating 1`] = `
|
|
33
|
-
<ForwardRef(AnimatedComponentWrapper)
|
|
34
|
-
pointerEvents="auto"
|
|
35
|
-
style={
|
|
36
|
-
[
|
|
37
|
-
{
|
|
38
|
-
"flex": 1,
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"paddingBottom": 49,
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"height": "100%",
|
|
45
|
-
"width": "100%",
|
|
46
|
-
},
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
>
|
|
50
|
-
<ContextProvider>
|
|
51
|
-
<ContextProvider>
|
|
52
|
-
<ScreenContextProvider />
|
|
53
|
-
</ContextProvider>
|
|
54
|
-
</ContextProvider>
|
|
55
|
-
<ForwardRef(AnimatedComponentWrapper)
|
|
56
|
-
style={
|
|
57
|
-
{
|
|
58
|
-
"opacity": 1,
|
|
59
17
|
}
|
|
60
18
|
}
|
|
61
19
|
/>
|
|
62
|
-
</
|
|
20
|
+
</View>
|
|
63
21
|
`;
|
|
22
|
+
|
|
23
|
+
exports[`<Scene /> renders the overlay while animating 1`] = `[Function]`;
|
|
@@ -9,7 +9,7 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
>
|
|
12
|
-
<
|
|
12
|
+
<View
|
|
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
|
+
</View>
|
|
27
27
|
</View>
|
|
28
28
|
`;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Text, View } from "react-native";
|
|
3
|
-
import { shallow } from "enzyme";
|
|
4
|
-
import { shallowToJson } from "enzyme-to-json";
|
|
5
3
|
|
|
6
4
|
import { TransitionerComponent } from "../Transitioner";
|
|
5
|
+
import { render } from "@testing-library/react-native";
|
|
6
|
+
|
|
7
|
+
jest.mock("../Scene", () => {
|
|
8
|
+
const View = jest.requireActual("react-native").View;
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
Scene(props) {
|
|
12
|
+
return <View {...props} />;
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
});
|
|
7
16
|
|
|
8
17
|
const children = (
|
|
9
18
|
<View foo="bar">
|
|
@@ -33,12 +42,12 @@ jest.mock("uuid");
|
|
|
33
42
|
|
|
34
43
|
describe("<TransitionerComponent />", () => {
|
|
35
44
|
it("renders correctly", () => {
|
|
36
|
-
const wrapper =
|
|
45
|
+
const wrapper = render(
|
|
37
46
|
<TransitionerComponent {...transitionerComponentProps}>
|
|
38
47
|
{children}
|
|
39
48
|
</TransitionerComponent>
|
|
40
49
|
);
|
|
41
50
|
|
|
42
|
-
expect(
|
|
51
|
+
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
43
52
|
});
|
|
44
53
|
});
|
|
@@ -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
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// /// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
//
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { useEffect } from "react";
|
|
4
5
|
|
|
5
6
|
import { AppState, AppStateStatus, View } from "react-native";
|
|
6
7
|
import { TrackedView } from "../TrackedView";
|
|
@@ -25,13 +26,15 @@ import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/player
|
|
|
25
26
|
import { getAutoplaySettings } from "./utils";
|
|
26
27
|
import { isString } from "@applicaster/zapp-react-native-utils/stringUtils";
|
|
27
28
|
import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
28
|
-
import { useEffect } from "react";
|
|
29
29
|
|
|
30
30
|
const { log_error, log_debug } = loggerLiveImageComponent;
|
|
31
31
|
|
|
32
32
|
const isMeasurement = (item: ZappEntry) =>
|
|
33
33
|
isString(item.id) && item.id.startsWith("pre-measurement-");
|
|
34
34
|
|
|
35
|
+
// Pixels by which the view can slightly extend outside the viewport and still be considered fully visible.
|
|
36
|
+
const CLIP_THRESHOLD = 10;
|
|
37
|
+
|
|
35
38
|
type Props = {
|
|
36
39
|
item: ZappEntry;
|
|
37
40
|
style: Record<string, any>;
|
|
@@ -44,7 +47,10 @@ type Props = {
|
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
const PlayerLiveImageComponent = (props: Props) => {
|
|
47
|
-
const dimensions = useDimensions("screen", {
|
|
50
|
+
const dimensions = useDimensions("screen", {
|
|
51
|
+
fullDimensions: true,
|
|
52
|
+
updateForInactiveScreens: false,
|
|
53
|
+
});
|
|
48
54
|
|
|
49
55
|
const { item, style, playerId } = props;
|
|
50
56
|
|
|
@@ -135,13 +141,16 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
135
141
|
} else {
|
|
136
142
|
throw new Error("Player factory item is null");
|
|
137
143
|
}
|
|
138
|
-
}, [playerId, item, playerPluginId, screenConfig]);
|
|
144
|
+
}, [playerId, item.id, playerPluginId, screenConfig]);
|
|
139
145
|
|
|
140
146
|
React.useEffect(() => {
|
|
141
147
|
liveImageItem.setMode = setModeDebounced;
|
|
142
148
|
}, [setModeDebounced, liveImageItem]);
|
|
143
149
|
|
|
144
|
-
const { start, end } = React.useMemo(
|
|
150
|
+
const { start, end } = React.useMemo(
|
|
151
|
+
() => getAutoplaySettings(item),
|
|
152
|
+
[item.id]
|
|
153
|
+
);
|
|
145
154
|
|
|
146
155
|
const controller = liveImageItem.getPlayer();
|
|
147
156
|
const player = usePlayer(playerId);
|
|
@@ -174,7 +183,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
174
183
|
|
|
175
184
|
unregister();
|
|
176
185
|
};
|
|
177
|
-
}, [item, liveImageItem]);
|
|
186
|
+
}, [item.id, liveImageItem]);
|
|
178
187
|
|
|
179
188
|
React.useEffect(() => {
|
|
180
189
|
if (!player) {
|
|
@@ -244,25 +253,27 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
244
253
|
}, [item.id]);
|
|
245
254
|
|
|
246
255
|
React.useEffect(() => {
|
|
247
|
-
if (playerManager) {
|
|
248
|
-
|
|
256
|
+
if (isMeasurement(item) || !playerManager) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
249
259
|
|
|
250
|
-
|
|
251
|
-
log_error(
|
|
252
|
-
`PlayerLiveImageComponent: player ${playerId} already registered`
|
|
253
|
-
);
|
|
254
|
-
} else {
|
|
255
|
-
playerManager.registerPlayer({
|
|
256
|
-
id: playerId,
|
|
257
|
-
playerController: controller,
|
|
258
|
-
});
|
|
260
|
+
const isPlayerRegistered = playerManager.isPlayerRegistered(playerId);
|
|
259
261
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
262
|
+
if (isPlayerRegistered) {
|
|
263
|
+
log_error(
|
|
264
|
+
`PlayerLiveImageComponent: player ${playerId} already registered`
|
|
265
|
+
);
|
|
266
|
+
} else {
|
|
267
|
+
playerManager.registerPlayer({
|
|
268
|
+
id: playerId,
|
|
269
|
+
playerController: controller,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
return () => {
|
|
273
|
+
playerManager.unregisterPlayer(playerId);
|
|
274
|
+
};
|
|
264
275
|
}
|
|
265
|
-
}, [liveImageItem, playerId, controller]);
|
|
276
|
+
}, [liveImageItem, playerId, controller, item.id]);
|
|
266
277
|
|
|
267
278
|
const onPositionUpdated = React.useCallback(
|
|
268
279
|
(data) => {
|
|
@@ -302,7 +313,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
302
313
|
LiveImageManager.instance.checkPlayerPosition(liveImageItem);
|
|
303
314
|
}
|
|
304
315
|
},
|
|
305
|
-
[liveImageItem, dimensions]
|
|
316
|
+
[liveImageItem, dimensions.height, dimensions.width]
|
|
306
317
|
);
|
|
307
318
|
|
|
308
319
|
const platformSpecificProps = isApplePlatform()
|
|
@@ -320,9 +331,10 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
320
331
|
<TrackedView
|
|
321
332
|
testId={`tracked-view-${playerId}-${item.title}`}
|
|
322
333
|
onPositionUpdated={onPositionUpdated}
|
|
334
|
+
clipThreshold={CLIP_THRESHOLD}
|
|
323
335
|
>
|
|
324
336
|
<View ref={trackViewRef}>
|
|
325
|
-
{isVideoMode
|
|
337
|
+
{isVideoMode ? (
|
|
326
338
|
<Player
|
|
327
339
|
autoplay={false}
|
|
328
340
|
ref={_assignRoot}
|
|
@@ -334,7 +346,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
334
346
|
resizeMode={"cover"}
|
|
335
347
|
{...platformSpecificProps}
|
|
336
348
|
/>
|
|
337
|
-
)}
|
|
349
|
+
) : null}
|
|
338
350
|
{
|
|
339
351
|
<AnimatedInOut
|
|
340
352
|
visible={isBackgroundImageVisible}
|
|
@@ -4,6 +4,7 @@ import { render } from "@testing-library/react-native";
|
|
|
4
4
|
import * as PlayerFactory from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
|
|
5
5
|
import { ThemeContext } from "@applicaster/zapp-react-native-utils/theme";
|
|
6
6
|
import * as navigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
7
|
+
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
7
8
|
|
|
8
9
|
import { PlayerLiveImage } from "../PlayerLiveImageComponent";
|
|
9
10
|
import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
|
|
@@ -32,7 +33,7 @@ const mockStore = configureStore();
|
|
|
32
33
|
|
|
33
34
|
const store = mockStore({ appData: {} });
|
|
34
35
|
|
|
35
|
-
const Wrapper = ({ children }: { children: React.
|
|
36
|
+
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
36
37
|
/* @ts-ignore */
|
|
37
38
|
<Provider store={store}>
|
|
38
39
|
<ThemeContext.Provider
|
|
@@ -118,4 +119,53 @@ describe("PlayerLiveImageComponent", () => {
|
|
|
118
119
|
|
|
119
120
|
// TODO: implement this test
|
|
120
121
|
});
|
|
122
|
+
|
|
123
|
+
it("should register the player for normal item", () => {
|
|
124
|
+
render(
|
|
125
|
+
<Wrapper>
|
|
126
|
+
<PlayerLiveImage {...defaultProps} />
|
|
127
|
+
</Wrapper>
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const isPlayerRegistered = playerManager.isPlayerRegistered(
|
|
131
|
+
defaultProps.playerId
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
expect(isPlayerRegistered).toBe(true);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("should unregister the player for normal item", () => {
|
|
138
|
+
const component = render(
|
|
139
|
+
<Wrapper>
|
|
140
|
+
<PlayerLiveImage {...defaultProps} />
|
|
141
|
+
</Wrapper>
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
component.unmount();
|
|
145
|
+
|
|
146
|
+
const isPlayerRegistered = playerManager.isPlayerRegistered(
|
|
147
|
+
defaultProps.playerId
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
expect(isPlayerRegistered).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("should not register the player for 'pre-measurement' item", () => {
|
|
154
|
+
const props = {
|
|
155
|
+
...defaultProps,
|
|
156
|
+
item: {
|
|
157
|
+
...defaultProps.item,
|
|
158
|
+
id: "pre-measurement-1",
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
render(
|
|
163
|
+
<Wrapper>
|
|
164
|
+
<PlayerLiveImage {...props} />
|
|
165
|
+
</Wrapper>
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const isPlayerRegistered = playerManager.isPlayerRegistered(props.playerId);
|
|
169
|
+
expect(isPlayerRegistered).toBe(false);
|
|
170
|
+
});
|
|
121
171
|
});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`PlayerLiveImageComponent should render correctly with default props 1`] = `
|
|
4
4
|
<TrackedView
|
|
5
|
+
clipThreshold={10}
|
|
5
6
|
onPositionUpdated={[Function]}
|
|
6
7
|
testId="tracked-view-player1-Test"
|
|
7
8
|
>
|
|
@@ -31,11 +32,6 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
|
|
|
31
32
|
playerId="player1"
|
|
32
33
|
resizeMode="cover"
|
|
33
34
|
screenConfig={{}}
|
|
34
|
-
source={
|
|
35
|
-
{
|
|
36
|
-
"uri": "",
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
35
|
style={{}}
|
|
40
36
|
/>
|
|
41
37
|
</View>
|
|
@@ -46,7 +46,7 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
46
46
|
|
|
47
47
|
React.useEffect(() => {
|
|
48
48
|
(playerAnimationState === PlayerAnimationStateEnum.minimize ||
|
|
49
|
-
playerAnimationState === PlayerAnimationStateEnum.
|
|
49
|
+
playerAnimationState === PlayerAnimationStateEnum.maximize) &&
|
|
50
50
|
setStartComponentsAnimation(true);
|
|
51
51
|
}, [playerAnimationState]);
|
|
52
52
|
|