@applicaster/quick-brick-player 13.0.0-rc.99 → 14.0.0-rc.2

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 (34) hide show
  1. package/package.json +5 -6
  2. package/src/Player/AudioLayer/AudioDescription.tsx +109 -68
  3. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +81 -189
  4. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +23 -5
  5. package/src/Player/AudioLayer/Layout/Controls/index.tsx +24 -49
  6. package/src/Player/AudioLayer/Layout/Controls/utils.ts +2 -2
  7. package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +38 -19
  8. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +4 -13
  9. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +38 -34
  10. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +4 -16
  11. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +1 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +99 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +37 -20
  14. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +19 -0
  15. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +101 -105
  16. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +2 -11
  17. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +19 -5
  18. package/src/Player/AudioLayer/Layout/const.ts +4 -0
  19. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +1 -1
  20. package/src/Player/AudioLayer/Layout/utils.ts +7 -0
  21. package/src/Player/AudioLayer/SleepTimerManager.ts +22 -11
  22. package/src/Player/AudioLayer/components/SleepTimerModalHeader/SleepTimerModalHeader.tsx +66 -0
  23. package/src/Player/AudioLayer/components/SleepTimerModalHeader/index.ts +1 -0
  24. package/src/Player/AudioLayer/useSleepTimerModal.ts +109 -0
  25. package/src/Player/Const/sleepTimerOptions.ts +7 -5
  26. package/src/Player/Utils/index.tsx +6 -0
  27. package/src/Player/hooks/useIsCasting.tsx +57 -0
  28. package/src/Player/index.tsx +78 -33
  29. package/src/QuickBrickPlayer.tsx +3 -0
  30. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.ts +0 -3
  31. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.web.ts +0 -3
  32. package/src/Player/AudioLayer/LinearGradient/index.ts +0 -1
  33. package/src/Player/AudioLayer/MagicBG/index.tsx +0 -155
  34. package/src/utils/utils.ts +0 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "13.0.0-rc.99",
3
+ "version": "14.0.0-rc.2",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -35,11 +35,11 @@
35
35
  },
36
36
  "homepage": "https://github.com/applicaster/quickbrick#readme",
