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