@applicaster/quick-brick-player 13.0.0-rc.12 → 13.0.0-rc.121

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 (44) hide show
  1. package/package.json +27 -14
  2. package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
  3. package/src/Player/AudioLayer/AudioDescription.tsx +107 -68
  4. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +205 -281
  5. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +45 -0
  6. package/src/Player/AudioLayer/Layout/Controls/index.tsx +320 -0
  7. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +7 -25
  8. package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
  9. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +77 -81
  10. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +230 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +70 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +20 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +108 -0
  14. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +36 -0
  15. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +220 -0
  16. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +223 -0
  17. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +128 -0
  18. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  19. package/src/Player/AudioLayer/Layout/const.ts +26 -0
  20. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  21. package/src/Player/AudioLayer/Layout/hooks/index.ts +5 -0
  22. package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
  23. package/src/Player/AudioLayer/Layout/hooks/useTabletLayoutImageSize.ts +105 -0
  24. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  25. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  26. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  27. package/src/Player/AudioLayer/Layout/utils.ts +7 -0
  28. package/src/Player/AudioLayer/SleepTimerManager.ts +119 -0
  29. package/src/Player/AudioLayer/SpeedManager.ts +52 -0
  30. package/src/Player/AudioLayer/utils.ts +27 -0
  31. package/src/Player/Const/sleepTimerOptions.ts +39 -0
  32. package/src/Player/Const/speedOptions.ts +4 -0
  33. package/src/Player/Utils/Utils.ts +0 -5
  34. package/src/Player/Utils/index.tsx +117 -0
  35. package/src/Player/hooks/useIsCasting.tsx +57 -0
  36. package/src/Player/index.tsx +39 -22
  37. package/src/QuickBrickPlayer.tsx +3 -0
  38. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
  39. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.ts +0 -3
  40. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.web.ts +0 -3
  41. package/src/Player/AudioLayer/LinearGradient/index.ts +0 -1
  42. package/src/Player/AudioLayer/MagicBG/index.tsx +0 -155
  43. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
  44. package/src/utils/utils.ts +0 -25
