@applicaster/quick-brick-player 13.0.0-alpha.2060875348 → 13.0.0-alpha.2082004638
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 +6 -10
- package/src/Player/AudioLayer/AudioDescription.tsx +6 -4
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +15 -9
- package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +26 -0
- package/src/Player/AudioLayer/Layout/Controls/index.tsx +307 -0
- package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +3 -11
- package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +29 -52
- package/src/Player/AudioLayer/Layout/MobileLayout.tsx +209 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/ScaledImage.tsx +83 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/StaticImage.tsx +32 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +101 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +17 -0
- package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +206 -0
- package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +218 -0
- package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +103 -0
- package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
- package/src/Player/AudioLayer/Layout/const.ts +19 -0
- package/src/Player/AudioLayer/Layout/debug.ts +5 -0
- package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -0
- package/src/Player/AudioLayer/Layout/hooks/useImageSize.ts +99 -0
- package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
- package/src/Player/AudioLayer/Layout/index.tsx +34 -30
- package/src/Player/AudioLayer/Layout/types.ts +49 -0
- package/src/Player/AudioLayer/MagicBG/index.tsx +1 -1
- package/src/Player/AudioLayer/utils.ts +24 -0
- package/src/Player/index.tsx +9 -6
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -453
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-player",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
3
|
+
"version": "13.0.0-alpha.2082004638",
|
|
4
4
|
"description": "Quick Brick Player",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "jest -w=2",
|
|
9
8
|
"build": "echo 'skipping ts build for core packages'"
|
|
10
9
|
},
|
|
11
10
|
"files": [
|
|
@@ -36,11 +35,11 @@
|
|
|
36
35
|
},
|
|
37
36
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
38
37
|
"dependencies": {
|
|
39
|
-
"@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.
|
|
40
|
-
"@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.
|
|
41
|
-
"@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.
|
|
43
|
-
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.
|
|
38
|
+
"@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.2082004638",
|
|
39
|
+
"@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
|
|
40
|
+
"@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.2082004638",
|
|
41
|
+
"@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.2082004638",
|
|
42
|
+
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.2082004638",
|
|
44
43
|
"keymirror": "^0.1.1",
|
|
45
44
|
"query-string": "7.1.3",
|
|
46
45
|
"react-native-web-linear-gradient": "1.1.2",
|
|
@@ -61,11 +60,8 @@
|
|
|
61
60
|
"@applicaster/zapp-react-native-tvos-ui-components": "*",
|
|
62
61
|
"@babel/runtime": "*",
|
|
63
62
|
"@react-native-community/netinfo": "*",
|
|
64
|
-
"@types/node": "*",
|
|
65
|
-
"@types/react-native": "0.69.6",
|
|
66
63
|
"immer": "*",
|
|
67
64
|
"react": "*",
|
|
68
|
-
"react-hot-loader": "*",
|
|
69
65
|
"react-native": "*",
|
|
70
66
|
"react-native-fs": "*",
|
|
71
67
|
"react-native-gesture-handler": "*",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Text, TextStyle, View } from "react-native";
|
|
2
|
+
import { Text, TextStyle, View, StyleSheet } from "react-native";
|
|
3
3
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
4
4
|
|
|
5
5
|
type AudioDescriptionProps = {
|
|
@@ -13,7 +13,9 @@ type AudioDescriptionProps = {
|
|
|
13
13
|
value: GetValue;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const styles = StyleSheet.create({
|
|
17
|
+
container: {},
|
|
18
|
+
});
|
|
17
19
|
|
|
18
20
|
const titleStyles = (value: GetValue, prefix: string): TextStyle => ({
|
|
19
21
|
textAlign: "left",
|
|
@@ -83,11 +85,11 @@ export const AudioDescription = (props: AudioDescriptionProps) => {
|
|
|
83
85
|
const prefix = layoutState.docked ? "docked_player_" : "";
|
|
84
86
|
|
|
85
87
|
return (
|
|
86
|
-
<View style={
|
|
88
|
+
<View style={styles.container}>
|
|
87
89
|
<Text style={titleStyles(value, prefix)} numberOfLines={1}>
|
|
88
90
|
{title}
|
|
89
91
|
</Text>
|
|
90
|
-
<Text style={summaryStyles(value, prefix)} numberOfLines={
|
|
92
|
+
<Text style={summaryStyles(value, prefix)} numberOfLines={1}>
|
|
91
93
|
{summary}
|
|
92
94
|
</Text>
|
|
93
95
|
</View>
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
ComponentAnimationType,
|
|
26
26
|
AnimatedScrollModal,
|
|
27
27
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
28
|
-
import { PADDING_HORIZONTAL } from "./Layout/
|
|
28
|
+
import { PADDING_HORIZONTAL } from "./Layout/const";
|
|
29
29
|
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
30
30
|
import {
|
|
31
31
|
speed_0_8,
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
} from "./SleepTimerManager";
|
|
42
42
|
import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
|
|
43
43
|
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
44
|
+
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
44
45
|
|
|
45
46
|
const { log_debug } = createLogger({
|
|
46
47
|
subsystem: "UIComponent",
|
|
@@ -58,6 +59,7 @@ type Configuration = {
|
|
|
58
59
|
[key: string]: any;
|
|
59
60
|
magic_background?: boolean;
|
|
60
61
|
audio_player_background_image_query?: string;
|
|
62
|
+
audio_player_background_image_default_color?: string;
|
|
61
63
|
tablet_landscape_sidebar_width?: string;
|
|
62
64
|
tablet_landscape_player_container_background_color?: string;
|
|
63
65
|
};
|
|
@@ -127,9 +129,12 @@ const sleeps = [
|
|
|
127
129
|
{ label: "2 hours", value: 120 },
|
|
128
130
|
];
|
|
129
131
|
|
|
132
|
+
const edges: Edge[] = ["right", "left", "top"];
|
|
133
|
+
|
|
130
134
|
export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
131
135
|
const player = usePlayer();
|
|
132
136
|
const playerState = usePlayerState("audio-player-wrapper");
|
|
137
|
+
const theme = useTheme();
|
|
133
138
|
|
|
134
139
|
const {
|
|
135
140
|
docked,
|
|
@@ -359,13 +364,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
359
364
|
player?.seekTo(0);
|
|
360
365
|
}, [player]);
|
|
361
366
|
|
|
362
|
-
const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
|
|
363
|
-
|
|
364
|
-
const ContainerView = SafeAreaView;
|
|
365
|
-
|
|
366
367
|
const MainContent = React.useMemo(() => {
|
|
367
368
|
return (
|
|
368
|
-
<
|
|
369
|
+
<SafeAreaView style={Styles.mainContainer(style)} edges={edges}>
|
|
369
370
|
<AnimationComponent
|
|
370
371
|
animationType={ComponentAnimationType.moveUpComponent}
|
|
371
372
|
additionalData={{ saveArea: true }}
|
|
@@ -420,7 +421,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
420
421
|
</View>
|
|
421
422
|
</AnimatedScrollModal>
|
|
422
423
|
</AnimationComponent>
|
|
423
|
-
</
|
|
424
|
+
</SafeAreaView>
|
|
424
425
|
);
|
|
425
426
|
}, [
|
|
426
427
|
docked,
|
|
@@ -451,16 +452,21 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
451
452
|
const queryParamName =
|
|
452
453
|
configuration.audio_player_background_image_query || "width";
|
|
453
454
|
|
|
455
|
+
const defaultBackgroundColor =
|
|
456
|
+
configuration.audio_player_background_image_default_color ||
|
|
457
|
+
theme?.app_background_color;
|
|
458
|
+
|
|
454
459
|
const queryParamValue = 15;
|
|
455
460
|
|
|
456
|
-
const url =
|
|
461
|
+
const url =
|
|
462
|
+
baseUrl && addQueryParam(baseUrl, queryParamName, queryParamValue);
|
|
457
463
|
|
|
458
464
|
return (
|
|
459
465
|
<MagicBG
|
|
460
466
|
image={url}
|
|
461
467
|
fallbackUrl={baseUrl}
|
|
462
468
|
colors={entry?.extensions?.backgroundColors}
|
|
463
|
-
defaultColor=
|
|
469
|
+
defaultColor={defaultBackgroundColor}
|
|
464
470
|
>
|
|
465
471
|
{MainContent}
|
|
466
472
|
</MagicBG>
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
...withDebug({ backgroundColor: "red" }),
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const VerticalGutter = () => {
|
|
23
|
+
const isTablet = useIsTablet();
|
|
24
|
+
|
|
25
|
+
return <View style={isTablet ? styles.fixedHeight : styles.flexingHeight} />;
|
|
26
|
+
};
|
|
@@ -0,0 +1,307 @@
|
|
|
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
|
+
CountDown,
|
|
9
|
+
ProgressBar,
|
|
10
|
+
} from "@applicaster/quick-brick-mobile-transport-controls";
|
|
11
|
+
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
AnimationComponent,
|
|
15
|
+
ComponentAnimationType,
|
|
16
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
17
|
+
|
|
18
|
+
import { AudioDescription } from "../../AudioDescription";
|
|
19
|
+
import { isValidDate } from "../../../Utils";
|
|
20
|
+
import { VerticalGutter } from "./VerticalGutter";
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
forwardButton,
|
|
24
|
+
playbackButton,
|
|
25
|
+
rewindButton,
|
|
26
|
+
skipToLiveButton,
|
|
27
|
+
skipToStartButton,
|
|
28
|
+
sleepButton,
|
|
29
|
+
speedButton,
|
|
30
|
+
} from "./utils";
|
|
31
|
+
|
|
32
|
+
import { PlayerState, LayoutState } from "../types";
|
|
33
|
+
|
|
34
|
+
const styles = StyleSheet.create({
|
|
35
|
+
flex: {
|
|
36
|
+
flex: 1,
|
|
37
|
+
},
|
|
38
|
+
nonFlex: {
|
|
39
|
+
flex: 0,
|
|
40
|
+
},
|
|
41
|
+
progressBar: {
|
|
42
|
+
flex: 0,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const controlsStyles = ({
|
|
47
|
+
isTablet,
|
|
48
|
+
isLiveShowFullControls,
|
|
49
|
+
}: {
|
|
50
|
+
isTablet: boolean;
|
|
51
|
+
isLiveShowFullControls: boolean;
|
|
52
|
+
}) => ({
|
|
53
|
+
height: isTablet ? undefined : 50,
|
|
54
|
+
marginHorizontal: isTablet ? undefined : 10,
|
|
55
|
+
justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
type Props = {
|
|
59
|
+
entry: ZappEntry;
|
|
60
|
+
layoutState: LayoutState;
|
|
61
|
+
playerState: PlayerState;
|
|
62
|
+
value: GetValue;
|
|
63
|
+
title: string | number;
|
|
64
|
+
summary: string | number;
|
|
65
|
+
sleepTimerDate: number;
|
|
66
|
+
cancelSleepTimer: () => void;
|
|
67
|
+
|
|
68
|
+
playbackSpeedName: string;
|
|
69
|
+
playbackSleepName: string;
|
|
70
|
+
|
|
71
|
+
onPlaybackButtonPress: () => void;
|
|
72
|
+
onRewindButtonPress: () => void;
|
|
73
|
+
onForwardButtonPress: () => void;
|
|
74
|
+
onPlayerSeek: (targetTime: number) => void;
|
|
75
|
+
onSkipStart: () => void;
|
|
76
|
+
onSkipLive: () => void;
|
|
77
|
+
onSpeedButtonPress: () => void;
|
|
78
|
+
onSleepButtonPress: () => void;
|
|
79
|
+
|
|
80
|
+
docked: boolean;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const Controls = (props: Props) => {
|
|
84
|
+
const {
|
|
85
|
+
entry,
|
|
86
|
+
layoutState,
|
|
87
|
+
playerState,
|
|
88
|
+
value,
|
|
89
|
+
title,
|
|
90
|
+
summary,
|
|
91
|
+
sleepTimerDate,
|
|
92
|
+
cancelSleepTimer,
|
|
93
|
+
|
|
94
|
+
playbackSpeedName,
|
|
95
|
+
playbackSleepName,
|
|
96
|
+
|
|
97
|
+
onPlaybackButtonPress,
|
|
98
|
+
onRewindButtonPress,
|
|
99
|
+
onForwardButtonPress,
|
|
100
|
+
onPlayerSeek,
|
|
101
|
+
onSkipStart,
|
|
102
|
+
onSkipLive,
|
|
103
|
+
onSpeedButtonPress,
|
|
104
|
+
onSleepButtonPress,
|
|
105
|
+
|
|
106
|
+
docked,
|
|
107
|
+
} = props;
|
|
108
|
+
|
|
109
|
+
const isTablet = useIsTablet();
|
|
110
|
+
const controller = playerManager.getActivePlayer();
|
|
111
|
+
let showFullControls = !controller?.isAd();
|
|
112
|
+
const liveButton = Boolean(value("live_badge_enabled"));
|
|
113
|
+
|
|
114
|
+
const isLiveContent = playerState.isLive;
|
|
115
|
+
|
|
116
|
+
if (isLiveContent) {
|
|
117
|
+
const seekEnabled = Boolean(value("liveSeekingEnabled"));
|
|
118
|
+
|
|
119
|
+
showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const sleepTitle = value("playback_sleep_countdown_label");
|
|
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
|
+
React.useEffect(() => {
|
|
131
|
+
if (showCounter && sleepTimerDate !== 0) {
|
|
132
|
+
setTimeLeft(sleepTimerDate - Date.now());
|
|
133
|
+
|
|
134
|
+
const intervalId = setInterval(() => {
|
|
135
|
+
setTimeLeft(() => {
|
|
136
|
+
const newTimeLeft = sleepTimerDate - Date.now();
|
|
137
|
+
|
|
138
|
+
if (newTimeLeft <= 0) {
|
|
139
|
+
clearInterval(intervalId);
|
|
140
|
+
|
|
141
|
+
cancelSleepTimer();
|
|
142
|
+
|
|
143
|
+
return 0;
|
|
144
|
+
} else {
|
|
145
|
+
return newTimeLeft;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}, 1000);
|
|
149
|
+
|
|
150
|
+
return () => clearInterval(intervalId);
|
|
151
|
+
} else {
|
|
152
|
+
setTimeLeft(0);
|
|
153
|
+
}
|
|
154
|
+
}, [sleepTimerDate, showCounter, cancelSleepTimer]);
|
|
155
|
+
|
|
156
|
+
const startTime = entry.extensions?.live?.start_time;
|
|
157
|
+
const endTime = entry.extensions?.live?.end_time;
|
|
158
|
+
|
|
159
|
+
const hasValidStartTime = isValidDate(startTime);
|
|
160
|
+
const hasValidEndTime = isValidDate(endTime);
|
|
161
|
+
|
|
162
|
+
const isDateBasedLiveContent =
|
|
163
|
+
isLiveContent && hasValidStartTime && hasValidEndTime;
|
|
164
|
+
|
|
165
|
+
const needsToShowProgressBar =
|
|
166
|
+
(isLiveContent &&
|
|
167
|
+
(Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
|
|
168
|
+
!isLiveContent;
|
|
169
|
+
|
|
170
|
+
const startTimestamp = hasValidStartTime
|
|
171
|
+
? dayjs.utc(startTime!).valueOf()
|
|
172
|
+
: undefined;
|
|
173
|
+
|
|
174
|
+
const endTimestamp = hasValidEndTime
|
|
175
|
+
? dayjs.utc(endTime!).valueOf()
|
|
176
|
+
: undefined;
|
|
177
|
+
|
|
178
|
+
const isLiveShowFullControls = showFullControls && isLiveContent;
|
|
179
|
+
|
|
180
|
+
const controlButtons = React.useCallback((): Array<ControlsButton> => {
|
|
181
|
+
const play = playbackButton({
|
|
182
|
+
playerState,
|
|
183
|
+
liveButton,
|
|
184
|
+
isTablet,
|
|
185
|
+
isLiveShowFullControls,
|
|
186
|
+
onPress: onPlaybackButtonPress,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (!showFullControls) {
|
|
190
|
+
return [play];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const rewind = rewindButton({
|
|
194
|
+
isTablet,
|
|
195
|
+
onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const forward = forwardButton({
|
|
199
|
+
isTablet,
|
|
200
|
+
onPress: controller?.hasSeekableDuration?.()
|
|
201
|
+
? onForwardButtonPress
|
|
202
|
+
: null,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const speed = speedButton({
|
|
206
|
+
isTablet,
|
|
207
|
+
onPress: onSpeedButtonPress,
|
|
208
|
+
name: playbackSpeedName,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const sleep = sleepButton({
|
|
212
|
+
isTablet,
|
|
213
|
+
onPress: onSleepButtonPress,
|
|
214
|
+
name: playbackSleepName,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (isLiveContent) {
|
|
218
|
+
const skipToStart = skipToStartButton({
|
|
219
|
+
isTablet,
|
|
220
|
+
onPress: onSkipStart,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const skipToLive = skipToLiveButton({
|
|
224
|
+
isTablet,
|
|
225
|
+
onPress: onSkipLive,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
return [skipToStart, rewind, play, forward, skipToLive];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return [speed, rewind, play, forward, sleep];
|
|
232
|
+
}, [
|
|
233
|
+
playerState,
|
|
234
|
+
liveButton,
|
|
235
|
+
isTablet,
|
|
236
|
+
onPlaybackButtonPress,
|
|
237
|
+
onRewindButtonPress,
|
|
238
|
+
onForwardButtonPress,
|
|
239
|
+
onSpeedButtonPress,
|
|
240
|
+
showFullControls,
|
|
241
|
+
onSkipStart,
|
|
242
|
+
onSkipLive,
|
|
243
|
+
isLiveContent,
|
|
244
|
+
playbackSpeedName,
|
|
245
|
+
playbackSleepName,
|
|
246
|
+
controller,
|
|
247
|
+
isLiveShowFullControls,
|
|
248
|
+
]);
|
|
249
|
+
|
|
250
|
+
if (docked) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
<AnimationComponent
|
|
256
|
+
animationType={ComponentAnimationType.componentFade}
|
|
257
|
+
style={isTablet ? styles.nonFlex : styles.flex}
|
|
258
|
+
>
|
|
259
|
+
<VerticalGutter />
|
|
260
|
+
|
|
261
|
+
<AudioDescription
|
|
262
|
+
title={title}
|
|
263
|
+
summary={summary}
|
|
264
|
+
value={value}
|
|
265
|
+
layoutState={layoutState}
|
|
266
|
+
/>
|
|
267
|
+
|
|
268
|
+
<VerticalGutter />
|
|
269
|
+
|
|
270
|
+
{needsToShowProgressBar ? (
|
|
271
|
+
<>
|
|
272
|
+
<ProgressBar
|
|
273
|
+
name={"audio-default-layout"}
|
|
274
|
+
content={entry}
|
|
275
|
+
value={value}
|
|
276
|
+
visible
|
|
277
|
+
layoutState={layoutState}
|
|
278
|
+
onPlayerSeek={onPlayerSeek}
|
|
279
|
+
playerState={playerState}
|
|
280
|
+
disableFullscreen
|
|
281
|
+
sliderStyle={2}
|
|
282
|
+
startTimestamp={startTimestamp}
|
|
283
|
+
endTimestamp={endTimestamp}
|
|
284
|
+
isDateBasedLiveContent={isDateBasedLiveContent}
|
|
285
|
+
onSkipLive={onSkipLive}
|
|
286
|
+
progressBarStyles={styles.progressBar}
|
|
287
|
+
/>
|
|
288
|
+
|
|
289
|
+
{showCounter && timeLeft >= 0 ? (
|
|
290
|
+
<CountDown timeLeft={timeLeft} value={value} title={sleepTitle} />
|
|
291
|
+
) : null}
|
|
292
|
+
|
|
293
|
+
<VerticalGutter />
|
|
294
|
+
</>
|
|
295
|
+
) : null}
|
|
296
|
+
|
|
297
|
+
<MobileTransportControls
|
|
298
|
+
value={value}
|
|
299
|
+
visible={true}
|
|
300
|
+
keepAlive={null}
|
|
301
|
+
buttons={controlButtons}
|
|
302
|
+
style={controlsStyles({ isTablet, isLiveShowFullControls })}
|
|
303
|
+
playerState={playerState}
|
|
304
|
+
/>
|
|
305
|
+
</AnimationComponent>
|
|
306
|
+
);
|
|
307
|
+
};
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
currentTime: number;
|
|
3
|
-
duration: number;
|
|
4
|
-
seekableDuration: number;
|
|
5
|
-
isLive: boolean;
|
|
6
|
-
isPaused: boolean;
|
|
7
|
-
isBuffering: boolean;
|
|
8
|
-
};
|
|
1
|
+
import { PlayerState } from "../types";
|
|
9
2
|
|
|
10
3
|
const rewindButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
|
|
11
4
|
isTablet ? "big" : "smallMargins";
|
|
@@ -17,9 +10,7 @@ const playbackButtonMargins = (
|
|
|
17
10
|
isTablet: boolean,
|
|
18
11
|
isLiveShowFullControls: boolean
|
|
19
12
|
): number =>
|
|
20
|
-
isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ?
|
|
21
|
-
|
|
22
|
-
export const PADDING_HORIZONTAL = 15;
|
|
13
|
+
isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
|
|
23
14
|
|
|
24
15
|
export const playbackButton = ({
|
|
25
16
|
playerState,
|
|
@@ -57,6 +48,7 @@ type ButtonsProps = {
|
|
|
57
48
|
style?: any;
|
|
58
49
|
name?: string;
|
|
59
50
|
};
|
|
51
|
+
|
|
60
52
|
type ButtonsByNameProps = ButtonsProps & { name?: string };
|
|
61
53
|
|
|
62
54
|
const rewindButtonByName = ({
|
|
@@ -22,36 +22,19 @@ import {
|
|
|
22
22
|
PlayerAnimationStateEnum,
|
|
23
23
|
useModalAnimationContext,
|
|
24
24
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
25
|
+
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
width: number;
|
|
28
|
-
height: number;
|
|
29
|
-
};
|
|
27
|
+
import { LayoutState, PlayerState, Configuration, DimensionsT } from "../types";
|
|
30
28
|
|
|
31
|
-
type
|
|
29
|
+
type Props = {
|
|
32
30
|
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
|
-
};
|
|
31
|
+
layoutState: LayoutState;
|
|
32
|
+
playerState: PlayerState;
|
|
46
33
|
value: GetValue;
|
|
47
|
-
configuration:
|
|
48
|
-
|
|
49
|
-
onRewindButtonPress: () => void;
|
|
50
|
-
onForwardButtonPress: () => void;
|
|
51
|
-
onPlayerSeek: (targetTime: number) => void;
|
|
34
|
+
configuration: Configuration;
|
|
35
|
+
dimensions: DimensionsT;
|
|
52
36
|
onCloseVideoModal: () => void;
|
|
53
|
-
|
|
54
|
-
dimensions: Dimensions;
|
|
37
|
+
onPlayerSeek: (targetTime: number) => void;
|
|
55
38
|
playNextData: PlayNextData;
|
|
56
39
|
title: string | number;
|
|
57
40
|
summary: string | number;
|
|
@@ -113,17 +96,21 @@ const playerDimensionsStyle = (
|
|
|
113
96
|
minimisedHeight: number,
|
|
114
97
|
addPadding: boolean
|
|
115
98
|
): ViewStyle => ({
|
|
116
|
-
paddingLeft: addPadding ? minimisedHeight
|
|
99
|
+
paddingLeft: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
|
|
117
100
|
});
|
|
118
101
|
|
|
119
|
-
const animatedContainerStyle = (
|
|
102
|
+
const animatedContainerStyle = (
|
|
103
|
+
docked: boolean,
|
|
104
|
+
progressBarHeight: number
|
|
105
|
+
): ViewStyle => ({
|
|
106
|
+
top: progressBarHeight,
|
|
120
107
|
position: "absolute",
|
|
121
108
|
width: "100%",
|
|
122
109
|
zIndex: docked ? 1 : -1,
|
|
123
110
|
});
|
|
124
111
|
|
|
125
112
|
const backgroundImageStyle = (
|
|
126
|
-
dimensions:
|
|
113
|
+
dimensions: DimensionsT,
|
|
127
114
|
minimisedHeight: number,
|
|
128
115
|
isActiveGesture: boolean
|
|
129
116
|
): ViewStyle => ({
|
|
@@ -133,24 +120,11 @@ const backgroundImageStyle = (
|
|
|
133
120
|
});
|
|
134
121
|
|
|
135
122
|
const controlButtons = (
|
|
136
|
-
isPlayNextEnabled: boolean,
|
|
137
123
|
live: boolean,
|
|
138
124
|
paused: boolean,
|
|
139
125
|
buffering: boolean,
|
|
140
126
|
playerId: string
|
|
141
127
|
): 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
128
|
if (buffering) {
|
|
155
129
|
return [
|
|
156
130
|
{
|
|
@@ -202,16 +176,16 @@ const controlButtons = (
|
|
|
202
176
|
];
|
|
203
177
|
};
|
|
204
178
|
|
|
205
|
-
export
|
|
179
|
+
export const DockedControls = (props: Props) => {
|
|
206
180
|
const {
|
|
181
|
+
entry,
|
|
207
182
|
layoutState,
|
|
183
|
+
playerState,
|
|
208
184
|
value,
|
|
185
|
+
configuration,
|
|
209
186
|
dimensions,
|
|
210
|
-
entry,
|
|
211
187
|
onCloseVideoModal,
|
|
212
188
|
onPlayerSeek,
|
|
213
|
-
playerState,
|
|
214
|
-
configuration,
|
|
215
189
|
playNextData,
|
|
216
190
|
title,
|
|
217
191
|
summary,
|
|
@@ -219,7 +193,6 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
219
193
|
|
|
220
194
|
const isTablet = useIsTablet();
|
|
221
195
|
|
|
222
|
-
const visible = true;
|
|
223
196
|
const liveButton = Boolean(value("live_badge_enabled"));
|
|
224
197
|
|
|
225
198
|
const {
|
|
@@ -227,10 +200,11 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
227
200
|
setPlayerAnimationState,
|
|
228
201
|
startComponentsAnimation,
|
|
229
202
|
minimisedHeight,
|
|
203
|
+
progressBarHeight,
|
|
230
204
|
} = useModalAnimationContext();
|
|
231
205
|
|
|
232
206
|
const maximazeVideoModal = React.useCallback(
|
|
233
|
-
() => setPlayerAnimationState(PlayerAnimationStateEnum.
|
|
207
|
+
() => setPlayerAnimationState(PlayerAnimationStateEnum.maximize),
|
|
234
208
|
[]
|
|
235
209
|
);
|
|
236
210
|
|
|
@@ -241,15 +215,19 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
241
215
|
animationType={ComponentAnimationType.componentAppears}
|
|
242
216
|
style={[
|
|
243
217
|
styles.container,
|
|
244
|
-
animatedContainerStyle(
|
|
218
|
+
animatedContainerStyle(
|
|
219
|
+
isActiveGesture || layoutState.docked,
|
|
220
|
+
progressBarHeight
|
|
221
|
+
),
|
|
245
222
|
]}
|
|
246
223
|
>
|
|
247
224
|
{!playerState.isLive &&
|
|
248
225
|
(layoutState.docked || startComponentsAnimation) ? (
|
|
249
226
|
<ProgressBar
|
|
227
|
+
name={"audio-docked-layout"}
|
|
250
228
|
content={entry}
|
|
251
229
|
value={value}
|
|
252
|
-
visible
|
|
230
|
+
visible
|
|
253
231
|
layoutState={layoutState}
|
|
254
232
|
onPlayerSeek={onPlayerSeek}
|
|
255
233
|
playerState={playerState}
|
|
@@ -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
|
+
};
|