@applicaster/quick-brick-player 12.0.0-alpha.7101461483 → 12.0.0-alpha.7254207052
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 -5
- package/src/CellPlayer/Assets/AssetsComponent.tsx +2 -1
- package/src/Player/AudioLayer/AudioDescription.tsx +3 -3
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +28 -2
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +19 -7
- package/src/Player/AudioLayer/Layout/DockedLayout.tsx +9 -1
- package/src/Player/AudioLayer/Layout/index.tsx +2 -0
- package/src/Player/AudioLayer/MagicBG/index.tsx +59 -22
- package/src/Player/Utils/Utils.ts +23 -0
- package/src/Player/Utils/index.tsx +0 -2
- package/src/Player/index.tsx +49 -20
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.7254207052",
|
|
4
4
|
"description": "Quick Brick Player",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -36,12 +36,13 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@applicaster/quick-brick-mobile-transport-controls": "12.0.0-
|
|
39
|
+
"@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.33",
|
|
40
40
|
"@applicaster/quick-brick-tv-transport-controls": "11.0.0-rc.133",
|
|
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.
|
|
41
|
+
"@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.7254207052",
|
|
42
|
+
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.7254207052",
|
|
43
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.7254207052",
|
|
44
44
|
"keymirror": "^0.1.1",
|
|
45
|
+
"query-string": "7.1.3",
|
|
45
46
|
"react-native-web-linear-gradient": "1.1.2",
|
|
46
47
|
"shaka-player": "4.3.5",
|
|
47
48
|
"typeface-montserrat": "^0.0.54",
|
|
@@ -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
|
|
|
@@ -3,7 +3,8 @@ import { Text, TextStyle, View } from "react-native";
|
|
|
3
3
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
4
4
|
|
|
5
5
|
type AudioDescriptionProps = {
|
|
6
|
-
|
|
6
|
+
title: string | number;
|
|
7
|
+
summary: string | number;
|
|
7
8
|
layoutState: {
|
|
8
9
|
inline: boolean;
|
|
9
10
|
docked: boolean;
|
|
@@ -78,8 +79,7 @@ const summaryStyles = (value: GetValue, prefix: string): TextStyle => ({
|
|
|
78
79
|
});
|
|
79
80
|
|
|
80
81
|
export const AudioDescription = (props: AudioDescriptionProps) => {
|
|
81
|
-
const {
|
|
82
|
-
const { title, summary } = content;
|
|
82
|
+
const { title, summary, layoutState, value } = props;
|
|
83
83
|
const prefix = layoutState.docked ? "docked_player_" : "";
|
|
84
84
|
|
|
85
85
|
return (
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
NAMESPACE,
|
|
25
25
|
} from "./utils";
|
|
26
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";
|
|
27
29
|
|
|
28
30
|
const { log_debug } = createLogger({
|
|
29
31
|
subsystem: "UIComponent",
|
|
@@ -40,6 +42,7 @@ type Dimensions = {
|
|
|
40
42
|
type Configuration = {
|
|
41
43
|
[key: string]: any;
|
|
42
44
|
magic_background?: boolean;
|
|
45
|
+
audio_player_background_image_query?: string;
|
|
43
46
|
tablet_landscape_sidebar_width?: string;
|
|
44
47
|
tablet_landscape_player_container_background_color?: string;
|
|
45
48
|
};
|
|
@@ -142,6 +145,17 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
142
145
|
|
|
143
146
|
const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
|
|
144
147
|
|
|
148
|
+
// TODO: Have generic place for live url from configuration. Currently its hardcoded for client.
|
|
149
|
+
|
|
150
|
+
const feedUrl = getLiveUrl(entry?.extensions?.live?.channel_src ?? "");
|
|
151
|
+
|
|
152
|
+
const { title, summary } = useTitleSummaryOverlay(
|
|
153
|
+
feedUrl,
|
|
154
|
+
entry,
|
|
155
|
+
playerState?.isLive,
|
|
156
|
+
configuration?.audio_live_player_update_interval
|
|
157
|
+
);
|
|
158
|
+
|
|
145
159
|
const [playbackSpeed, setPlaybackSpeed] = useState({
|
|
146
160
|
asset: configuration["speed_1"],
|
|
147
161
|
value: 1.0,
|
|
@@ -181,7 +195,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
181
195
|
});
|
|
182
196
|
|
|
183
197
|
setSleepTimerDate(0);
|
|
184
|
-
player?.pause();
|
|
185
198
|
|
|
186
199
|
await localStorage.removeItem("sleep", NAMESPACE);
|
|
187
200
|
};
|
|
@@ -400,6 +413,8 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
400
413
|
configuration={configuration}
|
|
401
414
|
dimensions={dimensions}
|
|
402
415
|
playNextData={playNextData}
|
|
416
|
+
title={title}
|
|
417
|
+
summary={summary}
|
|
403
418
|
/>
|
|
404
419
|
{children}
|
|
405
420
|
{!docked && (
|
|
@@ -438,9 +453,20 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
438
453
|
]);
|
|
439
454
|
|
|
440
455
|
if (configuration.magic_background) {
|
|
456
|
+
const baseUrl = entry?.extensions?.audio_player_background_image ?? "";
|
|
457
|
+
|
|
458
|
+
const queryParamName =
|
|
459
|
+
configuration.audio_player_background_image_query || "width";
|
|
460
|
+
|
|
461
|
+
const queryParamValue = 15;
|
|
462
|
+
|
|
463
|
+
const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
|
|
464
|
+
|
|
441
465
|
return (
|
|
442
466
|
<MagicBG
|
|
443
|
-
image={
|
|
467
|
+
image={url}
|
|
468
|
+
fallbackUrl={baseUrl}
|
|
469
|
+
colors={entry?.extensions?.backgroundColors}
|
|
444
470
|
defaultColor="#000000"
|
|
445
471
|
>
|
|
446
472
|
{MainContent}
|
|
@@ -61,6 +61,8 @@ type LayoutProps = {
|
|
|
61
61
|
onSkipLive: () => void;
|
|
62
62
|
onSkipStart: () => void;
|
|
63
63
|
dimensions: Dimensions;
|
|
64
|
+
title: string | number;
|
|
65
|
+
summary: string | number;
|
|
64
66
|
};
|
|
65
67
|
|
|
66
68
|
const Styles = {
|
|
@@ -83,8 +85,8 @@ const Styles = {
|
|
|
83
85
|
}),
|
|
84
86
|
backgroundImageContainer: (dimensions: Dimensions, isTablet: boolean) => {
|
|
85
87
|
return {
|
|
86
|
-
width: isTablet ? 463 : dimensions.width,
|
|
87
|
-
height: isTablet ? 463 : dimensions.width,
|
|
88
|
+
width: isTablet ? 463 : dimensions.width || 330,
|
|
89
|
+
height: isTablet ? 463 : dimensions.width || 330,
|
|
88
90
|
};
|
|
89
91
|
},
|
|
90
92
|
backgroundImageContainerImageStyle: (isTablet) => ({
|
|
@@ -135,6 +137,8 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
135
137
|
dimensions,
|
|
136
138
|
cancelSleepTimer,
|
|
137
139
|
sleepTimerDate,
|
|
140
|
+
title,
|
|
141
|
+
summary,
|
|
138
142
|
} = props;
|
|
139
143
|
|
|
140
144
|
const isTablet = useIsTablet();
|
|
@@ -154,8 +158,7 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
154
158
|
sleepTimerDate !== 0 ? sleepTimerDate - Date.now() : 0
|
|
155
159
|
);
|
|
156
160
|
|
|
157
|
-
let showFullControls =
|
|
158
|
-
controller?.hasContentDuration?.() && !controller?.isAd();
|
|
161
|
+
let showFullControls = !controller?.isAd();
|
|
159
162
|
|
|
160
163
|
if (isLiveContent) {
|
|
161
164
|
const seekEnabled = Boolean(value("liveSeekingEnabled"));
|
|
@@ -186,8 +189,15 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
186
189
|
return [play];
|
|
187
190
|
}
|
|
188
191
|
|
|
189
|
-
const rewind = rewindButton({
|
|
190
|
-
|
|
192
|
+
const rewind = rewindButton({
|
|
193
|
+
isTablet,
|
|
194
|
+
onPress: controller?.hasContentDuration?.() ? onRewindButtonPress : null,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const forward = forwardButton({
|
|
198
|
+
isTablet,
|
|
199
|
+
onPress: controller?.hasContentDuration?.() ? onForwardButtonPress : null,
|
|
200
|
+
});
|
|
191
201
|
|
|
192
202
|
const speed = speedButton({
|
|
193
203
|
isTablet,
|
|
@@ -231,6 +241,7 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
231
241
|
isLiveContent,
|
|
232
242
|
playbackSpeedName,
|
|
233
243
|
playbackSleepName,
|
|
244
|
+
controller,
|
|
234
245
|
]);
|
|
235
246
|
|
|
236
247
|
useEffect(() => {
|
|
@@ -298,7 +309,8 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
298
309
|
imageStyle={Styles.backgroundImageContainerImageStyle(isTablet)}
|
|
299
310
|
/>
|
|
300
311
|
<AudioDescription
|
|
301
|
-
|
|
312
|
+
title={title}
|
|
313
|
+
summary={summary}
|
|
302
314
|
value={value}
|
|
303
315
|
layoutState={layoutState}
|
|
304
316
|
/>
|
|
@@ -48,6 +48,8 @@ type LayoutProps = {
|
|
|
48
48
|
maximiseVideoModal: () => void;
|
|
49
49
|
dimensions: Dimensions;
|
|
50
50
|
playNextData: PlayNextData;
|
|
51
|
+
title: string | number;
|
|
52
|
+
summary: string | number;
|
|
51
53
|
};
|
|
52
54
|
|
|
53
55
|
const styles = StyleSheet.create({
|
|
@@ -196,6 +198,8 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
196
198
|
playerState,
|
|
197
199
|
configuration,
|
|
198
200
|
playNextData,
|
|
201
|
+
title,
|
|
202
|
+
summary,
|
|
199
203
|
} = props;
|
|
200
204
|
|
|
201
205
|
const isTablet = useIsTablet();
|
|
@@ -232,7 +236,11 @@ export default function DockedLayout(props: LayoutProps) {
|
|
|
232
236
|
!configuration.magic_background && backgroundColorStyle(value),
|
|
233
237
|
]}
|
|
234
238
|
>
|
|
235
|
-
<ContentInfo
|
|
239
|
+
<ContentInfo
|
|
240
|
+
content={{ ...entry, title, summary }}
|
|
241
|
+
value={value}
|
|
242
|
+
docked
|
|
243
|
+
/>
|
|
236
244
|
</View>
|
|
237
245
|
</View>
|
|
238
246
|
</TouchableWithoutFeedback>
|
|
@@ -4,14 +4,17 @@ import * as React from "react";
|
|
|
4
4
|
import { StyleSheet, View } from "react-native";
|
|
5
5
|
import LinearGradient from "../LinearGradient";
|
|
6
6
|
import { getDominantColor, getPalettes } from "../../../utils/utils";
|
|
7
|
+
import { useEffect } from "react";
|
|
7
8
|
|
|
8
9
|
type MagicBGProps = {
|
|
9
10
|
children: React.ReactNode;
|
|
10
11
|
image: string;
|
|
12
|
+
fallbackUrl?: string;
|
|
11
13
|
defaultColor: string;
|
|
14
|
+
colors: string[]; // Updated to type string[] as it holds hex values
|
|
12
15
|
};
|
|
13
16
|
|
|
14
|
-
const
|
|
17
|
+
const defaultColors = {
|
|
15
18
|
overlay: "rgba(0, 0, 0, 0.35)",
|
|
16
19
|
defaultGradientStart: "rgba(0, 0, 0, 0.25)",
|
|
17
20
|
defaultGradientEnd: "rgba(0, 0, 0, 0)",
|
|
@@ -23,7 +26,7 @@ const styles = StyleSheet.create({
|
|
|
23
26
|
},
|
|
24
27
|
fullScreenOverlay: {
|
|
25
28
|
...StyleSheet.absoluteFillObject,
|
|
26
|
-
backgroundColor:
|
|
29
|
+
backgroundColor: defaultColors.overlay,
|
|
27
30
|
},
|
|
28
31
|
gradientOverlay: {
|
|
29
32
|
position: "absolute",
|
|
@@ -34,47 +37,81 @@ const styles = StyleSheet.create({
|
|
|
34
37
|
},
|
|
35
38
|
});
|
|
36
39
|
|
|
40
|
+
const fetchPaletteAndDominantColor = async (imageUrl: string) => {
|
|
41
|
+
const palette = await getPalettes(imageUrl);
|
|
42
|
+
|
|
43
|
+
const colors = palette.map(
|
|
44
|
+
(color: { r: number; g: number; b: number }) =>
|
|
45
|
+
`rgb(${color.r}, ${color.g}, ${color.b})`
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const dominant = await getDominantColor(imageUrl);
|
|
49
|
+
const dominantColor = `rgb(${dominant.r}, ${dominant.g}, ${dominant.b})`;
|
|
50
|
+
|
|
51
|
+
return { gradientColors: colors.slice(0, 2), dominantColor };
|
|
52
|
+
};
|
|
53
|
+
|
|
37
54
|
export const MagicBG: React.FC<MagicBGProps> = ({
|
|
38
55
|
children,
|
|
39
56
|
image,
|
|
57
|
+
fallbackUrl = "",
|
|
58
|
+
colors = [],
|
|
40
59
|
defaultColor,
|
|
41
60
|
}) => {
|
|
42
61
|
const [dominantColor, setDominantColor] =
|
|
43
62
|
React.useState<string>(defaultColor);
|
|
44
63
|
|
|
45
64
|
const [gradientColors, setGradientColors] = React.useState<string[]>([
|
|
46
|
-
|
|
47
|
-
|
|
65
|
+
defaultColors.defaultGradientStart,
|
|
66
|
+
defaultColors.defaultGradientEnd,
|
|
48
67
|
]);
|
|
49
68
|
|
|
50
|
-
|
|
69
|
+
useEffect(() => {
|
|
51
70
|
const fetchColors = async () => {
|
|
52
|
-
if
|
|
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
|
|
53
78
|
try {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const colors = palette.map(
|
|
57
|
-
(color: { r: number; g: number; b: number }) =>
|
|
58
|
-
`rgb(${color.r}, ${color.g}, ${color.b})`
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
setGradientColors(colors.slice(0, 2));
|
|
79
|
+
const { gradientColors, dominantColor } =
|
|
80
|
+
await fetchPaletteAndDominantColor(image);
|
|
62
81
|
|
|
63
|
-
|
|
64
|
-
setDominantColor(
|
|
82
|
+
setGradientColors(gradientColors);
|
|
83
|
+
setDominantColor(dominantColor);
|
|
65
84
|
} catch (error) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
85
|
+
// If image fetch fails, try fallback URL
|
|
86
|
+
try {
|
|
87
|
+
const { gradientColors, dominantColor } =
|
|
88
|
+
await fetchPaletteAndDominantColor(fallbackUrl);
|
|
70
89
|
|
|
71
|
-
|
|
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
|
+
}
|
|
72
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);
|
|
73
110
|
}
|
|
74
111
|
};
|
|
75
112
|
|
|
76
113
|
fetchColors();
|
|
77
|
-
}, [
|
|
114
|
+
}, []);
|
|
78
115
|
|
|
79
116
|
return (
|
|
80
117
|
<View style={[styles.container, { backgroundColor: dominantColor }]}>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import queryString from "query-string";
|
|
2
|
+
|
|
1
3
|
export const toTypeString = (obj) => {
|
|
2
4
|
switch (typeof obj) {
|
|
3
5
|
case "object":
|
|
@@ -19,3 +21,24 @@ export const stringsOnlyObject = (obj) => {
|
|
|
19
21
|
|
|
20
22
|
return strObj;
|
|
21
23
|
};
|
|
24
|
+
|
|
25
|
+
export const getLiveUrl = (url: string) => {
|
|
26
|
+
// Use the replace method with a regular expression to replace all instances of subClass with livePage
|
|
27
|
+
return url.replace(new RegExp("subClass", "g"), "livePage");
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const addQueryParam = (
|
|
31
|
+
baseUrl: string,
|
|
32
|
+
paramName: string,
|
|
33
|
+
paramValue: string | number
|
|
34
|
+
) => {
|
|
35
|
+
const [urlWithoutQuery, query] = baseUrl.split("?");
|
|
36
|
+
|
|
37
|
+
const parsedQuery = queryString.parse(query);
|
|
38
|
+
|
|
39
|
+
parsedQuery[paramName] = paramValue.toString();
|
|
40
|
+
|
|
41
|
+
const updatedQueryString = queryString.stringify(parsedQuery);
|
|
42
|
+
|
|
43
|
+
return `${urlWithoutQuery}?${updatedQueryString}`;
|
|
44
|
+
};
|
package/src/Player/index.tsx
CHANGED
|
@@ -36,6 +36,8 @@ 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";
|
|
39
41
|
|
|
40
42
|
const RNPlayerManager = {
|
|
41
43
|
QuickBrickPlayerPlugin: isApplePlatform()
|
|
@@ -555,6 +557,26 @@ export default class VideoPlayer extends React.Component<
|
|
|
555
557
|
this.props.listener?.onPlayerDetached?.(nativeEvent);
|
|
556
558
|
};
|
|
557
559
|
|
|
560
|
+
onVideoFullscreenPlayerDidDismiss = () => {
|
|
561
|
+
this.props.listener?.onVideoFullscreenPlayerDidDismiss?.();
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
onVideoFullscreenPlayerDidPresent = () => {
|
|
565
|
+
this.props.listener?.onVideoFullscreenPlayerDidPresent?.();
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
onVideoFullscreenPlayerWillDismiss = () => {
|
|
569
|
+
this.props.listener?.onVideoFullscreenPlayerWillDismiss?.();
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
onVideoFullscreenPlayerWillPresent = () => {
|
|
573
|
+
this.props.listener?.onVideoFullscreenPlayerWillPresent?.();
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
onPlayerClose = () => {
|
|
577
|
+
this.props.listener?.onPlayerClose?.();
|
|
578
|
+
};
|
|
579
|
+
|
|
558
580
|
onPiPEnter = () => {
|
|
559
581
|
this.setState({ piped: true });
|
|
560
582
|
this.props.openPiP();
|
|
@@ -759,7 +781,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
759
781
|
render() {
|
|
760
782
|
const {
|
|
761
783
|
castAction,
|
|
762
|
-
controls,
|
|
763
784
|
docked,
|
|
764
785
|
entry,
|
|
765
786
|
fullscreen,
|
|
@@ -817,17 +838,31 @@ export default class VideoPlayer extends React.Component<
|
|
|
817
838
|
const liveCatchUpEnabled =
|
|
818
839
|
this.props.pluginConfiguration?.liveCatchUpEnabled;
|
|
819
840
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
: {};
|
|
841
|
+
// TODO: Get screen data more reliable way useCurrentScreenData
|
|
842
|
+
const screenData = getTargetScreenDataFromEntry(this.props.playableItem);
|
|
823
843
|
|
|
824
|
-
const
|
|
844
|
+
const isInlineTV = screenData?.ui_components?.length > 0 && isTV();
|
|
845
|
+
|
|
846
|
+
let platformSpecificProps: any = isApplePlatform()
|
|
825
847
|
? {
|
|
826
|
-
...hideNativeControls,
|
|
827
848
|
resizeMode: nativeResizeMode,
|
|
828
849
|
}
|
|
829
850
|
: {};
|
|
830
851
|
|
|
852
|
+
const supportsNativeControls =
|
|
853
|
+
!!this.props.controller?.supportsNativeControls?.();
|
|
854
|
+
|
|
855
|
+
const controls = isAppleTV()
|
|
856
|
+
? supportsNativeControls && !isInlineTV && !this.getPlayNextData()
|
|
857
|
+
: supportsNativeControls && !this.getPlayNextData();
|
|
858
|
+
|
|
859
|
+
const shouldUseNativeControls = controls && !docked;
|
|
860
|
+
|
|
861
|
+
platformSpecificProps = {
|
|
862
|
+
...platformSpecificProps,
|
|
863
|
+
controls: shouldUseNativeControls,
|
|
864
|
+
};
|
|
865
|
+
|
|
831
866
|
const pictureInPictureEnabled =
|
|
832
867
|
this.props.pluginConfiguration?.pictureInPictureEnabled;
|
|
833
868
|
|
|
@@ -835,7 +870,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
835
870
|
entry, // Must be passed first in list
|
|
836
871
|
...platformSpecificProps,
|
|
837
872
|
audioTrackId,
|
|
838
|
-
controls,
|
|
839
873
|
docked,
|
|
840
874
|
enableAutoAudioTrackSelection,
|
|
841
875
|
fullscreen, // TODO: Check fullscreen params not crash
|
|
@@ -890,22 +924,17 @@ export default class VideoPlayer extends React.Component<
|
|
|
890
924
|
onVideoEnd: this.onVideoEnd, // complete
|
|
891
925
|
onVideoError: this.onVideoError, // error
|
|
892
926
|
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
|
-
),
|
|
927
|
+
onVideoFullscreenPlayerDidDismiss: this.onVideoFullscreenPlayerDidDismiss,
|
|
928
|
+
onVideoFullscreenPlayerDidPresent: this.onVideoFullscreenPlayerDidPresent,
|
|
929
|
+
onVideoFullscreenPlayerWillDismiss:
|
|
930
|
+
this.onVideoFullscreenPlayerWillDismiss,
|
|
931
|
+
onVideoFullscreenPlayerWillPresent:
|
|
932
|
+
this.onVideoFullscreenPlayerWillPresent,
|
|
905
933
|
onVideoLoad: this.onVideoLoad,
|
|
906
934
|
onVideoLoadStart: this.unHandledEvent("onVideoLoadStart"),
|
|
907
935
|
onVideoBuffer: this.onVideoBuffer,
|
|
908
936
|
onPlaybackStalled: this.onPlaybackStalled,
|
|
937
|
+
onPlayerClose: this.onPlayerClose,
|
|
909
938
|
onPlayerAttached: this.onPlayerAttached,
|
|
910
939
|
onPlayerDetached: this.onPlayerDetached,
|
|
911
940
|
};
|
|
@@ -979,7 +1008,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
979
1008
|
!needToShowPlayNextOverlay &&
|
|
980
1009
|
this.props.mode !== "PIP";
|
|
981
1010
|
|
|
982
|
-
if (
|
|
1011
|
+
if (shouldUseNativeControls) {
|
|
983
1012
|
return null;
|
|
984
1013
|
}
|
|
985
1014
|
|