@@ -0,0 +1,320 @@
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
+ maxWidth?: number;
83
+
84
+ docked: boolean;
85
+ };
86
+
87
+ export const Controls = (props: Props) => {
88
+ const {
89
+ entry,
90
+ layoutState,
91
+ playerState,
92
+ value,
93
+ title,
94
+ summary,
95
+ sleepTimerDate,
96
+ cancelSleepTimer,
97
+
98
+ playbackSpeedName,
99
+ playbackSleepName,
100
+
101
+ onPlaybackButtonPress,
102
+ onRewindButtonPress,
103
+ onForwardButtonPress,
104
+ onPlayerSeek,
105
+ onSkipStart,
106
+ onSkipLive,
107
+ onSpeedButtonPress,
108
+ onSleepButtonPress,
109
+ maxWidth = 320,
110
+
111
+ docked,
112
+ } = props;
113
+
114
+ const isTablet = useIsTablet();
115
+ const controller = playerManager.getActivePlayer();
116
+ let showFullControls = !controller?.isAd();
117
+ const liveButton = Boolean(value("live_badge_enabled"));
118
+
119
+ const isLiveContent = playerState.isLive;
120
+
121
+ if (isLiveContent) {
122
+ const seekEnabled = Boolean(value("liveSeekingEnabled"));
123
+
124
+ showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
125
+ }
126
+
127
+ const [timeLeft, setTimeLeft] = React.useState(
128
+ sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
129
+ );
130
+
131
+ const showCounter = React.useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
132
+
133
+ const countDownOptions = React.useMemo(() => {
134
+ return {
135
+ showCounter: showCounter && timeLeft >= 0,
136
+ timeLeft,
137
+ };
138
+ }, [showCounter, timeLeft]);
139
+
140
+ React.useEffect(() => {
141
+ if (showCounter && sleepTimerDate !== 0) {
142
+ setTimeLeft(sleepTimerDate - Date.now());
143
+
144
+ const intervalId = setInterval(() => {
145
+ setTimeLeft(() => {
146
+ const newTimeLeft = sleepTimerDate - Date.now();
147
+
148
+ if (newTimeLeft <= 0) {
149
+ clearInterval(intervalId);
150
+
151
+ cancelSleepTimer();
152
+
153
+ return 0;
154
+ } else {
155
+ return newTimeLeft;
156
+ }
157
+ });
158
+ }, 1000);
159
+
160
+ return () => clearInterval(intervalId);
161
+ } else {
162
+ setTimeLeft(0);
163
+ }
164
+ }, [sleepTimerDate, showCounter, cancelSleepTimer]);
165
+
166
+ const startTime = entry.extensions?.live?.start_time;
167
+ const endTime = entry.extensions?.live?.end_time;
168
+
169
+ const hasValidStartTime = isValidDate(startTime);
170
+ const hasValidEndTime = isValidDate(endTime);
171
+
172
+ const isDateBasedLiveContent =
173
+ isLiveContent && hasValidStartTime && hasValidEndTime;
174
+
175
+ const needsToShowProgressBar =
176
+ (isLiveContent &&
177
+ (Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
178
+ !isLiveContent;
179
+
180
+ const startTimestamp = hasValidStartTime
181
+ ? dayjs.utc(startTime!).valueOf()
182
+ : undefined;
183
+
184
+ const endTimestamp = hasValidEndTime
185
+ ? dayjs.utc(endTime!).valueOf()
186
+ : undefined;
187
+
188
+ const isLiveShowFullControls = showFullControls && isLiveContent;
189
+
190
+ const controlButtons = React.useCallback((): Array<ControlsButton> => {
191
+ const play = playbackButton({
192
+ playerState,
193
+ liveButton,
194
+ isTablet,
195
+ isLiveShowFullControls,
196
+ onPress: onPlaybackButtonPress,
197
+ });
198
+
199
+ if (!showFullControls) {
200
+ return [play];
201
+ }
202
+
203
+ const rewind = rewindButton({
204
+ isTablet,
205
+ onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
206
+ });
207
+
208
+ const forward = forwardButton({
209
+ isTablet,
210
+ onPress: controller?.hasSeekableDuration?.()
211
+ ? onForwardButtonPress
212
+ : null,
213
+ });
214
+
215
+ const speed = speedButton({
216
+ isTablet,
217
+ onPress: onSpeedButtonPress,
218
+ name: playbackSpeedName,
219
+ });
220
+
221
+ const sleep = sleepButton({
222
+ isTablet,
223
+ onPress: onSleepButtonPress,
224
+ name: playbackSleepName,
225
+ });
226
+
227
+ if (isLiveContent) {
228
+ const skipToStart = skipToStartButton({
229
+ isTablet,
230
+ onPress: onSkipStart,
231
+ });
232
+
233
+ const skipToLive = skipToLiveButton({
234
+ isTablet,
235
+ onPress: onSkipLive,
236
+ });
237
+
238
+ return [skipToStart, rewind, play, forward, skipToLive];
239
+ }
240
+
241
+ return [speed, rewind, play, forward, sleep];
242
+ }, [
243
+ playerState,
244
+ liveButton,
245
+ isTablet,
246
+ onPlaybackButtonPress,
247
+ onRewindButtonPress,
248
+ onForwardButtonPress,
249
+ onSpeedButtonPress,
250
+ showFullControls,
251
+ onSkipStart,
252
+ onSkipLive,
253
+ isLiveContent,
254
+ playbackSpeedName,
255
+ playbackSleepName,
256
+ controller,
257
+ isLiveShowFullControls,
258
+ ]);
259
+
260
+ if (docked) {
261
+ return null;
262
+ }
263
+
264
+ return (
265
+ <AnimationComponent
266
+ animationType={ComponentAnimationType.componentFade}
267
+ style={isTablet ? styles.nonFlex : styles.flex}
268
+ >
269
+ <VerticalGutter />
270
+
271
+ <AudioDescription
272
+ title={title}
273
+ summary={summary}
274
+ value={value}
275
+ layoutState={layoutState}
276
+ maxWidth={maxWidth}
277
+ />
278
+
279
+ <VerticalGutter />
280
+
281
+ {needsToShowProgressBar ? (
282
+ <>
283
+ <ProgressBar
284
+ name={"audio-default-layout"}
285
+ content={entry}
286
+ value={value}
287
+ visible
288
+ layoutState={layoutState}
289
+ onPlayerSeek={onPlayerSeek}
290
+ playerState={playerState}
291
+ disableFullscreen
292
+ sliderStyle={2}
293
+ startTimestamp={startTimestamp}
294
+ endTimestamp={endTimestamp}
295
+ isDateBasedLiveContent={isDateBasedLiveContent}
296
+ onSkipLive={onSkipLive}
297
+ progressBarStyles={styles.progressBar}
298
+ countDownOptions={countDownOptions}
299
+ thumbStyles={styles.progressBarThumbStyles}
300
+ thumbStylesPressed={styles.progressBarThumbStyles_pressed}
301
+ trackStyles={styles.progressBarTrackStyles}
302
+ />
303
+
304
+ <VerticalGutter />
305
+ </>
306
+ ) : null}
307
+
308
+ <MobileTransportControls
309
+ value={value}
310
+ visible={true}
311
+ keepAlive={null}
312
+ buttons={controlButtons}
313
+ style={{
314
+ justifyContent: getControlJustifyContent(controlButtons().length),
315
+ }}
316
+ playerState={playerState}
317
+ />
318
+ </AnimationComponent>
319
+ );
320
+ };
@@ -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 ? 95 : 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;
@@ -37,11 +19,11 @@ export const playbackButton = ({
37
19
  const icon = playerState.isPaused
38
20
  ? "play"
39
21
  : playerState.isLive && liveButton
40
- ? "stop"
41
- : "pause";
22
+ ? "stop"
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,
@@ -0,0 +1,55 @@
1
+ /* eslint react-native/no-color-literals: off */
2
+ /* eslint react-native/no-inline-styles: off */
3
+
4
+ import * as React from "react";
5
+ import { View } from "react-native";
6
+
7
+ import { MOBILE } from "../const";
8
+
9
+ export const LeftDebugSquare = () => (
10
+ <View
11
+ style={{
12
+ position: "absolute",
13
+ top: 200,
14
+ left: 0,
15
+ width: MOBILE.MARGIN_HORIZONTAL,
16
+ height: MOBILE.MARGIN_HORIZONTAL,
17
+ backgroundColor: "blue",
18
+
19
+ borderWidth: 1,
20
+ borderColor: "yellow",
21
+ }}
22
+ />
23
+ );
24
+
25
+ export const RightDebugSquare = () => (
26
+ <View
27
+ style={{
28
+ position: "absolute",
29
+ top: 200,
30
+ right: 0,
31
+ width: MOBILE.MARGIN_HORIZONTAL,
32
+ height: MOBILE.MARGIN_HORIZONTAL,
33
+ backgroundColor: "blue",
34
+
35
+ borderWidth: 1,
36
+ borderColor: "yellow",
37
+ }}
38
+ />
39
+ );
40
+
41
+ export const BottomDebugSquare = () => (
42
+ <View
43
+ style={{
44
+ position: "absolute",
45
+ left: 170,
46
+ bottom: 0,
47
+ width: MOBILE.MARGIN_BOTTOM,
48
+ height: MOBILE.MARGIN_BOTTOM,
49
+ backgroundColor: "blue",
50
+
51
+ borderWidth: 1,
52
+ borderColor: "yellow",
53
+ }}
54
+ />
55
+ );