@applicaster/quick-brick-player 13.0.0-alpha.5033140607 → 13.0.0-alpha.5049772260

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.
Files changed (35) hide show
  1. package/package.json +27 -13
  2. package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
  3. package/src/Player/AudioLayer/AudioDescription.tsx +4 -6
  4. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +136 -181
  5. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +27 -0
  6. package/src/Player/AudioLayer/Layout/Controls/index.tsx +305 -0
  7. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +5 -15
  8. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +44 -67
  9. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +212 -0
  10. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +83 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +32 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +95 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +17 -0
  14. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +214 -0
  15. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +224 -0
  16. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +102 -0
  17. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  18. package/src/Player/AudioLayer/Layout/const.ts +20 -0
  19. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  20. package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -0
  21. package/src/Player/AudioLayer/Layout/hooks/useImageSize.ts +100 -0
  22. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  23. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  24. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  25. package/src/Player/AudioLayer/MagicBG/index.tsx +1 -1
  26. package/src/Player/AudioLayer/SleepTimerManager.ts +119 -0
  27. package/src/Player/AudioLayer/SpeedManager.ts +52 -0
  28. package/src/Player/AudioLayer/utils.ts +27 -0
  29. package/src/Player/Const/sleepTimerOptions.ts +39 -0
  30. package/src/Player/Const/speedOptions.ts +4 -0
  31. package/src/Player/Utils/Utils.ts +0 -5
  32. package/src/Player/Utils/index.tsx +117 -0
  33. package/src/Player/index.tsx +31 -19
  34. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
  35. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
