@applicaster/quick-brick-player 13.0.0-alpha.2060875348 → 13.0.0-alpha.2082004638

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 (27) hide show
  1. package/package.json +6 -10
  2. package/src/Player/AudioLayer/AudioDescription.tsx +6 -4
  3. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +15 -9
  4. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +26 -0
  5. package/src/Player/AudioLayer/Layout/Controls/index.tsx +307 -0
  6. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +3 -11
  7. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +29 -52
  8. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +209 -0
  9. package/src/Player/AudioLayer/Layout/PlayerImage/ScaledImage.tsx +83 -0
  10. package/src/Player/AudioLayer/Layout/PlayerImage/StaticImage.tsx +32 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +101 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +17 -0
  13. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +206 -0
  14. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +218 -0
  15. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +103 -0
  16. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  17. package/src/Player/AudioLayer/Layout/const.ts +19 -0
  18. package/src/Player/AudioLayer/Layout/debug.ts +5 -0
  19. package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -0
  20. package/src/Player/AudioLayer/Layout/hooks/useImageSize.ts +99 -0
  21. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  22. package/src/Player/AudioLayer/Layout/index.tsx +34 -30
  23. package/src/Player/AudioLayer/Layout/types.ts +49 -0
  24. package/src/Player/AudioLayer/MagicBG/index.tsx +1 -1
  25. package/src/Player/AudioLayer/utils.ts +24 -0
  26. package/src/Player/index.tsx +9 -6
  27. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -453
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "13.0.0-alpha.2060875348",
3
+ "version": "13.0.0-alpha.2082004638",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
7
7
  "scripts": {
8
- "test": "jest -w=2",
9
8
  "build": "echo 'skipping ts build for core packages'"
10
9
  },
11
10
  "files": [
@@ -36,11 +35,11 @@
36
35
  },
37
36
  "homepage": "https://github.com/applicaster/quickbrick#readme",
