@applicaster/quick-brick-player 12.0.0-alpha.9151207838 → 12.0.0-alpha.9233494544
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 -6
- package/src/CellPlayer/Assets/AssetsComponent.tsx +2 -1
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +94 -80
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +147 -68
- package/src/Player/AudioLayer/Layout/DockedLayout.tsx +65 -22
- package/src/Player/AudioLayer/Layout/defaultLayoutsConts.ts +2 -0
- package/src/Player/AudioLayer/Layout/index.tsx +1 -7
- package/src/Player/AudioLayer/MagicBG/index.tsx +40 -22
- package/src/Player/index.tsx +102 -52
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-player",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.9233494544",
|
|
4
4
|
"description": "Quick Brick Player",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@applicaster/quick-brick-mobile-transport-controls": "12.0.0-
|
|
40
|
-
"@applicaster/quick-brick-tv-transport-controls": "
|
|
41
|
-
"@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.
|
|
43
|
-
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.
|
|
39
|
+
"@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.51",
|
|
40
|
+
"@applicaster/quick-brick-tv-transport-controls": "12.0.0-alpha.9233494544",
|
|
41
|
+
"@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.9233494544",
|
|
42
|
+
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.9233494544",
|
|
43
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.9233494544",
|
|
44
44
|
"keymirror": "^0.1.1",
|
|
45
45
|
"query-string": "7.1.3",
|
|
46
46
|
"react-native-web-linear-gradient": "1.1.2",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
3
3
|
import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
|
|
4
4
|
import { MUTED_USAGE } from "../const";
|
|
5
5
|
import { LiveImageManager } from "@applicaster/zapp-react-native-ui-components/Components/VideoLive/LiveImageManager";
|
|
6
|
+
import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
|
|
6
7
|
|
|
7
8
|
type Asset = string | undefined;
|
|
8
9
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { ViewStyle, View
|
|
2
|
+
import { ViewStyle, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { SafeAreaView, Edge } from "react-native-safe-area-context";
|
|
5
5
|
import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
|
|
@@ -17,8 +17,6 @@ import { PlayerDetails } from "@applicaster/zapp-react-native-ui-components/Comp
|
|
|
17
17
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
18
18
|
import { useEffect, useState } from "react";
|
|
19
19
|
import { MagicBG } from "./MagicBG";
|
|
20
|
-
import { addQueryParam, getLiveUrl } from "../Utils";
|
|
21
|
-
import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
|
|
22
20
|
import {
|
|
23
21
|
formatSpeed,
|
|
24
22
|
hasDatePassed,
|
|
@@ -26,6 +24,14 @@ import {
|
|
|
26
24
|
NAMESPACE,
|
|
27
25
|
} from "./utils";
|
|
28
26
|
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
|
|
27
|
+
import { addQueryParam, getLiveUrl } from "../Utils";
|
|
28
|
+
import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
|
|
29
|
+
import {
|
|
30
|
+
AnimationComponent,
|
|
31
|
+
ComponentAnimationType,
|
|
32
|
+
AnimatedScrollModal,
|
|
33
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
34
|
+
import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
|
|
29
35
|
|
|
30
36
|
const { log_debug } = createLogger({
|
|
31
37
|
subsystem: "UIComponent",
|
|
@@ -48,7 +54,7 @@ type Configuration = {
|
|
|
48
54
|
};
|
|
49
55
|
|
|
50
56
|
type Props = {
|
|
51
|
-
children
|
|
57
|
+
children?: React.ReactNode;
|
|
52
58
|
inline?: boolean;
|
|
53
59
|
docked?: boolean;
|
|
54
60
|
configuration: Configuration;
|
|
@@ -68,29 +74,20 @@ export const defaultAspectRatioWidth = (height: number): number =>
|
|
|
68
74
|
(height / 9) * 16;
|
|
69
75
|
|
|
70
76
|
const Styles = {
|
|
71
|
-
mainContainer: (
|
|
77
|
+
mainContainer: (style: ViewStyle) => {
|
|
72
78
|
const combinedStyle: ViewStyle = {
|
|
73
79
|
flex: 1,
|
|
74
80
|
};
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
style
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return { ...combinedStyle, ...style };
|
|
82
|
-
},
|
|
83
|
-
playerContainer: (docked: boolean, style: ViewStyle) => {
|
|
84
|
-
const combinedStyle: ViewStyle = {
|
|
85
|
-
flex: 1,
|
|
82
|
+
return {
|
|
83
|
+
...combinedStyle,
|
|
84
|
+
...style,
|
|
86
85
|
};
|
|
87
|
-
|
|
88
|
-
if (docked) {
|
|
89
|
-
combinedStyle.height = style.height;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return combinedStyle;
|
|
93
86
|
},
|
|
87
|
+
playerContainer: {
|
|
88
|
+
flex: 1,
|
|
89
|
+
},
|
|
90
|
+
paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
|
|
94
91
|
|
|
95
92
|
controlsMobile: {
|
|
96
93
|
height: 50,
|
|
@@ -145,6 +142,17 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
145
142
|
|
|
146
143
|
const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
|
|
147
144
|
|
|
145
|
+
// TODO: Have generic place for live url from configuration. Currently its hardcoded for client.
|
|
146
|
+
|
|
147
|
+
const feedUrl = getLiveUrl(entry?.extensions?.live?.channel_src ?? "");
|
|
148
|
+
|
|
149
|
+
const { title, summary } = useTitleSummaryOverlay(
|
|
150
|
+
feedUrl,
|
|
151
|
+
entry,
|
|
152
|
+
playerState?.isLive,
|
|
153
|
+
configuration?.audio_live_player_update_interval
|
|
154
|
+
);
|
|
155
|
+
|
|
148
156
|
const [playbackSpeed, setPlaybackSpeed] = useState({
|
|
149
157
|
asset: configuration["speed_1"],
|
|
150
158
|
value: 1.0,
|
|
@@ -157,14 +165,8 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
157
165
|
|
|
158
166
|
const [sleepTimerDate, setSleepTimerDate] = useState(0);
|
|
159
167
|
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
const { title, summary } = useTitleSummaryOverlay(
|
|
163
|
-
feedUrl,
|
|
164
|
-
entry,
|
|
165
|
-
playerState?.isLive,
|
|
166
|
-
configuration?.audio_live_player_update_interval || 60
|
|
167
|
-
);
|
|
168
|
+
const [defaultDimensions, setDefaultDimensions] =
|
|
169
|
+
React.useState<Dimensions>(undefined);
|
|
168
170
|
|
|
169
171
|
const [dimensions, setDimensions] = React.useState<Dimensions>({
|
|
170
172
|
width: 0,
|
|
@@ -179,9 +181,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
179
181
|
const { width, height } = event.nativeEvent.layout;
|
|
180
182
|
|
|
181
183
|
setDimensions({
|
|
182
|
-
width
|
|
184
|
+
width,
|
|
183
185
|
height,
|
|
184
186
|
});
|
|
187
|
+
|
|
188
|
+
if (!defaultDimensions) setDefaultDimensions({ width, height });
|
|
185
189
|
};
|
|
186
190
|
|
|
187
191
|
const cancelSleepTimer = async () => {
|
|
@@ -193,7 +197,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
193
197
|
});
|
|
194
198
|
|
|
195
199
|
setSleepTimerDate(0);
|
|
196
|
-
player?.pause();
|
|
197
200
|
|
|
198
201
|
await localStorage.removeItem("sleep", NAMESPACE);
|
|
199
202
|
};
|
|
@@ -374,58 +377,64 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
374
377
|
player?.seekTo(0);
|
|
375
378
|
}, [player]);
|
|
376
379
|
|
|
377
|
-
const edges = React.useMemo<Edge[]>(
|
|
378
|
-
() => (docked ? [] : ["right", "left", "top"]),
|
|
379
|
-
[docked]
|
|
380
|
-
);
|
|
380
|
+
const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
|
|
381
381
|
|
|
382
|
-
const ContainerView =
|
|
382
|
+
const ContainerView = SafeAreaView;
|
|
383
383
|
|
|
384
384
|
const MainContent = React.useMemo(() => {
|
|
385
385
|
return (
|
|
386
|
-
<ContainerView style={Styles.mainContainer(
|
|
387
|
-
<
|
|
388
|
-
|
|
389
|
-
|
|
386
|
+
<ContainerView style={Styles.mainContainer(style)} edges={edges}>
|
|
387
|
+
<AnimationComponent
|
|
388
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
389
|
+
additionalData={{ saveArea: true }}
|
|
390
390
|
>
|
|
391
|
-
<
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
391
|
+
<AnimatedScrollModal>
|
|
392
|
+
<View style={Styles.playerContainer} onLayout={onLayout}>
|
|
393
|
+
<Layout
|
|
394
|
+
entry={entry}
|
|
395
|
+
playerState={playerState}
|
|
396
|
+
layoutState={layoutState}
|
|
397
|
+
value={value}
|
|
398
|
+
onPlaybackButtonPress={onPlaybackButtonPress}
|
|
399
|
+
onRewindButtonPress={onRewindButtonPress}
|
|
400
|
+
onForwardButtonPress={onForwardButtonPress}
|
|
401
|
+
onPlayerSeek={onPlayerSeek}
|
|
402
|
+
onSkipStart={onSkipStart}
|
|
403
|
+
onSpeedButtonPress={onSpeedButtonPress}
|
|
404
|
+
onSleepButtonPress={onSleepButtonPress}
|
|
405
|
+
playbackSpeedName={formatSpeed(playbackSpeed.value)}
|
|
406
|
+
playbackSleepName={
|
|
407
|
+
sleepTimer.value === 0 ? "sleep_timer" : "sleep_timer_active"
|
|
408
|
+
}
|
|
409
|
+
sleepTimerDate={sleepTimerDate}
|
|
410
|
+
cancelSleepTimer={cancelSleepTimer}
|
|
411
|
+
onSkipLive={onSkipLive}
|
|
412
|
+
onCloseVideoModal={onCloseVideoModal}
|
|
413
|
+
maximiseVideoModal={maximiseVideoModal}
|
|
414
|
+
configuration={configuration}
|
|
415
|
+
dimensions={dimensions}
|
|
416
|
+
playNextData={playNextData}
|
|
417
|
+
title={title}
|
|
418
|
+
summary={summary}
|
|
419
|
+
defaultDimensions={defaultDimensions}
|
|
420
|
+
/>
|
|
421
|
+
<View style={Styles.paddingHorizontal}>
|
|
422
|
+
{children}
|
|
423
|
+
<AnimationComponent
|
|
424
|
+
animationType={ComponentAnimationType.componentFade}
|
|
425
|
+
>
|
|
426
|
+
<PlayerDetails
|
|
427
|
+
configuration={configuration}
|
|
428
|
+
style={Styles.playerDetails}
|
|
429
|
+
entry={entry}
|
|
430
|
+
isTabletLandscape={isTabletLandscape}
|
|
431
|
+
isAudioPlayer={true}
|
|
432
|
+
/>
|
|
433
|
+
</AnimationComponent>
|
|
434
|
+
</View>
|
|
435
|
+
</View>
|
|
436
|
+
</AnimatedScrollModal>
|
|
437
|
+
</AnimationComponent>
|
|
429
438
|
</ContainerView>
|
|
430
439
|
);
|
|
431
440
|
}, [
|
|
@@ -457,12 +466,17 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
457
466
|
const queryParamName =
|
|
458
467
|
configuration.audio_player_background_image_query || "width";
|
|
459
468
|
|
|
460
|
-
const queryParamValue =
|
|
469
|
+
const queryParamValue = 15;
|
|
461
470
|
|
|
462
471
|
const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
|
|
463
472
|
|
|
464
473
|
return (
|
|
465
|
-
<MagicBG
|
|
474
|
+
<MagicBG
|
|
475
|
+
image={url}
|
|
476
|
+
fallbackUrl={baseUrl}
|
|
477
|
+
colors={entry?.extensions?.backgroundColors}
|
|
478
|
+
defaultColor="#000000"
|
|
479
|
+
>
|
|
466
480
|
{MainContent}
|
|
467
481
|
</MagicBG>
|
|
468
482
|
);
|
|
@@ -11,20 +11,28 @@ import {
|
|
|
11
11
|
|
|
12
12
|
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
13
13
|
|
|
14
|
-
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks
|
|
14
|
+
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
15
15
|
import {
|
|
16
16
|
forwardButton,
|
|
17
17
|
playbackButton,
|
|
18
18
|
rewindButton,
|
|
19
19
|
skipToStartButton,
|
|
20
20
|
skipToLiveButton,
|
|
21
|
+
PADDING_HORIZONTAL,
|
|
21
22
|
speedButton,
|
|
22
23
|
sleepButton,
|
|
23
24
|
} from "./defaultLayoutsConts";
|
|
24
25
|
import { AudioDescription } from "../AudioDescription";
|
|
25
26
|
import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
|
|
26
27
|
import { useLanguageData } from "@applicaster/zapp-react-native-utils/reactHooks/player";
|
|
28
|
+
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
27
29
|
import { useEffect, useMemo, useState } from "react";
|
|
30
|
+
import {
|
|
31
|
+
useModalAnimationContext,
|
|
32
|
+
AnimationComponent,
|
|
33
|
+
ComponentAnimationType,
|
|
34
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
35
|
+
import DockedLayout from "./DockedLayout";
|
|
28
36
|
|
|
29
37
|
type Dimensions = {
|
|
30
38
|
width: number;
|
|
@@ -60,9 +68,13 @@ type LayoutProps = {
|
|
|
60
68
|
onPlayerSeek: (targetTime: number) => void;
|
|
61
69
|
onSkipLive: () => void;
|
|
62
70
|
onSkipStart: () => void;
|
|
71
|
+
onCloseVideoModal: () => void;
|
|
72
|
+
maximiseVideoModal: () => void;
|
|
63
73
|
dimensions: Dimensions;
|
|
74
|
+
playNextData: PlayNextData;
|
|
64
75
|
title: string | number;
|
|
65
76
|
summary: string | number;
|
|
77
|
+
defaultDimensions: Dimensions;
|
|
66
78
|
};
|
|
67
79
|
|
|
68
80
|
const Styles = {
|
|
@@ -72,10 +84,13 @@ const Styles = {
|
|
|
72
84
|
alignItems: "center",
|
|
73
85
|
justifyContent: isPortraitMode ? "center" : "flex-start",
|
|
74
86
|
}),
|
|
75
|
-
|
|
76
|
-
width:
|
|
87
|
+
playerImageWrapper: {
|
|
88
|
+
width: "100%",
|
|
77
89
|
maxHeight: 750,
|
|
78
90
|
marginTop: 80,
|
|
91
|
+
},
|
|
92
|
+
tabletLayout: {
|
|
93
|
+
width: 463,
|
|
79
94
|
marginBottom: 80,
|
|
80
95
|
},
|
|
81
96
|
controls: (isTablet: boolean, isLiveShowFullControls: boolean) => ({
|
|
@@ -84,24 +99,31 @@ const Styles = {
|
|
|
84
99
|
justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
|
|
85
100
|
}),
|
|
86
101
|
backgroundImageContainer: (dimensions: Dimensions, isTablet: boolean) => {
|
|
102
|
+
const mobileValue = dimensions.width
|
|
103
|
+
? dimensions.width - PADDING_HORIZONTAL * 2
|
|
104
|
+
: 330;
|
|
105
|
+
|
|
87
106
|
return {
|
|
88
|
-
width: isTablet ? 463 :
|
|
89
|
-
height: isTablet ? 463 :
|
|
107
|
+
width: isTablet ? 463 : mobileValue,
|
|
108
|
+
height: isTablet ? 463 : mobileValue,
|
|
90
109
|
};
|
|
91
110
|
},
|
|
92
|
-
backgroundImageContainerImageStyle: (
|
|
93
|
-
|
|
111
|
+
backgroundImageContainerImageStyle: (
|
|
112
|
+
isTablet,
|
|
113
|
+
docked,
|
|
114
|
+
startComponentsAnimation,
|
|
115
|
+
isActiveGesture
|
|
116
|
+
) => ({
|
|
117
|
+
borderRadius:
|
|
118
|
+
(startComponentsAnimation && isActiveGesture) || docked
|
|
119
|
+
? 0
|
|
120
|
+
: isTablet
|
|
121
|
+
? 24
|
|
122
|
+
: 10,
|
|
94
123
|
}),
|
|
95
|
-
playerContainer: (docked: boolean, style) => {
|
|
96
|
-
const combinedStyle = {
|
|
97
|
-
flex: 1,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
if (docked) {
|
|
101
|
-
combinedStyle["height"] = style.height;
|
|
102
|
-
}
|
|
103
124
|
|
|
104
|
-
|
|
125
|
+
paddingHorizontal: {
|
|
126
|
+
paddingHorizontal: PADDING_HORIZONTAL,
|
|
105
127
|
},
|
|
106
128
|
|
|
107
129
|
controlsMobile: {
|
|
@@ -115,6 +137,12 @@ const Styles = {
|
|
|
115
137
|
separator: {
|
|
116
138
|
height: 20,
|
|
117
139
|
},
|
|
140
|
+
flexDirectionRow: {
|
|
141
|
+
flexDirection: "row",
|
|
142
|
+
},
|
|
143
|
+
alignItemsCenter: {
|
|
144
|
+
alignItems: "center",
|
|
145
|
+
},
|
|
118
146
|
};
|
|
119
147
|
|
|
120
148
|
export default function DefaultLayout(props: LayoutProps) {
|
|
@@ -139,12 +167,14 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
139
167
|
sleepTimerDate,
|
|
140
168
|
title,
|
|
141
169
|
summary,
|
|
170
|
+
defaultDimensions,
|
|
142
171
|
} = props;
|
|
143
172
|
|
|
144
173
|
const isTablet = useIsTablet();
|
|
145
174
|
const { width, height } = dimensions;
|
|
146
175
|
const isPortraitMode = width < height;
|
|
147
176
|
const isLiveContent = playerState.isLive;
|
|
177
|
+
const docked = layoutState.docked;
|
|
148
178
|
|
|
149
179
|
const languageData = useLanguageData("audio-player");
|
|
150
180
|
|
|
@@ -251,7 +281,7 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
251
281
|
|
|
252
282
|
// Setting up an interval to update the remaining time every second
|
|
253
283
|
const intervalId = setInterval(() => {
|
|
254
|
-
setTimeLeft((
|
|
284
|
+
setTimeLeft(() => {
|
|
255
285
|
const newTimeLeft = sleepTimerDate - Date.now();
|
|
256
286
|
|
|
257
287
|
// If the new remaining time is less than or equal to 0, clear the interval and trigger the cancelSleepTimer function
|
|
@@ -283,71 +313,120 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
283
313
|
const needsToShowProgressBar =
|
|
284
314
|
(isLiveContent && liveSeekingEnabled) || !isLiveContent;
|
|
285
315
|
|
|
316
|
+
const defaultImageDimensions = React.useMemo(
|
|
317
|
+
() =>
|
|
318
|
+
defaultDimensions &&
|
|
319
|
+
Styles.backgroundImageContainer(defaultDimensions, isTablet),
|
|
320
|
+
[defaultDimensions]
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
const { isActiveGesture, startComponentsAnimation } =
|
|
324
|
+
useModalAnimationContext();
|
|
325
|
+
|
|
286
326
|
return (
|
|
287
327
|
<View
|
|
288
328
|
style={
|
|
289
329
|
isTablet ? Styles.tabletContainer(isPortraitMode) : Styles.container
|
|
290
330
|
}
|
|
291
331
|
>
|
|
292
|
-
<
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
332
|
+
<AnimationComponent animationType={ComponentAnimationType.componentFade}>
|
|
333
|
+
<TransportInfo
|
|
334
|
+
content={entry}
|
|
335
|
+
value={value}
|
|
336
|
+
visible={true}
|
|
337
|
+
languageData={languageData}
|
|
338
|
+
layoutState={layoutState}
|
|
339
|
+
actionButtons={actionButtons}
|
|
340
|
+
/>
|
|
341
|
+
</AnimationComponent>
|
|
342
|
+
<AnimationComponent
|
|
343
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
344
|
+
style={isTablet ? Styles.playerImageWrapper : null}
|
|
304
345
|
>
|
|
305
|
-
<
|
|
346
|
+
<AnimationComponent
|
|
347
|
+
animationType={ComponentAnimationType.moveComponentHorizontal}
|
|
348
|
+
additionalData={{
|
|
349
|
+
disableAnimatedComponent: !isTablet,
|
|
350
|
+
moveValue: (dimensions.width - 463) / 2,
|
|
351
|
+
extraAnimation: !isTablet
|
|
352
|
+
? {
|
|
353
|
+
[ComponentAnimationType.audioPlayerPaddingHorizontal]: {
|
|
354
|
+
style: Styles.paddingHorizontal,
|
|
355
|
+
},
|
|
356
|
+
}
|
|
357
|
+
: null,
|
|
358
|
+
}}
|
|
359
|
+
style={isTablet ? Styles.alignItemsCenter : null}
|
|
360
|
+
>
|
|
306
361
|
<PlayerImageBackground
|
|
307
362
|
entry={entry}
|
|
308
363
|
style={Styles.backgroundImageContainer(dimensions, isTablet)}
|
|
309
|
-
imageStyle={Styles.backgroundImageContainerImageStyle(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
364
|
+
imageStyle={Styles.backgroundImageContainerImageStyle(
|
|
365
|
+
isTablet,
|
|
366
|
+
docked,
|
|
367
|
+
startComponentsAnimation,
|
|
368
|
+
isActiveGesture
|
|
369
|
+
)}
|
|
370
|
+
defaultImageDimensions={defaultImageDimensions}
|
|
316
371
|
/>
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
372
|
+
</AnimationComponent>
|
|
373
|
+
|
|
374
|
+
<DockedLayout {...props} />
|
|
375
|
+
</AnimationComponent>
|
|
376
|
+
<View
|
|
377
|
+
style={[
|
|
378
|
+
Styles.paddingHorizontal,
|
|
379
|
+
isTablet ? Styles.tabletLayout : null,
|
|
380
|
+
]}
|
|
381
|
+
>
|
|
382
|
+
{!docked && (
|
|
383
|
+
<AnimationComponent
|
|
384
|
+
animationType={ComponentAnimationType.componentFade}
|
|
385
|
+
>
|
|
386
|
+
<AudioDescription
|
|
387
|
+
title={title}
|
|
388
|
+
summary={summary}
|
|
389
|
+
value={value}
|
|
390
|
+
layoutState={layoutState}
|
|
391
|
+
/>
|
|
392
|
+
<Separator />
|
|
393
|
+
{needsToShowProgressBar && (
|
|
394
|
+
<View>
|
|
395
|
+
<ProgressBar
|
|
396
|
+
content={entry}
|
|
334
397
|
value={value}
|
|
335
|
-
|
|
398
|
+
visible={true}
|
|
399
|
+
layoutState={layoutState}
|
|
400
|
+
onPlayerSeek={onPlayerSeek}
|
|
401
|
+
playerState={playerState}
|
|
402
|
+
disableFullscreen={true}
|
|
403
|
+
sliderStyle={2}
|
|
336
404
|
/>
|
|
337
|
-
)}
|
|
338
405
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
406
|
+
{showCounter && timeLeft >= 0 && (
|
|
407
|
+
<CountDown
|
|
408
|
+
timeLeft={timeLeft}
|
|
409
|
+
value={value}
|
|
410
|
+
title={sleepTitle}
|
|
411
|
+
/>
|
|
412
|
+
)}
|
|
413
|
+
|
|
414
|
+
<Separator />
|
|
415
|
+
</View>
|
|
416
|
+
)}
|
|
417
|
+
<Controls
|
|
418
|
+
value={value}
|
|
419
|
+
visible={true}
|
|
420
|
+
keepAlive={null}
|
|
421
|
+
buttons={controlButtons}
|
|
422
|
+
style={Styles.controls(
|
|
423
|
+
isTablet,
|
|
424
|
+
isLiveContent && showFullControls
|
|
425
|
+
)}
|
|
426
|
+
playerState={playerState}
|
|
427
|
+
/>
|
|
428
|
+
</AnimationComponent>
|
|
429
|
+
)}
|
|
351
430
|
</View>
|
|
352
431
|
</View>
|
|
353
432
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
import {
|
|
3
3
|
StyleSheet,
|
|
4
4
|
TouchableWithoutFeedback,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ViewStyle,
|
|
7
7
|
} from "react-native";
|
|
8
8
|
import * as R from "ramda";
|
|
9
|
-
import {
|
|
9
|
+
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
ContentInfo,
|
|
@@ -15,8 +15,13 @@ import {
|
|
|
15
15
|
Button,
|
|
16
16
|
} from "@applicaster/quick-brick-mobile-transport-controls";
|
|
17
17
|
|
|
18
|
-
import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
|
|
19
18
|
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
19
|
+
import {
|
|
20
|
+
useModalAnimationContext,
|
|
21
|
+
AnimationComponent,
|
|
22
|
+
ComponentAnimationType,
|
|
23
|
+
PlayerAnimationStateEnum,
|
|
24
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
20
25
|
|
|
21
26
|
type Dimensions = {
|
|
22
27
|
width: number;
|
|
@@ -104,14 +109,26 @@ const backgroundColorStyle = (value: GetValue): ViewStyle => ({
|
|
|
104
109
|
backgroundColor: value("docked_player_background_color"),
|
|
105
110
|
});
|
|
106
111
|
|
|
107
|
-
const playerDimensionsStyle = (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
const playerDimensionsStyle = (
|
|
113
|
+
minimisedHeight: number,
|
|
114
|
+
addPadding: boolean
|
|
115
|
+
): ViewStyle => ({
|
|
116
|
+
paddingLeft: addPadding ? minimisedHeight || 100 : 0,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const animatedContainerStyle = (docked: boolean): ViewStyle => ({
|
|
120
|
+
top: docked ? 2 : null,
|
|
121
|
+
position: "absolute",
|
|
122
|
+
width: "100%",
|
|
123
|
+
zIndex: docked ? 1 : -1,
|
|
111
124
|
});
|
|
112
125
|
|
|
113
|
-
const backgroundImageStyle = (
|
|
114
|
-
|
|
126
|
+
const backgroundImageStyle = (
|
|
127
|
+
dimensions: Dimensions,
|
|
128
|
+
minimisedHeight: number,
|
|
129
|
+
isActiveGesture: boolean
|
|
130
|
+
): ViewStyle => ({
|
|
131
|
+
height: isActiveGesture ? minimisedHeight : dimensions.height,
|
|
115
132
|
aspectRatio: 1,
|
|
116
133
|
position: "absolute",
|
|
117
134
|
});
|
|
@@ -193,7 +210,6 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
193
210
|
dimensions,
|
|
194
211
|
entry,
|
|
195
212
|
onCloseVideoModal,
|
|
196
|
-
maximiseVideoModal,
|
|
197
213
|
onPlayerSeek,
|
|
198
214
|
playerState,
|
|
199
215
|
configuration,
|
|
@@ -202,16 +218,34 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
202
218
|
summary,
|
|
203
219
|
} = props;
|
|
204
220
|
|
|
205
|
-
const
|
|
206
|
-
deviceInfo: { isTablet },
|
|
207
|
-
} = useDimensions("screen", { deviceInfo: true });
|
|
221
|
+
const isTablet = useIsTablet();
|
|
208
222
|
|
|
209
223
|
const visible = true;
|
|
210
224
|
const liveButton = Boolean(value("live_badge_enabled"));
|
|
211
225
|
|
|
226
|
+
const {
|
|
227
|
+
isActiveGesture,
|
|
228
|
+
setPlayerAnimationState,
|
|
229
|
+
startComponentsAnimation,
|
|
230
|
+
minimisedHeight,
|
|
231
|
+
} = useModalAnimationContext();
|
|
232
|
+
|
|
233
|
+
const maximazeVideoModal = React.useCallback(
|
|
234
|
+
() => setPlayerAnimationState(PlayerAnimationStateEnum.maximaze),
|
|
235
|
+
[]
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
if (!layoutState.docked && !startComponentsAnimation) return null;
|
|
239
|
+
|
|
212
240
|
return (
|
|
213
|
-
<
|
|
214
|
-
{
|
|
241
|
+
<AnimationComponent
|
|
242
|
+
animationType={ComponentAnimationType.componentAppears}
|
|
243
|
+
style={[
|
|
244
|
+
styles.container,
|
|
245
|
+
animatedContainerStyle(isActiveGesture || layoutState.docked),
|
|
246
|
+
]}
|
|
247
|
+
>
|
|
248
|
+
{!playerState.isLive && layoutState.docked && (
|
|
215
249
|
<ProgressBar
|
|
216
250
|
content={entry}
|
|
217
251
|
value={value}
|
|
@@ -219,18 +253,27 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
219
253
|
layoutState={layoutState}
|
|
220
254
|
onPlayerSeek={onPlayerSeek}
|
|
221
255
|
playerState={playerState}
|
|
256
|
+
docked
|
|
222
257
|
/>
|
|
223
258
|
)}
|
|
224
259
|
|
|
225
260
|
<View style={styles.content}>
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
261
|
+
<View
|
|
262
|
+
style={backgroundImageStyle(
|
|
263
|
+
dimensions,
|
|
264
|
+
minimisedHeight,
|
|
265
|
+
isActiveGesture
|
|
266
|
+
)}
|
|
230
267
|
/>
|
|
231
|
-
<TouchableWithoutFeedback onPress={
|
|
268
|
+
<TouchableWithoutFeedback onPress={maximazeVideoModal}>
|
|
232
269
|
<View
|
|
233
|
-
style={[
|
|
270
|
+
style={[
|
|
271
|
+
styles.touchableArea,
|
|
272
|
+
playerDimensionsStyle(
|
|
273
|
+
minimisedHeight,
|
|
274
|
+
isActiveGesture || layoutState.docked
|
|
275
|
+
),
|
|
276
|
+
]}
|
|
234
277
|
>
|
|
235
278
|
<View
|
|
236
279
|
style={[
|
|
@@ -274,6 +317,6 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
274
317
|
/>
|
|
275
318
|
</View>
|
|
276
319
|
</View>
|
|
277
|
-
</
|
|
320
|
+
</AnimationComponent>
|
|
278
321
|
);
|
|
279
322
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import DefaultLayout from "./DefaultLayout";
|
|
3
|
-
import DockedLayout from "./DockedLayout";
|
|
4
3
|
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
5
4
|
|
|
6
5
|
type Dimensions = {
|
|
@@ -40,6 +39,7 @@ type LayoutProps = {
|
|
|
40
39
|
onSkipLive: () => void;
|
|
41
40
|
maximiseVideoModal: () => void;
|
|
42
41
|
dimensions: Dimensions;
|
|
42
|
+
defaultDimensions: Dimensions;
|
|
43
43
|
playNextData: PlayNextData;
|
|
44
44
|
title: string | number;
|
|
45
45
|
summary: string | number;
|
|
@@ -48,11 +48,5 @@ type LayoutProps = {
|
|
|
48
48
|
export default function Layout(
|
|
49
49
|
props: LayoutProps
|
|
50
50
|
): React.ReactElement<LayoutProps> {
|
|
51
|
-
const { layoutState } = props;
|
|
52
|
-
|
|
53
|
-
if (layoutState.docked) {
|
|
54
|
-
return <DockedLayout {...props} />;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
51
|
return <DefaultLayout {...props} />;
|
|
58
52
|
}
|
|
@@ -11,9 +11,10 @@ type MagicBGProps = {
|
|
|
11
11
|
image: string;
|
|
12
12
|
fallbackUrl?: string;
|
|
13
13
|
defaultColor: string;
|
|
14
|
+
colors: string[]; // Updated to type string[] as it holds hex values
|
|
14
15
|
};
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
+
const defaultColors = {
|
|
17
18
|
overlay: "rgba(0, 0, 0, 0.35)",
|
|
18
19
|
defaultGradientStart: "rgba(0, 0, 0, 0.25)",
|
|
19
20
|
defaultGradientEnd: "rgba(0, 0, 0, 0)",
|
|
@@ -25,7 +26,7 @@ const styles = StyleSheet.create({
|
|
|
25
26
|
},
|
|
26
27
|
fullScreenOverlay: {
|
|
27
28
|
...StyleSheet.absoluteFillObject,
|
|
28
|
-
backgroundColor:
|
|
29
|
+
backgroundColor: defaultColors.overlay,
|
|
29
30
|
},
|
|
30
31
|
gradientOverlay: {
|
|
31
32
|
position: "absolute",
|
|
@@ -54,46 +55,63 @@ export const MagicBG: React.FC<MagicBGProps> = ({
|
|
|
54
55
|
children,
|
|
55
56
|
image,
|
|
56
57
|
fallbackUrl = "",
|
|
58
|
+
colors = [],
|
|
57
59
|
defaultColor,
|
|
58
60
|
}) => {
|
|
59
61
|
const [dominantColor, setDominantColor] =
|
|
60
62
|
React.useState<string>(defaultColor);
|
|
61
63
|
|
|
62
64
|
const [gradientColors, setGradientColors] = React.useState<string[]>([
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
defaultColors.defaultGradientStart,
|
|
66
|
+
defaultColors.defaultGradientEnd,
|
|
65
67
|
]);
|
|
66
68
|
|
|
67
69
|
useEffect(() => {
|
|
68
70
|
const fetchColors = async () => {
|
|
69
|
-
if
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
setDominantColor(dominantColor);
|
|
77
|
-
} catch (error) {
|
|
71
|
+
// Check if colors are provided and not empty
|
|
72
|
+
if (colors && colors.length > 0) {
|
|
73
|
+
// Use provided colors for gradient and dominant color
|
|
74
|
+
setGradientColors(colors.slice(0, 2)); // First 2 colors for gradient
|
|
75
|
+
setDominantColor(colors[0]); // First color as dominant
|
|
76
|
+
} else if (image) {
|
|
77
|
+
// If no colors, try fetching from image
|
|
78
78
|
try {
|
|
79
79
|
const { gradientColors, dominantColor } =
|
|
80
|
-
await fetchPaletteAndDominantColor(
|
|
80
|
+
await fetchPaletteAndDominantColor(image);
|
|
81
81
|
|
|
82
82
|
setGradientColors(gradientColors);
|
|
83
83
|
setDominantColor(dominantColor);
|
|
84
|
-
} catch {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
} catch (error) {
|
|
85
|
+
// If image fetch fails, try fallback URL
|
|
86
|
+
try {
|
|
87
|
+
const { gradientColors, dominantColor } =
|
|
88
|
+
await fetchPaletteAndDominantColor(fallbackUrl);
|
|
89
|
+
|
|
90
|
+
setGradientColors(gradientColors);
|
|
91
|
+
setDominantColor(dominantColor);
|
|
92
|
+
} catch {
|
|
93
|
+
// If everything fails, use default color
|
|
94
|
+
setGradientColors([
|
|
95
|
+
defaultColors.defaultGradientStart,
|
|
96
|
+
defaultColors.defaultGradientEnd,
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
setDominantColor(defaultColor);
|
|
100
|
+
}
|
|
91
101
|
}
|
|
102
|
+
} else {
|
|
103
|
+
// If no image or colors, use default color
|
|
104
|
+
setGradientColors([
|
|
105
|
+
defaultColors.defaultGradientStart,
|
|
106
|
+
defaultColors.defaultGradientEnd,
|
|
107
|
+
]);
|
|
108
|
+
|
|
109
|
+
setDominantColor(defaultColor);
|
|
92
110
|
}
|
|
93
111
|
};
|
|
94
112
|
|
|
95
113
|
fetchColors();
|
|
96
|
-
}, [
|
|
114
|
+
}, []);
|
|
97
115
|
|
|
98
116
|
return (
|
|
99
117
|
<View style={[styles.container, { backgroundColor: dominantColor }]}>
|
package/src/Player/index.tsx
CHANGED
|
@@ -36,6 +36,12 @@ import { AudioPlayerWrapper } from "./AudioLayer/AudioPlayerWrapper";
|
|
|
36
36
|
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
37
37
|
import { getAllAccessibilityProps } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
38
38
|
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
39
|
+
import { getTargetScreenDataFromEntry } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useTargetScreenData";
|
|
40
|
+
import { isAppleTV } from "@applicaster/zapp-react-native-ui-components/Helpers/Platform";
|
|
41
|
+
import {
|
|
42
|
+
AnimationComponent,
|
|
43
|
+
ComponentAnimationType,
|
|
44
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
39
45
|
|
|
40
46
|
const RNPlayerManager = {
|
|
41
47
|
QuickBrickPlayerPlugin: isApplePlatform()
|
|
@@ -55,6 +61,7 @@ const styles = StyleSheet.create({
|
|
|
55
61
|
position: "absolute",
|
|
56
62
|
zIndex: 1,
|
|
57
63
|
},
|
|
64
|
+
playerSize: { width: "100%", height: "100%" },
|
|
58
65
|
});
|
|
59
66
|
|
|
60
67
|
const logger = createLogger({
|
|
@@ -555,6 +562,26 @@ export default class VideoPlayer extends React.Component<
|
|
|
555
562
|
this.props.listener?.onPlayerDetached?.(nativeEvent);
|
|
556
563
|
};
|
|
557
564
|
|
|
565
|
+
onVideoFullscreenPlayerDidDismiss = () => {
|
|
566
|
+
this.props.listener?.onVideoFullscreenPlayerDidDismiss?.();
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
onVideoFullscreenPlayerDidPresent = () => {
|
|
570
|
+
this.props.listener?.onVideoFullscreenPlayerDidPresent?.();
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
onVideoFullscreenPlayerWillDismiss = () => {
|
|
574
|
+
this.props.listener?.onVideoFullscreenPlayerWillDismiss?.();
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
onVideoFullscreenPlayerWillPresent = () => {
|
|
578
|
+
this.props.listener?.onVideoFullscreenPlayerWillPresent?.();
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
onPlayerClose = () => {
|
|
582
|
+
this.props.listener?.onPlayerClose?.();
|
|
583
|
+
};
|
|
584
|
+
|
|
558
585
|
onPiPEnter = () => {
|
|
559
586
|
this.setState({ piped: true });
|
|
560
587
|
this.props.openPiP();
|
|
@@ -758,8 +785,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
758
785
|
|
|
759
786
|
render() {
|
|
760
787
|
const {
|
|
761
|
-
castAction,
|
|
762
|
-
controls,
|
|
763
788
|
docked,
|
|
764
789
|
entry,
|
|
765
790
|
fullscreen,
|
|
@@ -769,8 +794,12 @@ export default class VideoPlayer extends React.Component<
|
|
|
769
794
|
isTabletPortrait,
|
|
770
795
|
muted,
|
|
771
796
|
style,
|
|
797
|
+
castAction,
|
|
798
|
+
controller,
|
|
772
799
|
} = this.props;
|
|
773
800
|
|
|
801
|
+
const supportNativeCast = controller.supportNativeCast();
|
|
802
|
+
|
|
774
803
|
const { audioTrackId, keyEvent, paused, seek, textTrackId, rate } =
|
|
775
804
|
this.state;
|
|
776
805
|
|
|
@@ -817,17 +846,32 @@ export default class VideoPlayer extends React.Component<
|
|
|
817
846
|
const liveCatchUpEnabled =
|
|
818
847
|
this.props.pluginConfiguration?.liveCatchUpEnabled;
|
|
819
848
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
: {};
|
|
849
|
+
// TODO: Get screen data more reliable way useCurrentScreenData
|
|
850
|
+
const screenData = getTargetScreenDataFromEntry(this.props.playableItem);
|
|
823
851
|
|
|
824
|
-
const
|
|
852
|
+
const isInlineTV = screenData?.ui_components?.length > 0 && isTV();
|
|
853
|
+
|
|
854
|
+
let platformSpecificProps: any = isApplePlatform()
|
|
825
855
|
? {
|
|
826
|
-
...hideNativeControls,
|
|
827
856
|
resizeMode: nativeResizeMode,
|
|
828
857
|
}
|
|
829
858
|
: {};
|
|
830
859
|
|
|
860
|
+
const supportsNativeControls =
|
|
861
|
+
!!this.props.controller?.supportsNativeControls?.();
|
|
862
|
+
|
|
863
|
+
const controls = isAppleTV()
|
|
864
|
+
? supportsNativeControls && !isInlineTV && !this.getPlayNextData()
|
|
865
|
+
: supportsNativeControls && !this.getPlayNextData();
|
|
866
|
+
|
|
867
|
+
const shouldUseNativeControls =
|
|
868
|
+
controls && !docked && !castAction?.state?.connected;
|
|
869
|
+
|
|
870
|
+
platformSpecificProps = {
|
|
871
|
+
...platformSpecificProps,
|
|
872
|
+
controls: shouldUseNativeControls,
|
|
873
|
+
};
|
|
874
|
+
|
|
831
875
|
const pictureInPictureEnabled =
|
|
832
876
|
this.props.pluginConfiguration?.pictureInPictureEnabled;
|
|
833
877
|
|
|
@@ -835,7 +879,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
835
879
|
entry, // Must be passed first in list
|
|
836
880
|
...platformSpecificProps,
|
|
837
881
|
audioTrackId,
|
|
838
|
-
controls,
|
|
839
882
|
docked,
|
|
840
883
|
enableAutoAudioTrackSelection,
|
|
841
884
|
fullscreen, // TODO: Check fullscreen params not crash
|
|
@@ -890,22 +933,17 @@ export default class VideoPlayer extends React.Component<
|
|
|
890
933
|
onVideoEnd: this.onVideoEnd, // complete
|
|
891
934
|
onVideoError: this.onVideoError, // error
|
|
892
935
|
onVideoProgress: this.onVideoProgress,
|
|
893
|
-
onVideoFullscreenPlayerDidDismiss: this.
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
onVideoFullscreenPlayerWillDismiss: this.unHandledEvent(
|
|
900
|
-
"onVideoFullscreenPlayerWillDismiss"
|
|
901
|
-
),
|
|
902
|
-
onVideoFullscreenPlayerWillPresent: this.unHandledEvent(
|
|
903
|
-
"onVideoFullscreenPlayerWillPresent"
|
|
904
|
-
),
|
|
936
|
+
onVideoFullscreenPlayerDidDismiss: this.onVideoFullscreenPlayerDidDismiss,
|
|
937
|
+
onVideoFullscreenPlayerDidPresent: this.onVideoFullscreenPlayerDidPresent,
|
|
938
|
+
onVideoFullscreenPlayerWillDismiss:
|
|
939
|
+
this.onVideoFullscreenPlayerWillDismiss,
|
|
940
|
+
onVideoFullscreenPlayerWillPresent:
|
|
941
|
+
this.onVideoFullscreenPlayerWillPresent,
|
|
905
942
|
onVideoLoad: this.onVideoLoad,
|
|
906
943
|
onVideoLoadStart: this.unHandledEvent("onVideoLoadStart"),
|
|
907
944
|
onVideoBuffer: this.onVideoBuffer,
|
|
908
945
|
onPlaybackStalled: this.onPlaybackStalled,
|
|
946
|
+
onPlayerClose: this.onPlayerClose,
|
|
909
947
|
onPlayerAttached: this.onPlayerAttached,
|
|
910
948
|
onPlayerDetached: this.onPlayerDetached,
|
|
911
949
|
};
|
|
@@ -979,7 +1017,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
979
1017
|
!needToShowPlayNextOverlay &&
|
|
980
1018
|
this.props.mode !== "PIP";
|
|
981
1019
|
|
|
982
|
-
if (
|
|
1020
|
+
if (shouldUseNativeControls) {
|
|
983
1021
|
return null;
|
|
984
1022
|
}
|
|
985
1023
|
|
|
@@ -1011,10 +1049,12 @@ export default class VideoPlayer extends React.Component<
|
|
|
1011
1049
|
inline,
|
|
1012
1050
|
docked,
|
|
1013
1051
|
isModal,
|
|
1052
|
+
pip: this.state.piped,
|
|
1014
1053
|
layoutState: {
|
|
1015
1054
|
inline,
|
|
1016
1055
|
docked,
|
|
1017
1056
|
isModal,
|
|
1057
|
+
pip: this.state.piped,
|
|
1018
1058
|
},
|
|
1019
1059
|
configuration: this.getPluginConfiguration(),
|
|
1020
1060
|
fullscreen: fullscreen,
|
|
@@ -1030,29 +1070,14 @@ export default class VideoPlayer extends React.Component<
|
|
|
1030
1070
|
const renderMobilePlayer = () => {
|
|
1031
1071
|
return isFullScreenAudioPlayer && isAudioItem ? (
|
|
1032
1072
|
<View style={containerStyle}>
|
|
1033
|
-
{!castAction?.state?.connected && (
|
|
1073
|
+
{(!castAction?.state?.connected || supportNativeCast) && (
|
|
1034
1074
|
<this.props.PlayerComponent
|
|
1035
1075
|
ref={this._assignRoot}
|
|
1036
1076
|
{...nativeEvents}
|
|
1037
1077
|
{...nativeProps}
|
|
1038
1078
|
/>
|
|
1039
1079
|
)}
|
|
1040
|
-
<AudioPlayerWrapper {...sharedWrapperViewProps}
|
|
1041
|
-
<View>
|
|
1042
|
-
{
|
|
1043
|
-
<PlayNextOverlay
|
|
1044
|
-
item={entry}
|
|
1045
|
-
playerIsDocked={docked}
|
|
1046
|
-
pluginConfiguration={this.getPluginConfiguration()}
|
|
1047
|
-
playerId={this.props.playerId}
|
|
1048
|
-
playNextData={this.getPlayNextData()}
|
|
1049
|
-
setNextVideoPreloadThresholdPercentage={
|
|
1050
|
-
this.props.setNextVideoPreloadThresholdPercentage
|
|
1051
|
-
}
|
|
1052
|
-
/>
|
|
1053
|
-
}
|
|
1054
|
-
</View>
|
|
1055
|
-
</AudioPlayerWrapper>
|
|
1080
|
+
<AudioPlayerWrapper {...sharedWrapperViewProps} />
|
|
1056
1081
|
</View>
|
|
1057
1082
|
) : (
|
|
1058
1083
|
<PlayerWrapper {...sharedWrapperViewProps}>
|
|
@@ -1067,11 +1092,24 @@ export default class VideoPlayer extends React.Component<
|
|
|
1067
1092
|
<View style={styles.container}>
|
|
1068
1093
|
<View style={[playerContainerStyles, playerDimensions]}>
|
|
1069
1094
|
{isAudioItem && (
|
|
1070
|
-
<
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1095
|
+
<AnimationComponent
|
|
1096
|
+
animationType={ComponentAnimationType.player}
|
|
1097
|
+
additionalData={{
|
|
1098
|
+
...playerDimensions,
|
|
1099
|
+
inlineAudioPlayer: true,
|
|
1100
|
+
}}
|
|
1101
|
+
style={getStyle(playerDimensions)}
|
|
1102
|
+
>
|
|
1103
|
+
<AudioPlayer
|
|
1104
|
+
style={
|
|
1105
|
+
isTV()
|
|
1106
|
+
? getStyle(playerDimensions)
|
|
1107
|
+
: styles.playerSize
|
|
1108
|
+
}
|
|
1109
|
+
audio_item={entry}
|
|
1110
|
+
plugin_configuration={this.getPluginConfiguration()}
|
|
1111
|
+
/>
|
|
1112
|
+
</AnimationComponent>
|
|
1075
1113
|
)}
|
|
1076
1114
|
|
|
1077
1115
|
{shouldRenderBackground && (
|
|
@@ -1083,17 +1121,28 @@ export default class VideoPlayer extends React.Component<
|
|
|
1083
1121
|
/>
|
|
1084
1122
|
)}
|
|
1085
1123
|
|
|
1086
|
-
{!castAction?.state?.connected && (
|
|
1087
|
-
<
|
|
1088
|
-
|
|
1089
|
-
{
|
|
1090
|
-
{...nativeProps}
|
|
1091
|
-
listener={this.props.listener}
|
|
1124
|
+
{(!castAction?.state?.connected || supportNativeCast) && (
|
|
1125
|
+
<AnimationComponent
|
|
1126
|
+
animationType={ComponentAnimationType.player}
|
|
1127
|
+
additionalData={playerDimensions}
|
|
1092
1128
|
style={getStyle(playerDimensions)}
|
|
1093
|
-
pluginConfiguration={this.getPluginConfiguration()}
|
|
1094
1129
|
>
|
|
1095
|
-
|
|
1096
|
-
|
|
1130
|
+
<this.props.PlayerComponent
|
|
1131
|
+
ref={this._assignRoot}
|
|
1132
|
+
{...nativeEvents}
|
|
1133
|
+
{...nativeProps}
|
|
1134
|
+
listener={this.props.listener}
|
|
1135
|
+
style={
|
|
1136
|
+
isTV()
|
|
1137
|
+
? getStyle(playerDimensions)
|
|
1138
|
+
: styles.playerSize
|
|
1139
|
+
}
|
|
1140
|
+
pluginConfiguration={this.getPluginConfiguration()}
|
|
1141
|
+
controller={this.props.controller}
|
|
1142
|
+
>
|
|
1143
|
+
{this.childrenWithPlayNext()}
|
|
1144
|
+
</this.props.PlayerComponent>
|
|
1145
|
+
</AnimationComponent>
|
|
1097
1146
|
)}
|
|
1098
1147
|
</View>
|
|
1099
1148
|
|
|
@@ -1127,6 +1176,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
1127
1176
|
listener={this.props.listener}
|
|
1128
1177
|
style={this.takeParentStyle}
|
|
1129
1178
|
pluginConfiguration={this.getPluginConfiguration()}
|
|
1179
|
+
controller={this.props.controller}
|
|
1130
1180
|
>
|
|
1131
1181
|
{this.childrenWithPlayNext()}
|
|
1132
1182
|
</this.props.PlayerComponent>
|