@applicaster/quick-brick-player 13.0.0-alpha.1442750538 → 13.0.0-alpha.1486614302

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 (29) hide show
  1. package/package.json +8 -13
  2. package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
  3. package/src/Player/AudioLayer/AudioDescription.tsx +4 -6
  4. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +36 -35
  5. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +27 -0
  6. package/src/Player/AudioLayer/Layout/Controls/index.tsx +305 -0
  7. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +3 -13
  8. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +44 -67
  9. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +212 -0
  10. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +83 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +32 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +95 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +17 -0
  14. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +214 -0
  15. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +224 -0
  16. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +109 -0
  17. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  18. package/src/Player/AudioLayer/Layout/const.ts +20 -0
  19. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  20. package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -0
  21. package/src/Player/AudioLayer/Layout/hooks/useImageSize.ts +100 -0
  22. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  23. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  24. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  25. package/src/Player/AudioLayer/MagicBG/index.tsx +1 -1
  26. package/src/Player/AudioLayer/utils.ts +27 -0
  27. package/src/Player/index.tsx +29 -17
  28. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
  29. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "13.0.0-alpha.1442750538",
3
+ "version": "13.0.0-alpha.1486614302",
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,12 +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-rc.28",
40
- "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.31",
41
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.1442750538",
42
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.1442750538",
43
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.1442750538",
44
- "keymirror": "^0.1.1",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.1486614302",
39
+ "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.1486614302",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.1486614302",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.1486614302",
45
43
  "query-string": "7.1.3",
46
44
  "react-native-web-linear-gradient": "1.1.2",
47
45
  "shaka-player": "4.3.5",
@@ -61,12 +59,9 @@
61
59
  "@applicaster/zapp-react-native-tvos-ui-components": "*",
62
60
  "@babel/runtime": "*",
63
61
  "@react-native-community/netinfo": "*",
64
- "@types/node": "*",
65
- "@types/react-native": "0.69.6",
66
62
  "immer": "*",
67
- "react": "17.0.2",
68
- "react-hot-loader": "*",
69
- "react-native": "0.68.6",
63
+ "react": "*",
64
+ "react-native": "*",
70
65
  "react-native-fs": "*",
71
66
  "react-native-gesture-handler": "*",
72
67
  "react-native-linear-gradient": "*",
@@ -55,6 +55,11 @@ const useMuteUnmuteListeners = (playerId, player, asset, setImageUri) =>
55
55
  return;
56
56
  }
57
57
 
58
+ // initial state setup - show correct mute/unmute icon based on current state
59
+ if (player?.playerState?.isReadyToPlay) {
60
+ setImageUri(player.getIsMuted() ? asset.active : asset.inactive);
61
+ }
62
+
58
63
  // active action = muted, inactive = unmuted
59
64
  return player.addListener({
60
65
  id: liveImageButtonsListenerKey,
@@ -73,10 +78,17 @@ const useMuteUnmuteListeners = (playerId, player, asset, setImageUri) =>
73
78
  setImageUri(player?.getIsMuted() ? asset.active : asset.inactive);
74
79
  },
75
80
  onPlayerClose: () => {
76
- setImageUri(null);
81
+ if (isCurrentPlayer(playerId)) {
82
+ setImageUri(null);
83
+ }
77
84
  },
78
85
  onVideoEnd: () => {
79
- setImageUri(null);
86
+ if (isCurrentPlayer(playerId)) {
87
+ setImageUri(null);
88
+ }
89
+ },
90
+ onPlayerResume: () => {
91
+ setImageUri(player?.getIsMuted() ? asset.active : asset.inactive);
80
92
  },
81
93
  },
82
94
  });
@@ -93,7 +105,7 @@ const styles = StyleSheet.create({
93
105
  },
94
106
  });
95
107
 