37
37
  "dependencies": {
38
- "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-rc.99",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-rc.124",
39
39
  "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-rc.99",
41
- "@applicaster/zapp-react-native-ui-components": "13.0.0-rc.99",
42
- "@applicaster/zapp-react-native-utils": "13.0.0-rc.99",
40
+ "@applicaster/zapp-react-native-tvos-app": "14.0.0-rc.2",
41
+ "@applicaster/zapp-react-native-ui-components": "14.0.0-rc.2",
42
+ "@applicaster/zapp-react-native-utils": "14.0.0-rc.2",
43
43
  "query-string": "7.1.3",
44
44
  "react-native-web-linear-gradient": "1.1.2",
45
45
  "shaka-player": "4.3.5",
@@ -52,7 +52,6 @@
52
52
  "@applicaster/applicaster-types": "*",
53
53
  "@applicaster/blur": "*",
54
54
  "@applicaster/quick-brick-xray": "*",
55
- "@applicaster/react-native-color-thief": "*",
56
55
  "@applicaster/zapp-pipes-v2-client": "*",
57
56
  "@applicaster/zapp-react-dom-ui-components": "*",
58
57
  "@applicaster/zapp-react-native-redux": "*",
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { Text, TextStyle } from "react-native";
2
+ import { StyleSheet, Text, TextStyle, View } from "react-native";
3
3
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
4
4
 
5
5
  type AudioDescriptionProps = {
@@ -10,84 +10,125 @@ type AudioDescriptionProps = {
10
10
  docked: boolean;
11
11
  isModal: boolean;
12
12
  };
13
+ maxWidth?: number;
13
14
  value: GetValue;
14
15
  };
15
16
 
16
- const titleStyles = (value: GetValue, prefix: string): TextStyle => ({
17
- textAlign: "left",
18
- color: value(`${prefix}title_color`),
19
- alignSelf: "center",
20
- paddingBottom: 5,
21
- lineHeight:
22
- Number(
23
- platformSelect({
24
- ios: value(`${prefix}title_lineheight_ios`),
25
- android: value(`${prefix}title_lineheight_android`),
26
- })
27
- ) || 18,
28
- letterSpacing:
29
- Number(
30
- platformSelect({
31
- ios: value(`${prefix}title_letterspacing_ios`),
32
- android: value(`${prefix}title_letterspacing_android`),
33
- })
34
- ) || 0,
35
- fontSize:
36
- Number(
37
- platformSelect({
38
- ios: value(`${prefix}title_fontsize_ios`),
39
- android: value(`${prefix}title_fontsize_android`),
40
- })
41
- ) || 16,
42
- fontFamily: platformSelect({
43
- ios: value(`${prefix}title_font_ios`),
44
- android: value(`${prefix}title_font_android`),
45
- }),
46
- });
17
+ const TITLE_PADDING_BOTTOM = 5;
18
+ const TITLE_LINES = 2;
19
+ const SUBTITLE_LINES = 1;
47
20
 
48
- const summaryStyles = (value: GetValue, prefix: string): TextStyle => ({
49
- textAlign: "left",
50
- color: value(`${prefix}subtitle_color`),
51
- alignSelf: "center",
52
- lineHeight:
53
- Number(
54
- platformSelect({
55
- ios: value(`${prefix}subtitle_lineheight_ios`),
56
- android: value(`${prefix}subtitle_lineheight_android`),
57
- })
58
- ) || 18,
59
- letterSpacing:
60
- Number(
61
- platformSelect({
62
- ios: value(`${prefix}subtitle_letterspacing_ios`),
63
- android: value(`${prefix}subtitle_letterspacing_android`),
64
- })
65
- ) || 0,
66
- fontSize:
67
- Number(
68
- platformSelect({
69
- ios: value(`${prefix}subtitle_fontsize_ios`),
70
- android: value(`${prefix}subtitle_fontsize_android`),
71
- })
72
- ) || 13,
73
- fontFamily: platformSelect({
74
- ios: value(`${prefix}subtitle_font_ios`),
75
- android: value(`${prefix}subtitle_font_android`),
76
- }),
21
+ const styles = StyleSheet.create({
22
+ wrapper: {
23
+ width: "100%",
24
+ alignSelf: "center",
25
+ alignItems: "center",
26
+ justifyContent: "center",
27
+ },
28
+ titleText: {
29
+ textAlign: "center",
30
+ alignSelf: "center",
31
+ paddingBottom: TITLE_PADDING_BOTTOM,
32
+ },
33
+ summaryText: {
34
+ textAlign: "left",
35
+ alignSelf: "center",
36
+ },
77
37
  });
78
38
 
39
+ const getTitleStyles = (value: GetValue, prefix: string) =>
40
+ ({
41
+ color: value(`${prefix}title_color`),
42
+ lineHeight:
43
+ Number(
44
+ platformSelect({
45
+ ios: value(`${prefix}title_lineheight_ios`),
46
+ android: value(`${prefix}title_lineheight_android`),
47
+ })
48
+ ) || 18,
49
+ letterSpacing:
50
+ Number(
51
+ platformSelect({
52
+ ios: value(`${prefix}title_letterspacing_ios`),
53
+ android: value(`${prefix}title_letterspacing_android`),
54
+ })
55
+ ) || 0,
56
+ fontSize:
57
+ Number(
58
+ platformSelect({
59
+ ios: value(`${prefix}title_fontsize_ios`),
60
+ android: value(`${prefix}title_fontsize_android`),
61
+ })
62
+ ) || 16,
63
+ fontFamily: platformSelect({
64
+ ios: value(`${prefix}title_font_ios`),
65
+ android: value(`${prefix}title_font_android`),
66
+ }),
67
+ }) as const;
68
+
69
+ const getSummaryStyles = (value: GetValue, prefix: string): TextStyle =>
70
+ ({
71
+ color: value(`${prefix}subtitle_color`),
72
+ lineHeight:
73
+ Number(
74
+ platformSelect({
75
+ ios: value(`${prefix}subtitle_lineheight_ios`),
76
+ android: value(`${prefix}subtitle_lineheight_android`),
77
+ })
78
+ ) || 18,
79
+ letterSpacing:
80
+ Number(
81
+ platformSelect({
82
+ ios: value(`${prefix}subtitle_letterspacing_ios`),
83
+ android: value(`${prefix}subtitle_letterspacing_android`),
84
+ })
85
+ ) || 0,
86
+ fontSize:
87
+ Number(
88
+ platformSelect({
89
+ ios: value(`${prefix}subtitle_fontsize_ios`),
90
+ android: value(`${prefix}subtitle_fontsize_android`),
91
+ })
92
+ ) || 13,
93
+ fontFamily: platformSelect({
94
+ ios: value(`${prefix}subtitle_font_ios`),
95
+ android: value(`${prefix}subtitle_font_android`),
96
+ }),
97
+ }) as const;
98
+
99
+ const getHeight = (titleLineHeight: number, subtitleLineHeight) =>
100
+ titleLineHeight * TITLE_LINES + subtitleLineHeight + TITLE_PADDING_BOTTOM;
101
+
79
102
  export const AudioDescription = (props: AudioDescriptionProps) => {
80
- const { title, summary, layoutState, value } = props;
103
+ const { title, summary, layoutState, value, maxWidth } = props;
81
104
  const prefix = layoutState.docked ? "docked_player_" : "";
82
105
 
106
+ const summaryStyles = getSummaryStyles(value, prefix);
107
+ const titleStyles = getTitleStyles(value, prefix);
108
+
109
+ const height = getHeight(titleStyles.lineHeight, summaryStyles.lineHeight);
110
+
83
111
  return (
84
- <>
85
- <Text style={titleStyles(value, prefix)} numberOfLines={2}>
112
+ <View
113
+ style={[
114
+ styles.wrapper,
115
+ {
116
+ maxWidth: Math.max(maxWidth, 320),
117
+ height,
118
+ },
119
+ ]}
120
+ >
121
+ <Text style={[styles.titleText, titleStyles]} numberOfLines={TITLE_LINES}>
86
122
  {title}
87
123
  </Text>
88
- <Text style={summaryStyles(value, prefix)} numberOfLines={1}>
89
- {summary}
90
- </Text>
91
- </>
124
+ {summary ? (
125
+ <Text
126
+ style={[styles.summaryText, summaryStyles]}
127
+ numberOfLines={SUBTITLE_LINES}
128
+ >
129
+ {summary}
130
+ </Text>
131
+ ) : null}
132
+ </View>
92
133
  );
93
134
  };
@@ -1,12 +1,13 @@
1
1
  import * as React from "react";
2
+ import { useEffect, useState } from "react";
2
3
  import {
4
+ Dimensions as ScreenDimensions,
3
5
  StyleSheet,
4
- ViewStyle,
5
6
  View,
6
- Dimensions as ScreenDimensions,
7
+ ViewStyle,
7
8
  } from "react-native";
8
9
 
9
- import { SafeAreaView, Edge } from "react-native-safe-area-context";
10
+ import { Edge, SafeAreaView } from "react-native-safe-area-context";
10
11
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
11
12
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
12
13
  import * as R from "ramda";
@@ -20,11 +21,8 @@ import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
20
21
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
21
22
  import { PlayerDetails } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/PlayerDetails";
22
23
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
23
- import { useEffect, useState } from "react";
24
- import { MagicBG } from "./MagicBG";
25
24
  import { formatSpeed } from "./utils";
26
25
  import {
27
- addQueryParam,
28
26
  getBottomSheetModalDefaultItemIcon,
29
27
  getBottomSheetModalIconProps,
30
28
  getBottomSheetModalItemProps,
@@ -33,22 +31,19 @@ import {
33
31
  } from "../Utils";
34
32
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
35
33
  import {
34
+ AnimatedScrollModal,
36
35
  AnimationComponent,
37
36
  ComponentAnimationType,
38
- AnimatedScrollModal,
39
37
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
40
38
  import { PADDING_HORIZONTAL } from "./Layout/const";
41
39
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
40
+
41
+ import { DEFAULT_SPEED, PlaybackSpeed, SpeedController } from "./SpeedManager";
42
42
  import {
43
- SleepTimerController,
44
- SleepTimerState,
45
- SLEEP_TIMER_OFF,
46
- } from "./SleepTimerManager";
47
- import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
48
- import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
49
- import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
50
- import { openBottomSheetModal } from "@applicaster/zapp-react-native-utils/modalState";
51
- import { getSleepTimerOptions } from "../Const/sleepTimerOptions";
43
+ dismissModal as dismissBottomSheetModal,
44
+ openBottomSheetModal,
45
+ useModalStoreState,
46
+ } from "@applicaster/zapp-react-native-utils/modalState";
52
47
  import { speedOptions } from "../Const/speedOptions";
53
48
 
54
49
  const { log_debug } = createLogger({
@@ -65,8 +60,6 @@ type Dimensions = {
65
60
 
66
61
  type Configuration = {
67
62
  [key: string]: any;
68
- magic_background?: boolean;
69
- audio_player_background_image_query?: string;
70
63
  audio_player_background_image_default_color?: string;
71
64
  tablet_landscape_sidebar_width?: string;
72
65
  tablet_landscape_player_container_background_color?: string;
@@ -75,7 +68,6 @@ type Configuration = {
75
68
  type Props = {
76
69
  children: React.ReactNode;
77
70
  inline?: boolean;
78
- docked?: boolean;
79
71
  configuration: Configuration;
80
72
  style: ViewStyle & Dimensions;
81
73
  entry: ZappEntry;
@@ -108,10 +100,10 @@ const edges: Edge[] = ["right", "left", "top"];
108
100
  export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
109
101
  const player = usePlayer();
110
102
  const playerState = usePlayerState("audio-player-wrapper");
111
- const theme = useTheme();
103
+
104
+ const modalBottomSheetState = useModalStoreState();
112
105
 
113
106
  const {
114
- docked,
115
107
  configuration,
116
108
  style,
117
109
  entry,
@@ -131,30 +123,39 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
131
123
  configuration?.audio_live_player_update_interval
132
124
  );
133
125
 
134
- const [sleepTimerManager, setSleepTimerManager] =
135
- useState<SleepTimerController | null>(null);
136
-
137
126
  const [speedManager, setSpeedManager] = useState<SpeedController | null>(
138
127
  null
139
128
  );
140
129
 
141
130
  useEffect(() => {
142
131
  if (player) {
143
- setSleepTimerManager(new SleepTimerController(player));
144
132
  setSpeedManager(new SpeedController(player));
145
133
  } else {
146
- setSleepTimerManager(null);
147
134
  setSpeedManager(null);
148
135
  }
149
136
  }, [player]);
150
137
 
138
+ useEffect(() => {
139
+ if (!player) return;
140
+
141
+ const unsubscribe = player.addListener({
142
+ id: "audio-player-wrapper-bottom-sheet-modal",
143
+ listener: {
144
+ onVideoEnd: () => {
145
+ // Dismiss the bottom sheet modal when the video ends to avoid audio breaks and app freeze
146
+ if (modalBottomSheetState.visible) {
147
+ dismissBottomSheetModal();
148
+ }
149
+ },
150
+ },
151
+ });
152
+
153
+ return () => unsubscribe?.();
154
+ }, [player, modalBottomSheetState.visible]);
155
+
151
156
  const [playbackSpeed, setPlaybackSpeed] =
152
157
  useState<PlaybackSpeed>(DEFAULT_SPEED);
153
158
 
154
- const [sleepTimerState, setSleepTimerState] = useState<SleepTimerState>(
155
- new SleepTimerState(SLEEP_TIMER_OFF, 0)
156
- );
157
-
158
159
  const [defaultDimensions, setDefaultDimensions] =
159
160
  React.useState<Dimensions>(undefined);
160
161
 
@@ -177,17 +178,13 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
177
178
  };
178
179
 
179
180
  useEffect(() => {
180
- const sleepSubscription =
181
- sleepTimerManager?.sleepTimerState$.subscribe(setSleepTimerState);
182
-
183
181
  const speedSubscription =
184
182
  speedManager?.playbackSpeed$.subscribe(setPlaybackSpeed);
185
183
 
186
184
  return () => {
187
- sleepSubscription?.unsubscribe();
188
185
  speedSubscription?.unsubscribe();
189
186
  };
190
- }, [sleepTimerManager, speedManager]);
187
+ }, [speedManager]);
191
188
 
192
189
  useEffect(() => {
193
190
  if (!playerState.isReadyToPlay) {
@@ -195,8 +192,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
195
192
  }
196
193
 
197
194
  void speedManager?.loadSpeed();
198
- void sleepTimerManager?.loadSleep();
199
- }, [playerState.isReadyToPlay, speedManager, sleepTimerManager]);
195
+ }, [playerState.isReadyToPlay, speedManager]);
200
196
 
201
197
  const getValue = (key: string, stylesObj: {}) =>
202
198
  R.propOr(null, key, stylesObj);
@@ -244,13 +240,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
244
240
  [speedManager]
245
241
  );
246
242
 
247
- const onSleepSelect = React.useCallback(
248
- async (item) => {
249
- await sleepTimerManager?.setSleepTimer(item);
250
- },
251
- [sleepTimerManager]
252
- );
253
-
254
243
  const onSpeedButtonPress = React.useCallback(() => {
255
244
  openBottomSheetModal({
256
245
  modalBottomSheetContentProps: {
@@ -275,42 +264,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
275
264
  });
276
265
  }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
277
266
 
278
- const onSleepButtonPress = React.useCallback(() => {
279
- openBottomSheetModal({
280
- modalBottomSheetContentProps: {
281
- items: getSleepTimerOptions(configuration),
282
- current_selection: sleepTimerState.timer,
283
- onPress: onSleepSelect,
284
- title: configuration["playback_sleep_title"],
285
- itemProps: getBottomSheetModalItemProps,
286
- iconProps: getBottomSheetModalIconProps,
287
- labelProps: getBottomSheetModalLabelProps,
288
- getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
289
- iconPlacement: "right",
290
- },
291
- options: {
292
- supportedOrientations: [
293
- "portrait",
294
- "landscape",
295
- "portrait-upside-down",
296
- ],
297
- },
298
- });
299
- }, [
300
- sleepTimerState.timer,
301
- configuration["playback_sleep_title"],
302
- configuration["playback_sleep_off_label"],
303
- onSleepSelect,
304
- ]);
305
-
306
- // This method does not actually cancel the sleep timer
307
- // (and should not to avoid race condition),
308
- // it just performs the cleanup when timer expires
309
- // TODO: rename it in code above
310
- const cancelSleepTimer = React.useCallback(() => {
311
- sleepTimerManager?.onTimerExpired();
312
- }, [sleepTimerManager]);
313
-
314
267
  const onCloseVideoModal = React.useCallback(() => {
315
268
  playerManager.close();
316
269
  }, [playerManager]);
@@ -330,114 +283,53 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
330
283
  player?.seekTo(0);
331
284
  }, [player]);
332
285
 
333
- const MainContent = React.useMemo(() => {
334
- return (
335
- <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
336
- <AnimationComponent
337
- animationType={ComponentAnimationType.moveUpComponent}
338
- additionalData={{ saveArea: true }}
339
- style={Styles.playerContainer}
340
- >
341
- <AnimatedScrollModal>
342
- <View style={Styles.playerContainer} onLayout={onLayout}>
343
- <Layout
344
- entry={entry}
345
- playerState={playerState}
346
- layoutState={layoutState}
347
- value={value}
348
- onPlaybackButtonPress={onPlaybackButtonPress}
349
- onRewindButtonPress={onRewindButtonPress}
350
- onForwardButtonPress={onForwardButtonPress}
351
- onPlayerSeek={onPlayerSeek}
352
- onSkipStart={onSkipStart}
353
- onSpeedButtonPress={onSpeedButtonPress}
354
- onSleepButtonPress={onSleepButtonPress}
355
- playbackSpeedName={formatSpeed(playbackSpeed.value)}
356
- playbackSleepName={
357
- sleepTimerState.timer.value === 0
358
- ? "sleep_timer"
359
- : "sleep_timer_active"
360
- }
361
- sleepTimerDate={sleepTimerState.timerDate}
362
- cancelSleepTimer={cancelSleepTimer}
363
- onSkipLive={onSkipLive}
364
- onCloseVideoModal={onCloseVideoModal}
365
- maximiseVideoModal={maximiseVideoModal}
366
- configuration={configuration}
367
- dimensions={dimensions}
368
- playNextData={playNextData}
369
- title={title}
370
- summary={summary}
371
- defaultDimensions={defaultDimensions}
372
- />
373
- <View style={Styles.paddingHorizontal}>
374
- {children}
375
- <AnimationComponent
376
- animationType={ComponentAnimationType.componentFade}
377
- >
378
- <PlayerDetails
379
- isAudioPlayer
380
- configuration={configuration}
381
- style={Styles.playerDetails}
382
- entry={entry}
383
- isTabletLandscape={isTabletLandscape}
384
- />
385
- </AnimationComponent>
386
- </View>
387
- </View>
388
- </AnimatedScrollModal>
389
- </AnimationComponent>
390
- </SafeAreaView>
391
- );
392
- }, [
393
- docked,
394
- style,
395
- entry,
396
- playerState,
397
- layoutState,
398
- value,
399
- onPlaybackButtonPress,
400
- onRewindButtonPress,
401
- onForwardButtonPress,
402
- onPlayerSeek,
403
- onCloseVideoModal,
404
- maximiseVideoModal,
405
- configuration,
406
- dimensions,
407
- children,
408
- playNextData,
409
- onSkipStart,
410
- onSkipLive,
411
- sleepTimerState.timer.value,
412
- sleepTimerState.timerDate,
413
- ]);
414
-
415
- if (configuration.magic_background) {
416
- const baseUrl = imageSrcFromMediaItem(entry, null);
417
-
418
- const queryParamName =
419
- configuration.audio_player_background_image_query || "width";
420
-
421
- const defaultBackgroundColor =
422
- configuration.audio_player_background_image_default_color ||
423
- theme?.app_background_color;
424
-
425
- const queryParamValue = 15;
426
-
427
- const url =
428
- baseUrl && addQueryParam(baseUrl, queryParamName, queryParamValue);
429
-
430
- return (
431
- <MagicBG
432
- image={url}
433
- fallbackUrl={baseUrl}
434
- colors={entry?.extensions?.backgroundColors}
435
- defaultColor={defaultBackgroundColor}
286
+ return (
287
+ <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
288
+ <AnimationComponent
289
+ animationType={ComponentAnimationType.moveUpComponent}
290
+ additionalData={{ saveArea: true }}
291
+ style={Styles.playerContainer}
436
292
  >
437
- {MainContent}
438
- </MagicBG>
439
- );
440
- }
441
-
442
- return MainContent;
293
+ <AnimatedScrollModal>
294
+ <View style={Styles.playerContainer} onLayout={onLayout}>
295
+ <Layout
296
+ entry={entry}
297
+ playerState={playerState}
298
+ layoutState={layoutState}
299
+ value={value}
300
+ onPlaybackButtonPress={onPlaybackButtonPress}
301
+ onRewindButtonPress={onRewindButtonPress}
302
+ onForwardButtonPress={onForwardButtonPress}
303
+ onPlayerSeek={onPlayerSeek}
304
+ onSkipStart={onSkipStart}
305
+ onSpeedButtonPress={onSpeedButtonPress}
306
+ playbackSpeedName={formatSpeed(playbackSpeed.value)}
307
+ onSkipLive={onSkipLive}
308
+ onCloseVideoModal={onCloseVideoModal}
309
+ maximiseVideoModal={maximiseVideoModal}
310
+ configuration={configuration}
311
+ dimensions={dimensions}
312
+ playNextData={playNextData}
313
+ title={title}
314
+ summary={summary}
315
+ />
316
+ <View style={Styles.paddingHorizontal}>
317
+ {children}
318
+ <AnimationComponent
319
+ animationType={ComponentAnimationType.componentFade}
320
+ >
321
+ <PlayerDetails
322
+ isAudioPlayer
323
+ configuration={configuration}
324
+ style={Styles.playerDetails}
325
+ entry={entry}
326
+ isTabletLandscape={isTabletLandscape}
327
+ />
328
+ </AnimationComponent>
329
+ </View>
330
+ </View>
331
+ </AnimatedScrollModal>
332
+ </AnimationComponent>
333
+ </SafeAreaView>
334
+ );
443
335
  };
@@ -3,25 +3,43 @@ import { View, StyleSheet } from "react-native";
3
3
 
4
4
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
5
5
 
6
- import { TABLET_VERTICAL_SEPARATOR_HEIGHT } from "../const";
6
+ import {
7
+ TABLET_VERTICAL_SEPARATOR_HEIGHT,
8
+ TABLET_VERTICAL_SEPARATOR_HEIGHT_S,
9
+ } from "../const";
7
10
 
8
11
  import { withDebug } from "../debug";
12
+ import { useSafeAreaFrame } from "react-native-safe-area-context";
13
+ import { isSmallTabletHeight } from "../utils";
9
14
 
10
15
  const styles = StyleSheet.create({
11
16
  flexingHeight: {
12
17
  flex: 1,
13
-
14
18
  ...withDebug({ backgroundColor: "red" }),
15
19
  },
16
20
  fixedHeight: {
17
21
  height: TABLET_VERTICAL_SEPARATOR_HEIGHT,
18
-
22
+ ...withDebug({ backgroundColor: "red" }),
23
+ },
24
+ fixedHeightSmall: {
25
+ height: TABLET_VERTICAL_SEPARATOR_HEIGHT_S,
19
26
  ...withDebug({ backgroundColor: "red" }),
20
27
  },
21
28
  });
22
29
 
23
30
  export const VerticalGutter = () => {
24
31
  const isTablet = useIsTablet();
25
-
26
- return <View style={isTablet ? styles.fixedHeight : styles.flexingHeight} />;
32
+ const { height } = useSafeAreaFrame();
33
+
34
+ return (
35
+ <View
36
+ style={
37
+ isTablet
38
+ ? isSmallTabletHeight(height)
39
+ ? styles.fixedHeightSmall
40
+ : styles.fixedHeight
41
+ : styles.flexingHeight
42
+ }
43
+ />
44
+ );
27
45
  };