@applicaster/quick-brick-player 13.0.0-alpha.6234681660 → 13.0.0-alpha.6372000108
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 +5 -6
- package/src/Player/AudioLayer/AudioDescription.tsx +1 -1
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +47 -81
- package/src/Player/AudioLayer/Layout/Controls/index.tsx +32 -23
- package/src/Player/AudioLayer/Layout/Controls/utils.ts +4 -14
- package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
- package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +7 -7
- package/src/Player/AudioLayer/Layout/MobileLayout.tsx +37 -15
- package/src/Player/AudioLayer/Layout/PlayerImage/{ScaledImage.tsx → AnimatedImage.tsx} +10 -10
- package/src/Player/AudioLayer/Layout/PlayerImage/{StaticImage.tsx → FlexImage.tsx} +4 -11
- package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +28 -19
- package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +9 -0
- package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +17 -7
- package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +10 -4
- package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +23 -12
- package/src/Player/AudioLayer/Layout/const.ts +3 -0
- package/src/Player/AudioLayer/Layout/debug.ts +2 -1
- package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -1
- package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
- package/src/Player/AudioLayer/Layout/hooks/{useImageSize.ts → useTabletLayoutImageSize.ts} +23 -11
- package/src/Player/AudioLayer/Layout/index.tsx +6 -37
- package/src/Player/AudioLayer/Layout/types.ts +3 -45
- package/src/Player/AudioLayer/utils.ts +6 -3
- 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 +4 -1
- package/src/Player/Helpers/VideoResizeMode.ts +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-player",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
3
|
+
"version": "13.0.0-alpha.6372000108",
|
|
4
4
|
"description": "Quick Brick Player",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -35,12 +35,11 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.
|
|
38
|
+
"@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.6372000108",
|
|
39
39
|
"@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
|
|
40
|
-
"@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.
|
|
41
|
-
"@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.
|
|
43
|
-
"keymirror": "^0.1.1",
|
|
40
|
+
"@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.6372000108",
|
|
41
|
+
"@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.6372000108",
|
|
42
|
+
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.6372000108",
|
|
44
43
|
"query-string": "7.1.3",
|
|
45
44
|
"react-native-web-linear-gradient": "1.1.2",
|
|
46
45
|
"shaka-player": "4.3.5",
|
|
@@ -82,7 +82,7 @@ export const AudioDescription = (props: AudioDescriptionProps) => {
|
|
|
82
82
|
|
|
83
83
|
return (
|
|
84
84
|
<>
|
|
85
|
-
<Text style={titleStyles(value, prefix)} numberOfLines={
|
|
85
|
+
<Text style={titleStyles(value, prefix)} numberOfLines={2}>
|
|
86
86
|
{title}
|
|
87
87
|
</Text>
|
|
88
88
|
<Text style={summaryStyles(value, prefix)} numberOfLines={1}>
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
StyleSheet,
|
|
4
|
+
ViewStyle,
|
|
5
|
+
View,
|
|
6
|
+
Dimensions as ScreenDimensions,
|
|
7
|
+
} from "react-native";
|
|
3
8
|
|
|
4
9
|
import { SafeAreaView, Edge } from "react-native-safe-area-context";
|
|
5
10
|
import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
|
|
@@ -18,7 +23,14 @@ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
|
18
23
|
import { useEffect, useState } from "react";
|
|
19
24
|
import { MagicBG } from "./MagicBG";
|
|
20
25
|
import { formatSpeed } from "./utils";
|
|
21
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
addQueryParam,
|
|
28
|
+
getBottomSheetModalDefaultItemIcon,
|
|
29
|
+
getBottomSheetModalIconProps,
|
|
30
|
+
getBottomSheetModalItemProps,
|
|
31
|
+
getBottomSheetModalLabelProps,
|
|
32
|
+
getBottomSheetModalSelectedItemIcon,
|
|
33
|
+
} from "../Utils";
|
|
22
34
|
import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
|
|
23
35
|
import {
|
|
24
36
|
AnimationComponent,
|
|
@@ -27,13 +39,6 @@ import {
|
|
|
27
39
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
28
40
|
import { PADDING_HORIZONTAL } from "./Layout/const";
|
|
29
41
|
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
30
|
-
import {
|
|
31
|
-
speed_0_8,
|
|
32
|
-
speed_1,
|
|
33
|
-
speed_1_2,
|
|
34
|
-
speed_1_5,
|
|
35
|
-
speed_2,
|
|
36
|
-
} from "@applicaster/quick-brick-mobile-transport-controls";
|
|
37
42
|
import {
|
|
38
43
|
SleepTimerController,
|
|
39
44
|
SleepTimerState,
|
|
@@ -42,6 +47,9 @@ import {
|
|
|
42
47
|
import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
|
|
43
48
|
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
44
49
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
50
|
+
import { openBottomSheetModal } from "@applicaster/zapp-react-native-utils/modalState";
|
|
51
|
+
import { getSleepTimerOptions } from "../Const/sleepTimerOptions";
|
|
52
|
+
import { speedOptions } from "../Const/speedOptions";
|
|
45
53
|
|
|
46
54
|
const { log_debug } = createLogger({
|
|
47
55
|
subsystem: "UIComponent",
|
|
@@ -83,51 +91,17 @@ type Props = {
|
|
|
83
91
|
|
|
84
92
|
const { width: SCREEN_WIDTH } = ScreenDimensions.get("screen");
|
|
85
93
|
|
|
86
|
-
const Styles = {
|
|
87
|
-
mainContainer: (style: ViewStyle) => {
|
|
88
|
-
const combinedStyle: ViewStyle = {
|
|
89
|
-
flex: 1,
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
...combinedStyle,
|
|
94
|
-
...style,
|
|
95
|
-
};
|
|
96
|
-
},
|
|
94
|
+
const Styles = StyleSheet.create({
|
|
97
95
|
playerContainer: {
|
|
98
96
|
flex: 1,
|
|
99
97
|
},
|
|
100
98
|
paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
|
|
101
|
-
|
|
102
|
-
controlsMobile: {
|
|
103
|
-
height: 50,
|
|
104
|
-
marginHorizontal: 24,
|
|
105
|
-
},
|
|
106
|
-
controlsTablet: {
|
|
107
|
-
height: 96,
|
|
108
|
-
marginHorizontal: 24,
|
|
109
|
-
},
|
|
110
99
|
playerDetails: {
|
|
111
100
|
marginTop: 60,
|
|
112
101
|
alignSelf: "center",
|
|
113
102
|
width: SCREEN_WIDTH - PADDING_HORIZONTAL * 2,
|
|
114
103
|
},
|
|
115
|
-
|
|
116
|
-
linearGradient: {
|
|
117
|
-
flex: 1,
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const sleeps = [
|
|
122
|
-
// { label: "End of episode", value: "episode" },
|
|
123
|
-
{ label: "5 minutes", value: 5 },
|
|
124
|
-
{ label: "10 minutes", value: 10 },
|
|
125
|
-
{ label: "15 minutes", value: 15 },
|
|
126
|
-
{ label: "30 minutes", value: 30 },
|
|
127
|
-
{ label: "45 minutes", value: 45 },
|
|
128
|
-
{ label: "1 hour", value: 60 },
|
|
129
|
-
{ label: "2 hours", value: 120 },
|
|
130
|
-
];
|
|
104
|
+
});
|
|
131
105
|
|
|
132
106
|
const edges: Edge[] = ["right", "left", "top"];
|
|
133
107
|
|
|
@@ -147,24 +121,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
147
121
|
isTabletPortrait,
|
|
148
122
|
} = props;
|
|
149
123
|
|
|
150
|
-
const speeds = [
|
|
151
|
-
{ asset: configuration["speed_0_8"] || speed_0_8, value: 0.8 },
|
|
152
|
-
{ asset: configuration["speed_1"] || speed_1, value: 1.0 },
|
|
153
|
-
{ asset: configuration["speed_1_2"] || speed_1_2, value: 1.2 },
|
|
154
|
-
{ asset: configuration["speed_1_5"] || speed_1_5, value: 1.5 },
|
|
155
|
-
{ asset: configuration["speed_2"] || speed_2, value: 2.0 },
|
|
156
|
-
];
|
|
157
|
-
|
|
158
124
|
const isTablet = useIsTablet();
|
|
159
125
|
|
|
160
126
|
const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
|
|
161
127
|
|
|
162
|
-
// TODO: Have generic place for live url from configuration. Currently its hardcoded for client.
|
|
163
|
-
|
|
164
|
-
const feedUrl = getLiveUrl(entry?.extensions?.live?.channel_src ?? "");
|
|
165
|
-
|
|
166
128
|
const { title, summary } = useTitleSummaryOverlay(
|
|
167
|
-
feedUrl,
|
|
168
129
|
entry,
|
|
169
130
|
playerState?.isLive,
|
|
170
131
|
configuration?.audio_live_player_update_interval
|
|
@@ -202,8 +163,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
202
163
|
height: 0,
|
|
203
164
|
});
|
|
204
165
|
|
|
205
|
-
const navigator = useNavigation();
|
|
206
|
-
|
|
207
166
|
const { maximiseVideoModal } = useNavigation();
|
|
208
167
|
|
|
209
168
|
const onLayout = (event: any) => {
|
|
@@ -293,44 +252,51 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
293
252
|
);
|
|
294
253
|
|
|
295
254
|
const onSpeedButtonPress = React.useCallback(() => {
|
|
296
|
-
|
|
255
|
+
openBottomSheetModal({
|
|
297
256
|
modalBottomSheetContentProps: {
|
|
298
|
-
items:
|
|
257
|
+
items: speedOptions,
|
|
299
258
|
current_selection: playbackSpeed,
|
|
300
259
|
onPress: onSpeedSelect,
|
|
301
260
|
title: configuration["playback_speed_title"],
|
|
261
|
+
itemProps: getBottomSheetModalItemProps,
|
|
262
|
+
iconProps: getBottomSheetModalIconProps,
|
|
263
|
+
labelProps: getBottomSheetModalLabelProps,
|
|
264
|
+
getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
|
|
265
|
+
getDefaultItemIcon: getBottomSheetModalDefaultItemIcon,
|
|
266
|
+
iconPlacement: "right",
|
|
302
267
|
},
|
|
303
268
|
options: {
|
|
304
|
-
supportedOrientations: [
|
|
269
|
+
supportedOrientations: [
|
|
270
|
+
"portrait",
|
|
271
|
+
"landscape",
|
|
272
|
+
"portrait-upside-down",
|
|
273
|
+
],
|
|
305
274
|
},
|
|
306
275
|
});
|
|
307
|
-
}, [
|
|
308
|
-
playbackSpeed,
|
|
309
|
-
setPlaybackSpeed,
|
|
310
|
-
navigator,
|
|
311
|
-
onSpeedSelect,
|
|
312
|
-
configuration["playback_speed_title"],
|
|
313
|
-
]);
|
|
276
|
+
}, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
|
|
314
277
|
|
|
315
278
|
const onSleepButtonPress = React.useCallback(() => {
|
|
316
|
-
|
|
279
|
+
openBottomSheetModal({
|
|
317
280
|
modalBottomSheetContentProps: {
|
|
318
|
-
items:
|
|
319
|
-
{
|
|
320
|
-
label: configuration["playback_sleep_off_label"],
|
|
321
|
-
value: 0,
|
|
322
|
-
},
|
|
323
|
-
].concat(sleeps),
|
|
281
|
+
items: getSleepTimerOptions(configuration),
|
|
324
282
|
current_selection: sleepTimerState.timer,
|
|
325
283
|
onPress: onSleepSelect,
|
|
326
284
|
title: configuration["playback_sleep_title"],
|
|
285
|
+
itemProps: getBottomSheetModalItemProps,
|
|
286
|
+
iconProps: getBottomSheetModalIconProps,
|
|
287
|
+
labelProps: getBottomSheetModalLabelProps,
|
|
288
|
+
getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
|
|
289
|
+
iconPlacement: "right",
|
|
327
290
|
},
|
|
328
291
|
options: {
|
|
329
|
-
supportedOrientations: [
|
|
292
|
+
supportedOrientations: [
|
|
293
|
+
"portrait",
|
|
294
|
+
"landscape",
|
|
295
|
+
"portrait-upside-down",
|
|
296
|
+
],
|
|
330
297
|
},
|
|
331
298
|
});
|
|
332
299
|
}, [
|
|
333
|
-
navigator,
|
|
334
300
|
sleepTimerState.timer,
|
|
335
301
|
configuration["playback_sleep_title"],
|
|
336
302
|
configuration["playback_sleep_off_label"],
|
|
@@ -366,7 +332,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
366
332
|
|
|
367
333
|
const MainContent = React.useMemo(() => {
|
|
368
334
|
return (
|
|
369
|
-
<SafeAreaView style={Styles.
|
|
335
|
+
<SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
|
|
370
336
|
<AnimationComponent
|
|
371
337
|
animationType={ComponentAnimationType.moveUpComponent}
|
|
372
338
|
additionalData={{ saveArea: true }}
|
|
@@ -410,11 +376,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
410
376
|
animationType={ComponentAnimationType.componentFade}
|
|
411
377
|
>
|
|
412
378
|
<PlayerDetails
|
|
379
|
+
isAudioPlayer
|
|
413
380
|
configuration={configuration}
|
|
414
381
|
style={Styles.playerDetails}
|
|
415
382
|
entry={entry}
|
|
416
383
|
isTabletLandscape={isTabletLandscape}
|
|
417
|
-
isAudioPlayer={true}
|
|
418
384
|
/>
|
|
419
385
|
</AnimationComponent>
|
|
420
386
|
</View>
|
|
@@ -5,7 +5,6 @@ import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
|
|
|
5
5
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
6
6
|
import {
|
|
7
7
|
Controls as MobileTransportControls,
|
|
8
|
-
CountDown,
|
|
9
8
|
ProgressBar,
|
|
10
9
|
} from "@applicaster/quick-brick-mobile-transport-controls";
|
|
11
10
|
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
@@ -29,8 +28,6 @@ import {
|
|
|
29
28
|
speedButton,
|
|
30
29
|
} from "./utils";
|
|
31
30
|
|
|
32
|
-
import { PlayerState, LayoutState } from "../types";
|
|
33
|
-
|
|
34
31
|
const styles = StyleSheet.create({
|
|
35
32
|
flex: {
|
|
36
33
|
flex: 1,
|
|
@@ -41,24 +38,29 @@ const styles = StyleSheet.create({
|
|
|
41
38
|
progressBar: {
|
|
42
39
|
flex: 0,
|
|
43
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
|
+
},
|
|
44
55
|
});
|
|
45
56
|
|
|
46
|
-
const
|
|
47
|
-
|
|
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
|
+
const getControlJustifyContent = (countOfButtons: number) =>
|
|
58
|
+
countOfButtons <= 1 ? "center" : "space-between";
|
|
57
59
|
|
|
58
60
|
type Props = {
|
|
59
61
|
entry: ZappEntry;
|
|
60
|
-
layoutState: LayoutState;
|
|
61
|
-
playerState: PlayerState;
|
|
62
|
+
layoutState: QuickBrickPlayer.LayoutState;
|
|
63
|
+
playerState: QuickBrickPlayer.PlayerState;
|
|
62
64
|
value: GetValue;
|
|
63
65
|
title: string | number;
|
|
64
66
|
summary: string | number;
|
|
@@ -119,14 +121,19 @@ export const Controls = (props: Props) => {
|
|
|
119
121
|
showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
const sleepTitle = value("playback_sleep_countdown_label");
|
|
123
|
-
|
|
124
124
|
const [timeLeft, setTimeLeft] = React.useState(
|
|
125
125
|
sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
|
|
126
126
|
);
|
|
127
127
|
|
|
128
128
|
const showCounter = React.useMemo(() => sleepTimerDate > 0, [sleepTimerDate]);
|
|
129
129
|
|
|
130
|
+
const countDownOptions = React.useMemo(() => {
|
|
131
|
+
return {
|
|
132
|
+
showCounter: showCounter && timeLeft >= 0,
|
|
133
|
+
timeLeft,
|
|
134
|
+
};
|
|
135
|
+
}, [showCounter, timeLeft]);
|
|
136
|
+
|
|
130
137
|
React.useEffect(() => {
|
|
131
138
|
if (showCounter && sleepTimerDate !== 0) {
|
|
132
139
|
setTimeLeft(sleepTimerDate - Date.now());
|
|
@@ -284,12 +291,12 @@ export const Controls = (props: Props) => {
|
|
|
284
291
|
isDateBasedLiveContent={isDateBasedLiveContent}
|
|
285
292
|
onSkipLive={onSkipLive}
|
|
286
293
|
progressBarStyles={styles.progressBar}
|
|
294
|
+
countDownOptions={countDownOptions}
|
|
295
|
+
thumbStyles={styles.progressBarThumbStyles}
|
|
296
|
+
thumbStylesPressed={styles.progressBarThumbStyles_pressed}
|
|
297
|
+
trackStyles={styles.progressBarTrackStyles}
|
|
287
298
|
/>
|
|
288
299
|
|
|
289
|
-
{showCounter && timeLeft >= 0 ? (
|
|
290
|
-
<CountDown timeLeft={timeLeft} value={value} title={sleepTitle} />
|
|
291
|
-
) : null}
|
|
292
|
-
|
|
293
300
|
<VerticalGutter />
|
|
294
301
|
</>
|
|
295
302
|
) : null}
|
|
@@ -299,7 +306,9 @@ export const Controls = (props: Props) => {
|
|
|
299
306
|
visible={true}
|
|
300
307
|
keepAlive={null}
|
|
301
308
|
buttons={controlButtons}
|
|
302
|
-
style={
|
|
309
|
+
style={{
|
|
310
|
+
justifyContent: getControlJustifyContent(controlButtons().length),
|
|
311
|
+
}}
|
|
303
312
|
playerState={playerState}
|
|
304
313
|
/>
|
|
305
314
|
</AnimationComponent>
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import { PlayerState } from "../types";
|
|
2
|
-
|
|
3
|
-
const rewindButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
|
|
4
|
-
isTablet ? "big" : "smallMargins";
|
|
5
|
-
|
|
6
|
-
const playbackButtonSize = (isTablet: boolean): keyof ButtonSizeStyles =>
|
|
7
|
-
isTablet ? "bigExtended" : "mediumExtended";
|
|
8
|
-
|
|
9
1
|
const playbackButtonMargins = (
|
|
10
2
|
isTablet: boolean,
|
|
11
3
|
isLiveShowFullControls: boolean
|
|
12
|
-
): number =>
|
|
13
|
-
isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
|
|
4
|
+
): number => (isLiveShowFullControls ? (isTablet ? 65 : 10) : undefined);
|
|
14
5
|
|
|
15
6
|
export const playbackButton = ({
|
|
16
7
|
playerState,
|
|
@@ -19,7 +10,7 @@ export const playbackButton = ({
|
|
|
19
10
|
isLiveShowFullControls,
|
|
20
11
|
onPress,
|
|
21
12
|
}: {
|
|
22
|
-
playerState: PlayerState;
|
|
13
|
+
playerState: QuickBrickPlayer.PlayerState;
|
|
23
14
|
liveButton: boolean;
|
|
24
15
|
isTablet: boolean;
|
|
25
16
|
isLiveShowFullControls: boolean;
|
|
@@ -32,7 +23,7 @@ export const playbackButton = ({
|
|
|
32
23
|
: "pause";
|
|
33
24
|
|
|
34
25
|
return {
|
|
35
|
-
size:
|
|
26
|
+
size: "bigExtended",
|
|
36
27
|
icon: playerState.isBuffering ? "buffering" : icon,
|
|
37
28
|
preferredFocus: true,
|
|
38
29
|
onPress,
|
|
@@ -54,10 +45,9 @@ type ButtonsByNameProps = ButtonsProps & { name?: string };
|
|
|
54
45
|
const rewindButtonByName = ({
|
|
55
46
|
name,
|
|
56
47
|
onPress,
|
|
57
|
-
isTablet,
|
|
58
48
|
style,
|
|
59
49
|
}: ButtonsByNameProps): ControlsButton => ({
|
|
60
|
-
size:
|
|
50
|
+
size: "big",
|
|
61
51
|
icon: name,
|
|
62
52
|
onPress,
|
|
63
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
|
+
);
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
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
21
|
AnimationComponent,
|
|
21
22
|
ComponentAnimationType,
|
|
@@ -24,15 +25,13 @@ import {
|
|
|
24
25
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
25
26
|
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
26
27
|
|
|
27
|
-
import { LayoutState, PlayerState, Configuration, DimensionsT } from "../types";
|
|
28
|
-
|
|
29
28
|
type Props = {
|
|
30
29
|
entry: ZappEntry;
|
|
31
|
-
layoutState: LayoutState;
|
|
32
|
-
playerState: PlayerState;
|
|
30
|
+
layoutState: QuickBrickPlayer.LayoutState;
|
|
31
|
+
playerState: QuickBrickPlayer.PlayerState;
|
|
33
32
|
value: GetValue;
|
|
34
|
-
configuration:
|
|
35
|
-
dimensions:
|
|
33
|
+
configuration: QuickBrickPlayer.AudioPlayerProps["configuration"];
|
|
34
|
+
dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
|
|
36
35
|
onCloseVideoModal: () => void;
|
|
37
36
|
onPlayerSeek: (targetTime: number) => void;
|
|
38
37
|
playNextData: PlayNextData;
|
|
@@ -110,7 +109,7 @@ const animatedContainerStyle = (
|
|
|
110
109
|
});
|
|
111
110
|
|
|
112
111
|
const backgroundImageStyle = (
|
|
113
|
-
dimensions:
|
|
112
|
+
dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"],
|
|
114
113
|
minimisedHeight: number,
|
|
115
114
|
isActiveGesture: boolean
|
|
116
115
|
): ViewStyle => ({
|
|
@@ -219,6 +218,7 @@ export const DockedControls = (props: Props) => {
|
|
|
219
218
|
isActiveGesture || layoutState.docked,
|
|
220
219
|
progressBarHeight
|
|
221
220
|
),
|
|
221
|
+
{ height: minimisedHeight },
|
|
222
222
|
]}
|
|
223
223
|
>
|
|
224
224
|
{!playerState.isLive &&
|
|
@@ -6,15 +6,21 @@ import {
|
|
|
6
6
|
} from "react-native-safe-area-context";
|
|
7
7
|
import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
8
8
|
|
|
9
|
-
import { MOBILE } from "./const";
|
|
10
|
-
import { Props } from "./types";
|
|
9
|
+
import { MOBILE, NAVBAR_HEIGHT } from "./const";
|
|
11
10
|
import { TransportInfo } from "./TransportInfo";
|
|
12
11
|
import { PlayerImage } from "./PlayerImage";
|
|
13
12
|
import { Controls } from "./Controls";
|
|
14
13
|
|
|
15
|
-
import {
|
|
14
|
+
import { useMobileLayoutImageSize, useTransportInfoHeight } from "./hooks";
|
|
16
15
|
import { DockedControls } from "./DockedControls";
|
|
17
|
-
import { withDebug } from "./debug";
|
|
16
|
+
import { withDebug, DEBUG } from "./debug";
|
|
17
|
+
import {
|
|
18
|
+
LeftDebugSquare,
|
|
19
|
+
RightDebugSquare,
|
|
20
|
+
BottomDebugSquare,
|
|
21
|
+
} from "./Debug/index";
|
|
22
|
+
|
|
23
|
+
import { Props } from "./types";
|
|
18
24
|
|
|
19
25
|
const styles = StyleSheet.create({
|
|
20
26
|
container: {
|
|
@@ -29,6 +35,8 @@ const styles = StyleSheet.create({
|
|
|
29
35
|
flex: 1,
|
|
30
36
|
justifyContent: "flex-start",
|
|
31
37
|
|
|
38
|
+
minHeight: MOBILE.MIN_HEIGHT,
|
|
39
|
+
|
|
32
40
|
marginLeft: MOBILE.MARGIN_HORIZONTAL,
|
|
33
41
|
marginRight: MOBILE.MARGIN_HORIZONTAL,
|
|
34
42
|
|
|
@@ -87,11 +95,27 @@ export function MobileLayout({
|
|
|
87
95
|
const { height: screenHeight } = useSafeAreaFrame();
|
|
88
96
|
const { progressBarHeight } = useModalAnimationContext();
|
|
89
97
|
|
|
90
|
-
const { imageSize
|
|
98
|
+
const { imageSize } = useMobileLayoutImageSize();
|
|
91
99
|
|
|
92
100
|
const { height: transportInfoHeight, onLayout: onTransportInfoLayout } =
|
|
93
101
|
useTransportInfoHeight();
|
|
94
102
|
|
|
103
|
+
const controlsContainerHeight = React.useMemo(() => {
|
|
104
|
+
return (
|
|
105
|
+
screenHeight -
|
|
106
|
+
topInset -
|
|
107
|
+
imageSize -
|
|
108
|
+
NAVBAR_HEIGHT -
|
|
109
|
+
MOBILE.MARGIN_BOTTOM -
|
|
110
|
+
MOBILE.MARGIN_TOP -
|
|
111
|
+
bottomInset
|
|
112
|
+
);
|
|
113
|
+
}, [screenHeight, topInset, imageSize, bottomInset]);
|
|
114
|
+
|
|
115
|
+
const verticalOffsetForImage = React.useMemo(() => {
|
|
116
|
+
return transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight;
|
|
117
|
+
}, [transportInfoHeight, progressBarHeight]);
|
|
118
|
+
|
|
95
119
|
return (
|
|
96
120
|
<View
|
|
97
121
|
style={[
|
|
@@ -104,6 +128,10 @@ export function MobileLayout({
|
|
|
104
128
|
}),
|
|
105
129
|
]}
|
|
106
130
|
>
|
|
131
|
+
{DEBUG ? <LeftDebugSquare /> : null}
|
|
132
|
+
{DEBUG ? <RightDebugSquare /> : null}
|
|
133
|
+
{DEBUG ? <BottomDebugSquare /> : null}
|
|
134
|
+
|
|
107
135
|
{/* TransportInfo */}
|
|
108
136
|
<TransportInfo
|
|
109
137
|
entry={entry}
|
|
@@ -136,7 +164,6 @@ export function MobileLayout({
|
|
|
136
164
|
}),
|
|
137
165
|
},
|
|
138
166
|
]}
|
|
139
|
-
onLayout={onLayout}
|
|
140
167
|
>
|
|
141
168
|
<PlayerImage
|
|
142
169
|
entry={entry}
|
|
@@ -152,20 +179,15 @@ export function MobileLayout({
|
|
|
152
179
|
summary={summary}
|
|
153
180
|
docked={docked}
|
|
154
181
|
imageWidth={imageSize}
|
|
155
|
-
verticalOffset={
|
|
156
|
-
transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight
|
|
157
|
-
}
|
|
182
|
+
verticalOffset={verticalOffsetForImage}
|
|
158
183
|
/>
|
|
159
184
|
</View>
|
|
160
185
|
{/* PlayerImage */}
|
|
161
186
|
|
|
162
187
|
<View
|
|
163
|
-
style={
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
marginBottom: MOBILE.MARGIN_BOTTOM,
|
|
167
|
-
},
|
|
168
|
-
]}
|
|
188
|
+
style={{
|
|
189
|
+
height: controlsContainerHeight,
|
|
190
|
+
}}
|
|
169
191
|
>
|
|
170
192
|
<Controls
|
|
171
193
|
entry={entry}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { Image, Animated, StyleSheet, ViewStyle } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
5
5
|
import {
|
|
@@ -14,6 +14,7 @@ const styles = StyleSheet.create({
|
|
|
14
14
|
// we have to specify flex:0 and dimensions to make animation work
|
|
15
15
|
flex: 0,
|
|
16
16
|
aspectRatio: 1,
|
|
17
|
+
overflow: "hidden",
|
|
17
18
|
},
|
|
18
19
|
});
|
|
19
20
|
|
|
@@ -21,13 +22,15 @@ type Props = PropsWithChildren<{
|
|
|
21
22
|
entry: ZappEntry;
|
|
22
23
|
style?: { [K: string]: any };
|
|
23
24
|
imageStyle?: { [K: string]: any };
|
|
25
|
+
wrapperViewStyle?: ViewStyle;
|
|
24
26
|
imageWidth: number;
|
|
25
27
|
}>;
|
|
26
28
|
|
|
27
|
-
export const
|
|
29
|
+
export const AnimatedImage = ({
|
|
28
30
|
entry,
|
|
29
31
|
style,
|
|
30
32
|
imageStyle,
|
|
33
|
+
wrapperViewStyle,
|
|
31
34
|
imageWidth,
|
|
32
35
|
}: Props) => {
|
|
33
36
|
const heightAnim = React.useRef(new Animated.Value(imageWidth)).current;
|
|
@@ -59,25 +62,22 @@ export const ScaledImage = ({
|
|
|
59
62
|
}
|
|
60
63
|
}, [playerAnimationState, imageWidth]);
|
|
61
64
|
|
|
62
|
-
if (!source) return
|
|
65
|
+
if (!source) return null;
|
|
63
66
|
|
|
64
67
|
return (
|
|
65
68
|
<Animated.View
|
|
66
69
|
style={[
|
|
67
70
|
styles.container,
|
|
71
|
+
wrapperViewStyle,
|
|
72
|
+
imageStyle,
|
|
68
73
|
{
|
|
69
74
|
width: heightAnim,
|
|
70
75
|
},
|
|
71
76
|
]}
|
|
72
77
|
>
|
|
73
|
-
<
|
|
74
|
-
resizeMode="cover"
|
|
75
|
-
style={style}
|
|
76
|
-
imageStyle={imageStyle}
|
|
77
|
-
source={source}
|
|
78
|
-
>
|
|
78
|
+
<Image resizeMode="cover" style={style} source={source}>
|
|
79
79
|
{null}
|
|
80
|
-
</
|
|
80
|
+
</Image>
|
|
81
81
|
</Animated.View>
|
|
82
82
|
);
|
|
83
83
|
};
|