96
- export function AssetComponent(props: CellActionAssetComponentProps) {
108
+ function AssetImage(props: CellActionAssetComponentProps) {
97
109
  const { cellUUID: playerId, asset } = props;
98
110
  const [imageUri, setImageUri] = useState<Asset>(null);
99
111
 
@@ -108,3 +120,5 @@ export function AssetComponent(props: CellActionAssetComponentProps) {
108
120
 
109
121
  return <View />;
110
122
  }
123
+
124
+ export const AssetComponent = React.memo(AssetImage);
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { Text, TextStyle, View } from "react-native";
2
+ import { Text, TextStyle } from "react-native";
3
3
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
4
4
 
5
5
  type AudioDescriptionProps = {
@@ -13,8 +13,6 @@ type AudioDescriptionProps = {
13
13
  value: GetValue;
14
14
  };
15
15
 
16
- const containerStyles = { paddingTop: 32, paddingBottom: 12 };
17
-
18
16
  const titleStyles = (value: GetValue, prefix: string): TextStyle => ({
19
17
  textAlign: "left",
20
18
  color: value(`${prefix}title_color`),
@@ -83,13 +81,13 @@ export const AudioDescription = (props: AudioDescriptionProps) => {
83
81
  const prefix = layoutState.docked ? "docked_player_" : "";
84
82
 
85
83
  return (
86
- <View style={containerStyles}>
84
+ <>
87
85
  <Text style={titleStyles(value, prefix)} numberOfLines={1}>
88
86
  {title}
89
87
  </Text>
90
- <Text style={summaryStyles(value, prefix)} numberOfLines={2}>
88
+ <Text style={summaryStyles(value, prefix)} numberOfLines={1}>
91
89
  {summary}
92
90
  </Text>
93
- </View>
91
+ </>
94
92
  );
95
93
  };
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { ViewStyle, View } from "react-native";
2
+ import { ViewStyle, View, Dimensions as ScreenDimensions } 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";
@@ -25,21 +25,18 @@ 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
- import {
31
- speed_0_8,
32
- speed_1,
33
- speed_1_2,
34
- speed_1_5,
35
- speed_2,
36
- } from "@applicaster/quick-brick-mobile-transport-controls";
30
+
37
31
  import {
38
32
  SleepTimerController,
39
33
  SleepTimerState,
40
34
  SLEEP_TIMER_OFF,
41
35
  } from "./SleepTimerManager";
42
36
  import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
37
+ import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
38
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
39
+ import { openBottomSheetModal } from "@applicaster/zapp-react-native-utils/modalState";
43
40
 
44
41
  const { log_debug } = createLogger({
45
42
  subsystem: "UIComponent",
@@ -57,6 +54,7 @@ type Configuration = {
57
54
  [key: string]: any;
58
55
  magic_background?: boolean;
59
56
  audio_player_background_image_query?: string;
57
+ audio_player_background_image_default_color?: string;
60
58
  tablet_landscape_sidebar_width?: string;
61
59
  tablet_landscape_player_container_background_color?: string;
62
60
  };
@@ -78,8 +76,7 @@ type Props = {
78
76
  isTabletPortrait?: boolean;
79
77
  };
80
78
 
81
- export const defaultAspectRatioWidth = (height: number): number =>
82
- (height / 9) * 16;
79
+ const { width: SCREEN_WIDTH } = ScreenDimensions.get("screen");
83
80
 
84
81
  const Styles = {
85
82
  mainContainer: (style: ViewStyle) => {
@@ -105,7 +102,11 @@ const Styles = {
105
102
  height: 96,
106
103
  marginHorizontal: 24,
107
104
  },
108
- playerDetails: { marginTop: 60 },
105
+ playerDetails: {
106
+ marginTop: 60,
107
+ alignSelf: "center",
108
+ width: SCREEN_WIDTH - PADDING_HORIZONTAL * 2,
109
+ },
109
110
 
110
111
  linearGradient: {
111
112
  flex: 1,
@@ -123,9 +124,20 @@ const sleeps = [
123
124
  { label: "2 hours", value: 120 },
124
125
  ];
125
126
 
127
+ const speeds = [
128
+ { label: "0.8x", value: 0.8 },
129
+ { label: "1x", value: 1.0 },
130
+ { label: "1.2x", value: 1.2 },
131
+ { label: "1.5x", value: 1.5 },
132
+ { label: "2x", value: 2.0 },
133
+ ];
134
+
135
+ const edges: Edge[] = ["right", "left", "top"];
136
+
126
137
  export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
127
138
  const player = usePlayer();
128
139
  const playerState = usePlayerState("audio-player-wrapper");
140
+ const theme = useTheme();
129
141
 
130
142
  const {
131
143
  docked,
@@ -138,14 +150,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
138
150
  isTabletPortrait,
139
151
  } = props;
140
152
 
141
- const speeds = [
142
- { asset: configuration["speed_0_8"] || speed_0_8, value: 0.8 },
143
- { asset: configuration["speed_1"] || speed_1, value: 1.0 },
144
- { asset: configuration["speed_1_2"] || speed_1_2, value: 1.2 },
145
- { asset: configuration["speed_1_5"] || speed_1_5, value: 1.5 },
146
- { asset: configuration["speed_2"] || speed_2, value: 2.0 },
147
- ];
148
-
149
153
  const isTablet = useIsTablet();
150
154
 
151
155
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
@@ -193,8 +197,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
193
197
  height: 0,
194
198
  });
195
199
 
196
- const navigator = useNavigation();
197
-
198
200
  const { maximiseVideoModal } = useNavigation();
199
201
 
200
202
  const onLayout = (event: any) => {
@@ -284,7 +286,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
284
286
  );
285
287
 
286
288
  const onSpeedButtonPress = React.useCallback(() => {
287
- navigator.openModalBottomSheet({
289
+ openBottomSheetModal({
288
290
  modalBottomSheetContentProps: {
289
291
  items: speeds,
290
292
  current_selection: playbackSpeed,
@@ -298,13 +300,12 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
298
300
  }, [
299
301
  playbackSpeed,
300
302
  setPlaybackSpeed,
301
- navigator,
302
303
  onSpeedSelect,
303
304
  configuration["playback_speed_title"],
304
305
  ]);
305
306
 
306
307
  const onSleepButtonPress = React.useCallback(() => {
307
- navigator.openModalBottomSheet({
308
+ openBottomSheetModal({
308
309
  modalBottomSheetContentProps: {
309
310
  items: [
310
311
  {
@@ -321,7 +322,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
321
322
  },
322
323
  });
323
324
  }, [
324
- navigator,
325
325
  sleepTimerState.timer,
326
326
  configuration["playback_sleep_title"],
327
327
  configuration["playback_sleep_off_label"],
@@ -355,13 +355,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
355
355
  player?.seekTo(0);
356
356
  }, [player]);
357
357
 
358
- const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
359
-
360
- const ContainerView = SafeAreaView;
361
-
362
358
  const MainContent = React.useMemo(() => {
363
359
  return (
364
- <ContainerView style={Styles.mainContainer(style)} edges={edges}>
360
+ <SafeAreaView style={Styles.mainContainer(style)} edges={edges}>
365
361
  <AnimationComponent
366
362
  animationType={ComponentAnimationType.moveUpComponent}
367
363
  additionalData={{ saveArea: true }}
@@ -416,7 +412,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
416
412
  </View>
417
413
  </AnimatedScrollModal>
418
414
  </AnimationComponent>
419
- </ContainerView>
415
+ </SafeAreaView>
420
416
  );
421
417
  }, [
422
418
  docked,
@@ -442,21 +438,26 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
442
438
  ]);
443
439
 
444
440
  if (configuration.magic_background) {
445
- const baseUrl = entry?.extensions?.audio_player_background_image ?? "";
441
+ const baseUrl = imageSrcFromMediaItem(entry, null);
446
442
 
447
443
  const queryParamName =
448
444
  configuration.audio_player_background_image_query || "width";
449
445
 
446
+ const defaultBackgroundColor =
447
+ configuration.audio_player_background_image_default_color ||
448
+ theme?.app_background_color;
449
+
450
450
  const queryParamValue = 15;
451
451
 
452
- const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
452
+ const url =
453
+ baseUrl && addQueryParam(baseUrl, queryParamName, queryParamValue);
453
454
 
454
455
  return (
455
456
  <MagicBG
456
457
  image={url}
457
458
  fallbackUrl={baseUrl}
458
459
  colors={entry?.extensions?.backgroundColors}
459
- defaultColor="#000000"
460
+ defaultColor={defaultBackgroundColor}
460
461
  >
461
462
  {MainContent}
462
463
  </MagicBG>
@@ -0,0 +1,27 @@
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
+
19
+ ...withDebug({ backgroundColor: "red" }),
20
+ },
21
+ });
22
+
23
+ export const VerticalGutter = () => {
24
+ const isTablet = useIsTablet();
25
+
26
+ return <View style={isTablet ? styles.fixedHeight : styles.flexingHeight} />;
27
+ };
@@ -0,0 +1,305 @@
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
+ const styles = StyleSheet.create({
33
+ flex: {
34
+ flex: 1,
35
+ },
36
+ nonFlex: {
37
+ flex: 0,
38
+ },
39
+ progressBar: {
40
+ flex: 0,
41
+ },
42
+ });
43
+
44
+ const controlsStyles = ({
45
+ isTablet,
46
+ isLiveShowFullControls,
47
+ }: {
48
+ isTablet: boolean;
49
+ isLiveShowFullControls: boolean;
50
+ }) => ({
51
+ height: isTablet ? undefined : 50,
52
+ marginHorizontal: isTablet ? undefined : 10,
53
+ justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
54
+ });
55
+
56
+ type Props = {
57
+ entry: ZappEntry;
58
+ layoutState: QuickBrickPlayer.LayoutState;
59
+ playerState: QuickBrickPlayer.PlayerState;
60
+ value: GetValue;
61
+ title: string | number;
62
+ summary: string | number;
63
+ sleepTimerDate: number;
64
+ cancelSleepTimer: Callback;
65
+
66
+ playbackSpeedName: string;
67
+ playbackSleepName: string;
68
+
69
+ onPlaybackButtonPress: Callback;
70
+ onRewindButtonPress: Callback;
71
+ onForwardButtonPress: Callback;
72
+ onPlayerSeek: (targetTime: number) => void;
73
+ onSkipStart: Callback;
74
+ onSkipLive: Callback;
75
+ onSpeedButtonPress: Callback;
76
+ onSleepButtonPress: Callback;
77
+
78
+ docked: boolean;
79
+ };
80
+
81
+ export const Controls = (props: Props) => {
82
+ const {
83
+ entry,
84
+ layoutState,
85
+ playerState,
86
+ value,
87
+ title,
88
+ summary,
89
+ sleepTimerDate,
90
+ cancelSleepTimer,
91
+
92
+ playbackSpeedName,
93
+ playbackSleepName,
94
+
95
+ onPlaybackButtonPress,
96
+ onRewindButtonPress,
97
+ onForwardButtonPress,
98
+ onPlayerSeek,
99
+ onSkipStart,
100
+ onSkipLive,
101
+ onSpeedButtonPress,
102
+ onSleepButtonPress,
103
+
104
+ docked,
105
+ } = props;
106
+
107
+ const isTablet = useIsTablet();
108
+ const controller = playerManager.getActivePlayer();
109
+ let showFullControls = !controller?.isAd();
110
+ const liveButton = Boolean(value("live_badge_enabled"));
111
+
112
+ const isLiveContent = playerState.isLive;
113
+
114
+ if (isLiveContent) {
115
+ const seekEnabled = Boolean(value("liveSeekingEnabled"));
116
+
117
+ showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
118
+ }
119
+
120
+ const sleepTitle = value("playback_sleep_countdown_label");
121
+
122
+ const [timeLeft, setTimeLeft] = React.useState(
123
+ sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
124
+ );
125
+
126
+ const showCounter = React.useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
127
+
128
+ React.useEffect(() => {
129
+ if (showCounter && sleepTimerDate !== 0) {
130
+ setTimeLeft(sleepTimerDate - Date.now());
131
+
132
+ const intervalId = setInterval(() => {
133
+ setTimeLeft(() => {
134
+ const newTimeLeft = sleepTimerDate - Date.now();
135
+
136
+ if (newTimeLeft <= 0) {
137
+ clearInterval(intervalId);
138
+
139
+ cancelSleepTimer();
140
+
141
+ return 0;
142
+ } else {
143
+ return newTimeLeft;
144
+ }
145
+ });
146
+ }, 1000);
147
+
148
+ return () => clearInterval(intervalId);
149
+ } else {
150
+ setTimeLeft(0);
151
+ }
152
+ }, [sleepTimerDate, showCounter, cancelSleepTimer]);
153
+
154
+ const startTime = entry.extensions?.live?.start_time;
155
+ const endTime = entry.extensions?.live?.end_time;
156
+
157
+ const hasValidStartTime = isValidDate(startTime);
158
+ const hasValidEndTime = isValidDate(endTime);
159
+
160
+ const isDateBasedLiveContent =
161
+ isLiveContent && hasValidStartTime && hasValidEndTime;
162
+
163
+ const needsToShowProgressBar =
164
+ (isLiveContent &&
165
+ (Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
166
+ !isLiveContent;
167
+
168
+ const startTimestamp = hasValidStartTime
169
+ ? dayjs.utc(startTime!).valueOf()
170
+ : undefined;
171
+
172
+ const endTimestamp = hasValidEndTime
173
+ ? dayjs.utc(endTime!).valueOf()
174
+ : undefined;
175
+
176
+ const isLiveShowFullControls = showFullControls && isLiveContent;
177
+
178
+ const controlButtons = React.useCallback((): Array<ControlsButton> => {
179
+ const play = playbackButton({
180
+ playerState,
181
+ liveButton,
182
+ isTablet,
183
+ isLiveShowFullControls,
184
+ onPress: onPlaybackButtonPress,
185
+ });
186
+
187
+ if (!showFullControls) {
188
+ return [play];
189
+ }
190
+
191
+ const rewind = rewindButton({
192
+ isTablet,
193
+ onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
194
+ });
195
+
196
+ const forward = forwardButton({
197
+ isTablet,
198
+ onPress: controller?.hasSeekableDuration?.()
199
+ ? onForwardButtonPress
200
+ : null,
201
+ });
202
+
203
+ const speed = speedButton({
204
+ isTablet,
205
+ onPress: onSpeedButtonPress,
206
+ name: playbackSpeedName,
207
+ });
208
+
209
+ const sleep = sleepButton({
210
+ isTablet,
211
+ onPress: onSleepButtonPress,
212
+ name: playbackSleepName,
213
+ });
214
+
215
+ if (isLiveContent) {
216
+ const skipToStart = skipToStartButton({
217
+ isTablet,
218
+ onPress: onSkipStart,
219
+ });
220
+
221
+ const skipToLive = skipToLiveButton({
222
+ isTablet,
223
+ onPress: onSkipLive,
224
+ });
225
+
226
+ return [skipToStart, rewind, play, forward, skipToLive];
227
+ }
228
+
229
+ return [speed, rewind, play, forward, sleep];
230
+ }, [
231
+ playerState,
232
+ liveButton,
233
+ isTablet,
234
+ onPlaybackButtonPress,
235
+ onRewindButtonPress,
236
+ onForwardButtonPress,
237
+ onSpeedButtonPress,
238
+ showFullControls,
239
+ onSkipStart,
240
+ onSkipLive,
241
+ isLiveContent,
242
+ playbackSpeedName,
243
+ playbackSleepName,
244
+ controller,
245
+ isLiveShowFullControls,
246
+ ]);
247
+
248
+ if (docked) {
249
+ return null;
250
+ }
251
+
252
+ return (
253
+ <AnimationComponent
254
+ animationType={ComponentAnimationType.componentFade}
255
+ style={isTablet ? styles.nonFlex : styles.flex}
256
+ >
257
+ <VerticalGutter />
258
+
259
+ <AudioDescription
260
+ title={title}
261
+ summary={summary}
262
+ value={value}
263
+ layoutState={layoutState}
264
+ />
265
+
266
+ <VerticalGutter />
267
+
268
+ {needsToShowProgressBar ? (
269
+ <>
270
+ <ProgressBar
271
+ name={"audio-default-layout"}
272
+ content={entry}
273
+ value={value}
274
+ visible
275
+ layoutState={layoutState}
276
+ onPlayerSeek={onPlayerSeek}
277
+ playerState={playerState}
278
+ disableFullscreen
279
+ sliderStyle={2}
280
+ startTimestamp={startTimestamp}
281
+ endTimestamp={endTimestamp}
282
+ isDateBasedLiveContent={isDateBasedLiveContent}
283
+ onSkipLive={onSkipLive}
284
+ progressBarStyles={styles.progressBar}
285
+ />
286
+
287
+ {showCounter && timeLeft >= 0 ? (
288
+ <CountDown timeLeft={timeLeft} value={value} title={sleepTitle} />
289
+ ) : null}
290
+
291
+ <VerticalGutter />
292
+ </>
293
+ ) : null}
294
+
295
+ <MobileTransportControls
296
+ value={value}
297
+ visible={true}
298
+ keepAlive={null}
299
+ buttons={controlButtons}
300
+ style={controlsStyles({ isTablet, isLiveShowFullControls })}
301
+ playerState={playerState}
302
+ />
303
+ </AnimationComponent>
304
+ );
305
+ };
@@ -1,12 +1,3 @@
1
- type PlayerState = {
2
- currentTime: number;
3
- duration: number;
4
- seekableDuration: number;
5
- isLive: boolean;
6
- isPaused: boolean;
7
- isBuffering: boolean;
8
- };
9
-
10
1
  const rewindButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
11
2
  isTablet ? "big" : "smallMargins";
12
3
 
@@ -17,9 +8,7 @@ const playbackButtonMargins = (
17
8
  isTablet: boolean,
18
9
  isLiveShowFullControls: boolean
19
10
  ): number =>
20
- isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? 95 : 40;
21
-
22
- export const PADDING_HORIZONTAL = 15;
11
+ isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
23
12
 
24
13
  export const playbackButton = ({
25
14
  playerState,
@@ -28,7 +17,7 @@ export const playbackButton = ({
28
17
  isLiveShowFullControls,
29
18
  onPress,
30
19
  }: {
31
- playerState: PlayerState;
20
+ playerState: QuickBrickPlayer.PlayerState;
32
21
  liveButton: boolean;
33
22
  isTablet: boolean;
34
23
  isLiveShowFullControls: boolean;
@@ -57,6 +46,7 @@ type ButtonsProps = {
57
46
  style?: any;
58
47
  name?: string;
59
48
  };
49
+
60
50
  type ButtonsByNameProps = ButtonsProps & { name?: string };
61
51
 
62
52
  const rewindButtonByName = ({