@applicaster/zapp-react-native-ui-components 14.0.0-alpha.7900711229 → 14.0.0-alpha.9567513212
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/{tv/index.tsx → AudioPlayer.tsx} +59 -12
- package/Components/AudioPlayer/{tv/Layout.tsx → AudioPlayerLayout.tsx} +72 -31
- package/Components/AudioPlayer/{mobile/__tests__/__snapshots__/audioPlayerMobileLayout.test.js.snap → __tests__/__snapshots__/audioPlayer.test.js.snap} +8 -2
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +72 -0
- package/Components/AudioPlayer/{tv/__tests__ → __tests__}/audioPlayer.test.js +3 -7
- package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +26 -0
- package/Components/AudioPlayer/{tv/helpers.tsx → helpers.tsx} +2 -1
- package/Components/AudioPlayer/index.ts +1 -0
- package/Components/MasterCell/utils/behaviorProvider.ts +14 -82
- package/Components/MasterCell/utils/index.ts +3 -23
- package/Components/PlayerContainer/PlayerContainer.tsx +19 -7
- package/Components/PlayerImageBackground/index.tsx +1 -1
- package/Components/Transitioner/Scene.tsx +0 -1
- 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 -240
- package/Components/VideoModal/hooks/index.ts +0 -2
- package/Components/VideoModal/utils.ts +6 -0
- package/Contexts/ScreenDataContext/index.tsx +0 -2
- package/Decorators/RiverFeedLoader/index.tsx +2 -8
- package/Decorators/RiverFeedLoader/utils/index.ts +2 -7
- package/Decorators/ZappPipesDataConnector/index.tsx +2 -20
- package/package.json +5 -5
- package/Components/AudioPlayer/index.tsx +0 -15
- package/Components/AudioPlayer/mobile/Layout.tsx +0 -66
- package/Components/AudioPlayer/mobile/__tests__/audioPlayerMobileLayout.test.js +0 -18
- package/Components/AudioPlayer/mobile/index.tsx +0 -18
- package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +0 -170
- package/Components/AudioPlayer/types.ts +0 -40
- package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
- /package/Components/AudioPlayer/{tv/Artwork.tsx → Artwork.tsx} +0 -0
- /package/Components/AudioPlayer/{tv/Channel.tsx → Channel.tsx} +0 -0
- /package/Components/AudioPlayer/{tv/Runtime.tsx → Runtime.tsx} +0 -0
- /package/Components/AudioPlayer/{tv/Summary.tsx → Summary.tsx} +0 -0
- /package/Components/AudioPlayer/{tv/Title.tsx → Title.tsx} +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/Runtime.test.js +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/__snapshots__/Runtime.test.js.snap +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/__snapshots__/artWork.test.js.snap +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/__snapshots__/channel.test.js.snap +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/__snapshots__/summary.test.js.snap +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/__snapshots__/title.test.js.snap +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/artWork.test.js +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/channel.test.js +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/summary.test.js +0 -0
- /package/Components/AudioPlayer/{tv/__tests__ → __tests__}/title.test.js +0 -0
|
@@ -1,24 +1,60 @@
|
|
|
1
1
|
import React, { useCallback, useMemo } from "react";
|
|
2
2
|
|
|
3
3
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
4
|
-
import { useArtworkImage } from "@applicaster/zapp-react-native-utils/audioPlayerUtils";
|
|
5
4
|
|
|
6
|
-
import {
|
|
5
|
+
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
7
6
|
|
|
7
|
+
import { AudioPlayerLayout } from "./AudioPlayerLayout";
|
|
8
8
|
import { Channel } from "./Channel";
|
|
9
9
|
import { Title } from "./Title";
|
|
10
10
|
import { Summary } from "./Summary";
|
|
11
11
|
import { Runtime } from "./Runtime";
|
|
12
12
|
import { getPropertyFromEntryOrConfig } from "./helpers";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
import { ViewStyle } from "react-native";
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
audio_item: ZappEntry & {
|
|
17
|
+
extensions?: {
|
|
18
|
+
audio_player_artwork_aspect_ratio?: string;
|
|
19
|
+
audio_player_background_image?: string;
|
|
20
|
+
audio_player_background_color?: string;
|
|
21
|
+
audio_player_channel_icon?: string;
|
|
22
|
+
audio_player_title_color?: string;
|
|
23
|
+
audio_player_summary_color?: string;
|
|
24
|
+
audio_player_rtl?: boolean;
|
|
25
|
+
audio_player_background_image_default_color?: string;
|
|
26
|
+
start_time?: string;
|
|
27
|
+
end_time?: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
plugin_configuration: {
|
|
31
|
+
audio_player_background_color?: string;
|
|
32
|
+
audio_player_title_color?: string;
|
|
33
|
+
audio_player_summary_color?: string;
|
|
34
|
+
audio_player_rtl?: string;
|
|
35
|
+
audio_player_background_image_default_color?: string;
|
|
36
|
+
audio_player_background_image?: string;
|
|
37
|
+
audio_player_artwork_aspect_ratio?: string;
|
|
38
|
+
lg_tv_audio_player_title_font_family?: string;
|
|
39
|
+
lg_tv_audio_player_title_font_size?: number;
|
|
40
|
+
lg_tv_audio_player_summary_font_family?: string;
|
|
41
|
+
lg_tv_audio_player_summary_font_size?: number;
|
|
42
|
+
samsung_tv_audio_player_title_font_family?: string;
|
|
43
|
+
samsung_tv_audio_player_title_font_size?: number;
|
|
44
|
+
samsung_tv_audio_player_summary_font_family?: string;
|
|
45
|
+
samsung_tv_audio_player_summary_font_size?: number;
|
|
46
|
+
tv_os_audio_player_title_font_family?: string;
|
|
47
|
+
tv_os_audio_player_title_font_size?: number;
|
|
48
|
+
tv_os_audio_player_summary_font_family?: string;
|
|
49
|
+
tv_os_audio_player_summary_font_size?: number;
|
|
50
|
+
};
|
|
51
|
+
style?: ViewStyle;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export function AudioPlayer(props: Props) {
|
|
55
|
+
const { audio_item, plugin_configuration } = props;
|
|
18
56
|
const { extensions, title, summary } = audio_item;
|
|
19
57
|
|
|
20
|
-
const artwork = useArtworkImage(audio_item);
|
|
21
|
-
|
|
22
58
|
const getProp = useCallback(
|
|
23
59
|
getPropertyFromEntryOrConfig({
|
|
24
60
|
entry: audio_item,
|
|
@@ -28,15 +64,20 @@ export function AudioPlayerTV(props: Props) {
|
|
|
28
64
|
);
|
|
29
65
|
|
|
30
66
|
const config = useMemo(() => {
|
|
31
|
-
// Checking if we are
|
|
67
|
+
// Checking if we are recieving items from the DSP
|
|
32
68
|
const titleColor = getProp("audio_player_title_color");
|
|
33
69
|
const summaryColor = getProp("audio_player_summary_color");
|
|
34
70
|
const backgroundColor = getProp("audio_player_background_color");
|
|
35
71
|
const backgroundImage = getProp("audio_player_background_image");
|
|
72
|
+
const artworkAspectRatio = getProp("audio_player_artwork_aspect_ratio");
|
|
36
73
|
const channelIcon = getProp("audio_player_channel_icon");
|
|
37
74
|
const rtlFlag = getProp("audio_player_rtl");
|
|
38
75
|
const artworkBorderRadius = getProp("audio_player_artwork_border_radius");
|
|
39
76
|
|
|
77
|
+
const audioPlayerBackgroundImageDefaultColor = getProp(
|
|
78
|
+
"audio_player_background_image_default_color"
|
|
79
|
+
);
|
|
80
|
+
|
|
40
81
|
const isRTL = rtlFlag === "1" || rtlFlag === "true" || rtlFlag === true;
|
|
41
82
|
|
|
42
83
|
const titleFontFamily = getProp(
|
|
@@ -111,17 +152,23 @@ export function AudioPlayerTV(props: Props) {
|
|
|
111
152
|
summaryFontSize,
|
|
112
153
|
runTimeFontFamily,
|
|
113
154
|
runTimeFontSize,
|
|
155
|
+
artworkAspectRatio,
|
|
114
156
|
channelIcon,
|
|
157
|
+
audioPlayerBackgroundImageDefaultColor,
|
|
115
158
|
artworkBorderRadius,
|
|
116
159
|
};
|
|
117
160
|
}, [getProp]);
|
|
118
161
|
|
|
162
|
+
const artwork = imageSrcFromMediaItem(audio_item, [
|
|
163
|
+
config?.artworkAspectRatio,
|
|
164
|
+
]);
|
|
165
|
+
|
|
119
166
|
return (
|
|
120
|
-
<
|
|
167
|
+
<AudioPlayerLayout artwork={artwork} config={config}>
|
|
121
168
|
<Channel srcImage={config?.channelIcon} config={config} />
|
|
122
169
|
<Title title={title} config={config} />
|
|
123
170
|
<Summary summary={summary} config={config} />
|
|
124
171
|
<Runtime {...extensions} config={config} />
|
|
125
|
-
</
|
|
172
|
+
</AudioPlayerLayout>
|
|
126
173
|
);
|
|
127
174
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { View, ImageBackground,
|
|
1
|
+
import React, { useRef } from "react";
|
|
2
|
+
import { View, ImageBackground, Animated } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
5
|
|
|
@@ -7,30 +7,34 @@ import { Artwork } from "./Artwork";
|
|
|
7
7
|
import { directionStyles } from "./helpers";
|
|
8
8
|
|
|
9
9
|
type Props = {
|
|
10
|
-
artwork
|
|
10
|
+
artwork?: string;
|
|
11
11
|
config: {
|
|
12
12
|
titleColor: string;
|
|
13
13
|
summaryColor: string;
|
|
14
14
|
backgroundColor: string;
|
|
15
|
-
backgroundImage:
|
|
15
|
+
backgroundImage: string;
|
|
16
16
|
isRTL: boolean;
|
|
17
17
|
artworkBorderRadius: Option<number>;
|
|
18
18
|
};
|
|
19
19
|
children: React.ReactNode;
|
|
20
|
-
style: ViewStyle;
|
|
21
20
|
};
|
|
22
21
|
|
|
23
|
-
export function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
export function AudioPlayerLayout({ artwork, config, children }: Props) {
|
|
23
|
+
const fadeAnimation = useRef(new Animated.Value(0)).current;
|
|
24
|
+
|
|
25
|
+
const fadeAudioPlayerIn = () => {
|
|
26
|
+
Animated.timing(fadeAnimation, {
|
|
27
|
+
toValue: 1,
|
|
28
|
+
duration: 3000,
|
|
29
|
+
useNativeDriver: true,
|
|
30
|
+
}).start();
|
|
31
|
+
};
|
|
32
|
+
|
|
29
33
|
const { isRTL, backgroundColor, backgroundImage } = config;
|
|
30
34
|
|
|
31
|
-
const backgroundImageSource = { uri: backgroundImage };
|
|
35
|
+
const backgroundImageSource = { uri: backgroundImage || artwork };
|
|
32
36
|
|
|
33
|
-
const backgroundColorStyle =
|
|
37
|
+
const backgroundColorStyle = backgroundImageSource.uri
|
|
34
38
|
? "transparent"
|
|
35
39
|
: backgroundColor;
|
|
36
40
|
|
|
@@ -62,7 +66,8 @@ export function AudioPlayerTVLayout({
|
|
|
62
66
|
native: {
|
|
63
67
|
backgroundColor: backgroundColorStyle,
|
|
64
68
|
overflow: "hidden",
|
|
65
|
-
|
|
69
|
+
width: "100%",
|
|
70
|
+
height: "100%",
|
|
66
71
|
},
|
|
67
72
|
samsung_tv: {
|
|
68
73
|
position: "absolute",
|
|
@@ -114,6 +119,9 @@ export function AudioPlayerTVLayout({
|
|
|
114
119
|
alignItems: "center",
|
|
115
120
|
justifyContent: "center",
|
|
116
121
|
},
|
|
122
|
+
native: {
|
|
123
|
+
flex: 1,
|
|
124
|
+
},
|
|
117
125
|
});
|
|
118
126
|
|
|
119
127
|
const textContainerStyles = platformSelect({
|
|
@@ -137,25 +145,58 @@ export function AudioPlayerTVLayout({
|
|
|
137
145
|
},
|
|
138
146
|
});
|
|
139
147
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
>
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return (
|
|
148
|
+
const audioPlayerLayoutTV = backgroundImageSource?.uri ? (
|
|
149
|
+
<ImageBackground
|
|
150
|
+
source={backgroundImageSource}
|
|
151
|
+
style={backgroundImgStyles}
|
|
152
|
+
resizeMode="cover"
|
|
153
|
+
>
|
|
154
|
+
<View style={mainContainerStyles}>
|
|
155
|
+
{!!artwork && <Artwork srcImage={artwork} config={config} />}
|
|
156
|
+
<View style={textContainerStyles}>{children}</View>
|
|
157
|
+
</View>
|
|
158
|
+
</ImageBackground>
|
|
159
|
+
) : (
|
|
156
160
|
<View style={mainContainerStyles}>
|
|
157
|
-
<Artwork srcImage={artwork} config={config} />
|
|
161
|
+
{!!artwork && <Artwork srcImage={artwork} config={config} />}
|
|
158
162
|
<View style={textContainerStyles}>{children}</View>
|
|
159
163
|
</View>
|
|
160
164
|
);
|
|
165
|
+
|
|
166
|
+
const audioPlayerLayoutMobile = () => {
|
|
167
|
+
fadeAudioPlayerIn();
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<View style={mainContainerStyles} pointerEvents="none">
|
|
171
|
+
<Animated.View
|
|
172
|
+
style={[
|
|
173
|
+
mainContainerStyles,
|
|
174
|
+
{
|
|
175
|
+
opacity: fadeAnimation,
|
|
176
|
+
},
|
|
177
|
+
]}
|
|
178
|
+
>
|
|
179
|
+
<ImageBackground
|
|
180
|
+
source={backgroundImageSource}
|
|
181
|
+
style={backgroundImgStyles}
|
|
182
|
+
resizeMode="cover"
|
|
183
|
+
>
|
|
184
|
+
<View style={mainContainerStyles} />
|
|
185
|
+
</ImageBackground>
|
|
186
|
+
</Animated.View>
|
|
187
|
+
</View>
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const audioPlayerLayout = platformSelect({
|
|
192
|
+
tvos: audioPlayerLayoutTV,
|
|
193
|
+
android_tv: audioPlayerLayoutTV,
|
|
194
|
+
web: audioPlayerLayoutTV,
|
|
195
|
+
samsung_tv: audioPlayerLayoutTV,
|
|
196
|
+
lg_tv: audioPlayerLayoutTV,
|
|
197
|
+
ios: audioPlayerLayoutMobile(),
|
|
198
|
+
android: audioPlayerLayoutMobile(),
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
return audioPlayerLayout;
|
|
161
202
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`<
|
|
3
|
+
exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
4
4
|
<View
|
|
5
5
|
pointerEvents="none"
|
|
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[`<AudioPlayerMobileLayout /> 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
|
>
|
|
@@ -32,7 +36,7 @@ exports[`<AudioPlayerMobileLayout /> renders correctly 1`] = `
|
|
|
32
36
|
resizeMode="cover"
|
|
33
37
|
source={
|
|
34
38
|
{
|
|
35
|
-
"uri": "
|
|
39
|
+
"uri": "https://example.com",
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
style={
|
|
@@ -56,7 +60,9 @@ exports[`<AudioPlayerMobileLayout /> 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
|
/>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<AudioPlayerLayout /> renders correctly 1`] = `
|
|
4
|
+
<View
|
|
5
|
+
pointerEvents="none"
|
|
6
|
+
style={
|
|
7
|
+
{
|
|
8
|
+
"backgroundColor": "transparent",
|
|
9
|
+
"height": "100%",
|
|
10
|
+
"overflow": "hidden",
|
|
11
|
+
"width": "100%",
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
>
|
|
15
|
+
<View
|
|
16
|
+
collapsable={false}
|
|
17
|
+
style={
|
|
18
|
+
{
|
|
19
|
+
"backgroundColor": "transparent",
|
|
20
|
+
"height": "100%",
|
|
21
|
+
"opacity": 0,
|
|
22
|
+
"overflow": "hidden",
|
|
23
|
+
"width": "100%",
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
>
|
|
27
|
+
<View
|
|
28
|
+
accessibilityIgnoresInvertColors={true}
|
|
29
|
+
style={
|
|
30
|
+
{
|
|
31
|
+
"flex": 1,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
>
|
|
35
|
+
<Image
|
|
36
|
+
resizeMode="cover"
|
|
37
|
+
source={
|
|
38
|
+
{
|
|
39
|
+
"uri": "https://example.com",
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
style={
|
|
43
|
+
[
|
|
44
|
+
{
|
|
45
|
+
"bottom": 0,
|
|
46
|
+
"left": 0,
|
|
47
|
+
"position": "absolute",
|
|
48
|
+
"right": 0,
|
|
49
|
+
"top": 0,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"height": undefined,
|
|
53
|
+
"width": undefined,
|
|
54
|
+
},
|
|
55
|
+
undefined,
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
/>
|
|
59
|
+
<View
|
|
60
|
+
style={
|
|
61
|
+
{
|
|
62
|
+
"backgroundColor": "transparent",
|
|
63
|
+
"height": "100%",
|
|
64
|
+
"overflow": "hidden",
|
|
65
|
+
"width": "100%",
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/>
|
|
69
|
+
</View>
|
|
70
|
+
</View>
|
|
71
|
+
</View>
|
|
72
|
+
`;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { render } from "@testing-library/react-native";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
jest.mock("@applicaster/zapp-react-native-utils/audioPlayerUtils", () => ({
|
|
7
|
-
useArtworkImage: jest.fn(() => "artwork_url"),
|
|
8
|
-
}));
|
|
4
|
+
import { AudioPlayer } from "../AudioPlayer";
|
|
9
5
|
|
|
10
6
|
const audioPlayerProps = {
|
|
11
7
|
audio_item: {
|
|
@@ -49,9 +45,9 @@ const audioPlayerProps = {
|
|
|
49
45
|
styles: {},
|
|
50
46
|
};
|
|
51
47
|
|
|
52
|
-
describe("<
|
|
48
|
+
describe("<AudioPlayer />", () => {
|
|
53
49
|
it("renders correctly", () => {
|
|
54
|
-
const { toJSON } = render(<
|
|
50
|
+
const { toJSON } = render(<AudioPlayer {...audioPlayerProps} />);
|
|
55
51
|
expect(toJSON()).toMatchSnapshot();
|
|
56
52
|
});
|
|
57
53
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@testing-library/react-native";
|
|
3
|
+
|
|
4
|
+
import { AudioPlayerLayout } from "../AudioPlayerLayout";
|
|
5
|
+
|
|
6
|
+
const audioPlayerLayoutProps = {
|
|
7
|
+
artwork: "string",
|
|
8
|
+
config: {
|
|
9
|
+
titleColor: "white",
|
|
10
|
+
summaryColor: "white",
|
|
11
|
+
backgroundColor: "black",
|
|
12
|
+
backgroundImage: "https://example.com",
|
|
13
|
+
isRTL: true,
|
|
14
|
+
},
|
|
15
|
+
children: [],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
describe("<AudioPlayerLayout />", () => {
|
|
19
|
+
it("renders correctly", () => {
|
|
20
|
+
const { toJSON } = render(
|
|
21
|
+
<AudioPlayerLayout {...audioPlayerLayoutProps} />
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
expect(toJSON()).toMatchSnapshot();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -2,8 +2,9 @@ const defaults = {
|
|
|
2
2
|
audio_player_title_color: "white",
|
|
3
3
|
audio_player_summary_color: "white",
|
|
4
4
|
audio_player_background_color: "black",
|
|
5
|
-
|
|
5
|
+
audio_player_artwork_aspect_ratio: "1:1",
|
|
6
6
|
audio_player_rtl: false,
|
|
7
|
+
audio_player_background_image_default_color: "",
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
export function getPropertyFromEntryOrConfig({ entry, plugin_configuration }) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AudioPlayer } from "./AudioPlayer";
|
|
@@ -1,58 +1,28 @@
|
|
|
1
1
|
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
2
|
-
import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-
|
|
2
|
+
import { StorageSingleValueProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageSingleSelectProvider";
|
|
3
3
|
import { PushTopicManager } from "@applicaster/zapp-react-native-bridge/PushNotifications/PushTopicManager";
|
|
4
|
-
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-
|
|
4
|
+
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
|
|
5
5
|
import React, { useEffect } from "react";
|
|
6
6
|
import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
|
|
7
7
|
import { BehaviorSubject } from "rxjs";
|
|
8
8
|
import { masterCellLogger } from "../logger";
|
|
9
9
|
import get from "lodash/get";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const parseContextKey = (
|
|
16
|
-
key: string,
|
|
17
|
-
context: string = "ctx"
|
|
18
|
-
): string | null => {
|
|
19
|
-
if (!key?.startsWith(`@{${context}/`)) return null;
|
|
20
|
-
|
|
21
|
-
return key.substring(`@{${context}/`.length, key.length - 1);
|
|
10
|
+
|
|
11
|
+
const parseContextKey = (key: string): string | null => {
|
|
12
|
+
if (!key?.startsWith("@{ctx/")) return null;
|
|
13
|
+
|
|
14
|
+
return key.substring("@{ctx/".length, key.length - 1);
|
|
22
15
|
};
|
|
23
16
|
|
|
24
17
|
const getDataSourceProvider = (
|
|
25
|
-
behavior: Behavior
|
|
26
|
-
screenRoute: string,
|
|
27
|
-
screenStateStore: ScreenStateStore
|
|
18
|
+
behavior: Behavior
|
|
28
19
|
): BehaviorSubject<string[] | string> | null => {
|
|
29
20
|
if (!behavior) return null;
|
|
30
21
|
|
|
31
22
|
const selection = String(behavior.current_selection);
|
|
32
|
-
const screenKey = parseContextKey(selection, "screen");
|
|
33
|
-
|
|
34
|
-
if (screenKey) {
|
|
35
|
-
if (behavior.select_mode === "multi") {
|
|
36
|
-
return ScreenMultiSelectProvider.getProvider(
|
|
37
|
-
screenKey,
|
|
38
|
-
screenRoute,
|
|
39
|
-
screenStateStore
|
|
40
|
-
).getObservable();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (behavior.select_mode === "single") {
|
|
44
|
-
return ScreenSingleValueProvider.getProvider(
|
|
45
|
-
screenKey,
|
|
46
|
-
screenRoute,
|
|
47
|
-
screenStateStore
|
|
48
|
-
).getObservable();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
23
|
const contextKey = parseContextKey(selection);
|
|
53
24
|
|
|
54
25
|
if (contextKey) {
|
|
55
|
-
// TODO: Add storage scope to behavior
|
|
56
26
|
if (behavior.select_mode === "multi") {
|
|
57
27
|
return StorageMultiSelectProvider.getProvider(contextKey).getObservable();
|
|
58
28
|
}
|
|
@@ -71,8 +41,6 @@ const getDataSourceProvider = (
|
|
|
71
41
|
|
|
72
42
|
export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
73
43
|
const [lastUpdate, setLastUpdate] = React.useState<number | null>(null);
|
|
74
|
-
const screenRoute = useRoute()?.pathname || "";
|
|
75
|
-
const screenStateStore = useScreenStateStore();
|
|
76
44
|
const player = usePlayer();
|
|
77
45
|
|
|
78
46
|
const triggerUpdate = () => setLastUpdate(Date.now());
|
|
@@ -80,11 +48,7 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
|
80
48
|
useEffect(() => {
|
|
81
49
|
if (!behavior) return;
|
|
82
50
|
|
|
83
|
-
const dataSource = getDataSourceProvider(
|
|
84
|
-
behavior,
|
|
85
|
-
screenRoute,
|
|
86
|
-
screenStateStore
|
|
87
|
-
);
|
|
51
|
+
const dataSource = getDataSourceProvider(behavior);
|
|
88
52
|
|
|
89
53
|
if (dataSource) {
|
|
90
54
|
const subscription = dataSource.subscribe(triggerUpdate);
|
|
@@ -108,17 +72,10 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
|
108
72
|
|
|
109
73
|
// We cant use async in this function (its inside render),
|
|
110
74
|
// so we rely on useBehaviorUpdate to update current value and trigger re-render
|
|
111
|
-
export const isCellSelected = (
|
|
112
|
-
item,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
behavior,
|
|
116
|
-
}: {
|
|
117
|
-
item: ZappEntry;
|
|
118
|
-
screenRoute: string;
|
|
119
|
-
screenStateStore: ScreenStateStore;
|
|
120
|
-
behavior?: Behavior;
|
|
121
|
-
}): boolean => {
|
|
75
|
+
export const isCellSelected = (
|
|
76
|
+
item: ZappEntry,
|
|
77
|
+
behavior?: Behavior
|
|
78
|
+
): boolean => {
|
|
122
79
|
if (!behavior) return false;
|
|
123
80
|
|
|
124
81
|
const id = behavior.selector ? get(item, behavior.selector) : item.id;
|
|
@@ -142,32 +99,7 @@ export const isCellSelected = ({
|
|
|
142
99
|
}
|
|
143
100
|
|
|
144
101
|
const selection = String(behavior.current_selection);
|
|
145
|
-
|
|
146
|
-
const screenKey = parseContextKey(selection, "screen");
|
|
147
|
-
|
|
148
|
-
if (screenKey) {
|
|
149
|
-
if (behavior.select_mode === "single") {
|
|
150
|
-
const selectedItem = ScreenSingleValueProvider.getProvider(
|
|
151
|
-
screenKey,
|
|
152
|
-
screenRoute,
|
|
153
|
-
screenStateStore
|
|
154
|
-
).getValue();
|
|
155
|
-
|
|
156
|
-
return selectedItem === String(id);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (behavior.select_mode === "multi") {
|
|
160
|
-
const selectedItems = ScreenMultiSelectProvider.getProvider(
|
|
161
|
-
screenKey,
|
|
162
|
-
screenRoute,
|
|
163
|
-
screenStateStore
|
|
164
|
-
).getSelectedItems();
|
|
165
|
-
|
|
166
|
-
return selectedItems?.includes(String(id));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const contextKey = parseContextKey(selection, "ctx");
|
|
102
|
+
const contextKey = parseContextKey(selection);
|
|
171
103
|
|
|
172
104
|
if (contextKey) {
|
|
173
105
|
if (behavior.select_mode === "single") {
|
|
@@ -8,8 +8,6 @@ import { masterCellLogger } from "../logger";
|
|
|
8
8
|
import { getCellState } from "../../Cell/utils";
|
|
9
9
|
import { getColorFromData } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
10
10
|
import { isCellSelected, useBehaviorUpdate } from "./behaviorProvider";
|
|
11
|
-
import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
|
-
import { useScreenStateStore } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useScreenStateStore";
|
|
13
11
|
|
|
14
12
|
const hasElementSpecificViewType = (viewType) => (element) => {
|
|
15
13
|
if (R.isNil(element)) {
|
|
@@ -192,18 +190,8 @@ export const getFocusedButtonId = (focusable) => {
|
|
|
192
190
|
});
|
|
193
191
|
};
|
|
194
192
|
|
|
195
|
-
export const isSelected = ({
|
|
196
|
-
item,
|
|
197
|
-
screenRoute,
|
|
198
|
-
screenStateStore,
|
|
199
|
-
behavior,
|
|
200
|
-
}: {
|
|
201
|
-
item: ZappEntry;
|
|
202
|
-
screenRoute: string;
|
|
203
|
-
screenStateStore: ScreenStateStore;
|
|
204
|
-
behavior?: Behavior;
|
|
205
|
-
}) => {
|
|
206
|
-
return isCellSelected({ item, screenRoute, screenStateStore, behavior });
|
|
193
|
+
export const isSelected = (item: ZappEntry, behavior?: Behavior) => {
|
|
194
|
+
return isCellSelected(item, behavior);
|
|
207
195
|
};
|
|
208
196
|
|
|
209
197
|
export const useCellState = ({
|
|
@@ -216,17 +204,9 @@ export const useCellState = ({
|
|
|
216
204
|
focused: boolean;
|
|
217
205
|
}): CellState => {
|
|
218
206
|
const lastUpdate = useBehaviorUpdate(behavior);
|
|
219
|
-
const router = useRoute();
|
|
220
|
-
const screenStateStore = useScreenStateStore();
|
|
221
207
|
|
|
222
208
|
const _isSelected = useMemo(
|
|
223
|
-
() =>
|
|
224
|
-
isSelected({
|
|
225
|
-
item,
|
|
226
|
-
screenRoute: router?.pathname,
|
|
227
|
-
screenStateStore,
|
|
228
|
-
behavior,
|
|
229
|
-
}),
|
|
209
|
+
() => isSelected(item, behavior),
|
|
230
210
|
[behavior, item, lastUpdate]
|
|
231
211
|
);
|
|
232
212
|
|