@applicaster/quick-brick-player 13.0.0-alpha.7586259907 → 13.0.0-alpha.7620873141

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 (33) hide show
  1. package/package.json +5 -6
  2. package/src/Player/AudioLayer/AudioDescription.tsx +5 -7
  3. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +49 -85
  4. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +27 -0
  5. package/src/Player/AudioLayer/Layout/Controls/index.tsx +316 -0
  6. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +5 -23
  7. package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
  8. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +28 -39
  9. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +231 -0
  10. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +83 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +25 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +101 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +26 -0
  14. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +216 -0
  15. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +224 -0
  16. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +114 -0
  17. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  18. package/src/Player/AudioLayer/Layout/const.ts +22 -0
  19. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  20. package/src/Player/AudioLayer/Layout/hooks/index.ts +5 -0
  21. package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
  22. package/src/Player/AudioLayer/Layout/hooks/useTabletLayoutImageSize.ts +105 -0
  23. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  24. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  25. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  26. package/src/Player/AudioLayer/utils.ts +6 -3
  27. package/src/Player/Const/sleepTimerOptions.ts +39 -0
  28. package/src/Player/Const/speedOptions.ts +4 -0
  29. package/src/Player/Utils/Utils.ts +0 -5
  30. package/src/Player/Utils/index.tsx +117 -0
  31. package/src/Player/index.tsx +4 -1
  32. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -495
  33. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "13.0.0-alpha.7586259907",
3
+ "version": "13.0.0-alpha.7620873141",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -35,12 +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.88",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-rc.99",
39
39
  "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.7586259907",
41
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.7586259907",
42
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7586259907",
43
- "keymirror": "^0.1.1",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.7620873141",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.7620873141",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7620873141",
44
43
  "query-string": "7.1.3",
45
44
  "react-native-web-linear-gradient": "1.1.2",
46
45
  "shaka-player": "4.3.5",
@@ -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}>
87
- <Text style={titleStyles(value, prefix)} numberOfLines={1}>
84
+ <>
85
+ <Text style={titleStyles(value, prefix)} numberOfLines={2}>
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,10 @@
1
1
  import * as React from "react";
2
- import { ViewStyle, View, Dimensions as ScreenDimensions } from "react-native";
2
+ import {
3
+ StyleSheet,
4
+ ViewStyle,
5
+ View,
6
+ Dimensions as ScreenDimensions,
7
+ } from "react-native";
3
8
 
4
9
  import { SafeAreaView, Edge } from "react-native-safe-area-context";
5
10
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
@@ -18,22 +23,22 @@ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
18
23
  import { useEffect, useState } from "react";
19
24
  import { MagicBG } from "./MagicBG";
20
25
  import { formatSpeed } from "./utils";
