@applicaster/quick-brick-player 13.0.0-rc.93 → 13.0.0-rc.95

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 (30) hide show
  1. package/package.json +5 -6
  2. package/src/Player/AudioLayer/AudioDescription.tsx +4 -6
  3. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +36 -66
  4. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +27 -0
  5. package/src/Player/AudioLayer/Layout/Controls/index.tsx +305 -0
  6. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +2 -12
  7. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +28 -39
  8. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +212 -0
  9. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +83 -0
  10. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +32 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +95 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +17 -0
  13. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +214 -0
  14. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +224 -0
  15. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +102 -0
  16. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  17. package/src/Player/AudioLayer/Layout/const.ts +20 -0
  18. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  19. package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -0
  20. package/src/Player/AudioLayer/Layout/hooks/useImageSize.ts +101 -0
  21. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  22. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  23. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  24. package/src/Player/AudioLayer/utils.ts +6 -3
  25. package/src/Player/Const/sleepTimerOptions.ts +10 -0
  26. package/src/Player/Const/speedOptions.ts +4 -0
  27. package/src/Player/Utils/Utils.ts +0 -5
  28. package/src/Player/Utils/index.tsx +117 -0
  29. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -495
  30. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
@@ -1,495 +0,0 @@
1
- import * as React from "react";
2
- import { useEffect, useMemo, useState } from "react";
3
- import * as R from "ramda";
4
- import { View, Dimensions as ScreenDimensions } from "react-native";
5
- import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
6
-
7
- import {
8
- Controls,
9
- CountDown,
10
- ProgressBar,
11
- TransportInfo,
12
- } from "@applicaster/quick-brick-mobile-transport-controls";
13
-
14
- import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
15
-
16
- import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
17
- import {
18
- forwardButton,
19
- PADDING_HORIZONTAL,
20
- playbackButton,
21
- rewindButton,
22
- skipToLiveButton,
23
- skipToStartButton,
24
- sleepButton,
25
- speedButton,
26
- } from "./defaultLayoutsConts";
27
- import { AudioDescription } from "../AudioDescription";
28
- import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
29
- import { useLanguageData } from "@applicaster/zapp-react-native-utils/reactHooks/player";
30
- import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
31
- import {
32
- AnimationComponent,
33
- ComponentAnimationType,
34
- useModalAnimationContext,
35
- } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
36
- import { PlayerAnimationStateT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/ModalAnimationContext";
37
- import DockedLayout from "./DockedLayout";
38
- import { isValidDate } from "../../Utils";
39
- import { calculateBorderRadius } from "../utils";
40
-
41
- const getAudioPlayerWidthForTablet = (isPortraitMode: boolean) =>
42
- isPortraitMode ? 463 : 350;
43
-
44
- type Dimensions = {
45
- width: number;
46
- height: number;
47
- };
48
-
49
- type LayoutProps = {
50
- entry: ZappEntry;
51
- layoutState: {
52
- inline: boolean;
53
- docked: boolean;
54
- isModal: boolean;
55
- };
56
- playerState: {
57
- currentTime: number;
58
- duration: number;
59
- seekableDuration: number;
60
- isLive: boolean;
61
- isPaused: boolean;
62
- isBuffering: boolean;
63
- };
64
- sleepTimerDate: number;
65
- value: GetValue;
66
- playbackSpeedName: string;
67
- playbackSleepName: string;
68
- configuration: { [key: string]: any };
69
- onPlaybackButtonPress: () => void;
70
- onRewindButtonPress: () => void;
71
- onForwardButtonPress: () => void;
72
- onSpeedButtonPress: () => void;
73
- onSleepButtonPress: () => void;
74
- cancelSleepTimer: () => void;
75
- onPlayerSeek: (targetTime: number) => void;
76
- onSkipLive: () => void;
77
- onSkipStart: () => void;
78
- onCloseVideoModal: () => void;
79
- maximiseVideoModal: () => void;
80
- dimensions: Dimensions;
81
- playNextData: PlayNextData;
82
- title: string | number;
83
- summary: string | number;
84
- defaultDimensions: Dimensions;
85
- };
86
-
87
- const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } =
88
- ScreenDimensions.get("screen");
89
-
90
- const Styles = {
91
- container: { flex: 1 },
92
- tabletContainer: (isPortraitMode: boolean) => ({
93
- flex: 1,
94
- alignItems: "center",
95
- justifyContent: isPortraitMode ? "center" : "flex-start",
96
- }),
97
- playerImageWrapper: (docked: boolean) => ({
98
- width: "100%",
99
- maxHeight: 750,
100
- marginTop: docked ? 80 : 20,
101
- }),
102
- playerInfoWrapper: {
103
- flex: 1,
104
- alignItems: "center",
105
- justifyContent: "space-between",
106
- },
107
- tabletLayout: (isPortraitMode: boolean) => ({
108
- width: getAudioPlayerWidthForTablet(isPortraitMode),
109
- marginBottom: 80,
110
- paddingHorizontal: undefined, // override paddingHorizontal
111
- }),
112
- controls: (isTablet: boolean, isLiveShowFullControls: boolean) => ({
113
- height: isTablet ? 64 : 50,
114
- marginHorizontal: isTablet ? undefined : 10,
115
- justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
116
- }),
117
- backgroundImageContainer: (
118
- dimensions: Dimensions,
119
- isTablet: boolean,
120
- isPortraitMode: boolean
121
- ) => {
122
- if (isTablet) {
123
- const size = getAudioPlayerWidthForTablet(isPortraitMode);
124
-
125
- return {
126
- width: size,
127
- height: size,
128
- };
129
- }
130
-
131
- const mobileValue = dimensions?.width
132
- ? dimensions.width - PADDING_HORIZONTAL * 2
133
- : SCREEN_WIDTH - PADDING_HORIZONTAL * 2;
134
-
135
- return {
136
- width: mobileValue,
137
- height: mobileValue,
138
- };
139
- },
140
- backgroundImageContainerImageStyle: (
141
- isTablet: boolean,
142
- docked: boolean,
143
- startComponentsAnimation: boolean,
144
- isActiveGesture: boolean,
145
- playerAnimationState: PlayerAnimationStateT
146
- ) => ({
147
- borderRadius: calculateBorderRadius(
148
- isTablet,
149
- docked,
150
- startComponentsAnimation,
151
- isActiveGesture,
152
- playerAnimationState
153
- ),
154
- }),
155
-
156
- paddingHorizontal: {
157
- paddingHorizontal: PADDING_HORIZONTAL,
158
- },
159
-
160
- controlsMobile: {
161
- height: 50,
162
- marginHorizontal: 24,
163
- },
164
- controlsTablet: {
165
- height: 96,
166
- marginHorizontal: 24,
167
- },
168
- separator: {
169
- height: 20,
170
- },
171
- flexDirectionRow: {
172
- flexDirection: "row",
173
- },
174
- alignItemsCenter: {
175
- alignItems: "center",
176
- },
177
- };
178
-
179
- export default function DefaultLayout(props: LayoutProps) {
180
- const {
181
- entry,
182
- layoutState,
183
- playerState,
184
- value,
185
- onPlaybackButtonPress,
186
- onRewindButtonPress,
187
- onForwardButtonPress,
188
- onPlayerSeek,
189
- onSkipStart,
190
- onSkipLive,
191
- onSpeedButtonPress,
192
- onSleepButtonPress,
193
- playbackSpeedName,
194
- playbackSleepName,
195
- configuration,
196
- dimensions,
197
- cancelSleepTimer,
198
- sleepTimerDate,
199
- title,
200
- summary,
201
- defaultDimensions,
202
- } = props;
203
-
204
- const isTablet = useIsTablet();
205
- const isPortraitMode = SCREEN_WIDTH < SCREEN_HEIGHT;
206
- const isLiveContent = playerState.isLive;
207
- const docked = layoutState.docked;
208
-
209
- const languageData = useLanguageData("audio-player");
210
-
211
- const showCounter = useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
212
-
213
- const controller = playerManager.getActivePlayer();
214
- const liveButton = Boolean(value("live_badge_enabled"));
215
- const sleepTitle = value("playback_sleep_countdown_label");
216
-
217
- const [timeLeft, setTimeLeft] = useState(
218
- sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
219
- );
220
-
221
- let showFullControls = !controller?.isAd();
222
-
223
- const startTime = entry.extensions?.live?.start_time;
224
- const endTime = entry.extensions?.live?.end_time;
225
-
226
- const hasValidStartTime = isValidDate(startTime);
227
- const hasValidEndTime = isValidDate(endTime);
228
-
229
- const isDateBasedLiveContent =
230
- isLiveContent && hasValidStartTime && hasValidEndTime;
231
-
232
- const needsToShowProgressBar =
233
- (isLiveContent &&
234
- (Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
235
- !isLiveContent;
236
-
237
- const startTimestamp = hasValidStartTime
238
- ? dayjs.utc(startTime!).valueOf()
239
- : undefined;
240
-
241
- const endTimestamp = hasValidEndTime
242
- ? dayjs.utc(endTime!).valueOf()
243
- : undefined;
244
-
245
- if (isLiveContent) {
246
- const seekEnabled = Boolean(value("liveSeekingEnabled"));
247
-
248
- showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
249
- }
250
-
251
- const actionButtons = React.useMemo(
252
- () =>
253
- R.compose(
254
- R.take(2),
255
- R.map(R.trim),
256
- R.split(","),
257
- R.propOr("", "player_action_buttons")
258
- )(configuration),
259
- [configuration.player_action_buttons]
260
- );
261
-
262
- const controlButtons = React.useCallback((): Array<ControlsButton> => {
263
- const play = playbackButton({
264
- playerState,
265
- liveButton,
266
- isTablet,
267
- isLiveShowFullControls: showFullControls && isLiveContent,
268
- onPress: onPlaybackButtonPress,
269
- });
270
-
271
- if (!showFullControls) {
272
- return [play];
273
- }
274
-
275
- const rewind = rewindButton({
276
- isTablet,
277
- onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
278
- });
279
-
280
- const forward = forwardButton({
281
- isTablet,
282
- onPress: controller?.hasSeekableDuration?.()
283
- ? onForwardButtonPress
284
- : null,
285
- });
286
-
287
- const speed = speedButton({
288
- isTablet,
289
- onPress: onSpeedButtonPress,
290
- name: playbackSpeedName,
291
- });
292
-
293
- const sleep = sleepButton({
294
- isTablet,
295
- onPress: onSleepButtonPress,
296
- name: playbackSleepName,
297
- });
298
-
299
- if (isLiveContent) {
300
- const skipToStart = skipToStartButton({
301
- isTablet,
302
- onPress: onSkipStart,
303
- });
304
-
305
- const skipToLive = skipToLiveButton({
306
- isTablet,
307
- onPress: onSkipLive,
308
- });
309
-
310
- return [skipToStart, rewind, play, forward, skipToLive];
311
- }
312
-
313
- return [speed, rewind, play, forward, sleep];
314
- }, [
315
- playerState,
316
- liveButton,
317
- isTablet,
318
- onPlaybackButtonPress,
319
- onRewindButtonPress,
320
- onForwardButtonPress,
321
- onSpeedButtonPress,
322
- showFullControls,
323
- onSkipStart,
324
- onSkipLive,
325
- isLiveContent,
326
- playbackSpeedName,
327
- playbackSleepName,
328
- controller,
329
- ]);
330
-
331
- useEffect(() => {
332
- if (showCounter && sleepTimerDate !== 0) {
333
- setTimeLeft(sleepTimerDate - Date.now());
334
-
335
- const intervalId = setInterval(() => {
336
- setTimeLeft(() => {
337
- const newTimeLeft = sleepTimerDate - Date.now();
338
-
339
- if (newTimeLeft <= 0) {
340
- clearInterval(intervalId);
341
-
342
- cancelSleepTimer();
343
-
344
- return 0;
345
- } else {
346
- return newTimeLeft;
347
- }
348
- });
349
- }, 1000);
350
-
351
- return () => clearInterval(intervalId);
352
- } else {
353
- setTimeLeft(0);
354
- }
355
- }, [sleepTimerDate, showCounter, cancelSleepTimer]);
356
-
357
- const Separator = () => <View style={Styles.separator} />;
358
-
359
- const defaultImageDimensions = React.useMemo(
360
- () =>
361
- Styles.backgroundImageContainer(
362
- defaultDimensions,
363
- isTablet,
364
- isPortraitMode
365
- ),
366
- [defaultDimensions, isTablet, isPortraitMode]
367
- );
368
-
369
- const { isActiveGesture, startComponentsAnimation, playerAnimationState } =
370
- useModalAnimationContext();
371
-
372
- return (
373
- <View
374
- style={
375
- isTablet ? Styles.tabletContainer(isPortraitMode) : Styles.container
376
- }
377
- >
378
- <AnimationComponent
379
- animationType={ComponentAnimationType.componentFade}
380
- style={isTablet ? Styles.playerInfoWrapper : undefined}
381
- >
382
- <TransportInfo
383
- content={entry}
384
- value={value}
385
- visible={true}
386
- languageData={languageData}
387
- layoutState={layoutState}
388
- actionButtons={actionButtons}
389
- />
390
- </AnimationComponent>
391
- <AnimationComponent
392
- animationType={ComponentAnimationType.moveUpComponent}
393
- style={isTablet ? Styles.playerImageWrapper(docked) : undefined}
394
- >
395
- <AnimationComponent
396
- animationType={ComponentAnimationType.moveComponentHorizontal}
397
- additionalData={{
398
- disableAnimatedComponent: !isTablet,
399
- moveValue:
400
- (dimensions.width -
401
- getAudioPlayerWidthForTablet(isPortraitMode)) /
402
- 2,
403
- extraAnimation: !isTablet
404
- ? {
405
- [ComponentAnimationType.audioPlayerPaddingHorizontal]: {
406
- style: Styles.paddingHorizontal,
407
- },
408
- }
409
- : null,
410
- }}
411
- style={isTablet ? Styles.alignItemsCenter : undefined}
412
- >
413
- <PlayerImageBackground
414
- entry={entry}
415
- style={Styles.backgroundImageContainer(
416
- dimensions,
417
- isTablet,
418
- isPortraitMode
419
- )}
420
- imageStyle={Styles.backgroundImageContainerImageStyle(
421
- isTablet,
422
- docked,
423
- startComponentsAnimation,
424
- isActiveGesture,
425
- playerAnimationState
426
- )}
427
- defaultImageDimensions={defaultImageDimensions}
428
- />
429
- </AnimationComponent>
430
-
431
- <DockedLayout {...props} />
432
- </AnimationComponent>
433
- <View
434
- style={[
435
- Styles.paddingHorizontal,
436
- isTablet ? Styles.tabletLayout(isPortraitMode) : undefined,
437
- ]}
438
- >
439
- {!docked && (
440
- <AnimationComponent
441
- animationType={ComponentAnimationType.componentFade}
442
- >
443
- <AudioDescription
444
- title={title}
445
- summary={summary}
446
- value={value}
447
- layoutState={layoutState}
448
- />
449
- <Separator />
450
- {needsToShowProgressBar ? (
451
- <View>
452
- <ProgressBar
453
- name={"audio-default-layout"}
454
- content={entry}
455
- value={value}
456
- visible={true}
457
- layoutState={layoutState}
458
- onPlayerSeek={onPlayerSeek}
459
- playerState={playerState}
460
- disableFullscreen={true}
461
- sliderStyle={2}
462
- startTimestamp={startTimestamp}
463
- endTimestamp={endTimestamp}
464
- isDateBasedLiveContent={isDateBasedLiveContent}
465
- onSkipLive={onSkipLive}
466
- />
467
-
468
- {showCounter && timeLeft >= 0 ? (
469
- <CountDown
470
- timeLeft={timeLeft}
471
- value={value}
472
- title={sleepTitle}
473
- />
474
- ) : null}
475
-
476
- <Separator />
477
- </View>
478
- ) : null}
479
- <Controls
480
- value={value}
481
- visible={true}
482
- keepAlive={null}
483
- buttons={controlButtons}
484
- style={Styles.controls(
485
- isTablet,
486
- isLiveContent && showFullControls
487
- )}
488
- playerState={playerState}
489
- />
490
- </AnimationComponent>
491
- )}
492
- </View>
493
- </View>
494
- );
495
- }
@@ -1,7 +0,0 @@
1
- import keyMirror from "keymirror";
2
-
3
- export default keyMirror({
4
- contain: null,
5
- cover: null,
6
- stretch: null,
7
- });