@applicaster/quick-brick-player 12.0.0-alpha.5251355865 → 12.0.0-alpha.5347482137

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "12.0.0-alpha.5251355865",
3
+ "version": "12.0.0-alpha.5347482137",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "homepage": "https://github.com/applicaster/quickbrick#readme",
38
38
  "dependencies": {
39
- "@applicaster/quick-brick-mobile-transport-controls": "12.0.0-alpha.5251355865",
40
- "@applicaster/quick-brick-tv-transport-controls": "11.0.0-rc.133",
41
- "@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.5251355865",
42
- "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5251355865",
43
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5251355865",
39
+ "@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.83",
40
+ "@applicaster/quick-brick-tv-transport-controls": "12.0.0-rc.83",
41
+ "@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.5347482137",
42
+ "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5347482137",
43
+ "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5347482137",
44
44
  "keymirror": "^0.1.1",
45
45
  "query-string": "7.1.3",
46
46
  "react-native-web-linear-gradient": "1.1.2",
@@ -1,8 +1,9 @@
1
1
  import React, { useEffect, useState } from "react";
2
- import { Image, StyleSheet, View } from "react-native";
2
+ import { StyleSheet, View } from "react-native";
3
3
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
4
4
  import { MUTED_USAGE } from "../const";
5
5
  import { LiveImageManager } from "@applicaster/zapp-react-native-ui-components/Components/VideoLive/LiveImageManager";
6
+ import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
6
7
 
7
8
  type Asset = string | undefined;
8
9
 
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { ViewStyle, View, ScrollView } from "react-native";
2
+ import { ViewStyle, View } from "react-native";
3
3
 
4
4
  import { SafeAreaView, Edge } from "react-native-safe-area-context";
5
5
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
@@ -24,8 +24,15 @@ import {
24
24
  NAMESPACE,
25
25
  } from "./utils";
26
26
  import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
27
- import { getLiveUrl } from "../Utils";
27
+ import { addQueryParam, getLiveUrl } from "../Utils";
28
28
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
29
+ import {
30
+ AnimationComponent,
31
+ ComponentAnimationType,
32
+ AnimatedScrollModal,
33
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
34
+ import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
35
+ import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
29
36
 
30
37
  const { log_debug } = createLogger({
31
38
  subsystem: "UIComponent",
@@ -68,29 +75,20 @@ export const defaultAspectRatioWidth = (height: number): number =>
68
75
  (height / 9) * 16;
69
76
 
70
77
  const Styles = {
71
- mainContainer: (docked: boolean, style: ViewStyle) => {
78
+ mainContainer: (style: ViewStyle) => {
72
79
  const combinedStyle: ViewStyle = {
73
80
  flex: 1,
74
81
  };
75
82
 
76
- if (!docked) {
77
- style.paddingTop = 0;
78
- style.paddingHorizontal = 15;
79
- }
80
-
81
- return { ...combinedStyle, ...style };
82
- },
83
- playerContainer: (docked: boolean, style: ViewStyle) => {
84
- const combinedStyle: ViewStyle = {
85
- flex: 1,
83
+ return {
84
+ ...combinedStyle,
85
+ ...style,
86
86
  };
87
-
88
- if (docked) {
89
- combinedStyle.height = style.height;
90
- }
91
-
92
- return combinedStyle;
93
87
  },
88
+ playerContainer: {
89
+ flex: 1,
90
+ },
91
+ paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
94
92
 
95
93
  controlsMobile: {
96
94
  height: 50,
@@ -168,6 +166,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
168
166
 
169
167
  const [sleepTimerDate, setSleepTimerDate] = useState(0);
170
168
 
169
+ const [defaultDimensions, setDefaultDimensions] =
170
+ React.useState<Dimensions>(undefined);
171
+
171
172
  const [dimensions, setDimensions] = React.useState<Dimensions>({
172
173
  width: 0,
173
174
  height: 0,
@@ -181,9 +182,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
181
182
  const { width, height } = event.nativeEvent.layout;
182
183
 
183
184
  setDimensions({
184
- width: docked ? defaultAspectRatioWidth(height) : width,
185
+ width,
185
186
  height,
186
187
  });
188
+
189
+ if (!defaultDimensions) setDefaultDimensions({ width, height });
187
190
  };
188
191
 
189
192
  const cancelSleepTimer = async () => {
@@ -195,7 +198,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
195
198
  });
196
199
 
197
200
  setSleepTimerDate(0);
198
- player?.pause();
199
201
 
200
202
  await localStorage.removeItem("sleep", NAMESPACE);
201
203
  };
@@ -293,7 +295,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
293
295
  playerState.isPaused ? player?.play() : player.pause();
294
296
  }, [playerState, player]);
295
297
 
296
- const seekDuration = Number(value("seek_duration"));
298
+ const seekDuration = toNumberWithDefault(10, value("seek_duration"));
297
299
 
298
300
  const onRewindButtonPress = React.useCallback(() => {
299
301
  player?.rewind(seekDuration);
@@ -376,58 +378,65 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
376
378
  player?.seekTo(0);
377
379
  }, [player]);
378
380
 
379
- const edges = React.useMemo<Edge[]>(
380
- () => (docked ? [] : ["right", "left", "top"]),
381
- [docked]
382
- );
381
+ const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
383
382
 
384
- const ContainerView = docked ? View : SafeAreaView;
383
+ const ContainerView = SafeAreaView;
385
384
 
386
385
  const MainContent = React.useMemo(() => {
387
386
  return (
388
- <ContainerView style={Styles.mainContainer(docked, style)} edges={edges}>
389
- <ScrollView
390
- style={Styles.playerContainer(docked, style)}
391
- onLayout={onLayout}
387
+ <ContainerView style={Styles.mainContainer(style)} edges={edges}>
388
+ <AnimationComponent
389
+ animationType={ComponentAnimationType.moveUpComponent}
390
+ additionalData={{ saveArea: true }}
391
+ style={Styles.playerContainer}
392
392
  >
393
- <Layout
394
- entry={entry}
395
- playerState={playerState}
396
- layoutState={layoutState}
397
- value={value}
398
- onPlaybackButtonPress={onPlaybackButtonPress}
399
- onRewindButtonPress={onRewindButtonPress}
400
- onForwardButtonPress={onForwardButtonPress}
401
- onPlayerSeek={onPlayerSeek}
402
- onSkipStart={onSkipStart}
403
- onSpeedButtonPress={onSpeedButtonPress}
404
- onSleepButtonPress={onSleepButtonPress}
405
- playbackSpeedName={formatSpeed(playbackSpeed.value)}
406
- playbackSleepName={
407
- sleepTimer.value === 0 ? "sleep_timer" : "sleep_timer_active"
408
- }
409
- sleepTimerDate={sleepTimerDate}
410
- cancelSleepTimer={cancelSleepTimer}
411
- onSkipLive={onSkipLive}
412
- onCloseVideoModal={onCloseVideoModal}
413
- maximiseVideoModal={maximiseVideoModal}
414
- configuration={configuration}
415
- dimensions={dimensions}
416
- playNextData={playNextData}
417
- title={title}
418
- summary={summary}
419
- />
420
- {children}
421
- {!docked && (
422
- <PlayerDetails
423
- configuration={configuration}
424
- style={Styles.playerDetails}
425
- entry={entry}
426
- isTabletLandscape={isTabletLandscape}
427
- isAudioPlayer={true}
428
- />
429
- )}
430
- </ScrollView>
393
+ <AnimatedScrollModal>
394
+ <View style={Styles.playerContainer} onLayout={onLayout}>
395
+ <Layout
396
+ entry={entry}
397
+ playerState={playerState}
398
+ layoutState={layoutState}
399
+ value={value}
400
+ onPlaybackButtonPress={onPlaybackButtonPress}
401
+ onRewindButtonPress={onRewindButtonPress}
402
+ onForwardButtonPress={onForwardButtonPress}
403
+ onPlayerSeek={onPlayerSeek}
404
+ onSkipStart={onSkipStart}
405
+ onSpeedButtonPress={onSpeedButtonPress}
406
+ onSleepButtonPress={onSleepButtonPress}
407
+ playbackSpeedName={formatSpeed(playbackSpeed.value)}
408
+ playbackSleepName={
409
+ sleepTimer.value === 0 ? "sleep_timer" : "sleep_timer_active"
410
+ }
411
+ sleepTimerDate={sleepTimerDate}
412
+ cancelSleepTimer={cancelSleepTimer}
413
+ onSkipLive={onSkipLive}
414
+ onCloseVideoModal={onCloseVideoModal}
415
+ maximiseVideoModal={maximiseVideoModal}
416
+ configuration={configuration}
417
+ dimensions={dimensions}
418
+ playNextData={playNextData}
419
+ title={title}
420
+ summary={summary}
421
+ defaultDimensions={defaultDimensions}
422
+ />
423
+ <View style={Styles.paddingHorizontal}>
424
+ {children}
425
+ <AnimationComponent
426
+ animationType={ComponentAnimationType.componentFade}
427
+ >
428
+ <PlayerDetails
429
+ configuration={configuration}
430
+ style={Styles.playerDetails}
431
+ entry={entry}
432
+ isTabletLandscape={isTabletLandscape}
433
+ isAudioPlayer={true}
434
+ />
435
+ </AnimationComponent>
436
+ </View>
437
+ </View>
438
+ </AnimatedScrollModal>
439
+ </AnimationComponent>
431
440
  </ContainerView>
432
441
  );
433
442
  }, [
@@ -456,17 +465,20 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
456
465
  if (configuration.magic_background) {
457
466
  const baseUrl = entry?.extensions?.audio_player_background_image ?? "";
458
467
 
459
- // TODO: To be added when background is ready
468
+ const queryParamName =
469
+ configuration.audio_player_background_image_query || "width";
470
+
471
+ const queryParamValue = 15;
460
472
 
461
- // const queryParamName =
462
- // configuration.audio_player_background_image_query || "width";
463
- //
464
- // const queryParamValue = 15;
465
- //
466
- // const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
473
+ const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
467
474
 
468
475
  return (
469
- <MagicBG image={baseUrl} fallbackUrl={baseUrl} defaultColor="#000000">
476
+ <MagicBG
477
+ image={url}
478
+ fallbackUrl={baseUrl}
479
+ colors={entry?.extensions?.backgroundColors}
480
+ defaultColor="#000000"
481
+ >
470
482
  {MainContent}
471
483
  </MagicBG>
472
484
  );
@@ -1,6 +1,7 @@
1
1
  import * as React from "react";
2
2
  import * as R from "ramda";
3
3
  import { View } from "react-native";
4
+ import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
4
5
 
5
6
  import {
6
7
  ProgressBar,
@@ -18,13 +19,22 @@ import {
18
19
  rewindButton,
19
20
  skipToStartButton,
20
21
  skipToLiveButton,
22
+ PADDING_HORIZONTAL,
21
23
  speedButton,
22
24
  sleepButton,
23
25
  } from "./defaultLayoutsConts";
24
26
  import { AudioDescription } from "../AudioDescription";
25
27
  import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
26
28
  import { useLanguageData } from "@applicaster/zapp-react-native-utils/reactHooks/player";
29
+ import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
27
30
  import { useEffect, useMemo, useState } from "react";
31
+ import {
32
+ useModalAnimationContext,
33
+ AnimationComponent,
34
+ ComponentAnimationType,
35
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
36
+ import DockedLayout from "./DockedLayout";
37
+ import { isValidDate } from "../../Utils";
28
38
 
29
39
  type Dimensions = {
30
40
  width: number;
@@ -60,22 +70,29 @@ type LayoutProps = {
60
70
  onPlayerSeek: (targetTime: number) => void;
61
71
  onSkipLive: () => void;
62
72
  onSkipStart: () => void;
73
+ onCloseVideoModal: () => void;
74
+ maximiseVideoModal: () => void;
63
75
  dimensions: Dimensions;
76
+ playNextData: PlayNextData;
64
77
  title: string | number;
65
78
  summary: string | number;
79
+ defaultDimensions: Dimensions;
66
80
  };
67
81
 
68
82
  const Styles = {
69
83
  container: { flex: 1 },
70
- tabletContainer: (isPortraitMode) => ({
84
+ tabletContainer: (isPortraitMode: boolean) => ({
71
85
  flex: 1,
72
86
  alignItems: "center",
73
87
  justifyContent: isPortraitMode ? "center" : "flex-start",
74
88
  }),
75
- tabletLayout: {
76
- width: 463,
89
+ playerImageWrapper: {
90
+ width: "100%",
77
91
  maxHeight: 750,
78
92
  marginTop: 80,
93
+ },
94
+ tabletLayout: {
95
+ width: 463,
79
96
  marginBottom: 80,
80
97
  },
81
98
  controls: (isTablet: boolean, isLiveShowFullControls: boolean) => ({
@@ -84,24 +101,31 @@ const Styles = {
84
101
  justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
85
102
  }),
86
103
  backgroundImageContainer: (dimensions: Dimensions, isTablet: boolean) => {
104
+ const mobileValue = dimensions.width
105
+ ? dimensions.width - PADDING_HORIZONTAL * 2
106
+ : 330;
107
+
87
108
  return {
88
- width: isTablet ? 463 : dimensions.width || 330,
89
- height: isTablet ? 463 : dimensions.width || 330,
109
+ width: isTablet ? 463 : mobileValue,
110
+ height: isTablet ? 463 : mobileValue,
90
111
  };
91
112
  },
92
- backgroundImageContainerImageStyle: (isTablet) => ({
93
- borderRadius: isTablet ? 24 : 10,
113
+ backgroundImageContainerImageStyle: (
114
+ isTablet: boolean,
115
+ docked: boolean,
116
+ startComponentsAnimation: boolean,
117
+ isActiveGesture: boolean
118
+ ) => ({
119
+ borderRadius:
120
+ (startComponentsAnimation && isActiveGesture) || docked
121
+ ? 0
122
+ : isTablet
123
+ ? 24
124
+ : 10,
94
125
  }),
95
- playerContainer: (docked: boolean, style) => {
96
- const combinedStyle = {
97
- flex: 1,
98
- };
99
126
 
100
- if (docked) {
101
- combinedStyle["height"] = style.height;
102
- }
103
-
104
- return combinedStyle;
127
+ paddingHorizontal: {
128
+ paddingHorizontal: PADDING_HORIZONTAL,
105
129
  },
106
130
 
107
131
  controlsMobile: {
@@ -115,6 +139,12 @@ const Styles = {
115
139
  separator: {
116
140
  height: 20,
117
141
  },
142
+ flexDirectionRow: {
143
+ flexDirection: "row",
144
+ },
145
+ alignItemsCenter: {
146
+ alignItems: "center",
147
+ },
118
148
  };
119
149
 
120
150
  export default function DefaultLayout(props: LayoutProps) {
@@ -139,12 +169,14 @@ export default function DefaultLayout(props: LayoutProps) {
139
169
  sleepTimerDate,
140
170
  title,
141
171
  summary,
172
+ defaultDimensions,
142
173
  } = props;
143
174
 
144
175
  const isTablet = useIsTablet();
145
176
  const { width, height } = dimensions;
146
177
  const isPortraitMode = width < height;
147
178
  const isLiveContent = playerState.isLive;
179
+ const docked = layoutState.docked;
148
180
 
149
181
  const languageData = useLanguageData("audio-player");
150
182
 
@@ -160,8 +192,31 @@ export default function DefaultLayout(props: LayoutProps) {
160
192
 
161
193
  let showFullControls = !controller?.isAd();
162
194
 
195
+ const startTime = entry.extensions?.live?.start_time;
196
+ const endTime = entry.extensions?.live?.end_time;
197
+
198
+ const hasValidStartTime = isValidDate(startTime);
199
+ const hasValidEndTime = isValidDate(endTime);
200
+
201
+ const isDateBasedLiveContent =
202
+ isLiveContent && hasValidStartTime && hasValidEndTime;
203
+
204
+ const needsToShowProgressBar =
205
+ (isLiveContent &&
206
+ (Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
207
+ !isLiveContent;
208
+
209
+ const startTimestamp = hasValidStartTime
210
+ ? dayjs.utc(startTime!).valueOf()
211
+ : undefined;
212
+
213
+ const endTimestamp = hasValidEndTime
214
+ ? dayjs.utc(endTime!).valueOf()
215
+ : undefined;
216
+
163
217
  if (isLiveContent) {
164
218
  const seekEnabled = Boolean(value("liveSeekingEnabled"));
219
+
165
220
  showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
166
221
  }
167
222
 
@@ -191,12 +246,14 @@ export default function DefaultLayout(props: LayoutProps) {
191
246
 
192
247
  const rewind = rewindButton({
193
248
  isTablet,
194
- onPress: controller?.hasContentDuration?.() ? onRewindButtonPress : null,
249
+ onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
195
250
  });
196
251
 
197
252
  const forward = forwardButton({
198
253
  isTablet,
199
- onPress: controller?.hasContentDuration?.() ? onForwardButtonPress : null,
254
+ onPress: controller?.hasSeekableDuration?.()
255
+ ? onForwardButtonPress
256
+ : null,
200
257
  });
201
258
 
202
259
  const speed = speedButton({
@@ -225,7 +282,6 @@ export default function DefaultLayout(props: LayoutProps) {
225
282
  return [skipToStart, rewind, play, forward, skipToLive];
226
283
  }
227
284
 
228
- // Temporary empty button until we add sleep button. It will ensure the buttons will not break in their position
229
285
  return [speed, rewind, play, forward, sleep];
230
286
  }, [
231
287
  playerState,
@@ -246,15 +302,12 @@ export default function DefaultLayout(props: LayoutProps) {
246
302
 
247
303
  useEffect(() => {
248
304
  if (showCounter && sleepTimerDate !== 0) {
249
- // Setting the initial timeLeft based on sleepTimerDate
250
305
  setTimeLeft(sleepTimerDate - Date.now());
251
306
 
252
- // Setting up an interval to update the remaining time every second
253
307
  const intervalId = setInterval(() => {
254
308
  setTimeLeft(() => {
255
309
  const newTimeLeft = sleepTimerDate - Date.now();
256
310
 
257
- // If the new remaining time is less than or equal to 0, clear the interval and trigger the cancelSleepTimer function
258
311
  if (newTimeLeft <= 0) {
259
312
  clearInterval(intervalId);
260
313
 
@@ -262,26 +315,28 @@ export default function DefaultLayout(props: LayoutProps) {
262
315
 
263
316
  return 0;
264
317
  } else {
265
- // Otherwise, update the state with the new remaining time
266
318
  return newTimeLeft;
267
319
  }
268
320
  });
269
321
  }, 1000);
270
322
 
271
- // Clearing the interval when the component unmounts or dependencies change
272
323
  return () => clearInterval(intervalId);
273
324
  } else {
274
- // Ensure the timeLeft state is set correctly if showCounter is false
275
325
  setTimeLeft(0);
276
326
  }
277
327
  }, [sleepTimerDate, showCounter, cancelSleepTimer]);
278
328
 
279
329
  const Separator = () => <View style={Styles.separator} />;
280
330
 
281
- const liveSeekingEnabled = value("liveSeekingEnabled");
331
+ const defaultImageDimensions = React.useMemo(
332
+ () =>
333
+ defaultDimensions &&
334
+ Styles.backgroundImageContainer(defaultDimensions, isTablet),
335
+ [defaultDimensions, isTablet]
336
+ );
282
337
 
283
- const needsToShowProgressBar =
284
- (isLiveContent && liveSeekingEnabled) || !isLiveContent;
338
+ const { isActiveGesture, startComponentsAnimation } =
339
+ useModalAnimationContext();
285
340
 
286
341
  return (
287
342
  <View
@@ -289,65 +344,108 @@ export default function DefaultLayout(props: LayoutProps) {
289
344
  isTablet ? Styles.tabletContainer(isPortraitMode) : Styles.container
290
345
  }
291
346
  >
292
- <TransportInfo
293
- content={entry}
294
- value={value}
295
- visible={true}
296
- languageData={languageData}
297
- layoutState={layoutState}
298
- actionButtons={actionButtons}
299
- />
300
- <View
301
- style={
302
- isTablet ? Styles.tabletContainer(isPortraitMode) : Styles.container
303
- }
347
+ <AnimationComponent animationType={ComponentAnimationType.componentFade}>
348
+ <TransportInfo
349
+ content={entry}
350
+ value={value}
351
+ visible={true}
352
+ languageData={languageData}
353
+ layoutState={layoutState}
354
+ actionButtons={actionButtons}
355
+ />
356
+ </AnimationComponent>
357
+ <AnimationComponent
358
+ animationType={ComponentAnimationType.moveUpComponent}
359
+ style={isTablet ? Styles.playerImageWrapper : undefined}
304
360
  >
305
- <View style={isTablet ? Styles.tabletLayout : null}>
361
+ <AnimationComponent
362
+ animationType={ComponentAnimationType.moveComponentHorizontal}
363
+ additionalData={{
364
+ disableAnimatedComponent: !isTablet,
365
+ moveValue: (dimensions.width - 463) / 2,
366
+ extraAnimation: !isTablet
367
+ ? {
368
+ [ComponentAnimationType.audioPlayerPaddingHorizontal]: {
369
+ style: Styles.paddingHorizontal,
370
+ },
371
+ }
372
+ : null,
373
+ }}
374
+ style={isTablet ? Styles.alignItemsCenter : undefined}
375
+ >
306
376
  <PlayerImageBackground
307
377
  entry={entry}
308
378
  style={Styles.backgroundImageContainer(dimensions, isTablet)}
309
- imageStyle={Styles.backgroundImageContainerImageStyle(isTablet)}
310
- />
311
- <AudioDescription
312
- title={title}
313
- summary={summary}
314
- value={value}
315
- layoutState={layoutState}
379
+ imageStyle={Styles.backgroundImageContainerImageStyle(
380
+ isTablet,
381
+ docked,
382
+ startComponentsAnimation,
383
+ isActiveGesture
384
+ )}
385
+ defaultImageDimensions={defaultImageDimensions}
316
386
  />
317
- <Separator />
318
- {needsToShowProgressBar && (
319
- <View>
320
- <ProgressBar
321
- content={entry}
322
- value={value}
323
- visible={true}
324
- layoutState={layoutState}
325
- onPlayerSeek={onPlayerSeek}
326
- playerState={playerState}
327
- disableFullscreen={true}
328
- sliderStyle={2}
329
- />
330
-
331
- {showCounter && timeLeft >= 0 && (
332
- <CountDown
333
- timeLeft={timeLeft}
387
+ </AnimationComponent>
388
+
389
+ <DockedLayout {...props} />
390
+ </AnimationComponent>
391
+ <View
392
+ style={[
393
+ Styles.paddingHorizontal,
394
+ isTablet ? Styles.tabletLayout : undefined,
395
+ ]}
396
+ >
397
+ {!docked && (
398
+ <AnimationComponent
399
+ animationType={ComponentAnimationType.componentFade}
400
+ >
401
+ <AudioDescription
402
+ title={title}
403
+ summary={summary}
404
+ value={value}
405
+ layoutState={layoutState}
406
+ />
407
+ <Separator />
408
+ {needsToShowProgressBar && (
409
+ <View>
410
+ <ProgressBar
411
+ content={entry}
334
412
  value={value}
335
- title={sleepTitle}
413
+ visible={true}
414
+ layoutState={layoutState}
415
+ onPlayerSeek={onPlayerSeek}
416
+ playerState={playerState}
417
+ disableFullscreen={true}
418
+ sliderStyle={2}
419
+ startTimestamp={startTimestamp}
420
+ endTimestamp={endTimestamp}
421
+ isDateBasedLiveContent={isDateBasedLiveContent}
422
+ onSkipLive={onSkipLive}
336
423
  />
337
- )}
338
424
 
339
- <Separator />
340
- </View>
341
- )}
342
- <Controls
343
- value={value}
344
- visible={true}
345
- keepAlive={null}
346
- buttons={controlButtons}
347
- style={Styles.controls(isTablet, isLiveContent && showFullControls)}
348
- playerState={playerState}
349
- />
350
- </View>
425
+ {showCounter && timeLeft >= 0 && (
426
+ <CountDown
427
+ timeLeft={timeLeft}
428
+ value={value}
429
+ title={sleepTitle}
430
+ />
431
+ )}
432
+
433
+ <Separator />
434
+ </View>
435
+ )}
436
+ <Controls
437
+ value={value}
438
+ visible={true}
439
+ keepAlive={null}
440
+ buttons={controlButtons}
441
+ style={Styles.controls(
442
+ isTablet,
443
+ isLiveContent && showFullControls
444
+ )}
445
+ playerState={playerState}
446
+ />
447
+ </AnimationComponent>
448
+ )}
351
449
  </View>
352
450
  </View>
353
451
  );