38
37
  "dependencies": {
39
- "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.2060875348",
40
- "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.46",
41
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.2060875348",
42
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.2060875348",
43
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.2060875348",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.2082004638",
39
+ "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.2082004638",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.2082004638",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.2082004638",
44
43
  "keymirror": "^0.1.1",
45
44
  "query-string": "7.1.3",
46
45
  "react-native-web-linear-gradient": "1.1.2",
@@ -61,11 +60,8 @@
61
60
  "@applicaster/zapp-react-native-tvos-ui-components": "*",
62
61
  "@babel/runtime": "*",
63
62
  "@react-native-community/netinfo": "*",
64
- "@types/node": "*",
65
- "@types/react-native": "0.69.6",
66
63
  "immer": "*",
67
64
  "react": "*",
68
- "react-hot-loader": "*",
69
65
  "react-native": "*",
70
66
  "react-native-fs": "*",
71
67
  "react-native-gesture-handler": "*",
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { Text, TextStyle, View } from "react-native";
2
+ import { Text, TextStyle, View, StyleSheet } from "react-native";
3
3
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
4
4
 
5
5
  type AudioDescriptionProps = {
@@ -13,7 +13,9 @@ type AudioDescriptionProps = {
13
13
  value: GetValue;
14
14
  };
15
15
 
16
- const containerStyles = { paddingTop: 32, paddingBottom: 12 };
16
+ const styles = StyleSheet.create({
17
+ container: {},
18
+ });
17
19
 
18
20
  const titleStyles = (value: GetValue, prefix: string): TextStyle => ({
19
21
  textAlign: "left",
@@ -83,11 +85,11 @@ export const AudioDescription = (props: AudioDescriptionProps) => {
83
85
  const prefix = layoutState.docked ? "docked_player_" : "";
84
86
 
85
87
  return (
86
- <View style={containerStyles}>
88
+ <View style={styles.container}>
87
89
  <Text style={titleStyles(value, prefix)} numberOfLines={1}>
88
90
  {title}
89
91
  </Text>
90
- <Text style={summaryStyles(value, prefix)} numberOfLines={2}>
92
+ <Text style={summaryStyles(value, prefix)} numberOfLines={1}>
91
93
  {summary}
92
94
  </Text>
93
95
  </View>
@@ -25,7 +25,7 @@ import {
25
25
  ComponentAnimationType,
26
26
  AnimatedScrollModal,
27
27
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
28
- import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
28
+ import { PADDING_HORIZONTAL } from "./Layout/const";
29
29
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
30
30
  import {
31
31
  speed_0_8,
@@ -41,6 +41,7 @@ import {
41
41
  } from "./SleepTimerManager";
42
42
  import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
43
43
  import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
44
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
44
45
 
45
46
  const { log_debug } = createLogger({
46
47
  subsystem: "UIComponent",
@@ -58,6 +59,7 @@ type Configuration = {
58
59
  [key: string]: any;
59
60
  magic_background?: boolean;
60
61
  audio_player_background_image_query?: string;
62
+ audio_player_background_image_default_color?: string;
61
63
  tablet_landscape_sidebar_width?: string;
62
64
  tablet_landscape_player_container_background_color?: string;
63
65
  };
@@ -127,9 +129,12 @@ const sleeps = [
127
129
  { label: "2 hours", value: 120 },
128
130
  ];
129
131
 
132
+ const edges: Edge[] = ["right", "left", "top"];
133
+
130
134
  export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
131
135
  const player = usePlayer();
132
136
  const playerState = usePlayerState("audio-player-wrapper");
137
+ const theme = useTheme();
133
138
 
134
139
  const {
135
140
  docked,
@@ -359,13 +364,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
359
364
  player?.seekTo(0);
360
365
  }, [player]);
361
366
 
362
- const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
363
-
364
- const ContainerView = SafeAreaView;
365
-
366
367
  const MainContent = React.useMemo(() => {
367
368
  return (
368
- <ContainerView style={Styles.mainContainer(style)} edges={edges}>
369
+ <SafeAreaView style={Styles.mainContainer(style)} edges={edges}>
369
370
  <AnimationComponent
370
371
  animationType={ComponentAnimationType.moveUpComponent}
371
372
  additionalData={{ saveArea: true }}
@@ -420,7 +421,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
420
421
  </View>
421
422
  </AnimatedScrollModal>
422
423
  </AnimationComponent>
423
- </ContainerView>
424
+ </SafeAreaView>
424
425
  );
425
426
  }, [
426
427
  docked,
@@ -451,16 +452,21 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
451
452
  const queryParamName =
452
453
  configuration.audio_player_background_image_query || "width";
453
454
 
455
+ const defaultBackgroundColor =
456
+ configuration.audio_player_background_image_default_color ||
457
+ theme?.app_background_color;
458
+
454
459
  const queryParamValue = 15;
455
460
 
456
- const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
461
+ const url =
462
+ baseUrl && addQueryParam(baseUrl, queryParamName, queryParamValue);
457
463
 
458
464
  return (
459
465
  <MagicBG
460
466
  image={url}
461
467
  fallbackUrl={baseUrl}
462
468
  colors={entry?.extensions?.backgroundColors}
463
- defaultColor="#000000"
469
+ defaultColor={defaultBackgroundColor}
464
470
  >
465
471
  {MainContent}
466
472
  </MagicBG>
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+
4
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+
6
+ import { TABLET_VERTICAL_SEPARATOR_HEIGHT } from "../const";
7
+
8
+ import { withDebug } from "../debug";
9
+
10
+ const styles = StyleSheet.create({
11
+ flexingHeight: {
12
+ flex: 1,
13
+
14
+ ...withDebug({ backgroundColor: "red" }),
15
+ },
16
+ fixedHeight: {
17
+ height: TABLET_VERTICAL_SEPARATOR_HEIGHT,
18
+ ...withDebug({ backgroundColor: "red" }),
19
+ },
20
+ });
21
+
22
+ export const VerticalGutter = () => {
23
+ const isTablet = useIsTablet();
24
+
25
+ return <View style={isTablet ? styles.fixedHeight : styles.flexingHeight} />;
26
+ };
@@ -0,0 +1,307 @@
1
+ import * as React from "react";
2
+ import { StyleSheet } from "react-native";
3
+
4
+ import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
5
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
6
+ import {
7
+ Controls as MobileTransportControls,
8
+ CountDown,
9
+ ProgressBar,
10
+ } from "@applicaster/quick-brick-mobile-transport-controls";
11
+ import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
12
+
13
+ import {
14
+ AnimationComponent,
15
+ ComponentAnimationType,
16
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
17
+
18
+ import { AudioDescription } from "../../AudioDescription";
19
+ import { isValidDate } from "../../../Utils";
20
+ import { VerticalGutter } from "./VerticalGutter";
21
+
22
+ import {
23
+ forwardButton,
24
+ playbackButton,
25
+ rewindButton,
26
+ skipToLiveButton,
27
+ skipToStartButton,
28
+ sleepButton,
29
+ speedButton,
30
+ } from "./utils";
31
+
32
+ import { PlayerState, LayoutState } from "../types";
33
+
34
+ const styles = StyleSheet.create({
35
+ flex: {
36
+ flex: 1,
37
+ },
38
+ nonFlex: {
39
+ flex: 0,
40
+ },
41
+ progressBar: {
42
+ flex: 0,
43
+ },
44
+ });
45
+
46
+ const controlsStyles = ({
47
+ isTablet,
48
+ isLiveShowFullControls,
49
+ }: {
50
+ isTablet: boolean;
51
+ isLiveShowFullControls: boolean;
52
+ }) => ({
53
+ height: isTablet ? undefined : 50,
54
+ marginHorizontal: isTablet ? undefined : 10,
55
+ justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
56
+ });
57
+
58
+ type Props = {
59
+ entry: ZappEntry;
60
+ layoutState: LayoutState;
61
+ playerState: PlayerState;
62
+ value: GetValue;
63
+ title: string | number;
64
+ summary: string | number;
65
+ sleepTimerDate: number;
66
+ cancelSleepTimer: () => void;
67
+
68
+ playbackSpeedName: string;
69
+ playbackSleepName: string;
70
+
71
+ onPlaybackButtonPress: () => void;
72
+ onRewindButtonPress: () => void;
73
+ onForwardButtonPress: () => void;
74
+ onPlayerSeek: (targetTime: number) => void;
75
+ onSkipStart: () => void;
76
+ onSkipLive: () => void;
77
+ onSpeedButtonPress: () => void;
78
+ onSleepButtonPress: () => void;
79
+
80
+ docked: boolean;
81
+ };
82
+
83
+ export const Controls = (props: Props) => {
84
+ const {
85
+ entry,
86
+ layoutState,
87
+ playerState,
88
+ value,
89
+ title,
90
+ summary,
91
+ sleepTimerDate,
92
+ cancelSleepTimer,
93
+
94
+ playbackSpeedName,
95
+ playbackSleepName,
96
+
97
+ onPlaybackButtonPress,
98
+ onRewindButtonPress,
99
+ onForwardButtonPress,
100
+ onPlayerSeek,
101
+ onSkipStart,
102
+ onSkipLive,
103
+ onSpeedButtonPress,
104
+ onSleepButtonPress,
105
+
106
+ docked,
107
+ } = props;
108
+
109
+ const isTablet = useIsTablet();
110
+ const controller = playerManager.getActivePlayer();
111
+ let showFullControls = !controller?.isAd();
112
+ const liveButton = Boolean(value("live_badge_enabled"));
113
+
114
+ const isLiveContent = playerState.isLive;
115
+
116
+ if (isLiveContent) {
117
+ const seekEnabled = Boolean(value("liveSeekingEnabled"));
118
+
119
+ showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
120
+ }
121
+
122
+ const sleepTitle = value("playback_sleep_countdown_label");
123
+
124
+ const [timeLeft, setTimeLeft] = React.useState(
125
+ sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
126
+ );
127
+
128
+ const showCounter = React.useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
129
+
130
+ React.useEffect(() => {
131
+ if (showCounter && sleepTimerDate !== 0) {
132
+ setTimeLeft(sleepTimerDate - Date.now());
133
+
134
+ const intervalId = setInterval(() => {
135
+ setTimeLeft(() => {
136
+ const newTimeLeft = sleepTimerDate - Date.now();
137
+
138
+ if (newTimeLeft <= 0) {
139
+ clearInterval(intervalId);
140
+
141
+ cancelSleepTimer();
142
+
143
+ return 0;
144
+ } else {
145
+ return newTimeLeft;
146
+ }
147
+ });
148
+ }, 1000);
149
+
150
+ return () => clearInterval(intervalId);
151
+ } else {
152
+ setTimeLeft(0);
153
+ }
154
+ }, [sleepTimerDate, showCounter, cancelSleepTimer]);
155
+
156
+ const startTime = entry.extensions?.live?.start_time;
157
+ const endTime = entry.extensions?.live?.end_time;
158
+
159
+ const hasValidStartTime = isValidDate(startTime);
160
+ const hasValidEndTime = isValidDate(endTime);
161
+
162
+ const isDateBasedLiveContent =
163
+ isLiveContent && hasValidStartTime && hasValidEndTime;
164
+
165
+ const needsToShowProgressBar =
166
+ (isLiveContent &&
167
+ (Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
168
+ !isLiveContent;
169
+
170
+ const startTimestamp = hasValidStartTime
171
+ ? dayjs.utc(startTime!).valueOf()
172
+ : undefined;
173
+
174
+ const endTimestamp = hasValidEndTime
175
+ ? dayjs.utc(endTime!).valueOf()
176
+ : undefined;
177
+
178
+ const isLiveShowFullControls = showFullControls && isLiveContent;
179
+
180
+ const controlButtons = React.useCallback((): Array<ControlsButton> => {
181
+ const play = playbackButton({
182
+ playerState,
183
+ liveButton,
184
+ isTablet,
185
+ isLiveShowFullControls,
186
+ onPress: onPlaybackButtonPress,
187
+ });
188
+
189
+ if (!showFullControls) {
190
+ return [play];
191
+ }
192
+
193
+ const rewind = rewindButton({
194
+ isTablet,
195
+ onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
196
+ });
197
+
198
+ const forward = forwardButton({
199
+ isTablet,
200
+ onPress: controller?.hasSeekableDuration?.()
201
+ ? onForwardButtonPress
202
+ : null,
203
+ });
204
+
205
+ const speed = speedButton({
206
+ isTablet,
207
+ onPress: onSpeedButtonPress,
208
+ name: playbackSpeedName,
209
+ });
210
+
211
+ const sleep = sleepButton({
212
+ isTablet,
213
+ onPress: onSleepButtonPress,
214
+ name: playbackSleepName,
215
+ });
216
+
217
+ if (isLiveContent) {
218
+ const skipToStart = skipToStartButton({
219
+ isTablet,
220
+ onPress: onSkipStart,
221
+ });
222
+
223
+ const skipToLive = skipToLiveButton({
224
+ isTablet,
225
+ onPress: onSkipLive,
226
+ });
227
+
228
+ return [skipToStart, rewind, play, forward, skipToLive];
229
+ }
230
+
231
+ return [speed, rewind, play, forward, sleep];
232
+ }, [
233
+ playerState,
234
+ liveButton,
235
+ isTablet,
236
+ onPlaybackButtonPress,
237
+ onRewindButtonPress,
238
+ onForwardButtonPress,
239
+ onSpeedButtonPress,
240
+ showFullControls,
241
+ onSkipStart,
242
+ onSkipLive,
243
+ isLiveContent,
244
+ playbackSpeedName,
245
+ playbackSleepName,
246
+ controller,
247
+ isLiveShowFullControls,
248
+ ]);
249
+
250
+ if (docked) {
251
+ return null;
252
+ }
253
+
254
+ return (
255
+ <AnimationComponent
256
+ animationType={ComponentAnimationType.componentFade}
257
+ style={isTablet ? styles.nonFlex : styles.flex}
258
+ >
259
+ <VerticalGutter />
260
+
261
+ <AudioDescription
262
+ title={title}
263
+ summary={summary}
264
+ value={value}
265
+ layoutState={layoutState}
266
+ />
267
+
268
+ <VerticalGutter />
269
+
270
+ {needsToShowProgressBar ? (
271
+ <>
272
+ <ProgressBar
273
+ name={"audio-default-layout"}
274
+ content={entry}
275
+ value={value}
276
+ visible
277
+ layoutState={layoutState}
278
+ onPlayerSeek={onPlayerSeek}
279
+ playerState={playerState}
280
+ disableFullscreen
281
+ sliderStyle={2}
282
+ startTimestamp={startTimestamp}
283
+ endTimestamp={endTimestamp}
284
+ isDateBasedLiveContent={isDateBasedLiveContent}
285
+ onSkipLive={onSkipLive}
286
+ progressBarStyles={styles.progressBar}
287
+ />
288
+
289
+ {showCounter && timeLeft >= 0 ? (
290
+ <CountDown timeLeft={timeLeft} value={value} title={sleepTitle} />
291
+ ) : null}
292
+
293
+ <VerticalGutter />
294
+ </>
295
+ ) : null}
296
+
297
+ <MobileTransportControls
298
+ value={value}
299
+ visible={true}
300
+ keepAlive={null}
301
+ buttons={controlButtons}
302
+ style={controlsStyles({ isTablet, isLiveShowFullControls })}
303
+ playerState={playerState}
304
+ />
305
+ </AnimationComponent>
306
+ );
307
+ };
@@ -1,11 +1,4 @@
1
- type PlayerState = {
2
- currentTime: number;
3
- duration: number;
4
- seekableDuration: number;
5
- isLive: boolean;
6
- isPaused: boolean;
7
- isBuffering: boolean;
8
- };
1
+ import { PlayerState } from "../types";
9
2
 
10
3
  const rewindButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
11
4
  isTablet ? "big" : "smallMargins";
@@ -17,9 +10,7 @@ const playbackButtonMargins = (
17
10
  isTablet: boolean,
18
11
  isLiveShowFullControls: boolean
19
12
  ): number =>
20
- isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? 95 : 40;
21
-
22
- export const PADDING_HORIZONTAL = 15;
13
+ isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
23
14
 
24
15
  export const playbackButton = ({
25
16
  playerState,
@@ -57,6 +48,7 @@ type ButtonsProps = {
57
48
  style?: any;
58
49
  name?: string;
59
50
  };
51
+
60
52
  type ButtonsByNameProps = ButtonsProps & { name?: string };
61
53
 
62
54
  const rewindButtonByName = ({
@@ -22,36 +22,19 @@ import {
22
22
  PlayerAnimationStateEnum,
23
23
  useModalAnimationContext,
24
24
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
25
+ import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
25
26
 
26
- type Dimensions = {
27
- width: number;
28
- height: number;
29
- };
27
+ import { LayoutState, PlayerState, Configuration, DimensionsT } from "../types";
30
28
 
31
- type LayoutProps = {
29
+ type Props = {
32
30
  entry: ZappEntry;
33
- layoutState: {
34
- inline: boolean;
35
- docked: boolean;
36
- isModal: boolean;
37
- };
38
- playerState: {
39
- currentTime: number;
40
- duration: number;
41
- seekableDuration: number;
42
- isLive: boolean;
43
- isPaused: boolean;
44
- isBuffering: boolean;
45
- };
31
+ layoutState: LayoutState;
32
+ playerState: PlayerState;
46
33
  value: GetValue;
47
- configuration: { [key: string]: any };
48
- onPlaybackButtonPress: () => void;
49
- onRewindButtonPress: () => void;
50
- onForwardButtonPress: () => void;
51
- onPlayerSeek: (targetTime: number) => void;
34
+ configuration: Configuration;
35
+ dimensions: DimensionsT;
52
36
  onCloseVideoModal: () => void;
53
- maximiseVideoModal: () => void;
54
- dimensions: Dimensions;
37
+ onPlayerSeek: (targetTime: number) => void;
55
38
  playNextData: PlayNextData;
56
39
  title: string | number;
57
40
  summary: string | number;
@@ -113,17 +96,21 @@ const playerDimensionsStyle = (
113
96
  minimisedHeight: number,
114
97
  addPadding: boolean
115
98
  ): ViewStyle => ({
116
- paddingLeft: addPadding ? minimisedHeight || 100 : 0,
99
+ paddingLeft: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
117
100
  });
118
101
 
119
- const animatedContainerStyle = (docked: boolean): ViewStyle => ({
102
+ const animatedContainerStyle = (
103
+ docked: boolean,
104
+ progressBarHeight: number
105
+ ): ViewStyle => ({
106
+ top: progressBarHeight,
120
107
  position: "absolute",
121
108
  width: "100%",
122
109
  zIndex: docked ? 1 : -1,
123
110
  });
124
111
 
125
112
  const backgroundImageStyle = (
126
- dimensions: Dimensions,
113
+ dimensions: DimensionsT,
127
114
  minimisedHeight: number,
128
115
  isActiveGesture: boolean
129
116
  ): ViewStyle => ({
@@ -133,24 +120,11 @@ const backgroundImageStyle = (
133
120
  });
134
121
 
135
122
  const controlButtons = (
136
- isPlayNextEnabled: boolean,
137
123
  live: boolean,
138
124
  paused: boolean,
139
125
  buffering: boolean,
140
126
  playerId: string
141
127
  ): Array<ControlsButton> => {
142
- if (isPlayNextEnabled) {
143
- return [
144
- {
145
- size: "medium",
146
- name: "play_next",
147
- icon: "play_next",
148
- preferredFocus: true,
149
- style: styles.buttons,
150
- },
151
- ];
152
- }
153
-
154
128
  if (buffering) {
155
129
  return [
156
130
  {
@@ -202,16 +176,16 @@ const controlButtons = (
202
176
  ];
203
177
  };
204
178
 
205
- export default function DockedLayout(props: LayoutProps) {
179
+ export const DockedControls = (props: Props) => {
206
180
  const {
181
+ entry,
207
182
  layoutState,
183
+ playerState,
208
184
  value,
185
+ configuration,
209
186
  dimensions,
210
- entry,
211
187
  onCloseVideoModal,
212
188
  onPlayerSeek,
213
- playerState,
214
- configuration,
215
189
  playNextData,
216
190
  title,
217
191
  summary,
@@ -219,7 +193,6 @@ export default function DockedLayout(props: LayoutProps) {
219
193
 
220
194
  const isTablet = useIsTablet();
221
195
 
222
- const visible = true;
223
196
  const liveButton = Boolean(value("live_badge_enabled"));
224
197
 
225
198
  const {
@@ -227,10 +200,11 @@ export default function DockedLayout(props: LayoutProps) {
227
200
  setPlayerAnimationState,
228
201
  startComponentsAnimation,
229
202
  minimisedHeight,
203
+ progressBarHeight,
230
204
  } = useModalAnimationContext();
231
205
 
232
206
  const maximazeVideoModal = React.useCallback(
233
- () => setPlayerAnimationState(PlayerAnimationStateEnum.maximaze),
207
+ () => setPlayerAnimationState(PlayerAnimationStateEnum.maximize),
234
208
  []
235
209
  );
236
210
 
@@ -241,15 +215,19 @@ export default function DockedLayout(props: LayoutProps) {
241
215
  animationType={ComponentAnimationType.componentAppears}
242
216
  style={[
243
217
  styles.container,
244
- animatedContainerStyle(isActiveGesture || layoutState.docked),
218
+ animatedContainerStyle(
219
+ isActiveGesture || layoutState.docked,
220
+ progressBarHeight
221
+ ),
245
222
  ]}
246
223
  >
247
224
  {!playerState.isLive &&
248
225
  (layoutState.docked || startComponentsAnimation) ? (
249
226
  <ProgressBar
227
+ name={"audio-docked-layout"}
250
228
  content={entry}
251
229
  value={value}
252
- visible={visible}
230
+ visible
253
231
  layoutState={layoutState}
254
232
  onPlayerSeek={onPlayerSeek}
255
233
  playerState={playerState}
@@ -300,9 +278,8 @@ export default function DockedLayout(props: LayoutProps) {
300
278
  >
301
279
  <Controls
302
280
  value={value}
303
- visible={visible}
281
+ visible
304
282
  buttons={R.partial(controlButtons, [
305
- playNextData,
306
283
  playerState.isLive && liveButton,
307
284
  ])}
308
285
  style={styles.playPauseButton}
@@ -320,4 +297,4 @@ export default function DockedLayout(props: LayoutProps) {
320
297
  </View>
321
298
  </AnimationComponent>
322
299
  );
323
- }
300
+ };