@applicaster/quick-brick-player 13.0.0-rc.11 → 13.0.0-rc.111
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 -14
- package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
- package/src/Player/AudioLayer/AudioDescription.tsx +5 -7
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +174 -280
- 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 -74
- package/src/Player/AudioLayer/Layout/MobileLayout.tsx +230 -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 +215 -0
- package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +223 -0
- package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +115 -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/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/hooks/useIsCasting.tsx +57 -0
- package/src/Player/index.tsx +39 -22
- package/src/QuickBrickPlayer.tsx +3 -0
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
- package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.ts +0 -3
- package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.web.ts +0 -3
- package/src/Player/AudioLayer/LinearGradient/index.ts +0 -1
- package/src/Player/AudioLayer/MagicBG/index.tsx +0 -155
- package/src/Player/Helpers/VideoResizeMode.ts +0 -7
- package/src/utils/utils.ts +0 -25
|
@@ -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,30 @@ 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
|
-
|
|
48
|
-
onPlaybackButtonPress: () => void;
|
|
49
|
-
onRewindButtonPress: () => void;
|
|
50
|
-
onForwardButtonPress: () => void;
|
|
51
|
-
onPlayerSeek: (targetTime: number) => void;
|
|
33
|
+
dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
|
|
52
34
|
onCloseVideoModal: () => void;
|
|
53
|
-
|
|
54
|
-
dimensions: Dimensions;
|
|
35
|
+
onPlayerSeek: (targetTime: number) => void;
|
|
55
36
|
playNextData: PlayNextData;
|
|
56
37
|
title: string | number;
|
|
57
38
|
summary: string | number;
|
|
@@ -113,17 +94,21 @@ const playerDimensionsStyle = (
|
|
|
113
94
|
minimisedHeight: number,
|
|
114
95
|
addPadding: boolean
|
|
115
96
|
): ViewStyle => ({
|
|
116
|
-
paddingLeft: addPadding ? minimisedHeight
|
|
97
|
+
paddingLeft: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
|
|
117
98
|
});
|
|
118
99
|
|
|
119
|
-
const animatedContainerStyle = (
|
|
100
|
+
const animatedContainerStyle = (
|
|
101
|
+
docked: boolean,
|
|
102
|
+
progressBarHeight: number
|
|
103
|
+
): ViewStyle => ({
|
|
104
|
+
top: progressBarHeight,
|
|
120
105
|
position: "absolute",
|
|
121
106
|
width: "100%",
|
|
122
107
|
zIndex: docked ? 1 : -1,
|
|
123
108
|
});
|
|
124
109
|
|
|
125
110
|
const backgroundImageStyle = (
|
|
126
|
-
dimensions:
|
|
111
|
+
dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"],
|
|
127
112
|
minimisedHeight: number,
|
|
128
113
|
isActiveGesture: boolean
|
|
129
114
|
): ViewStyle => ({
|
|
@@ -133,24 +118,11 @@ const backgroundImageStyle = (
|
|
|
133
118
|
});
|
|
134
119
|
|
|
135
120
|
const controlButtons = (
|
|
136
|
-
isPlayNextEnabled: boolean,
|
|
137
121
|
live: boolean,
|
|
138
122
|
paused: boolean,
|
|
139
123
|
buffering: boolean,
|
|
140
124
|
playerId: string
|
|
141
125
|
): 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
126
|
if (buffering) {
|
|
155
127
|
return [
|
|
156
128
|
{
|
|
@@ -202,16 +174,15 @@ const controlButtons = (
|
|
|
202
174
|
];
|
|
203
175
|
};
|
|
204
176
|
|
|
205
|
-
export
|
|
177
|
+
export const DockedControls = (props: Props) => {
|
|
206
178
|
const {
|
|
179
|
+
entry,
|
|
207
180
|
layoutState,
|
|
181
|
+
playerState,
|
|
208
182
|
value,
|
|
209
183
|
dimensions,
|
|
210
|
-
entry,
|
|
211
184
|
onCloseVideoModal,
|
|
212
185
|
onPlayerSeek,
|
|
213
|
-
playerState,
|
|
214
|
-
configuration,
|
|
215
186
|
playNextData,
|
|
216
187
|
title,
|
|
217
188
|
summary,
|
|
@@ -219,7 +190,6 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
219
190
|
|
|
220
191
|
const isTablet = useIsTablet();
|
|
221
192
|
|
|
222
|
-
const visible = true;
|
|
223
193
|
const liveButton = Boolean(value("live_badge_enabled"));
|
|
224
194
|
|
|
225
195
|
const {
|
|
@@ -227,10 +197,11 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
227
197
|
setPlayerAnimationState,
|
|
228
198
|
startComponentsAnimation,
|
|
229
199
|
minimisedHeight,
|
|
200
|
+
progressBarHeight,
|
|
230
201
|
} = useModalAnimationContext();
|
|
231
202
|
|
|
232
203
|
const maximazeVideoModal = React.useCallback(
|
|
233
|
-
() => setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
204
|
+
() => setPlayerAnimationState(PlayerAnimationStateEnum.maximize),
|
|
234
205
|
[]
|
|
235
206
|
);
|
|
236
207
|
|
|
@@ -241,22 +212,27 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
241
212
|
animationType={ComponentAnimationType.componentAppears}
|
|
242
213
|
style={[
|
|
243
214
|
styles.container,
|
|
244
|
-
animatedContainerStyle(
|
|
215
|
+
animatedContainerStyle(
|
|
216
|
+
isActiveGesture || layoutState.docked,
|
|
217
|
+
progressBarHeight
|
|
218
|
+
),
|
|
219
|
+
{ height: minimisedHeight },
|
|
245
220
|
]}
|
|
246
221
|
>
|
|
247
222
|
{!playerState.isLive &&
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
223
|
+
(layoutState.docked || startComponentsAnimation) ? (
|
|
224
|
+
<ProgressBar
|
|
225
|
+
name={"audio-docked-layout"}
|
|
226
|
+
content={entry}
|
|
227
|
+
value={value}
|
|
228
|
+
visible
|
|
229
|
+
layoutState={layoutState}
|
|
230
|
+
onPlayerSeek={onPlayerSeek}
|
|
231
|
+
playerState={playerState}
|
|
232
|
+
startComponentsAnimation={startComponentsAnimation}
|
|
233
|
+
docked
|
|
234
|
+
/>
|
|
235
|
+
) : null}
|
|
260
236
|
|
|
261
237
|
<View style={styles.content}>
|
|
262
238
|
<View
|
|
@@ -276,12 +252,7 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
276
252
|
),
|
|
277
253
|
]}
|
|
278
254
|
>
|
|
279
|
-
<View
|
|
280
|
-
style={[
|
|
281
|
-
styles.contentInfo,
|
|
282
|
-
!configuration.magic_background && backgroundColorStyle(value),
|
|
283
|
-
]}
|
|
284
|
-
>
|
|
255
|
+
<View style={[styles.contentInfo, backgroundColorStyle(value)]}>
|
|
285
256
|
<ContentInfo
|
|
286
257
|
content={{ ...entry, title, summary }}
|
|
287
258
|
value={value}
|
|
@@ -295,14 +266,13 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
295
266
|
isTablet
|
|
296
267
|
? styles.controlsContainerForTablet
|
|
297
268
|
: styles.controlsContainerForMobile,
|
|
298
|
-
|
|
269
|
+
backgroundColorStyle(value),
|
|
299
270
|
]}
|
|
300
271
|
>
|
|
301
272
|
<Controls
|
|
302
273
|
value={value}
|
|
303
|
-
visible
|
|
274
|
+
visible
|
|
304
275
|
buttons={R.partial(controlButtons, [
|
|
305
|
-
playNextData,
|
|
306
276
|
playerState.isLive && liveButton,
|
|
307
277
|
])}
|
|
308
278
|
style={styles.playPauseButton}
|
|
@@ -320,4 +290,4 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
320
290
|
</View>
|
|
321
291
|
</AnimationComponent>
|
|
322
292
|
);
|
|
323
|
-
}
|
|
293
|
+
};
|