@applicaster/quick-brick-player 13.0.0-rc.10 → 13.0.0-rc.100
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.
- package/package.json +27 -13
- package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
- package/src/Player/AudioLayer/AudioDescription.tsx +5 -7
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +136 -181
- package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +27 -0
- package/src/Player/AudioLayer/Layout/Controls/index.tsx +316 -0
- package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +7 -25
- package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
- package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +44 -67
- package/src/Player/AudioLayer/Layout/MobileLayout.tsx +231 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +83 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +25 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +101 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +26 -0
- package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +216 -0
- package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +224 -0
- package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +114 -0
- package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
- package/src/Player/AudioLayer/Layout/const.ts +22 -0
- package/src/Player/AudioLayer/Layout/debug.ts +6 -0
- package/src/Player/AudioLayer/Layout/hooks/index.ts +5 -0
- package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
- package/src/Player/AudioLayer/Layout/hooks/useTabletLayoutImageSize.ts +105 -0
- package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
- package/src/Player/AudioLayer/Layout/index.tsx +21 -48
- package/src/Player/AudioLayer/Layout/types.ts +7 -0
- package/src/Player/AudioLayer/MagicBG/index.tsx +1 -1
- package/src/Player/AudioLayer/SleepTimerManager.ts +119 -0
- package/src/Player/AudioLayer/SpeedManager.ts +52 -0
- package/src/Player/AudioLayer/utils.ts +27 -0
- package/src/Player/Const/sleepTimerOptions.ts +39 -0
- package/src/Player/Const/speedOptions.ts +4 -0
- package/src/Player/Utils/Utils.ts +0 -5
- package/src/Player/Utils/index.tsx +117 -0
- package/src/Player/index.tsx +31 -19
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
- package/src/Player/Helpers/VideoResizeMode.ts +0 -7
|
@@ -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 ? 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
|
-
|
|
41
|
-
|
|
22
|
+
? "stop"
|
|
23
|
+
: "pause";
|
|
42
24
|
|
|
43
25
|
return {
|
|
44
|
-
size:
|
|
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:
|
|
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
|
+
);
|
|
@@ -9,49 +9,31 @@ import * as R from "ramda";
|
|
|
9
9
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
|
+
Button,
|
|
12
13
|
ContentInfo,
|
|
13
|
-
ProgressBar,
|
|
14
14
|
Controls,
|
|
15
|
-
|
|
15
|
+
ProgressBar,
|
|
16
16
|
} from "@applicaster/quick-brick-mobile-transport-controls";
|
|
17
17
|
|
|
18
18
|
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
19
|
+
|
|
19
20
|
import {
|
|
20
|
-
useModalAnimationContext,
|
|
21
21
|
AnimationComponent,
|
|
22
22
|
ComponentAnimationType,
|
|
23
23
|
PlayerAnimationStateEnum,
|
|
24
|
+
useModalAnimationContext,
|
|
24
25
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
26
|
+
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
25
27
|
|
|
26
|
-
type
|
|
27
|
-
width: number;
|
|
28
|
-
height: number;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
type LayoutProps = {
|
|
28
|
+
type Props = {
|
|
32
29
|
entry: ZappEntry;
|
|
33
|
-
layoutState:
|
|
34
|
-
|
|
35
|
-
docked: boolean;
|
|
36
|
-
isModal: boolean;
|
|
37
|
-
};
|
|
38
|
-
playerState: {
|
|
39
|
-
currentTime: number;
|
|
40
|
-
duration: number;
|
|
41
|
-
seekableDuration: number;
|
|
42
|
-
isLive: boolean;
|
|
43
|
-
isPaused: boolean;
|
|
44
|
-
isBuffering: boolean;
|
|
45
|
-
};
|
|
30
|
+
layoutState: QuickBrickPlayer.LayoutState;
|
|
31
|
+
playerState: QuickBrickPlayer.PlayerState;
|
|
46
32
|
value: GetValue;
|
|
47
|
-
configuration:
|
|
48
|
-
|
|
49
|
-
onRewindButtonPress: () => void;
|
|
50
|
-
onForwardButtonPress: () => void;
|
|
51
|
-
onPlayerSeek: (targetTime: number) => void;
|
|
33
|
+
configuration: QuickBrickPlayer.AudioPlayerProps["configuration"];
|
|
34
|
+
dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
|
|
52
35
|
onCloseVideoModal: () => void;
|
|
53
|
-
|
|
54
|
-
dimensions: Dimensions;
|
|
36
|
+
onPlayerSeek: (targetTime: number) => void;
|
|
55
37
|
playNextData: PlayNextData;
|
|
56
38
|
title: string | number;
|
|
57
39
|
summary: string | number;
|
|
@@ -113,17 +95,21 @@ const playerDimensionsStyle = (
|
|
|
113
95
|
minimisedHeight: number,
|
|
114
96
|
addPadding: boolean
|
|
115
97
|
): ViewStyle => ({
|
|
116
|
-
paddingLeft: addPadding ? minimisedHeight
|
|
98
|
+
paddingLeft: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
|
|
117
99
|
});
|
|
118
100
|
|
|
119
|
-
const animatedContainerStyle = (
|
|
101
|
+
const animatedContainerStyle = (
|
|
102
|
+
docked: boolean,
|
|
103
|
+
progressBarHeight: number
|
|
104
|
+
): ViewStyle => ({
|
|
105
|
+
top: progressBarHeight,
|
|
120
106
|
position: "absolute",
|
|
121
107
|
width: "100%",
|
|
122
108
|
zIndex: docked ? 1 : -1,
|
|
123
109
|
});
|
|
124
110
|
|
|
125
111
|
const backgroundImageStyle = (
|
|
126
|
-
dimensions:
|
|
112
|
+
dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"],
|
|
127
113
|
minimisedHeight: number,
|
|
128
114
|
isActiveGesture: boolean
|
|
129
115
|
): ViewStyle => ({
|
|
@@ -133,24 +119,11 @@ const backgroundImageStyle = (
|
|
|
133
119
|
});
|
|
134
120
|
|
|
135
121
|
const controlButtons = (
|
|
136
|
-
isPlayNextEnabled: boolean,
|
|
137
122
|
live: boolean,
|
|
138
123
|
paused: boolean,
|
|
139
124
|
buffering: boolean,
|
|
140
125
|
playerId: string
|
|
141
126
|
): Array<ControlsButton> => {
|
|
142
|
-
if (isPlayNextEnabled) {
|
|
143
|
-
return [
|
|
144
|
-
{
|
|
145
|
-
size: "medium",
|
|
146
|
-
name: "play_next",
|
|
147
|
-
icon: "play_next",
|
|
148
|
-
preferredFocus: true,
|
|
149
|
-
style: styles.buttons,
|
|
150
|
-
},
|
|
151
|
-
];
|
|
152
|
-
}
|
|
153
|
-
|
|
154
127
|
if (buffering) {
|
|
155
128
|
return [
|
|
156
129
|
{
|
|
@@ -202,16 +175,16 @@ const controlButtons = (
|
|
|
202
175
|
];
|
|
203
176
|
};
|
|
204
177
|
|
|
205
|
-
export
|
|
178
|
+
export const DockedControls = (props: Props) => {
|
|
206
179
|
const {
|
|
180
|
+
entry,
|
|
207
181
|
layoutState,
|
|
182
|
+
playerState,
|
|
208
183
|
value,
|
|
184
|
+
configuration,
|
|
209
185
|
dimensions,
|
|
210
|
-
entry,
|
|
211
186
|
onCloseVideoModal,
|
|
212
187
|
onPlayerSeek,
|
|
213
|
-
playerState,
|
|
214
|
-
configuration,
|
|
215
188
|
playNextData,
|
|
216
189
|
title,
|
|
217
190
|
summary,
|
|
@@ -219,7 +192,6 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
219
192
|
|
|
220
193
|
const isTablet = useIsTablet();
|
|
221
194
|
|
|
222
|
-
const visible = true;
|
|
223
195
|
const liveButton = Boolean(value("live_badge_enabled"));
|
|
224
196
|
|
|
225
197
|
const {
|
|
@@ -227,10 +199,11 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
227
199
|
setPlayerAnimationState,
|
|
228
200
|
startComponentsAnimation,
|
|
229
201
|
minimisedHeight,
|
|
202
|
+
progressBarHeight,
|
|
230
203
|
} = useModalAnimationContext();
|
|
231
204
|
|
|
232
205
|
const maximazeVideoModal = React.useCallback(
|
|
233
|
-
() => setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
206
|
+
() => setPlayerAnimationState(PlayerAnimationStateEnum.maximize),
|
|
234
207
|
[]
|
|
235
208
|
);
|
|
236
209
|
|
|
@@ -241,22 +214,27 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
241
214
|
animationType={ComponentAnimationType.componentAppears}
|
|
242
215
|
style={[
|
|
243
216
|
styles.container,
|
|
244
|
-
animatedContainerStyle(
|
|
217
|
+
animatedContainerStyle(
|
|
218
|
+
isActiveGesture || layoutState.docked,
|
|
219
|
+
progressBarHeight
|
|
220
|
+
),
|
|
221
|
+
{ height: minimisedHeight },
|
|
245
222
|
]}
|
|
246
223
|
>
|
|
247
224
|
{!playerState.isLive &&
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
225
|
+
(layoutState.docked || startComponentsAnimation) ? (
|
|
226
|
+
<ProgressBar
|
|
227
|
+
name={"audio-docked-layout"}
|
|
228
|
+
content={entry}
|
|
229
|
+
value={value}
|
|
230
|
+
visible
|
|
231
|
+
layoutState={layoutState}
|
|
232
|
+
onPlayerSeek={onPlayerSeek}
|
|
233
|
+
playerState={playerState}
|
|
234
|
+
startComponentsAnimation={startComponentsAnimation}
|
|
235
|
+
docked
|
|
236
|
+
/>
|
|
237
|
+
) : null}
|
|
260
238
|
|
|
261
239
|
<View style={styles.content}>
|
|
262
240
|
<View
|
|
@@ -300,9 +278,8 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
300
278
|
>
|
|
301
279
|
<Controls
|
|
302
280
|
value={value}
|
|
303
|
-
visible
|
|
281
|
+
visible
|
|
304
282
|
buttons={R.partial(controlButtons, [
|
|
305
|
-
playNextData,
|
|
306
283
|
playerState.isLive && liveButton,
|
|
307
284
|
])}
|
|
308
285
|
style={styles.playPauseButton}
|
|
@@ -320,4 +297,4 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
320
297
|
</View>
|
|
321
298
|
</AnimationComponent>
|
|
322
299
|
);
|
|
323
|
-
}
|
|
300
|
+
};
|