21
- import { addQueryParam, getLiveUrl } from "../Utils";
26
+ import {
27
+ addQueryParam,
28
+ getBottomSheetModalDefaultItemIcon,
29
+ getBottomSheetModalIconProps,
30
+ getBottomSheetModalItemProps,
31
+ getBottomSheetModalLabelProps,
32
+ getBottomSheetModalSelectedItemIcon,
33
+ } from "../Utils";
22
34
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
35
  import {
24
36
  AnimationComponent,
25
37
  ComponentAnimationType,
26
38
  AnimatedScrollModal,
27
39
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
28
- import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
40
+ import { PADDING_HORIZONTAL } from "./Layout/const";
29
41
  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";
37
42
  import {
38
43
  SleepTimerController,
39
44
  SleepTimerState,
@@ -42,6 +47,9 @@ import {
42
47
  import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
43
48
  import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
44
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";
52
+ import { speedOptions } from "../Const/speedOptions";
45
53
 
46
54
  const { log_debug } = createLogger({
47
55
  subsystem: "UIComponent",
@@ -83,51 +91,17 @@ type Props = {
83
91
 
84
92
  const { width: SCREEN_WIDTH } = ScreenDimensions.get("screen");
85
93
 
86
- const Styles = {
87
- mainContainer: (style: ViewStyle) => {
88
- const combinedStyle: ViewStyle = {
89
- flex: 1,
90
- };
91
-
92
- return {
93
- ...combinedStyle,
94
- ...style,
95
- };
96
- },
94
+ const Styles = StyleSheet.create({
97
95
  playerContainer: {
98
96
  flex: 1,
99
97
  },
100
98
  paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
101
-
102
- controlsMobile: {
103
- height: 50,
104
- marginHorizontal: 24,
105
- },
106
- controlsTablet: {
107
- height: 96,
108
- marginHorizontal: 24,
109
- },
110
99
  playerDetails: {
111
100
  marginTop: 60,
112
101
  alignSelf: "center",
113
102
  width: SCREEN_WIDTH - PADDING_HORIZONTAL * 2,
114
103
  },
115
-
116
- linearGradient: {
117
- flex: 1,
118
- },
119
- };
120
-
121
- const sleeps = [
122
- // { label: "End of episode", value: "episode" },
123
- { label: "5 minutes", value: 5 },
124
- { label: "10 minutes", value: 10 },
125
- { label: "15 minutes", value: 15 },
126
- { label: "30 minutes", value: 30 },
127
- { label: "45 minutes", value: 45 },
128
- { label: "1 hour", value: 60 },
129
- { label: "2 hours", value: 120 },
130
- ];
104
+ });
131
105
 
132
106
  const edges: Edge[] = ["right", "left", "top"];
133
107
 
@@ -147,24 +121,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
147
121
  isTabletPortrait,
148
122
  } = props;
149
123
 
150
- const speeds = [
151
- { asset: configuration["speed_0_8"] || speed_0_8, value: 0.8 },
152
- { asset: configuration["speed_1"] || speed_1, value: 1.0 },
153
- { asset: configuration["speed_1_2"] || speed_1_2, value: 1.2 },
154
- { asset: configuration["speed_1_5"] || speed_1_5, value: 1.5 },
155
- { asset: configuration["speed_2"] || speed_2, value: 2.0 },
156
- ];
157
-
158
124
  const isTablet = useIsTablet();
159
125
 
160
126
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
161
127
 
162
- // TODO: Have generic place for live url from configuration. Currently its hardcoded for client.
163
-
164
- const feedUrl = getLiveUrl(entry?.extensions?.live?.channel_src ?? "");
165
-
166
128
  const { title, summary } = useTitleSummaryOverlay(
167
- feedUrl,
168
129
  entry,
169
130
  playerState?.isLive,
170
131
  configuration?.audio_live_player_update_interval
@@ -202,8 +163,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
202
163
  height: 0,
203
164
  });
204
165
 
205
- const navigator = useNavigation();
206
-
207
166
  const { maximiseVideoModal } = useNavigation();
208
167
 
209
168
  const onLayout = (event: any) => {
@@ -293,44 +252,51 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
293
252
  );
294
253
 
295
254
  const onSpeedButtonPress = React.useCallback(() => {
296
- navigator.openModalBottomSheet({
255
+ openBottomSheetModal({
297
256
  modalBottomSheetContentProps: {
298
- items: speeds,
257
+ items: speedOptions,
299
258
  current_selection: playbackSpeed,
300
259
  onPress: onSpeedSelect,
301
260
  title: configuration["playback_speed_title"],
261
+ itemProps: getBottomSheetModalItemProps,
262
+ iconProps: getBottomSheetModalIconProps,
263
+ labelProps: getBottomSheetModalLabelProps,
264
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
265
+ getDefaultItemIcon: getBottomSheetModalDefaultItemIcon,
266
+ iconPlacement: "right",
302
267
  },
303
268
  options: {
304
- supportedOrientations: ["portrait"],
269
+ supportedOrientations: [
270
+ "portrait",
271
+ "landscape",
272
+ "portrait-upside-down",
273
+ ],
305
274
  },
306
275
  });
307
- }, [
308
- playbackSpeed,
309
- setPlaybackSpeed,
310
- navigator,
311
- onSpeedSelect,
312
- configuration["playback_speed_title"],
313
- ]);
276
+ }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
314
277
 
315
278
  const onSleepButtonPress = React.useCallback(() => {
316
- navigator.openModalBottomSheet({
279
+ openBottomSheetModal({
317
280
  modalBottomSheetContentProps: {
318
- items: [
319
- {
320
- label: configuration["playback_sleep_off_label"],
321
- value: 0,
322
- },
323
- ].concat(sleeps),
281
+ items: getSleepTimerOptions(configuration),
324
282
  current_selection: sleepTimerState.timer,
325
283
  onPress: onSleepSelect,
326
284
  title: configuration["playback_sleep_title"],
285
+ itemProps: getBottomSheetModalItemProps,
286
+ iconProps: getBottomSheetModalIconProps,
287
+ labelProps: getBottomSheetModalLabelProps,
288
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
289
+ iconPlacement: "right",
327
290
  },
328
291
  options: {
329
- supportedOrientations: ["portrait"],
292
+ supportedOrientations: [
293
+ "portrait",
294
+ "landscape",
295
+ "portrait-upside-down",
296
+ ],
330
297
  },
331
298
  });
332
299
  }, [
333
- navigator,
334
300
  sleepTimerState.timer,
335
301
  configuration["playback_sleep_title"],
336
302
  configuration["playback_sleep_off_label"],
@@ -364,11 +330,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
364
330
  player?.seekTo(0);
365
331
  }, [player]);
366
332
 
367
- const ContainerView = SafeAreaView;
368
-
369
333
  const MainContent = React.useMemo(() => {
370
334
  return (
371
- <ContainerView style={Styles.mainContainer(style)} edges={edges}>
335
+ <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
372
336
  <AnimationComponent
373
337
  animationType={ComponentAnimationType.moveUpComponent}
374
338
  additionalData={{ saveArea: true }}
@@ -412,18 +376,18 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
412
376
  animationType={ComponentAnimationType.componentFade}
413
377
  >
414
378
  <PlayerDetails
379
+ isAudioPlayer
415
380
  configuration={configuration}
416
381
  style={Styles.playerDetails}
417
382
  entry={entry}
418
383
  isTabletLandscape={isTabletLandscape}
419
- isAudioPlayer={true}
420
384
  />
421
385
  </AnimationComponent>
422
386
  </View>
423
387
  </View>
424
388
  </AnimatedScrollModal>
425
389
  </AnimationComponent>
426
- </ContainerView>
390
+ </SafeAreaView>
427
391
  );
428
392
  }, [
429
393
  docked,
@@ -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,316 @@
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
+ ProgressBar,
9
+ } from "@applicaster/quick-brick-mobile-transport-controls";
10
+ import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
11
+
12
+ import {
13
+ AnimationComponent,
14
+ ComponentAnimationType,
15
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
16
+
17
+ import { AudioDescription } from "../../AudioDescription";
18
+ import { isValidDate } from "../../../Utils";
19
+ import { VerticalGutter } from "./VerticalGutter";
20
+
21
+ import {
22
+ forwardButton,
23
+ playbackButton,
24
+ rewindButton,
25
+ skipToLiveButton,
26
+ skipToStartButton,
27
+ sleepButton,
28
+ speedButton,
29
+ } from "./utils";
30
+
31
+ const styles = StyleSheet.create({
32
+ flex: {
33
+ flex: 1,
34
+ },
35
+ nonFlex: {
36
+ flex: 0,
37
+ },
38
+ progressBar: {
39
+ flex: 0,
40
+ },
41
+ progressBarTrackStyles: {
42
+ borderRadius: 3,
43
+ height: 6,
44
+ },
45
+ progressBarThumbStyles: {
46
+ width: 14,
47
+ height: 14,
48
+ borderRadius: 7,
49
+ },
50
+ progressBarThumbStyles_pressed: {
51
+ width: 20,
52
+ height: 20,
53
+ borderRadius: 10,
54
+ },
55
+ });
56
+
57
+ const getControlJustifyContent = (countOfButtons: number) =>
58
+ countOfButtons <= 1 ? "center" : "space-between";
59
+
60
+ type Props = {
61
+ entry: ZappEntry;
62
+ layoutState: QuickBrickPlayer.LayoutState;
63
+ playerState: QuickBrickPlayer.PlayerState;
64
+ value: GetValue;
65
+ title: string | number;
66
+ summary: string | number;
67
+ sleepTimerDate: number;
68
+ cancelSleepTimer: Callback;
69
+
70
+ playbackSpeedName: string;
71
+ playbackSleepName: string;
72
+
73
+ onPlaybackButtonPress: Callback;
74
+ onRewindButtonPress: Callback;
75
+ onForwardButtonPress: Callback;
76
+ onPlayerSeek: (targetTime: number) => void;
77
+ onSkipStart: Callback;
78
+ onSkipLive: Callback;
79
+ onSpeedButtonPress: Callback;
80
+ onSleepButtonPress: Callback;
81
+
82
+ docked: boolean;
83
+ };
84
+
85
+ export const Controls = (props: Props) => {
86
+ const {
87
+ entry,
88
+ layoutState,
89
+ playerState,
90
+ value,
91
+ title,
92
+ summary,
93
+ sleepTimerDate,
94
+ cancelSleepTimer,
95
+
96
+ playbackSpeedName,
97
+ playbackSleepName,
98
+
99
+ onPlaybackButtonPress,
100
+ onRewindButtonPress,
101
+ onForwardButtonPress,
102
+ onPlayerSeek,
103
+ onSkipStart,
104
+ onSkipLive,
105
+ onSpeedButtonPress,
106
+ onSleepButtonPress,
107
+
108
+ docked,
109
+ } = props;
110
+
111
+ const isTablet = useIsTablet();
112
+ const controller = playerManager.getActivePlayer();
113
+ let showFullControls = !controller?.isAd();
114
+ const liveButton = Boolean(value("live_badge_enabled"));
115
+
116
+ const isLiveContent = playerState.isLive;
117
+
118
+ if (isLiveContent) {
119
+ const seekEnabled = Boolean(value("liveSeekingEnabled"));
120
+
121
+ showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
122
+ }
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
+ const countDownOptions = React.useMemo(() => {
131
+ return {
132
+ showCounter: showCounter && timeLeft >= 0,
133
+ timeLeft,
134
+ };
135
+ }, [showCounter, timeLeft]);
136
+
137
+ React.useEffect(() => {
138
+ if (showCounter && sleepTimerDate !== 0) {
139
+ setTimeLeft(sleepTimerDate - Date.now());
140
+
141
+ const intervalId = setInterval(() => {
142
+ setTimeLeft(() => {
143
+ const newTimeLeft = sleepTimerDate - Date.now();
144
+
145
+ if (newTimeLeft <= 0) {
146
+ clearInterval(intervalId);
147
+
148
+ cancelSleepTimer();
149
+
150
+ return 0;
151
+ } else {
152
+ return newTimeLeft;
153
+ }
154
+ });
155
+ }, 1000);
156
+
157
+ return () => clearInterval(intervalId);
158
+ } else {
159
+ setTimeLeft(0);
160
+ }
161
+ }, [sleepTimerDate, showCounter, cancelSleepTimer]);
162
+
163
+ const startTime = entry.extensions?.live?.start_time;
164
+ const endTime = entry.extensions?.live?.end_time;
165
+
166
+ const hasValidStartTime = isValidDate(startTime);
167
+ const hasValidEndTime = isValidDate(endTime);
168
+
169
+ const isDateBasedLiveContent =
170
+ isLiveContent && hasValidStartTime && hasValidEndTime;
171
+
172
+ const needsToShowProgressBar =
173
+ (isLiveContent &&
174
+ (Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
175
+ !isLiveContent;
176
+
177
+ const startTimestamp = hasValidStartTime
178
+ ? dayjs.utc(startTime!).valueOf()
179
+ : undefined;
180
+
181
+ const endTimestamp = hasValidEndTime
182
+ ? dayjs.utc(endTime!).valueOf()
183
+ : undefined;
184
+
185
+ const isLiveShowFullControls = showFullControls && isLiveContent;
186
+
187
+ const controlButtons = React.useCallback((): Array<ControlsButton> => {
188
+ const play = playbackButton({
189
+ playerState,
190
+ liveButton,
191
+ isTablet,
192
+ isLiveShowFullControls,
193
+ onPress: onPlaybackButtonPress,
194
+ });
195
+
196
+ if (!showFullControls) {
197
+ return [play];
198
+ }
199
+
200
+ const rewind = rewindButton({
201
+ isTablet,
202
+ onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
203
+ });
204
+
205
+ const forward = forwardButton({
206
+ isTablet,
207
+ onPress: controller?.hasSeekableDuration?.()
208
+ ? onForwardButtonPress
209
+ : null,
210
+ });
211
+
212
+ const speed = speedButton({
213
+ isTablet,
214
+ onPress: onSpeedButtonPress,
215
+ name: playbackSpeedName,
216
+ });
217
+
218
+ const sleep = sleepButton({
219
+ isTablet,
220
+ onPress: onSleepButtonPress,
221
+ name: playbackSleepName,
222
+ });
223
+
224
+ if (isLiveContent) {
225
+ const skipToStart = skipToStartButton({
226
+ isTablet,
227
+ onPress: onSkipStart,
228
+ });
229
+
230
+ const skipToLive = skipToLiveButton({
231
+ isTablet,
232
+ onPress: onSkipLive,
233
+ });
234
+
235
+ return [skipToStart, rewind, play, forward, skipToLive];
236
+ }
237
+
238
+ return [speed, rewind, play, forward, sleep];
239
+ }, [
240
+ playerState,
241
+ liveButton,
242
+ isTablet,
243
+ onPlaybackButtonPress,
244
+ onRewindButtonPress,
245
+ onForwardButtonPress,
246
+ onSpeedButtonPress,
247
+ showFullControls,
248
+ onSkipStart,
249
+ onSkipLive,
250
+ isLiveContent,
251
+ playbackSpeedName,
252
+ playbackSleepName,
253
+ controller,
254
+ isLiveShowFullControls,
255
+ ]);
256
+
257
+ if (docked) {
258
+ return null;
259
+ }
260
+
261
+ return (
262
+ <AnimationComponent
263
+ animationType={ComponentAnimationType.componentFade}
264
+ style={isTablet ? styles.nonFlex : styles.flex}
265
+ >
266
+ <VerticalGutter />
267
+
268
+ <AudioDescription
269
+ title={title}
270
+ summary={summary}
271
+ value={value}
272
+ layoutState={layoutState}
273
+ />
274
+
275
+ <VerticalGutter />
276
+
277
+ {needsToShowProgressBar ? (
278
+ <>
279
+ <ProgressBar
280
+ name={"audio-default-layout"}
281
+ content={entry}
282
+ value={value}
283
+ visible
284
+ layoutState={layoutState}
285
+ onPlayerSeek={onPlayerSeek}
286
+ playerState={playerState}
287
+ disableFullscreen
288
+ sliderStyle={2}
289
+ startTimestamp={startTimestamp}
290
+ endTimestamp={endTimestamp}
291
+ isDateBasedLiveContent={isDateBasedLiveContent}
292
+ onSkipLive={onSkipLive}
293
+ progressBarStyles={styles.progressBar}
294
+ countDownOptions={countDownOptions}
295
+ thumbStyles={styles.progressBarThumbStyles}
296
+ thumbStylesPressed={styles.progressBarThumbStyles_pressed}
297
+ trackStyles={styles.progressBarTrackStyles}
298
+ />
299
+
300
+ <VerticalGutter />
301
+ </>
302
+ ) : null}
303
+
304
+ <MobileTransportControls
305
+ value={value}
306
+ visible={true}
307
+ keepAlive={null}
308
+ buttons={controlButtons}
309
+ style={{
310
+ justifyContent: getControlJustifyContent(controlButtons().length),
311
+ }}
312
+ playerState={playerState}
313
+ />
314
+ </AnimationComponent>
315
+ );
316
+ };
@@ -1,25 +1,7 @@
1
- type PlayerState = {
2
- currentTime: number;
3
- duration: number;
4
- seekableDuration: number;
5
- isLive: boolean;
6
- isPaused: boolean;
7
- isBuffering: boolean;
8
- };
9
-
10
- const rewindButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
11
- isTablet ? "big" : "smallMargins";
12
-
13
- const playbackButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
14
- isTablet ? "bigExtended" : "mediumExtended";
15
-
16
1
  const playbackButtonMargins = (
17
2
  isTablet: boolean,
18
3
  isLiveShowFullControls: boolean
19
- ): number =>
20
- isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
21
-
22
- export const PADDING_HORIZONTAL = 15;
4
+ ): number => (isLiveShowFullControls ? (isTablet ? 65 : 10) : undefined);
23
5
 
24
6
  export const playbackButton = ({
25
7
  playerState,
@@ -28,7 +10,7 @@ export const playbackButton = ({
28
10
  isLiveShowFullControls,
29
11
  onPress,
30
12
  }: {
31
- playerState: PlayerState;
13
+ playerState: QuickBrickPlayer.PlayerState;
32
14
  liveButton: boolean;
33
15
  isTablet: boolean;
34
16
  isLiveShowFullControls: boolean;
@@ -41,7 +23,7 @@ export const playbackButton = ({
41
23
  : "pause";
42
24
 
43
25
  return {
44
- size: playbackButtonSize(isTablet),
26
+ size: "bigExtended",
45
27
  icon: playerState.isBuffering ? "buffering" : icon,
46
28
  preferredFocus: true,
47
29
  onPress,
@@ -57,15 +39,15 @@ type ButtonsProps = {
57
39
  style?: any;
58
40
  name?: string;
59
41
  };
42
+
60
43
  type ButtonsByNameProps = ButtonsProps & { name?: string };
61
44
 
62
45
  const rewindButtonByName = ({
63
46
  name,
64
47
  onPress,
65
- isTablet,
66
48
  style,
67
49
  }: ButtonsByNameProps): ControlsButton => ({
68
- size: rewindButtonSize(isTablet),
50
+ size: "big",
69
51
  icon: name,
70
52
  onPress,
71
53
  style,