@@ -0,0 +1,212 @@
1
+ import * as React from "react";
2
+ import { View, ViewStyle, StyleSheet } from "react-native";
3
+ import {
4
+ useSafeAreaInsets,
5
+ useSafeAreaFrame,
6
+ } from "react-native-safe-area-context";
7
+ import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
8
+
9
+ import { MOBILE } from "./const";
10
+ import { TransportInfo } from "./TransportInfo";
11
+ import { PlayerImage } from "./PlayerImage";
12
+ import { Controls } from "./Controls";
13
+
14
+ import { useImageSize, useTransportInfoHeight } from "./hooks";
15
+ import { DockedControls } from "./DockedControls";
16
+ import { withDebug } from "./debug";
17
+
18
+ import { Props } from "./types";
19
+
20
+ const styles = StyleSheet.create({
21
+ container: {
22
+ flex: 1,
23
+ },
24
+
25
+ flex: {
26
+ flex: 1,
27
+ },
28
+
29
+ audioPlayerContainer: {
30
+ flex: 1,
31
+ justifyContent: "flex-start",
32
+
33
+ minHeight: MOBILE.MIN_HEIGHT,
34
+
35
+ marginLeft: MOBILE.MARGIN_HORIZONTAL,
36
+ marginRight: MOBILE.MARGIN_HORIZONTAL,
37
+
38
+ marginTop: MOBILE.MARGIN_TOP,
39
+
40
+ ...withDebug({
41
+ borderWidth: 2,
42
+ borderColor: "blue",
43
+ }),
44
+ },
45
+ });
46
+
47
+ const mobileStyles = ({
48
+ screenHeight,
49
+ topInset,
50
+ bottomInset,
51
+ imageSize,
52
+ }): ViewStyle => ({
53
+ height: screenHeight - topInset - bottomInset,
54
+
55
+ opacity: imageSize ? 1 : 0, // hide content until imageSize is calculated
56
+
57
+ ...withDebug({
58
+ borderWidth: 2,
59
+ borderColor: "magenta",
60
+ }),
61
+ });
62
+
63
+ export function MobileLayout({
64
+ entry,
65
+ layoutState,
66
+ playerState,
67
+ value,
68
+ onPlaybackButtonPress,
69
+ onRewindButtonPress,
70
+ onForwardButtonPress,
71
+ onPlayerSeek,
72
+ onSkipStart,
73
+ onSkipLive,
74
+ onSpeedButtonPress,
75
+ onSleepButtonPress,
76
+ onCloseVideoModal,
77
+ playbackSpeedName,
78
+ playbackSleepName,
79
+ configuration,
80
+ dimensions,
81
+ playNextData,
82
+ cancelSleepTimer,
83
+ sleepTimerDate,
84
+ title,
85
+ summary,
86
+ }: Props) {
87
+ const { docked } = layoutState;
88
+
89
+ const { bottom: bottomInset, top: topInset } = useSafeAreaInsets();
90
+ const { height: screenHeight } = useSafeAreaFrame();
91
+ const { progressBarHeight } = useModalAnimationContext();
92
+
93
+ const { imageSize, onLayout } = useImageSize({ isPortraitMode: true });
94
+
95
+ const { height: transportInfoHeight, onLayout: onTransportInfoLayout } =
96
+ useTransportInfoHeight();
97
+
98
+ return (
99
+ <View
100
+ style={[
101
+ styles.container,
102
+ mobileStyles({
103
+ screenHeight,
104
+ topInset,
105
+ bottomInset,
106
+ imageSize,
107
+ }),
108
+ ]}
109
+ >
110
+ {/* TransportInfo */}
111
+ <TransportInfo
112
+ entry={entry}
113
+ layoutState={layoutState}
114
+ value={value}
115
+ configuration={configuration}
116
+ onLayout={onTransportInfoLayout}
117
+ />
118
+
119
+ {/* TransportInfo */}
120
+
121
+ <View
122
+ style={[
123
+ styles.audioPlayerContainer,
124
+ {
125
+ width: imageSize,
126
+ },
127
+ ]}
128
+ >
129
+ {/* PlayerImage */}
130
+ <View
131
+ style={[
132
+ styles.flex,
133
+ {
134
+ maxHeight: imageSize,
135
+
136
+ ...withDebug({
137
+ borderWidth: 2,
138
+ borderColor: "yellow",
139
+ }),
140
+ },
141
+ ]}
142
+ onLayout={onLayout}
143
+ >
144
+ <PlayerImage
145
+ entry={entry}
146
+ layoutState={layoutState}
147
+ playerState={playerState}
148
+ value={value}
149
+ configuration={configuration}
150
+ onPlayerSeek={onPlayerSeek}
151
+ onCloseVideoModal={onCloseVideoModal}
152
+ dimensions={dimensions}
153
+ playNextData={playNextData}
154
+ title={title}
155
+ summary={summary}
156
+ docked={docked}
157
+ imageWidth={imageSize}
158
+ verticalOffset={
159
+ transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight
160
+ }
161
+ />
162
+ </View>
163
+ {/* PlayerImage */}
164
+
165
+ <View
166
+ style={[
167
+ styles.flex,
168
+ {
169
+ marginBottom: MOBILE.MARGIN_BOTTOM,
170
+ },
171
+ ]}
172
+ >
173
+ <Controls
174
+ entry={entry}
175
+ layoutState={layoutState}
176
+ playerState={playerState}
177
+ value={value}
178
+ title={title}
179
+ summary={summary}
180
+ sleepTimerDate={sleepTimerDate}
181
+ cancelSleepTimer={cancelSleepTimer}
182
+ playbackSpeedName={playbackSpeedName}
183
+ playbackSleepName={playbackSleepName}
184
+ onPlaybackButtonPress={onPlaybackButtonPress}
185
+ onRewindButtonPress={onRewindButtonPress}
186
+ onForwardButtonPress={onForwardButtonPress}
187
+ onPlayerSeek={onPlayerSeek}
188
+ onSkipStart={onSkipStart}
189
+ onSkipLive={onSkipLive}
190
+ onSpeedButtonPress={onSpeedButtonPress}
191
+ onSleepButtonPress={onSleepButtonPress}
192
+ docked={docked}
193
+ />
194
+ </View>
195
+ </View>
196
+
197
+ <DockedControls
198
+ entry={entry}
199
+ layoutState={layoutState}
200
+ playerState={playerState}
201
+ value={value}
202
+ configuration={configuration}
203
+ dimensions={dimensions}
204
+ onCloseVideoModal={onCloseVideoModal}
205
+ onPlayerSeek={onPlayerSeek}
206
+ playNextData={playNextData}
207
+ title={title}
208
+ summary={summary}
209
+ />
210
+ </View>
211
+ );
212
+ }
@@ -0,0 +1,83 @@
1
+ import React, { PropsWithChildren } from "react";
2
+ import { ImageBackground, Animated, StyleSheet } from "react-native";
3
+
4
+ import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
5
+ import {
6
+ useModalAnimationContext,
7
+ PlayerAnimationStateEnum,
8
+ DURATION_TO_MINIMIZE,
9
+ DURATION_TO_MAXIMIZE,
10
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
11
+
12
+ const styles = StyleSheet.create({
13
+ container: {
14
+ // we have to specify flex:0 and dimensions to make animation work
15
+ flex: 0,
16
+ aspectRatio: 1,
17
+ },
18
+ });
19
+
20
+ type Props = PropsWithChildren<{
21
+ entry: ZappEntry;
22
+ style?: { [K: string]: any };
23
+ imageStyle?: { [K: string]: any };
24
+ imageWidth: number;
25
+ }>;
26
+
27
+ export const AnimatedImage = ({
28
+ entry,
29
+ style,
30
+ imageStyle,
31
+ imageWidth,
32
+ }: Props) => {
33
+ const heightAnim = React.useRef(new Animated.Value(imageWidth)).current;
34
+
35
+ const source = React.useMemo(
36
+ () => ({ uri: imageSrcFromMediaItem(entry, undefined) }),
37
+ [entry]
38
+ );
39
+
40
+ const { playerAnimationState, minimisedHeight } = useModalAnimationContext();
41
+
42
+ React.useEffect(() => {
43
+ if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
44
+ Animated.timing(heightAnim, {
45
+ toValue: minimisedHeight,
46
+ duration: DURATION_TO_MINIMIZE,
47
+ useNativeDriver: false, // width/height can't use native driver
48
+ }).start();
49
+
50
+ return;
51
+ }
52
+
53
+ if (playerAnimationState === PlayerAnimationStateEnum.maximize) {
54
+ Animated.timing(heightAnim, {
55
+ toValue: imageWidth,
56
+ duration: DURATION_TO_MAXIMIZE,
57
+ useNativeDriver: false, // width/height can't use native driver
58
+ }).start();
59
+ }
60
+ }, [playerAnimationState, imageWidth]);
61
+
62
+ if (!source) return null;
63
+
64
+ return (
65
+ <Animated.View
66
+ style={[
67
+ styles.container,
68
+ {
69
+ width: heightAnim,
70
+ },
71
+ ]}
72
+ >
73
+ <ImageBackground
74
+ resizeMode="cover"
75
+ style={style}
76
+ imageStyle={imageStyle}
77
+ source={source}
78
+ >
79
+ {null}
80
+ </ImageBackground>
81
+ </Animated.View>
82
+ );
83
+ };
@@ -0,0 +1,32 @@
1
+ import * as React from "react";
2
+ import { ImageBackground } from "react-native";
3
+
4
+ import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
5
+
6
+ type Props = {
7
+ entry: ZappEntry;
8
+ style?: { [K: string]: any };
9
+ imageStyle?: { [K: string]: any };
10
+ };
11
+
12
+ const style = { flex: 1, aspectRatio: 1 };
13
+
14
+ export const FlexImage = ({ entry, imageStyle }: Props) => {
15
+ const source = React.useMemo(
16
+ () => ({ uri: imageSrcFromMediaItem(entry, undefined) }),
17
+ [entry]
18
+ );
19
+
20
+ if (!source) return null;
21
+
22
+ return (
23
+ <ImageBackground
24
+ resizeMode="cover"
25
+ style={style}
26
+ source={source}
27
+ imageStyle={imageStyle}
28
+ >
29
+ {null}
30
+ </ImageBackground>
31
+ );
32
+ };
@@ -0,0 +1,95 @@
1
+ import * as React from "react";
2
+
3
+ import {
4
+ AnimationComponent,
5
+ ComponentAnimationType,
6
+ useModalAnimationContext,
7
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
8
+
9
+ import { AnimatedImage } from "./AnimatedImage";
10
+ import { FlexImage } from "./FlexImage";
11
+
12
+ import { styles } from "./styles";
13
+ import { calculateBorderRadius } from "../../utils";
14
+ import { PlayNextData } from "../types";
15
+
16
+ type Props = {
17
+ entry: ZappEntry;
18
+ layoutState: QuickBrickPlayer.LayoutState;
19
+ playerState: QuickBrickPlayer.PlayerState;
20
+ value: GetValue;
21
+ configuration: QuickBrickPlayer.AudioPlayerProps["configuration"];
22
+ dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
23
+ onCloseVideoModal: Callback;
24
+ onPlayerSeek: (targetTime: number) => void;
25
+ playNextData: PlayNextData;
26
+ title: string | number;
27
+ summary: string | number;
28
+ docked: boolean;
29
+ imageWidth: Option<number>;
30
+ verticalOffset: number;
31
+ };
32
+
33
+ export const PlayerImage = (props: Props) => {
34
+ const {
35
+ entry,
36
+ dimensions,
37
+ docked,
38
+ imageWidth,
39
+ verticalOffset,
40
+ configuration,
41
+ } = props;
42
+
43
+ const {
44
+ isActiveGesture,
45
+ startComponentsAnimation,
46
+ playerAnimationState,
47
+ minimisedHeight,
48
+ } = useModalAnimationContext();
49
+
50
+ const borderRadius = calculateBorderRadius(
51
+ docked,
52
+ startComponentsAnimation,
53
+ isActiveGesture,
54
+ playerAnimationState,
55
+ configuration
56
+ );
57
+
58
+ return (
59
+ <AnimationComponent
60
+ animationType={ComponentAnimationType.moveUpComponent}
61
+ additionalData={{
62
+ marginTop: verticalOffset,
63
+ }}
64
+ style={styles.flex}
65
+ >
66
+ <AnimationComponent
67
+ animationType={ComponentAnimationType.moveComponentHorizontal}
68
+ additionalData={{
69
+ // we move image horiontally to this value due artwork is centered
70
+ moveValue: (dimensions.width - minimisedHeight) / 2,
71
+ }}
72
+ style={styles.alignItemsCenter}
73
+ >
74
+ {!imageWidth ? (
75
+ // we render image with flex until we get size of this image
76
+ <FlexImage
77
+ entry={entry}
78
+ style={styles.backgroundImageContainer}
79
+ imageStyle={{ borderRadius }}
80
+ />
81
+ ) : null}
82
+
83
+ {imageWidth ? (
84
+ // we have imageSize here and now we could animate resizing of this image
85
+ <AnimatedImage
86
+ entry={entry}
87
+ style={styles.backgroundImageContainer}
88
+ imageStyle={{ borderRadius }}
89
+ imageWidth={imageWidth}
90
+ />
91
+ ) : null}
92
+ </AnimationComponent>
93
+ </AnimationComponent>
94
+ );
95
+ };
@@ -0,0 +1,17 @@
1
+ import { StyleSheet } from "react-native";
2
+
3
+ export const styles = StyleSheet.create({
4
+ backgroundImageContainer: {
5
+ flex: 1,
6
+ aspectRatio: 1,
7
+ },
8
+
9
+ alignItemsCenter: {
10
+ flex: 1,
11
+ alignItems: "center",
12
+ },
13
+
14
+ flex: {
15
+ flex: 1,
16
+ },
17
+ });
@@ -0,0 +1,214 @@
1
+ import * as React from "react";
2
+ import { View, ViewStyle, StyleSheet } from "react-native";
3
+ import {
4
+ useSafeAreaInsets,
5
+ useSafeAreaFrame,
6
+ } from "react-native-safe-area-context";
7
+ import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
8
+ import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
9
+
10
+ import { TABLET_LANDSCAPE } from "./const";
11
+ import { TransportInfo } from "./TransportInfo";
12
+ import { PlayerImage } from "./PlayerImage";
13
+ import { Controls } from "./Controls";
14
+
15
+ import { useImageSize, useTransportInfoHeight } from "./hooks";
16
+ import { DockedControls } from "./DockedControls";
17
+ import { withDebug } from "./debug";
18
+
19
+ import { Props } from "./types";
20
+
21
+ const isIOS = isApplePlatform();
22
+
23
+ const styles = StyleSheet.create({
24
+ container: {
25
+ flex: 1,
26
+ ...withDebug({
27
+ borderWidth: 2,
28
+ borderColor: "magenta",
29
+ }),
30
+ },
31
+ flex: {
32
+ flex: 1,
33
+ },
34
+ audioPlayerContainer: {
35
+ flex: 1,
36
+ maxHeight: TABLET_LANDSCAPE.MAX_HEIGHT,
37
+ flexDirection: "column",
38
+ alignItems: "center",
39
+
40
+ ...withDebug({
41
+ borderWidth: 2,
42
+ borderColor: "blue",
43
+ }),
44
+ },
45
+ });
46
+
47
+ const tabletStyles = ({
48
+ screenHeight,
49
+ topInset,
50
+ bottomInset,
51
+ imageSize,
52
+ }): ViewStyle => ({
53
+ alignItems: "center",
54
+
55
+ height: screenHeight - topInset - bottomInset,
56
+ paddingBottom: TABLET_LANDSCAPE.MARGIN_VERTICAL,
57
+
58
+ opacity: imageSize ? 1 : 0, // hide content until imageSize is calculated
59
+ });
60
+
61
+ const isTabletWithHomeButton = (bottomInset: number): boolean =>
62
+ bottomInset === 0;
63
+
64
+ const withAdditionalOffset = ({ progressBarHeight, bottomInset }) => {
65
+ if (isIOS && isTabletWithHomeButton(bottomInset)) {
66
+ return progressBarHeight === 0 ? 8 : progressBarHeight + 2;
67
+ }
68
+
69
+ if (isIOS && !isTabletWithHomeButton(bottomInset)) {
70
+ return progressBarHeight === 0 ? 4 : 1;
71
+ }
72
+
73
+ // android
74
+ return progressBarHeight === 0 ? 4 : 0.5;
75
+ };
76
+
77
+ export function TabletLandscapeLayout({
78
+ entry,
79
+ layoutState,
80
+ playerState,
81
+ value,
82
+ onPlaybackButtonPress,
83
+ onRewindButtonPress,
84
+ onForwardButtonPress,
85
+ onPlayerSeek,
86
+ onSkipStart,
87
+ onSkipLive,
88
+ onSpeedButtonPress,
89
+ onSleepButtonPress,
90
+ onCloseVideoModal,
91
+ playbackSpeedName,
92
+ playbackSleepName,
93
+ configuration,
94
+ dimensions,
95
+ playNextData,
96
+ cancelSleepTimer,
97
+ sleepTimerDate,
98
+ title,
99
+ summary,
100
+ }: Props) {
101
+ const { docked } = layoutState;
102
+
103
+ const { bottom: bottomInset, top: topInset } = useSafeAreaInsets();
104
+ const { height: screenHeight } = useSafeAreaFrame();
105
+ const { progressBarHeight } = useModalAnimationContext();
106
+
107
+ const { imageSize, onLayout } = useImageSize({ isPortraitMode: false });
108
+
109
+ const { height: transportInfoHeight, onLayout: onTransportInfoLayout } =
110
+ useTransportInfoHeight();
111
+
112
+ return (
113
+ <View
114
+ style={[
115
+ styles.container,
116
+ tabletStyles({
117
+ screenHeight,
118
+ topInset,
119
+ bottomInset,
120
+ imageSize,
121
+ }),
122
+ ]}
123
+ >
124
+ {/* TransportInfo */}
125
+ <TransportInfo
126
+ entry={entry}
127
+ layoutState={layoutState}
128
+ value={value}
129
+ configuration={configuration}
130
+ onLayout={onTransportInfoLayout}
131
+ />
132
+
133
+ {/* TransportInfo */}
134
+
135
+ <View style={styles.audioPlayerContainer}>
136
+ {/* PlayerImage */}
137
+ <View
138
+ style={[
139
+ styles.flex,
140
+ withDebug({
141
+ borderWidth: 2,
142
+ borderColor: "yellow",
143
+ }),
144
+ ]}
145
+ onLayout={onLayout}
146
+ >
147
+ <PlayerImage
148
+ entry={entry}
149
+ layoutState={layoutState}
150
+ playerState={playerState}
151
+ value={value}
152
+ configuration={configuration}
153
+ onPlayerSeek={onPlayerSeek}
154
+ onCloseVideoModal={onCloseVideoModal}
155
+ dimensions={dimensions}
156
+ playNextData={playNextData}
157
+ title={title}
158
+ summary={summary}
159
+ docked={docked}
160
+ imageWidth={imageSize}
161
+ verticalOffset={
162
+ transportInfoHeight +
163
+ topInset +
164
+ withAdditionalOffset({ progressBarHeight, bottomInset })
165
+ }
166
+ />
167
+ </View>
168
+ {/* PlayerImage */}
169
+
170
+ <View
171
+ style={{
172
+ maxWidth: imageSize,
173
+ }}
174
+ >
175
+ <Controls
176
+ entry={entry}
177
+ layoutState={layoutState}
178
+ playerState={playerState}
179
+ value={value}
180
+ title={title}
181
+ summary={summary}
182
+ sleepTimerDate={sleepTimerDate}
183
+ cancelSleepTimer={cancelSleepTimer}
184
+ playbackSpeedName={playbackSpeedName}
185
+ playbackSleepName={playbackSleepName}
186
+ onPlaybackButtonPress={onPlaybackButtonPress}
187
+ onRewindButtonPress={onRewindButtonPress}
188
+ onForwardButtonPress={onForwardButtonPress}
189
+ onPlayerSeek={onPlayerSeek}
190
+ onSkipStart={onSkipStart}
191
+ onSkipLive={onSkipLive}
192
+ onSpeedButtonPress={onSpeedButtonPress}
193
+ onSleepButtonPress={onSleepButtonPress}
194
+ docked={docked}
195
+ />
196
+ </View>
197
+ </View>
198
+
199
+ <DockedControls
200
+ entry={entry}
201
+ layoutState={layoutState}
202
+ playerState={playerState}
203
+ value={value}
204
+ configuration={configuration}
205
+ dimensions={dimensions}
206
+ onCloseVideoModal={onCloseVideoModal}
207
+ onPlayerSeek={onPlayerSeek}
208
+ playNextData={playNextData}
209
+ title={title}
210
+ summary={summary}
211
+ />
212
+ </View>
213
+ );
214
+ }