@applicaster/zapp-react-native-ui-components 14.0.0-alpha.5521273514 → 14.0.0-alpha.5621117258
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/AudioPlayer/Artwork.tsx +17 -12
- package/Components/AudioPlayer/AudioPlayer.tsx +4 -2
- package/Components/AudioPlayer/AudioPlayerLayout.tsx +11 -11
- package/Components/AudioPlayer/Runtime.tsx +2 -1
- package/Components/AudioPlayer/Summary.tsx +12 -9
- package/Components/AudioPlayer/Title.tsx +12 -9
- package/Components/AudioPlayer/__tests__/__snapshots__/Runtime.test.js.snap +2 -2
- package/Components/AudioPlayer/__tests__/__snapshots__/artWork.test.js.snap +9 -4
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +6 -0
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +6 -0
- package/Components/AudioPlayer/__tests__/__snapshots__/summary.test.js.snap +1 -1
- package/Components/AudioPlayer/__tests__/__snapshots__/title.test.js.snap +1 -1
- package/Components/AudioPlayer/helpers.tsx +2 -2
- package/Components/Cell/index.js +2 -6
- package/Components/PlayerContainer/PlayerContainer.tsx +21 -6
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +9 -1
- package/Components/VideoModal/PlayerDetails.tsx +24 -2
- package/Components/VideoModal/PlayerWrapper.tsx +26 -142
- package/Components/VideoModal/VideoModal.tsx +3 -17
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -180
- package/Components/VideoModal/hooks/index.ts +0 -2
- package/Components/VideoModal/utils.ts +6 -0
- package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
- package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
- package/package.json +5 -5
- package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { View, Image } from "react-native";
|
|
2
|
+
import { View, Image, StyleSheet } from "react-native";
|
|
3
|
+
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
4
|
+
|
|
5
|
+
const styles = StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
marginHorizontal: 24,
|
|
8
|
+
},
|
|
9
|
+
image: {
|
|
10
|
+
width: 400,
|
|
11
|
+
height: 400,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
3
14
|
|
|
4
15
|
type Props = {
|
|
5
16
|
srcImage: string;
|
|
@@ -9,25 +20,19 @@ type Props = {
|
|
|
9
20
|
backgroundColor: string;
|
|
10
21
|
backgroundImage: string;
|
|
11
22
|
isRTL: boolean;
|
|
23
|
+
artworkBorderRadius: Option<number>;
|
|
12
24
|
};
|
|
13
25
|
};
|
|
14
26
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const imageStyles = {
|
|
20
|
-
width: 400,
|
|
21
|
-
height: 400,
|
|
22
|
-
};
|
|
27
|
+
export function Artwork({ srcImage, config }: Props) {
|
|
28
|
+
const borderRadius = toNumberWithDefaultZero(config.artworkBorderRadius);
|
|
23
29
|
|
|
24
|
-
export function Artwork({ srcImage }: Props) {
|
|
25
30
|
return (
|
|
26
|
-
<View style={
|
|
31
|
+
<View style={styles.container}>
|
|
27
32
|
<Image
|
|
28
33
|
fadeDuration={0}
|
|
29
34
|
source={{ uri: srcImage }}
|
|
30
|
-
style={
|
|
35
|
+
style={[styles.image, { borderRadius }]}
|
|
31
36
|
resizeMode="cover"
|
|
32
37
|
/>
|
|
33
38
|
</View>
|
|
@@ -52,7 +52,7 @@ type Props = {
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
export function AudioPlayer(props: Props) {
|
|
55
|
-
const { audio_item, plugin_configuration
|
|
55
|
+
const { audio_item, plugin_configuration } = props;
|
|
56
56
|
const { extensions, title, summary } = audio_item;
|
|
57
57
|
|
|
58
58
|
const getProp = useCallback(
|
|
@@ -72,6 +72,7 @@ export function AudioPlayer(props: Props) {
|
|
|
72
72
|
const artworkAspectRatio = getProp("audio_player_artwork_aspect_ratio");
|
|
73
73
|
const channelIcon = getProp("audio_player_channel_icon");
|
|
74
74
|
const rtlFlag = getProp("audio_player_rtl");
|
|
75
|
+
const artworkBorderRadius = getProp("audio_player_artwork_border_radius");
|
|
75
76
|
|
|
76
77
|
const audioPlayerBackgroundImageDefaultColor = getProp(
|
|
77
78
|
"audio_player_background_image_default_color"
|
|
@@ -154,6 +155,7 @@ export function AudioPlayer(props: Props) {
|
|
|
154
155
|
artworkAspectRatio,
|
|
155
156
|
channelIcon,
|
|
156
157
|
audioPlayerBackgroundImageDefaultColor,
|
|
158
|
+
artworkBorderRadius,
|
|
157
159
|
};
|
|
158
160
|
}, [getProp]);
|
|
159
161
|
|
|
@@ -162,7 +164,7 @@ export function AudioPlayer(props: Props) {
|
|
|
162
164
|
]);
|
|
163
165
|
|
|
164
166
|
return (
|
|
165
|
-
<AudioPlayerLayout artwork={artwork} config={config}
|
|
167
|
+
<AudioPlayerLayout artwork={artwork} config={config}>
|
|
166
168
|
<Channel srcImage={config?.channelIcon} config={config} />
|
|
167
169
|
<Title title={title} config={config} />
|
|
168
170
|
<Summary summary={summary} config={config} />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useRef } from "react";
|
|
2
|
-
import { View, ImageBackground, Animated
|
|
2
|
+
import { View, ImageBackground, Animated } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
5
|
|
|
@@ -14,12 +14,12 @@ type Props = {
|
|
|
14
14
|
backgroundColor: string;
|
|
15
15
|
backgroundImage: string;
|
|
16
16
|
isRTL: boolean;
|
|
17
|
+
artworkBorderRadius: Option<number>;
|
|
17
18
|
};
|
|
18
19
|
children: React.ReactNode;
|
|
19
|
-
style: ViewStyle;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
export function AudioPlayerLayout({ artwork, config, children
|
|
22
|
+
export function AudioPlayerLayout({ artwork, config, children }: Props) {
|
|
23
23
|
const fadeAnimation = useRef(new Animated.Value(0)).current;
|
|
24
24
|
|
|
25
25
|
const fadeAudioPlayerIn = () => {
|
|
@@ -32,25 +32,24 @@ export function AudioPlayerLayout({ artwork, config, children, style }: Props) {
|
|
|
32
32
|
|
|
33
33
|
const { isRTL, backgroundColor, backgroundImage } = config;
|
|
34
34
|
|
|
35
|
-
const backgroundImageSource = { uri: backgroundImage };
|
|
35
|
+
const backgroundImageSource = { uri: backgroundImage || artwork };
|
|
36
36
|
|
|
37
|
-
const backgroundColorStyle =
|
|
37
|
+
const backgroundColorStyle = backgroundImageSource.uri
|
|
38
38
|
? "transparent"
|
|
39
39
|
: backgroundColor;
|
|
40
40
|
|
|
41
41
|
const mainContainerStyles = platformSelect({
|
|
42
42
|
tvos: {
|
|
43
|
-
width:
|
|
44
|
-
height:
|
|
43
|
+
width: "100%",
|
|
44
|
+
height: "100%",
|
|
45
45
|
alignItems: "center",
|
|
46
46
|
justifyContent: "center",
|
|
47
47
|
flexDirection: directionStyles(isRTL).flexDirection,
|
|
48
48
|
backgroundColor: backgroundColorStyle,
|
|
49
49
|
},
|
|
50
50
|
android_tv: {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
height: 1080,
|
|
51
|
+
width: "100%",
|
|
52
|
+
height: "100%",
|
|
54
53
|
alignItems: "center",
|
|
55
54
|
justifyContent: "center",
|
|
56
55
|
flexDirection: directionStyles(isRTL).flexDirection,
|
|
@@ -67,7 +66,8 @@ export function AudioPlayerLayout({ artwork, config, children, style }: Props) {
|
|
|
67
66
|
native: {
|
|
68
67
|
backgroundColor: backgroundColorStyle,
|
|
69
68
|
overflow: "hidden",
|
|
70
|
-
|
|
69
|
+
width: "100%",
|
|
70
|
+
height: "100%",
|
|
71
71
|
},
|
|
72
72
|
samsung_tv: {
|
|
73
73
|
position: "absolute",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { View, Text, ViewStyle, TextStyle } from "react-native";
|
|
3
|
+
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
3
4
|
import { directionStyles } from "./helpers";
|
|
4
5
|
|
|
5
6
|
type Props = {
|
|
@@ -31,7 +32,7 @@ const textStyles = ({
|
|
|
31
32
|
}) => ({
|
|
32
33
|
color: summaryColor,
|
|
33
34
|
opacity: 0.8,
|
|
34
|
-
fontSize:
|
|
35
|
+
fontSize: toNumberWithDefault(20, runTimeFontSize),
|
|
35
36
|
fontFamily: runTimeFontFamily || null,
|
|
36
37
|
...directionStyles(isRTL),
|
|
37
38
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { View, Text, TextStyle } from "react-native";
|
|
2
|
+
import { View, Text, TextStyle, StyleSheet } from "react-native";
|
|
3
|
+
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
3
4
|
|
|
4
5
|
type Props = {
|
|
5
6
|
config: {
|
|
@@ -14,11 +15,13 @@ type Props = {
|
|
|
14
15
|
summary: string | number;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const styles = StyleSheet.create({
|
|
19
|
+
container: {
|
|
20
|
+
width: 600,
|
|
21
|
+
height: 80,
|
|
22
|
+
marginBottom: 30,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
22
25
|
|
|
23
26
|
const textStyles = ({
|
|
24
27
|
summaryColor,
|
|
@@ -26,8 +29,8 @@ const textStyles = ({
|
|
|
26
29
|
summaryFontFamily,
|
|
27
30
|
summaryFontSize,
|
|
28
31
|
}) => ({
|
|
29
|
-
textAlign: (isRTL ? "
|
|
30
|
-
fontSize:
|
|
32
|
+
textAlign: (isRTL ? "right" : "left") as TextStyle["textAlign"],
|
|
33
|
+
fontSize: toNumberWithDefault(20, summaryFontSize),
|
|
31
34
|
color: summaryColor,
|
|
32
35
|
fontWeight: "600" as TextStyle["fontWeight"],
|
|
33
36
|
opacity: 0.8,
|
|
@@ -36,7 +39,7 @@ const textStyles = ({
|
|
|
36
39
|
|
|
37
40
|
export function Summary({ summary, config }: Props) {
|
|
38
41
|
return (
|
|
39
|
-
<View style={
|
|
42
|
+
<View style={styles.container}>
|
|
40
43
|
<Text style={textStyles(config)} numberOfLines={2}>
|
|
41
44
|
{summary}
|
|
42
45
|
</Text>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { View, Text, TextStyle } from "react-native";
|
|
2
|
+
import { View, Text, TextStyle, StyleSheet } from "react-native";
|
|
3
|
+
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
3
4
|
|
|
4
5
|
type Props = {
|
|
5
6
|
config: {
|
|
@@ -14,15 +15,17 @@ type Props = {
|
|
|
14
15
|
title: string | number;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const styles = StyleSheet.create({
|
|
19
|
+
container: {
|
|
20
|
+
width: 600,
|
|
21
|
+
height: 100,
|
|
22
|
+
marginBottom: 12,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
22
25
|
|
|
23
26
|
const textStyles = ({ titleColor, isRTL, titleFontFamily, titleFontSize }) => ({
|
|
24
|
-
textAlign: (isRTL ? "
|
|
25
|
-
fontSize:
|
|
27
|
+
textAlign: (isRTL ? "right" : "left") as TextStyle["textAlign"],
|
|
28
|
+
fontSize: toNumberWithDefault(38, titleFontSize),
|
|
26
29
|
fontWeight: "600" as TextStyle["fontWeight"],
|
|
27
30
|
color: titleColor,
|
|
28
31
|
fontFamily: titleFontFamily || null,
|
|
@@ -30,7 +33,7 @@ const textStyles = ({ titleColor, isRTL, titleFontFamily, titleFontSize }) => ({
|
|
|
30
33
|
|
|
31
34
|
export function Title({ title, config }: Props) {
|
|
32
35
|
return (
|
|
33
|
-
<View style={
|
|
36
|
+
<View style={styles.container}>
|
|
34
37
|
<Text style={textStyles(config)} numberOfLines={2}>
|
|
35
38
|
{title}
|
|
36
39
|
</Text>
|
|
@@ -20,7 +20,7 @@ exports[`<Runtime /> LTR renders correctly 1`] = `
|
|
|
20
20
|
"fontSize": 20,
|
|
21
21
|
"justifyContent": "flex-start",
|
|
22
22
|
"opacity": 0.8,
|
|
23
|
-
"textAlign": "
|
|
23
|
+
"textAlign": "left",
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
>
|
|
@@ -49,7 +49,7 @@ exports[`<Runtime /> RTL renders correctly 1`] = `
|
|
|
49
49
|
"fontSize": 20,
|
|
50
50
|
"justifyContent": "flex-end",
|
|
51
51
|
"opacity": 0.8,
|
|
52
|
-
"textAlign": "
|
|
52
|
+
"textAlign": "right",
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
>
|
|
@@ -6,7 +6,9 @@ exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
|
6
6
|
style={
|
|
7
7
|
{
|
|
8
8
|
"backgroundColor": "transparent",
|
|
9
|
+
"height": "100%",
|
|
9
10
|
"overflow": "hidden",
|
|
11
|
+
"width": "100%",
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
14
|
>
|
|
@@ -15,8 +17,10 @@ exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
|
15
17
|
style={
|
|
16
18
|
{
|
|
17
19
|
"backgroundColor": "transparent",
|
|
20
|
+
"height": "100%",
|
|
18
21
|
"opacity": 0,
|
|
19
22
|
"overflow": "hidden",
|
|
23
|
+
"width": "100%",
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
>
|
|
@@ -56,7 +60,9 @@ exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
|
56
60
|
style={
|
|
57
61
|
{
|
|
58
62
|
"backgroundColor": "transparent",
|
|
63
|
+
"height": "100%",
|
|
59
64
|
"overflow": "hidden",
|
|
65
|
+
"width": "100%",
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
/>
|
|
@@ -6,7 +6,9 @@ exports[`<AudioPlayerLayout /> renders correctly 1`] = `
|
|
|
6
6
|
style={
|
|
7
7
|
{
|
|
8
8
|
"backgroundColor": "transparent",
|
|
9
|
+
"height": "100%",
|
|
9
10
|
"overflow": "hidden",
|
|
11
|
+
"width": "100%",
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
14
|
>
|
|
@@ -15,8 +17,10 @@ exports[`<AudioPlayerLayout /> renders correctly 1`] = `
|
|
|
15
17
|
style={
|
|
16
18
|
{
|
|
17
19
|
"backgroundColor": "transparent",
|
|
20
|
+
"height": "100%",
|
|
18
21
|
"opacity": 0,
|
|
19
22
|
"overflow": "hidden",
|
|
23
|
+
"width": "100%",
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
>
|
|
@@ -56,7 +60,9 @@ exports[`<AudioPlayerLayout /> renders correctly 1`] = `
|
|
|
56
60
|
style={
|
|
57
61
|
{
|
|
58
62
|
"backgroundColor": "transparent",
|
|
63
|
+
"height": "100%",
|
|
59
64
|
"overflow": "hidden",
|
|
65
|
+
"width": "100%",
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
/>
|
|
@@ -26,14 +26,14 @@ export function getPropertyFromEntryOrConfig({ entry, plugin_configuration }) {
|
|
|
26
26
|
const LTR = {
|
|
27
27
|
flexDirection: "row",
|
|
28
28
|
justifyContent: "flex-start",
|
|
29
|
-
textAlign: "
|
|
29
|
+
textAlign: "left",
|
|
30
30
|
alignItems: "flex-end",
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
const RTL = {
|
|
34
34
|
flexDirection: "row-reverse",
|
|
35
35
|
justifyContent: "flex-end",
|
|
36
|
-
textAlign: "
|
|
36
|
+
textAlign: "right",
|
|
37
37
|
alignItems: "flex-start",
|
|
38
38
|
};
|
|
39
39
|
|
package/Components/Cell/index.js
CHANGED
|
@@ -3,15 +3,11 @@ import * as R from "ramda";
|
|
|
3
3
|
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
4
4
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
HorizontalScrollContext,
|
|
8
|
-
RiverOffsetContext,
|
|
9
|
-
ScreenScrollingContext,
|
|
10
|
-
} from "../../Contexts";
|
|
11
|
-
|
|
6
|
+
import { HorizontalScrollContext, RiverOffsetContext } from "../../Contexts";
|
|
12
7
|
import { CellComponent } from "./Cell";
|
|
13
8
|
import { TvOSCellComponent } from "./TvOSCellComponent";
|
|
14
9
|
import { withConsumer } from "../../Contexts/HeaderOffsetContext";
|
|
10
|
+
import { ScreenScrollingContext } from "../../Contexts/ScreenScrollingContext";
|
|
15
11
|
|
|
16
12
|
import { ScreenLayoutContextConsumer } from "../../Contexts/ScreenLayoutContext";
|
|
17
13
|
import { createContext } from "@applicaster/zapp-react-native-utils/reactUtils/createContext";
|
|
@@ -88,7 +88,7 @@ export const VideoModalMode = {
|
|
|
88
88
|
MAXIMIZED: "MAXIMIZED",
|
|
89
89
|
MINIMIZED: "MINIMIZED",
|
|
90
90
|
FULLSCREEN: "FULLSCREEN",
|
|
91
|
-
};
|
|
91
|
+
} as const;
|
|
92
92
|
|
|
93
93
|
export type PlayNextData = {
|
|
94
94
|
state: PlayNextState;
|
|
@@ -105,6 +105,11 @@ const isTvOS = isTvOSPlatform();
|
|
|
105
105
|
// height for container with additional content below player
|
|
106
106
|
const INLINE_CONTAINER_CONTENT_HEIGHT = 400;
|
|
107
107
|
|
|
108
|
+
// Default Y offset for anchor points on non-Android TV platforms
|
|
109
|
+
const DEFAULT_OFFSET_Y = -600;
|
|
110
|
+
|
|
111
|
+
const EXTRA_ANCHOR_POINT_Y_OFFSET = isAndroidTV ? 0 : DEFAULT_OFFSET_Y;
|
|
112
|
+
|
|
108
113
|
const withBorderHack = () => {
|
|
109
114
|
if (isAndroidTV) {
|
|
110
115
|
/* @HACK: see GH#7269 */
|
|
@@ -127,7 +132,7 @@ const webStyles = {
|
|
|
127
132
|
playerScreen: {
|
|
128
133
|
flex: 1,
|
|
129
134
|
height: "100vh",
|
|
130
|
-
|
|
135
|
+
backgroundColor: "black",
|
|
131
136
|
},
|
|
132
137
|
playerWrapper: {
|
|
133
138
|
height: "100%",
|
|
@@ -565,8 +570,9 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
565
570
|
const isInlineTV = isInlineTVUtil(screenData);
|
|
566
571
|
|
|
567
572
|
const inline =
|
|
568
|
-
[VideoModalMode.MAXIMIZED, VideoModalMode.MINIMIZED].includes(
|
|
569
|
-
|
|
573
|
+
[VideoModalMode.MAXIMIZED, VideoModalMode.MINIMIZED].includes(
|
|
574
|
+
mode as any
|
|
575
|
+
) || isInlineTV;
|
|
570
576
|
|
|
571
577
|
const value = React.useMemo(
|
|
572
578
|
() => ({ playerId: state.playerId }),
|
|
@@ -587,7 +593,11 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
587
593
|
);
|
|
588
594
|
}
|
|
589
595
|
|
|
590
|
-
if (
|
|
596
|
+
if (
|
|
597
|
+
screen_background_color &&
|
|
598
|
+
mode !== VideoModalMode.FULLSCREEN &&
|
|
599
|
+
isTV()
|
|
600
|
+
) {
|
|
591
601
|
updatedStyles.playerScreen.backgroundColor = screen_background_color;
|
|
592
602
|
}
|
|
593
603
|
|
|
@@ -637,14 +647,17 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
637
647
|
preferredFocus
|
|
638
648
|
shouldUsePreferredFocus
|
|
639
649
|
groupId={groupId}
|
|
650
|
+
pointerEvents={mode === "MINIMIZED" ? "box-none" : "auto"}
|
|
640
651
|
>
|
|
641
652
|
{/* Video player and components */}
|
|
642
653
|
<View
|
|
643
654
|
style={styles.playerScreen}
|
|
644
655
|
testID={"player-screen-container"}
|
|
656
|
+
pointerEvents={mode === "MINIMIZED" ? "box-none" : "auto"}
|
|
645
657
|
>
|
|
646
658
|
{/* Player container */}
|
|
647
659
|
<View
|
|
660
|
+
pointerEvents={mode === "MINIMIZED" ? "box-none" : "auto"}
|
|
648
661
|
style={[
|
|
649
662
|
styles.playerWrapper,
|
|
650
663
|
// eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
|
|
@@ -716,7 +729,9 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
716
729
|
key={item.id}
|
|
717
730
|
groupId={FocusableGroupMainContainerId}
|
|
718
731
|
cellTapAction={onCellTap}
|
|
719
|
-
extraAnchorPointYOffset={
|
|
732
|
+
extraAnchorPointYOffset={
|
|
733
|
+
EXTRA_ANCHOR_POINT_Y_OFFSET
|
|
734
|
+
}
|
|
720
735
|
isScreenWrappedInContainer={true}
|
|
721
736
|
containerHeight={styles.inlineRiver.height}
|
|
722
737
|
componentsMapExtraProps={{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
-
import { Animated } from "react-native";
|
|
2
|
+
import { Animated, Dimensions } from "react-native";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
useSafeAreaInsets,
|
|
@@ -23,6 +23,7 @@ export enum PlayerAnimationStateEnum {
|
|
|
23
23
|
export type PlayerAnimationStateT = number | PlayerAnimationStateEnum | null;
|
|
24
24
|
|
|
25
25
|
export type ModalAnimationContextT = {
|
|
26
|
+
yTranslate: React.MutableRefObject<Animated.Value | null>;
|
|
26
27
|
isActiveGesture: boolean;
|
|
27
28
|
playerAnimationState: PlayerAnimationStateT;
|
|
28
29
|
setPlayerAnimationState: (value: PlayerAnimationStateT) => void;
|
|
@@ -48,6 +49,7 @@ export type ModalAnimationContextT = {
|
|
|
48
49
|
};
|
|
49
50
|
|
|
50
51
|
export const ReactContext = React.createContext<ModalAnimationContextT>({
|
|
52
|
+
yTranslate: React.createRef<Animated.Value | null>(),
|
|
51
53
|
isActiveGesture: false,
|
|
52
54
|
playerAnimationState: null,
|
|
53
55
|
setPlayerAnimationState: () => null,
|
|
@@ -73,6 +75,10 @@ export const ReactContext = React.createContext<ModalAnimationContextT>({
|
|
|
73
75
|
});
|
|
74
76
|
|
|
75
77
|
const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
78
|
+
const yTranslate = React.useRef(
|
|
79
|
+
new Animated.Value(Dimensions.get("window").height)
|
|
80
|
+
);
|
|
81
|
+
|
|
76
82
|
const [playerAnimationState, setPlayerAnimationState] =
|
|
77
83
|
React.useState<PlayerAnimationStateT>(null);
|
|
78
84
|
|
|
@@ -100,6 +106,7 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
100
106
|
// Reset player animation state when video modal is closed
|
|
101
107
|
if (!visible) {
|
|
102
108
|
resetPlayerAnimationState();
|
|
109
|
+
yTranslate.current?.setValue(Dimensions.get("window").height);
|
|
103
110
|
}
|
|
104
111
|
}, [visible, resetPlayerAnimationState]);
|
|
105
112
|
|
|
@@ -141,6 +148,7 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
141
148
|
return (
|
|
142
149
|
<ReactContext.Provider
|
|
143
150
|
value={{
|
|
151
|
+
yTranslate,
|
|
144
152
|
startComponentsAnimation,
|
|
145
153
|
setStartComponentsAnimation,
|
|
146
154
|
isActiveGesture: playerAnimationState !== null,
|
|
@@ -11,6 +11,8 @@ import { useTargetScreenData } from "@applicaster/zapp-react-native-utils/reactH
|
|
|
11
11
|
import { ComponentsMap } from "@applicaster/zapp-react-native-ui-components/Components/River/ComponentsMap";
|
|
12
12
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
13
13
|
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
14
|
+
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
15
|
+
import { useDelayedPlayerDetails } from "./hooks";
|
|
14
16
|
|
|
15
17
|
const { width: SCREEN_WIDTH } = Dimensions.get("screen");
|
|
16
18
|
|
|
@@ -26,6 +28,10 @@ type Props = {
|
|
|
26
28
|
isTabletLandscape?: boolean;
|
|
27
29
|
isAudioPlayer?: boolean;
|
|
28
30
|
isTablet?: boolean;
|
|
31
|
+
inline?: any;
|
|
32
|
+
docked?: boolean;
|
|
33
|
+
isModal?: boolean;
|
|
34
|
+
pip?: boolean;
|
|
29
35
|
};
|
|
30
36
|
|
|
31
37
|
const containerStyle = ({
|
|
@@ -42,8 +48,24 @@ export const PlayerDetails = ({
|
|
|
42
48
|
configuration,
|
|
43
49
|
isTabletLandscape = false,
|
|
44
50
|
isAudioPlayer,
|
|
45
|
-
|
|
51
|
+
inline,
|
|
52
|
+
docked,
|
|
53
|
+
isModal,
|
|
54
|
+
pip,
|
|
46
55
|
}: Props) => {
|
|
56
|
+
const isInlineModal = inline && isModal;
|
|
57
|
+
|
|
58
|
+
// Mounting the PlayerDetails component is a resource-intensive process.
|
|
59
|
+
// Therefore, for performance reasons, we mount it with a delay to make the rotation process as smooth as possible.
|
|
60
|
+
// The flow is as follows: the rotation occurs first, and then, after a short delay, we mount the PlayerDetails component.
|
|
61
|
+
// This helps to avoid blocking the rotation and any animations related to the rotation.
|
|
62
|
+
const isShowPlayerDetails = useDelayedPlayerDetails({
|
|
63
|
+
isInline: isInlineModal,
|
|
64
|
+
isDocked: docked,
|
|
65
|
+
isPip: pip,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const isTablet = useIsTablet();
|
|
47
69
|
const screenData = useTargetScreenData(entry);
|
|
48
70
|
const insets = useSafeAreaInsets();
|
|
49
71
|
|
|
@@ -79,7 +101,7 @@ export const PlayerDetails = ({
|
|
|
79
101
|
}
|
|
80
102
|
}, [isAudioPlayer]);
|
|
81
103
|
|
|
82
|
-
if (isNilOrEmpty(screenData?.ui_components)) {
|
|
104
|
+
if (isNilOrEmpty(screenData?.ui_components) || !isShowPlayerDetails) {
|
|
83
105
|
return null;
|
|
84
106
|
}
|
|
85
107
|
|
|
@@ -9,16 +9,8 @@ import {
|
|
|
9
9
|
import { Edge, SafeAreaView } from "react-native-safe-area-context";
|
|
10
10
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
11
11
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
|
-
import { PlayerDetails } from "./PlayerDetails";
|
|
13
12
|
import { playerDimensionsHack } from "./utils";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
AnimatedScrollModal,
|
|
18
|
-
AnimatedVideoPlayerComponent,
|
|
19
|
-
AnimationComponent,
|
|
20
|
-
ComponentAnimationType,
|
|
21
|
-
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
13
|
+
import { getTabletWidth } from "@applicaster/zapp-react-native-utils/playerUtils";
|
|
22
14
|
|
|
23
15
|
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get("screen");
|
|
24
16
|
|
|
@@ -44,29 +36,15 @@ type Props = {
|
|
|
44
36
|
isModal?: boolean;
|
|
45
37
|
fullscreen?: boolean;
|
|
46
38
|
isTabletPortrait?: boolean;
|
|
47
|
-
children: (playerDimensions: DimensionsT) => React.ReactNode;
|
|
48
39
|
configuration: Configuration;
|
|
40
|
+
|
|
41
|
+
playerContent: (styles: ViewStyle) => React.ReactNode;
|
|
49
42
|
};
|
|
50
43
|
|
|
51
44
|
const defaultStyles = StyleSheet.create({
|
|
52
45
|
playerContainer: { position: "relative", alignSelf: "center", zIndex: 200 },
|
|
53
|
-
playerDetails: { flex: 1, paddingTop: 20 },
|
|
54
|
-
flex: { flex: 1 },
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const orientationStyles = StyleSheet.create({
|
|
58
|
-
landscape: { flexDirection: "row" },
|
|
59
|
-
portrait: { flexDirection: "column" },
|
|
60
46
|
});
|
|
61
47
|
|
|
62
|
-
const directionStyles = (isTabletLandscape: boolean): ViewStyle => {
|
|
63
|
-
if (isTabletLandscape) {
|
|
64
|
-
return orientationStyles.landscape;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return orientationStyles.portrait;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
48
|
const getScreenAspectRatio = () => {
|
|
71
49
|
const longEdge = Math.max(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
72
50
|
const shortEdge = Math.min(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
@@ -86,51 +64,6 @@ const getEdges = (isTablet: boolean, isInlineModal: boolean) => {
|
|
|
86
64
|
return ["top"];
|
|
87
65
|
};
|
|
88
66
|
|
|
89
|
-
const isPercentage = (value: string | number): boolean => {
|
|
90
|
-
if (typeof value === "string") {
|
|
91
|
-
return value.includes("%");
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return false;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const getPercentageOf = (percent: string, value: number) => {
|
|
98
|
-
const percentageValue = parseFloat(percent.replace("%", ""));
|
|
99
|
-
|
|
100
|
-
if (isNaN(percentageValue)) {
|
|
101
|
-
return value;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return (value * percentageValue) / 100;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const getTabletWidth = (
|
|
108
|
-
configuration: Configuration,
|
|
109
|
-
dimensions: DimensionsT
|
|
110
|
-
) => {
|
|
111
|
-
const tablet_landscape_sidebar_width =
|
|
112
|
-
configuration?.tablet_landscape_sidebar_width;
|
|
113
|
-
|
|
114
|
-
const { width } = dimensions;
|
|
115
|
-
let widthValue = Number(width);
|
|
116
|
-
|
|
117
|
-
if (isPercentage(width)) {
|
|
118
|
-
widthValue = getPercentageOf(width.toString(), SCREEN_WIDTH);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const sidebarWidth = Number(tablet_landscape_sidebar_width?.replace("%", ""));
|
|
122
|
-
|
|
123
|
-
if (tablet_landscape_sidebar_width?.includes("%")) {
|
|
124
|
-
return widthValue * (1 - sidebarWidth / 100);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (Number.isNaN(sidebarWidth)) {
|
|
128
|
-
return widthValue * 0.65;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return widthValue - sidebarWidth;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
67
|
const PlayerWrapperComponent = (props: Props) => {
|
|
135
68
|
const {
|
|
136
69
|
entry,
|
|
@@ -139,35 +72,26 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
139
72
|
inline,
|
|
140
73
|
docked,
|
|
141
74
|
isModal,
|
|
142
|
-
children,
|
|
143
75
|
isTabletPortrait,
|
|
144
76
|
configuration,
|
|
145
|
-
fullscreen,
|
|
146
77
|
pip,
|
|
78
|
+
playerContent,
|
|
147
79
|
} = props;
|
|
148
80
|
|
|
149
81
|
const isTablet = useIsTablet();
|
|
150
82
|
|
|
151
83
|
const isInlineModal = inline && isModal;
|
|
152
84
|
|
|
153
|
-
// Mounting the PlayerDetails component is a resource-intensive process.
|
|
154
|
-
// Therefore, for performance reasons, we mount it with a delay to make the rotation process as smooth as possible.
|
|
155
|
-
// The flow is as follows: the rotation occurs first, and then, after a short delay, we mount the PlayerDetails component.
|
|
156
|
-
// This helps to avoid blocking the rotation and any animations related to the rotation.
|
|
157
|
-
const isShowPlayerDetails = useDelayedPlayerDetails({
|
|
158
|
-
isInline: isInlineModal,
|
|
159
|
-
isDocked: docked,
|
|
160
|
-
isPip: pip,
|
|
161
|
-
});
|
|
162
|
-
|
|
163
85
|
const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
|
|
164
86
|
|
|
165
|
-
const tabletWidth = getTabletWidth(
|
|
87
|
+
const tabletWidth = getTabletWidth(
|
|
88
|
+
configuration.tablet_landscape_sidebar_width,
|
|
89
|
+
style
|
|
90
|
+
);
|
|
166
91
|
|
|
167
92
|
const baseDimensions: DimensionsT = React.useMemo(
|
|
168
93
|
() => ({
|
|
169
|
-
width:
|
|
170
|
-
isInlineModal && !docked && isTabletLandscape ? tabletWidth : "100%",
|
|
94
|
+
width: isInlineModal && isTabletLandscape ? tabletWidth : "100%",
|
|
171
95
|
height: undefined,
|
|
172
96
|
}),
|
|
173
97
|
[isInlineModal, tabletWidth, docked]
|
|
@@ -176,7 +100,7 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
176
100
|
const playerDimensions: DimensionsT = React.useMemo(
|
|
177
101
|
() => ({
|
|
178
102
|
...baseDimensions,
|
|
179
|
-
width:
|
|
103
|
+
width: baseDimensions.width,
|
|
180
104
|
aspectRatio: !isInlineModal && !pip ? getScreenAspectRatio() : 16 / 9,
|
|
181
105
|
}),
|
|
182
106
|
[baseDimensions, isInlineModal, pip]
|
|
@@ -185,8 +109,7 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
185
109
|
const containerDimensions: DimensionsT = React.useMemo(
|
|
186
110
|
() => ({
|
|
187
111
|
...baseDimensions,
|
|
188
|
-
aspectRatio:
|
|
189
|
-
isInlineModal && docked ? undefined : playerDimensions.aspectRatio,
|
|
112
|
+
aspectRatio: playerDimensions.aspectRatio,
|
|
190
113
|
}),
|
|
191
114
|
[baseDimensions, isInlineModal, docked, playerDimensions.aspectRatio]
|
|
192
115
|
);
|
|
@@ -194,68 +117,29 @@ const PlayerWrapperComponent = (props: Props) => {
|
|
|
194
117
|
const WrapperView = React.useMemo(() => (isTV() ? View : SafeAreaView), []);
|
|
195
118
|
|
|
196
119
|
const childrenStyles = React.useMemo(
|
|
197
|
-
() => ({
|
|
120
|
+
() => ({
|
|
121
|
+
...playerDimensions,
|
|
122
|
+
...playerDimensionsHack,
|
|
123
|
+
}),
|
|
198
124
|
[containerDimensions, playerDimensionsHack]
|
|
199
125
|
);
|
|
200
126
|
|
|
201
|
-
const wrapperViewStyle: ViewStyle = {
|
|
202
|
-
backgroundColor:
|
|
203
|
-
isTablet && !fullscreen
|
|
204
|
-
? configuration?.tablet_landscape_player_container_background_color
|
|
205
|
-
: "transparent",
|
|
206
|
-
};
|
|
207
|
-
|
|
208
127
|
return (
|
|
209
128
|
<WrapperView
|
|
210
129
|
edges={getEdges(isTablet, isInlineModal) as readonly Edge[]}
|
|
211
|
-
style={
|
|
130
|
+
style={playerDimensionsHack}
|
|
212
131
|
>
|
|
213
|
-
<
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
132
|
+
<View
|
|
133
|
+
testID={`${entry?.id}-player-container`}
|
|
134
|
+
style={[
|
|
135
|
+
defaultStyles.playerContainer,
|
|
136
|
+
playerDimensionsHack,
|
|
137
|
+
containerDimensions,
|
|
138
|
+
containerStyle,
|
|
139
|
+
]}
|
|
217
140
|
>
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
style={[
|
|
221
|
-
defaultStyles.playerContainer,
|
|
222
|
-
containerDimensions,
|
|
223
|
-
containerStyle,
|
|
224
|
-
playerDimensionsHack,
|
|
225
|
-
]}
|
|
226
|
-
>
|
|
227
|
-
<AnimationComponent
|
|
228
|
-
animationType={ComponentAnimationType.moveUpComponent}
|
|
229
|
-
style={isTabletLandscape ? defaultStyles.flex : undefined}
|
|
230
|
-
additionalData={{
|
|
231
|
-
useLayoutMeasure: isTabletLandscape,
|
|
232
|
-
disableAnimatedComponent: !isTabletLandscape,
|
|
233
|
-
resetAnimationValue: isTabletLandscape && docked,
|
|
234
|
-
}}
|
|
235
|
-
>
|
|
236
|
-
<AnimatedVideoPlayerComponent>
|
|
237
|
-
{children(childrenStyles)}
|
|
238
|
-
</AnimatedVideoPlayerComponent>
|
|
239
|
-
</AnimationComponent>
|
|
240
|
-
</View>
|
|
241
|
-
|
|
242
|
-
<AnimatedScrollModal>
|
|
243
|
-
{isShowPlayerDetails ? (
|
|
244
|
-
<AnimationComponent
|
|
245
|
-
animationType={ComponentAnimationType.componentFade}
|
|
246
|
-
style={defaultStyles.flex}
|
|
247
|
-
>
|
|
248
|
-
<PlayerDetails
|
|
249
|
-
configuration={configuration}
|
|
250
|
-
style={defaultStyles.playerDetails}
|
|
251
|
-
entry={entry}
|
|
252
|
-
isTabletLandscape={isTabletLandscape}
|
|
253
|
-
isTablet={isTablet}
|
|
254
|
-
/>
|
|
255
|
-
</AnimationComponent>
|
|
256
|
-
) : null}
|
|
257
|
-
</AnimatedScrollModal>
|
|
258
|
-
</AnimationComponent>
|
|
141
|
+
{playerContent(childrenStyles)}
|
|
142
|
+
</View>
|
|
259
143
|
</WrapperView>
|
|
260
144
|
);
|
|
261
145
|
};
|
|
@@ -17,11 +17,7 @@ import {
|
|
|
17
17
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
|
|
18
18
|
|
|
19
19
|
import { withModalNavigationContextProvider } from "../../Contexts/ModalNavigationContext";
|
|
20
|
-
import {
|
|
21
|
-
useModalSize,
|
|
22
|
-
useBackgroundColor,
|
|
23
|
-
useInitialPlayerState,
|
|
24
|
-
} from "./hooks";
|
|
20
|
+
import { useModalSize, useInitialPlayerState } from "./hooks";
|
|
25
21
|
|
|
26
22
|
import { APP_EVENTS } from "@applicaster/zapp-react-native-utils/appUtils/events";
|
|
27
23
|
import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
|
|
@@ -33,8 +29,6 @@ import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
|
33
29
|
import { Spinner } from "../Spinner";
|
|
34
30
|
import { OpaqueLayer } from "./OpaqueLayer";
|
|
35
31
|
|
|
36
|
-
import { AnimatedPlayerModalWrapper } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
37
|
-
|
|
38
32
|
const LOADER_BACKGROUND_COLOR = "rgba(64,64,64,0.5)";
|
|
39
33
|
|
|
40
34
|
const styles = StyleSheet.create({
|
|
@@ -65,7 +59,6 @@ const VideoModalComponent = () => {
|
|
|
65
59
|
|
|
66
60
|
const modalSize = useModalSize();
|
|
67
61
|
const isFirstRender = useIsInitialRender();
|
|
68
|
-
const backgroundColor = useBackgroundColor();
|
|
69
62
|
|
|
70
63
|
const {
|
|
71
64
|
closeVideoModal,
|
|
@@ -145,20 +138,13 @@ const VideoModalComponent = () => {
|
|
|
145
138
|
{mode === "FULLSCREEN" && <OpaqueLayer />}
|
|
146
139
|
|
|
147
140
|
{itemIdHooksFinished === item?.id ? (
|
|
148
|
-
<
|
|
149
|
-
style={[
|
|
150
|
-
styles.container,
|
|
151
|
-
{
|
|
152
|
-
backgroundColor,
|
|
153
|
-
},
|
|
154
|
-
]}
|
|
155
|
-
>
|
|
141
|
+
<View pointerEvents="box-none" style={styles.container}>
|
|
156
142
|
<HandlePlayable
|
|
157
143
|
item={item}
|
|
158
144
|
isModal={mode !== "PIP"}
|
|
159
145
|
mode={mode}
|
|
160
146
|
/>
|
|
161
|
-
</
|
|
147
|
+
</View>
|
|
162
148
|
) : (
|
|
163
149
|
<View style={styles.loaderContainer}>
|
|
164
150
|
<Spinner />
|
|
@@ -13,6 +13,7 @@ const props = {
|
|
|
13
13
|
tablet_landscape_sidebar_width: "35%",
|
|
14
14
|
tablet_landscape_player_container_background_color: "red",
|
|
15
15
|
},
|
|
16
|
+
playerContent: jest.fn(() => <></>),
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
const mockUseIsDeviceTablet = jest.fn();
|
|
@@ -122,13 +123,6 @@ describe("PlayerWrapper", () => {
|
|
|
122
123
|
</PlayerWrapper>
|
|
123
124
|
);
|
|
124
125
|
|
|
125
|
-
const expectDimensions = {
|
|
126
|
-
...dimensions,
|
|
127
|
-
width: undefined,
|
|
128
|
-
aspectRatio: 16 / 9,
|
|
129
|
-
};
|
|
130
|
-
|
|
131
126
|
expect(element).toMatchSnapshot();
|
|
132
|
-
expect(children).toHaveBeenCalledWith(expectDimensions);
|
|
133
127
|
});
|
|
134
128
|
});
|
|
@@ -21,57 +21,27 @@ exports[`PlayerWrapper renders inline 1`] = `
|
|
|
21
21
|
"top": "additive",
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
style={
|
|
25
|
-
[
|
|
26
|
-
{
|
|
27
|
-
"backgroundColor": "transparent",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"height": 800,
|
|
31
|
-
"width": 300,
|
|
32
|
-
},
|
|
33
|
-
{},
|
|
34
|
-
]
|
|
35
|
-
}
|
|
24
|
+
style={{}}
|
|
36
25
|
>
|
|
37
26
|
<View
|
|
38
|
-
additionalData={
|
|
39
|
-
{
|
|
40
|
-
"saveArea": true,
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
animationType="moveUpComponent"
|
|
44
27
|
style={
|
|
45
28
|
[
|
|
46
29
|
{
|
|
47
|
-
"
|
|
30
|
+
"alignSelf": "center",
|
|
31
|
+
"position": "relative",
|
|
32
|
+
"zIndex": 200,
|
|
48
33
|
},
|
|
34
|
+
{},
|
|
49
35
|
{
|
|
50
|
-
"
|
|
36
|
+
"aspectRatio": 1.7777777777777777,
|
|
37
|
+
"height": undefined,
|
|
38
|
+
"width": "100%",
|
|
51
39
|
},
|
|
40
|
+
{},
|
|
52
41
|
]
|
|
53
42
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
style={
|
|
57
|
-
[
|
|
58
|
-
{
|
|
59
|
-
"alignSelf": "center",
|
|
60
|
-
"position": "relative",
|
|
61
|
-
"zIndex": 200,
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"aspectRatio": 1.7777777777777777,
|
|
65
|
-
"height": undefined,
|
|
66
|
-
"width": "100%",
|
|
67
|
-
},
|
|
68
|
-
{},
|
|
69
|
-
{},
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
testID="test-player-container"
|
|
73
|
-
/>
|
|
74
|
-
</View>
|
|
43
|
+
testID="test-player-container"
|
|
44
|
+
/>
|
|
75
45
|
</RNCSafeAreaView>
|
|
76
46
|
</RNCSafeAreaProvider>
|
|
77
47
|
`;
|
|
@@ -97,57 +67,27 @@ exports[`PlayerWrapper renders inline and docked 1`] = `
|
|
|
97
67
|
"top": "additive",
|
|
98
68
|
}
|
|
99
69
|
}
|
|
100
|
-
style={
|
|
101
|
-
[
|
|
102
|
-
{
|
|
103
|
-
"backgroundColor": "transparent",
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
"height": undefined,
|
|
107
|
-
"width": 300,
|
|
108
|
-
},
|
|
109
|
-
{},
|
|
110
|
-
]
|
|
111
|
-
}
|
|
70
|
+
style={{}}
|
|
112
71
|
>
|
|
113
72
|
<View
|
|
114
|
-
additionalData={
|
|
115
|
-
{
|
|
116
|
-
"saveArea": true,
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
animationType="moveUpComponent"
|
|
120
73
|
style={
|
|
121
74
|
[
|
|
122
75
|
{
|
|
123
|
-
"
|
|
76
|
+
"alignSelf": "center",
|
|
77
|
+
"position": "relative",
|
|
78
|
+
"zIndex": 200,
|
|
124
79
|
},
|
|
80
|
+
{},
|
|
125
81
|
{
|
|
126
|
-
"
|
|
82
|
+
"aspectRatio": 1.7777777777777777,
|
|
83
|
+
"height": undefined,
|
|
84
|
+
"width": "100%",
|
|
127
85
|
},
|
|
86
|
+
{},
|
|
128
87
|
]
|
|
129
88
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
style={
|
|
133
|
-
[
|
|
134
|
-
{
|
|
135
|
-
"alignSelf": "center",
|
|
136
|
-
"position": "relative",
|
|
137
|
-
"zIndex": 200,
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
"aspectRatio": undefined,
|
|
141
|
-
"height": undefined,
|
|
142
|
-
"width": "100%",
|
|
143
|
-
},
|
|
144
|
-
{},
|
|
145
|
-
{},
|
|
146
|
-
]
|
|
147
|
-
}
|
|
148
|
-
testID="test-player-container"
|
|
149
|
-
/>
|
|
150
|
-
</View>
|
|
89
|
+
testID="test-player-container"
|
|
90
|
+
/>
|
|
151
91
|
</RNCSafeAreaView>
|
|
152
92
|
</RNCSafeAreaProvider>
|
|
153
93
|
`;
|
|
@@ -173,73 +113,27 @@ exports[`PlayerWrapper renders inline on tablet in landscape orientation 1`] = `
|
|
|
173
113
|
"top": "additive",
|
|
174
114
|
}
|
|
175
115
|
}
|
|
176
|
-
style={
|
|
177
|
-
[
|
|
178
|
-
{
|
|
179
|
-
"backgroundColor": "red",
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
"height": 800,
|
|
183
|
-
"width": 300,
|
|
184
|
-
},
|
|
185
|
-
{},
|
|
186
|
-
]
|
|
187
|
-
}
|
|
116
|
+
style={{}}
|
|
188
117
|
>
|
|
189
118
|
<View
|
|
190
|
-
additionalData={
|
|
191
|
-
{
|
|
192
|
-
"saveArea": true,
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
animationType="moveUpComponent"
|
|
196
119
|
style={
|
|
197
120
|
[
|
|
198
121
|
{
|
|
199
|
-
"
|
|
122
|
+
"alignSelf": "center",
|
|
123
|
+
"position": "relative",
|
|
124
|
+
"zIndex": 200,
|
|
200
125
|
},
|
|
126
|
+
{},
|
|
201
127
|
{
|
|
202
|
-
"
|
|
128
|
+
"aspectRatio": 1.7777777777777777,
|
|
129
|
+
"height": undefined,
|
|
130
|
+
"width": 195,
|
|
203
131
|
},
|
|
132
|
+
{},
|
|
204
133
|
]
|
|
205
134
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
style={
|
|
209
|
-
[
|
|
210
|
-
{
|
|
211
|
-
"alignSelf": "center",
|
|
212
|
-
"position": "relative",
|
|
213
|
-
"zIndex": 200,
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
"aspectRatio": 1.7777777777777777,
|
|
217
|
-
"height": undefined,
|
|
218
|
-
"width": 195,
|
|
219
|
-
},
|
|
220
|
-
{},
|
|
221
|
-
{},
|
|
222
|
-
]
|
|
223
|
-
}
|
|
224
|
-
testID="test-player-container"
|
|
225
|
-
>
|
|
226
|
-
<View
|
|
227
|
-
additionalData={
|
|
228
|
-
{
|
|
229
|
-
"disableAnimatedComponent": false,
|
|
230
|
-
"resetAnimationValue": undefined,
|
|
231
|
-
"useLayoutMeasure": true,
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
animationType="moveUpComponent"
|
|
235
|
-
style={
|
|
236
|
-
{
|
|
237
|
-
"flex": 1,
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
/>
|
|
241
|
-
</View>
|
|
242
|
-
</View>
|
|
135
|
+
testID="test-player-container"
|
|
136
|
+
/>
|
|
243
137
|
</RNCSafeAreaView>
|
|
244
138
|
</RNCSafeAreaProvider>
|
|
245
139
|
`;
|
|
@@ -265,57 +159,27 @@ exports[`PlayerWrapper renders properly 1`] = `
|
|
|
265
159
|
"top": "additive",
|
|
266
160
|
}
|
|
267
161
|
}
|
|
268
|
-
style={
|
|
269
|
-
[
|
|
270
|
-
{
|
|
271
|
-
"backgroundColor": "transparent",
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
"height": 800,
|
|
275
|
-
"width": 300,
|
|
276
|
-
},
|
|
277
|
-
{},
|
|
278
|
-
]
|
|
279
|
-
}
|
|
162
|
+
style={{}}
|
|
280
163
|
>
|
|
281
164
|
<View
|
|
282
|
-
additionalData={
|
|
283
|
-
{
|
|
284
|
-
"saveArea": true,
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
animationType="moveUpComponent"
|
|
288
165
|
style={
|
|
289
166
|
[
|
|
290
167
|
{
|
|
291
|
-
"
|
|
168
|
+
"alignSelf": "center",
|
|
169
|
+
"position": "relative",
|
|
170
|
+
"zIndex": 200,
|
|
292
171
|
},
|
|
172
|
+
{},
|
|
293
173
|
{
|
|
294
|
-
"
|
|
174
|
+
"aspectRatio": 1.7786666666666666,
|
|
175
|
+
"height": undefined,
|
|
176
|
+
"width": "100%",
|
|
295
177
|
},
|
|
178
|
+
{},
|
|
296
179
|
]
|
|
297
180
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
style={
|
|
301
|
-
[
|
|
302
|
-
{
|
|
303
|
-
"alignSelf": "center",
|
|
304
|
-
"position": "relative",
|
|
305
|
-
"zIndex": 200,
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
"aspectRatio": 1.7786666666666666,
|
|
309
|
-
"height": undefined,
|
|
310
|
-
"width": "100%",
|
|
311
|
-
},
|
|
312
|
-
{},
|
|
313
|
-
{},
|
|
314
|
-
]
|
|
315
|
-
}
|
|
316
|
-
testID="test-player-container"
|
|
317
|
-
/>
|
|
318
|
-
</View>
|
|
181
|
+
testID="test-player-container"
|
|
182
|
+
/>
|
|
319
183
|
</RNCSafeAreaView>
|
|
320
184
|
</RNCSafeAreaProvider>
|
|
321
185
|
`;
|
|
@@ -34,6 +34,9 @@ export const useConfiguration = () => {
|
|
|
34
34
|
minimised_height = 0,
|
|
35
35
|
minimised_height_tablet = 0,
|
|
36
36
|
modal_background_color,
|
|
37
|
+
tablet_landscape_player_container_background_color,
|
|
38
|
+
screen_background_color,
|
|
39
|
+
audio_player_background_color,
|
|
37
40
|
} = config;
|
|
38
41
|
|
|
39
42
|
const minimisedHeight = useIsTablet()
|
|
@@ -43,6 +46,9 @@ export const useConfiguration = () => {
|
|
|
43
46
|
return {
|
|
44
47
|
minimised_height: Number(minimisedHeight),
|
|
45
48
|
modal_background_color,
|
|
49
|
+
tablet_landscape_player_container_background_color,
|
|
50
|
+
audio_player_background_color,
|
|
51
|
+
screen_background_color,
|
|
46
52
|
};
|
|
47
53
|
};
|
|
48
54
|
|
|
@@ -4,8 +4,8 @@ which helps in detecting whether a given component is visible within the viewpor
|
|
|
4
4
|
It is useful for implementing lazy loading or triggering specific actions when a component comes into view.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, {
|
|
8
|
-
import {
|
|
7
|
+
import React, { useEffect, useState, useRef, ReactNode, FC } from "react";
|
|
8
|
+
import { View, Dimensions } from "react-native";
|
|
9
9
|
import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
|
|
10
10
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
11
11
|
|
|
@@ -78,7 +78,7 @@ const VisibilitySensorComponent: FC<Props> = ({
|
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
const stopWatching = () => {
|
|
81
|
-
clearInterval(interval);
|
|
81
|
+
interval = clearInterval(interval);
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
const isInViewPort = () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "14.0.0-alpha.
|
|
3
|
+
"version": "14.0.0-alpha.5621117258",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"redux-mock-store": "^1.5.3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@applicaster/applicaster-types": "14.0.0-alpha.
|
|
35
|
-
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.
|
|
36
|
-
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.
|
|
37
|
-
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.
|
|
34
|
+
"@applicaster/applicaster-types": "14.0.0-alpha.5621117258",
|
|
35
|
+
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.5621117258",
|
|
36
|
+
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.5621117258",
|
|
37
|
+
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.5621117258",
|
|
38
38
|
"promise": "^8.3.0",
|
|
39
39
|
"url": "^0.11.0",
|
|
40
40
|
"uuid": "^3.3.2"
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
2
|
-
import { useConfiguration } from "../utils";
|
|
3
|
-
|
|
4
|
-
export const useBackgroundColor = (): string => {
|
|
5
|
-
const { modal_background_color: modalBackgroundColor } = useConfiguration();
|
|
6
|
-
|
|
7
|
-
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
8
|
-
|
|
9
|
-
return modalBackgroundColor || theme?.status_background_color;
|
|
10
|
-
};
|