@applicaster/quick-brick-player 15.0.0-alpha.4368022015 → 15.0.0-alpha.4374322811
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/Player/AudioLayer/Layout/DockedControls/index.tsx +9 -4
- package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +25 -5
- package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +6 -1
- package/src/Player/PlayNextOverlay/index.tsx +2 -2
- package/src/Player/PlayerModal/PlayerModal.tsx +11 -17
- package/src/Player/PlayerModal/VideoPlayerModal.tsx +127 -112
- package/src/Player/PlayerModal/hooks/index.ts +111 -148
- package/src/Player/PlayerModal/styles.ts +1 -0
- package/src/Player/PlayerModal/utils/index.ts +87 -5
- package/src/Player/Utils/index.tsx +9 -9
- package/src/Player/hooks/progressStates/__tests__/utils.test.ts +23 -0
- package/src/Player/hooks/progressStates/useLiveProgressState.tsx +78 -0
- package/src/Player/hooks/progressStates/useProgressState.tsx +30 -0
- package/src/Player/hooks/progressStates/useVodProgressState.tsx +115 -0
- package/src/Player/hooks/progressStates/utils.ts +33 -0
- package/src/Player/index.tsx +19 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-player",
|
|
3
|
-
"version": "15.0.0-alpha.
|
|
3
|
+
"version": "15.0.0-alpha.4374322811",
|
|
4
4
|
"description": "Quick Brick Player",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@applicaster/quick-brick-mobile-transport-controls": "15.0.0-rc.
|
|
39
|
-
"@applicaster/quick-brick-tv-transport-controls": "15.0.0-rc.
|
|
40
|
-
"@applicaster/zapp-react-native-tvos-app": "15.0.0-alpha.
|
|
41
|
-
"@applicaster/zapp-react-native-ui-components": "15.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-utils": "15.0.0-alpha.
|
|
38
|
+
"@applicaster/quick-brick-mobile-transport-controls": "15.0.0-rc.52",
|
|
39
|
+
"@applicaster/quick-brick-tv-transport-controls": "15.0.0-rc.45",
|
|
40
|
+
"@applicaster/zapp-react-native-tvos-app": "15.0.0-alpha.4374322811",
|
|
41
|
+
"@applicaster/zapp-react-native-ui-components": "15.0.0-alpha.4374322811",
|
|
42
|
+
"@applicaster/zapp-react-native-utils": "15.0.0-alpha.4374322811",
|
|
43
43
|
"query-string": "7.1.3",
|
|
44
44
|
"shaka-player": "4.3.5",
|
|
45
45
|
"typeface-montserrat": "^0.0.54",
|
|
@@ -23,7 +23,7 @@ import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/pl
|
|
|
23
23
|
import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/utils";
|
|
24
24
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
25
25
|
import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
|
|
26
|
-
import {
|
|
26
|
+
import { isBottomTabVisible } from "@applicaster/zapp-react-native-ui-components/Components/Screen/navigationHandler";
|
|
27
27
|
import { usePlugins } from "@applicaster/zapp-react-native-redux";
|
|
28
28
|
import { partial } from "@applicaster/zapp-react-native-utils/utils";
|
|
29
29
|
|
|
@@ -167,7 +167,12 @@ export const DockedControls = (props: Props) => {
|
|
|
167
167
|
const { currentRoute, screenData } = useNavigation();
|
|
168
168
|
|
|
169
169
|
const plugins = usePlugins();
|
|
170
|
-
|
|
170
|
+
|
|
171
|
+
const bottomTabsVisible = isBottomTabVisible(
|
|
172
|
+
currentRoute,
|
|
173
|
+
screenData,
|
|
174
|
+
plugins
|
|
175
|
+
);
|
|
171
176
|
|
|
172
177
|
const { minimised_height: minimisedHeight } = useConfiguration();
|
|
173
178
|
|
|
@@ -248,13 +253,13 @@ export const DockedControls = (props: Props) => {
|
|
|
248
253
|
);
|
|
249
254
|
|
|
250
255
|
const bottomSpacerStyle = React.useMemo(() => {
|
|
251
|
-
const tabBarHeight =
|
|
256
|
+
const tabBarHeight = bottomTabsVisible ? bottomTabBarHeight : 0;
|
|
252
257
|
const safeAreaBottomInset = insets.bottom || 0;
|
|
253
258
|
|
|
254
259
|
return {
|
|
255
260
|
height: safeAreaBottomInset + tabBarHeight,
|
|
256
261
|
};
|
|
257
|
-
}, [
|
|
262
|
+
}, [bottomTabsVisible, insets.bottom]);
|
|
258
263
|
|
|
259
264
|
const contentInfoContent = React.useMemo(
|
|
260
265
|
() => ({ ...entry, title, summary }),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { LayoutChangeEvent, View } from "react-native";
|
|
2
|
+
import { Animated, LayoutChangeEvent, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
5
5
|
import { toBooleanWithDefaultTrue } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
@@ -8,6 +8,7 @@ import { FlexImage } from "./FlexImage";
|
|
|
8
8
|
|
|
9
9
|
import { styles } from "./styles";
|
|
10
10
|
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
11
|
+
import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
11
12
|
|
|
12
13
|
type Props = {
|
|
13
14
|
entry: ZappEntry;
|
|
@@ -29,15 +30,34 @@ export const PlayerImage = (props: Props) => {
|
|
|
29
30
|
configuration.audio_player_artwork_border_radius
|
|
30
31
|
);
|
|
31
32
|
|
|
33
|
+
const { yTranslate } = useModalAnimationContext();
|
|
34
|
+
|
|
35
|
+
const isModalExpanded = yTranslate.current.interpolate({
|
|
36
|
+
inputRange: [0, 1], // this should be end with `1` only when it's in initial state ( 0pos), otherwise `0`
|
|
37
|
+
outputRange: [1, 0],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// do not use styles.shadow when isModalExpanded is 0
|
|
41
|
+
|
|
42
|
+
const animatedStyle = {
|
|
43
|
+
opacity: isModalExpanded,
|
|
44
|
+
};
|
|
45
|
+
|
|
32
46
|
return (
|
|
33
47
|
<View style={styles.alignItemsCenter}>
|
|
48
|
+
{/* Using an Animated.View to apply shadow to the image */}
|
|
49
|
+
<Animated.View
|
|
50
|
+
style={[
|
|
51
|
+
animatedStyle,
|
|
52
|
+
shouldShowShadow ? styles.shadow : undefined,
|
|
53
|
+
{ borderRadius },
|
|
54
|
+
]}
|
|
55
|
+
/>
|
|
34
56
|
<View
|
|
35
57
|
onLayout={onLayoutImage}
|
|
36
|
-
style={[
|
|
58
|
+
style={[styles.defaultImageWrapperView, { borderRadius }]}
|
|
37
59
|
>
|
|
38
|
-
<
|
|
39
|
-
<FlexImage entry={entry} style={styles.backgroundImageContainer} />
|
|
40
|
-
</View>
|
|
60
|
+
<FlexImage entry={entry} style={styles.backgroundImageContainer} />
|
|
41
61
|
</View>
|
|
42
62
|
</View>
|
|
43
63
|
);
|
|
@@ -23,7 +23,12 @@ export const styles = StyleSheet.create({
|
|
|
23
23
|
overflow: "hidden",
|
|
24
24
|
},
|
|
25
25
|
shadow: {
|
|
26
|
-
|
|
26
|
+
zIndex: 0,
|
|
27
|
+
position: "absolute",
|
|
28
|
+
top: 0,
|
|
29
|
+
left: 0,
|
|
30
|
+
right: 0,
|
|
31
|
+
bottom: 0,
|
|
27
32
|
shadowColor: SHADOW_COLOR,
|
|
28
33
|
shadowOffset: { width: 0, height: 24 },
|
|
29
34
|
shadowOpacity: platformSelect({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { usePlugins } from "@applicaster/zapp-react-native-redux";
|
|
5
5
|
import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
|
|
6
6
|
|
|
7
7
|
type Props = {
|
|
@@ -32,7 +32,7 @@ export const PlayNextOverlay = ({
|
|
|
32
32
|
playNextData,
|
|
33
33
|
setNextVideoPreloadThresholdPercentage,
|
|
34
34
|
}: Props) => {
|
|
35
|
-
const
|
|
35
|
+
const plugins = usePlugins();
|
|
36
36
|
|
|
37
37
|
const OverlayPlugin = getOverlayPlugin(plugins);
|
|
38
38
|
|
|
@@ -5,8 +5,8 @@ import { PanGestureHandler } from "react-native-gesture-handler";
|
|
|
5
5
|
import { useStyles } from "./styles";
|
|
6
6
|
import { useVideoModalState } from "./hooks";
|
|
7
7
|
import { MODAL_COLLAPSE_RATIO, MODAL_RADIUS } from "./consts";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { getWindowHeight } from "./utils";
|
|
9
|
+
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
10
10
|
|
|
11
11
|
type AnimatedModalProps = {
|
|
12
12
|
content?: ReactElement;
|
|
@@ -17,23 +17,18 @@ export function AnimatedModal({
|
|
|
17
17
|
content,
|
|
18
18
|
collapsedContent,
|
|
19
19
|
}: AnimatedModalProps) {
|
|
20
|
-
const
|
|
20
|
+
const { translateY, collapsed, gestureHandlerProps, expand, offset } =
|
|
21
|
+
useVideoModalState();
|
|
21
22
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
collapsed,
|
|
25
|
-
collapsedHeight,
|
|
26
|
-
gestureHandlerProps,
|
|
27
|
-
expand,
|
|
28
|
-
} = useVideoModalState(translateYRef);
|
|
23
|
+
const frame = useSafeAreaFrame();
|
|
24
|
+
const collapsedHeight = frame.height - offset.current;
|
|
29
25
|
|
|
30
|
-
const
|
|
26
|
+
const height = getWindowHeight();
|
|
27
|
+
const heightAboveMinimised = height - collapsedHeight;
|
|
31
28
|
|
|
32
|
-
const
|
|
33
|
-
const heightAboveMinimised = WINDOW_HEIGHT - collapsedHeight;
|
|
34
|
-
const screenHeight = getScreenHeight();
|
|
29
|
+
const styles = useStyles({ height: collapsedHeight, type: "audio" });
|
|
35
30
|
|
|
36
|
-
const MODAL_COLLAPSE_START =
|
|
31
|
+
const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
|
|
37
32
|
|
|
38
33
|
// Interpolated opacities for smooth cross-fade
|
|
39
34
|
const collapsedOpacity = translateY.interpolate({
|
|
@@ -64,7 +59,7 @@ export function AnimatedModal({
|
|
|
64
59
|
borderTopLeftRadius: borderTopRadiusAnimated,
|
|
65
60
|
borderTopRightRadius: borderTopRadiusAnimated,
|
|
66
61
|
transform: [{ translateY }],
|
|
67
|
-
height:
|
|
62
|
+
height: height,
|
|
68
63
|
},
|
|
69
64
|
]}
|
|
70
65
|
>
|
|
@@ -74,7 +69,6 @@ export function AnimatedModal({
|
|
|
74
69
|
{
|
|
75
70
|
borderTopLeftRadius: borderTopRadiusAnimated,
|
|
76
71
|
borderTopRightRadius: borderTopRadiusAnimated,
|
|
77
|
-
height: screenHeight,
|
|
78
72
|
},
|
|
79
73
|
]}
|
|
80
74
|
>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { ReactElement, useMemo, useRef } from "react";
|
|
2
2
|
|
|
3
|
-
import { Animated, Pressable
|
|
3
|
+
import { Animated, Pressable } from "react-native";
|
|
4
4
|
import { PanGestureHandler } from "react-native-gesture-handler";
|
|
5
5
|
import { useStyles } from "./styles";
|
|
6
6
|
import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/utils";
|
|
@@ -12,22 +12,25 @@ import {
|
|
|
12
12
|
VIDEO_TRANSITION_THRESHOLD,
|
|
13
13
|
} from "./consts";
|
|
14
14
|
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
15
|
-
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
16
|
-
import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/useModalAnimationContext";
|
|
17
15
|
import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
|
|
18
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
SafeAreaView,
|
|
18
|
+
useSafeAreaFrame,
|
|
19
|
+
useSafeAreaInsets,
|
|
20
|
+
} from "react-native-safe-area-context";
|
|
19
21
|
import { GestureAnimatedScrollView } from "./GestureAnimatedScrollView";
|
|
20
22
|
import { PlayerDetailsWrapperHeightContext } from "./context";
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
import {
|
|
24
|
+
getInsetsOffset,
|
|
25
|
+
getWindowHeight,
|
|
26
|
+
getWindowWidth,
|
|
27
|
+
directionStyles,
|
|
28
|
+
getScaledPos,
|
|
29
|
+
getExtraContentPadding,
|
|
30
|
+
} from "./utils";
|
|
31
|
+
import { addOrientationChangeListener } from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
27
32
|
|
|
28
|
-
const
|
|
29
|
-
return isLandscape ? orientationStyles.landscape : orientationStyles.portrait;
|
|
30
|
-
};
|
|
33
|
+
const AnimatedSafeAreaView = Animated.createAnimatedComponent(SafeAreaView);
|
|
31
34
|
|
|
32
35
|
type AnimatedModalProps = {
|
|
33
36
|
pip?: boolean;
|
|
@@ -59,45 +62,61 @@ export function VideoPlayerModal({
|
|
|
59
62
|
const enabled = !!modal && !fullscreen;
|
|
60
63
|
const isTablet = useIsTablet();
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
// remember initial width, ignore rotation changes
|
|
66
|
+
const width = useMemo(
|
|
67
|
+
() =>
|
|
68
|
+
isTablet && !isTabletPortrait
|
|
69
|
+
? style.tabletLandscapeWidth
|
|
70
|
+
: getWindowWidth(isTablet, !isTabletPortrait),
|
|
71
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
72
|
+
[]
|
|
73
|
+
);
|
|
66
74
|
|
|
67
|
-
|
|
75
|
+
const height = useMemo(
|
|
76
|
+
() => getWindowHeight(isTablet, !isTabletPortrait),
|
|
77
|
+
[]
|
|
78
|
+
); // remember initial height, ignore rotation changes
|
|
68
79
|
|
|
69
|
-
|
|
70
|
-
width = style?.tabletLandscapeWidth || width;
|
|
71
|
-
}
|
|
80
|
+
const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
|
|
72
81
|
|
|
73
82
|
const { minimised_height: minimisedHeight } = useConfiguration();
|
|
74
83
|
const scrollViewRef = useRef<typeof Animated.ScrollView | null>(null);
|
|
75
84
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
const dummyRef = useRef(new Animated.Value(0));
|
|
85
|
+
const { translateY, collapsed, gestureHandlerProps, expand, offset } =
|
|
86
|
+
useVideoModalState();
|
|
79
87
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
collapsed,
|
|
83
|
-
collapsedHeight,
|
|
84
|
-
gestureHandlerProps,
|
|
85
|
-
expand,
|
|
86
|
-
} = useVideoModalState(modal ? translateYRef : dummyRef);
|
|
88
|
+
const frame = useSafeAreaFrame();
|
|
89
|
+
const collapsedHeight = frame.height - offset.current;
|
|
87
90
|
|
|
88
91
|
const heightAboveMinimised = height - collapsedHeight;
|
|
89
92
|
|
|
90
|
-
const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
|
|
91
|
-
|
|
92
93
|
const styles = useStyles({ height: collapsedHeight });
|
|
93
94
|
|
|
94
95
|
const SCALE_FACTOR = 1 / (width / aspectRatio / minimisedHeight); // Scale factor for expanded content
|
|
95
96
|
|
|
96
97
|
const insets = useSafeAreaInsets();
|
|
97
98
|
|
|
98
|
-
const
|
|
99
|
+
const [isFullScreenMode, setFullScreenMode] = React.useState(
|
|
100
|
+
fullscreen || pip
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
React.useEffect(() => {
|
|
104
|
+
const listener = addOrientationChangeListener(({ toOrientation }) => {
|
|
105
|
+
/* ignored in collapsed mode non-PiP player */
|
|
106
|
+
if (collapsed && !pip) return;
|
|
107
|
+
setFullScreenMode(!(toOrientation === 1));
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return () => {
|
|
111
|
+
listener.remove();
|
|
112
|
+
};
|
|
113
|
+
}, [collapsed, pip]);
|
|
114
|
+
|
|
115
|
+
const isFullScreenOrPIP = isFullScreenMode;
|
|
116
|
+
|
|
117
|
+
const vidHeight = width / aspectRatio;
|
|
99
118
|
|
|
100
|
-
//
|
|
119
|
+
// animated opacity for smooth cross-fade of collapsed content
|
|
101
120
|
const collapsedOpacity = !isFullScreenOrPIP
|
|
102
121
|
? translateY.interpolate({
|
|
103
122
|
inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
|
|
@@ -106,6 +125,7 @@ export function VideoPlayerModal({
|
|
|
106
125
|
})
|
|
107
126
|
: new Animated.Value(0);
|
|
108
127
|
|
|
128
|
+
// animated opacity for extra content
|
|
109
129
|
const expandedOpacity = !isFullScreenOrPIP
|
|
110
130
|
? translateY.interpolate({
|
|
111
131
|
inputRange: [0, heightAboveMinimised],
|
|
@@ -114,6 +134,7 @@ export function VideoPlayerModal({
|
|
|
114
134
|
})
|
|
115
135
|
: new Animated.Value(1);
|
|
116
136
|
|
|
137
|
+
// animated x position for video content
|
|
117
138
|
const xPosition = !isFullScreenOrPIP
|
|
118
139
|
? translateY.interpolate({
|
|
119
140
|
inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
|
|
@@ -122,32 +143,23 @@ export function VideoPlayerModal({
|
|
|
122
143
|
})
|
|
123
144
|
: new Animated.Value(0);
|
|
124
145
|
|
|
125
|
-
|
|
126
|
-
|
|
146
|
+
// animated y position for video content
|
|
127
147
|
const yPosition = !isFullScreenOrPIP
|
|
128
148
|
? translateY.interpolate({
|
|
129
149
|
inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
|
|
130
150
|
outputRange: [
|
|
131
151
|
0,
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
2
|
|
138
|
-
)
|
|
139
|
-
: -(
|
|
140
|
-
PROGRESS_BAR_HEIGHT +
|
|
141
|
-
insets.top / 2 +
|
|
142
|
-
(WINDOW_WIDTH / aspectRatio -
|
|
143
|
-
(WINDOW_WIDTH / aspectRatio) * SCALE_FACTOR) /
|
|
144
|
-
2
|
|
145
|
-
),
|
|
152
|
+
-(
|
|
153
|
+
PROGRESS_BAR_HEIGHT +
|
|
154
|
+
getInsetsOffset(insets, isTabletPortrait) +
|
|
155
|
+
getScaledPos(height, vidHeight, minimisedHeight, isTabletPortrait)
|
|
156
|
+
),
|
|
146
157
|
],
|
|
147
158
|
extrapolate: "clamp",
|
|
148
159
|
})
|
|
149
160
|
: new Animated.Value(0);
|
|
150
161
|
|
|
162
|
+
// animated position for video content
|
|
151
163
|
const scalePosition = !isFullScreenOrPIP
|
|
152
164
|
? translateY.interpolate({
|
|
153
165
|
inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
|
|
@@ -158,7 +170,7 @@ export function VideoPlayerModal({
|
|
|
158
170
|
|
|
159
171
|
const borderTopRadiusAnimated = !isFullScreenOrPIP
|
|
160
172
|
? translateY.interpolate({
|
|
161
|
-
inputRange: [0,
|
|
173
|
+
inputRange: [0, heightAboveMinimised],
|
|
162
174
|
outputRange: [MODAL_RADIUS, 0],
|
|
163
175
|
extrapolate: "clamp",
|
|
164
176
|
})
|
|
@@ -182,93 +194,96 @@ export function VideoPlayerModal({
|
|
|
182
194
|
<PanGestureHandler
|
|
183
195
|
enabled={enabled}
|
|
184
196
|
waitFor={scrollViewRef}
|
|
197
|
+
activeOffsetY={[-25, 25]}
|
|
198
|
+
activeOffsetX={[-25, 25]}
|
|
185
199
|
{...gestureHandlerProps}
|
|
186
200
|
>
|
|
187
|
-
<
|
|
188
|
-
pointerEvents={"auto"}
|
|
189
|
-
style={[
|
|
190
|
-
styles.modalWrapper,
|
|
191
|
-
{
|
|
192
|
-
borderTopLeftRadius: borderTopRadiusAnimated,
|
|
193
|
-
borderTopRightRadius: borderTopRadiusAnimated,
|
|
194
|
-
transform: [{ translateY: isFullScreenOrPIP ? 0 : translateY }],
|
|
195
|
-
height: screenHeight,
|
|
196
|
-
},
|
|
197
|
-
]}
|
|
198
|
-
>
|
|
201
|
+
<AnimatedSafeAreaView pointerEvents="box-none" edges={["bottom"]}>
|
|
199
202
|
<Animated.View
|
|
200
203
|
pointerEvents={"auto"}
|
|
201
204
|
style={[
|
|
202
|
-
styles.
|
|
203
|
-
collapsed ? styles.collapsedModalBg : null,
|
|
205
|
+
styles.modalWrapper,
|
|
204
206
|
{
|
|
205
207
|
borderTopLeftRadius: borderTopRadiusAnimated,
|
|
206
208
|
borderTopRightRadius: borderTopRadiusAnimated,
|
|
207
|
-
|
|
209
|
+
transform: [{ translateY: isFullScreenOrPIP ? 0 : translateY }],
|
|
210
|
+
height: frame.height,
|
|
208
211
|
},
|
|
209
212
|
]}
|
|
210
213
|
>
|
|
211
214
|
<Animated.View
|
|
212
|
-
pointerEvents={
|
|
215
|
+
pointerEvents={"auto"}
|
|
213
216
|
style={[
|
|
214
|
-
|
|
215
|
-
|
|
217
|
+
styles.modal,
|
|
218
|
+
collapsed ? styles.collapsedModalBg : null,
|
|
219
|
+
{
|
|
220
|
+
borderTopLeftRadius: borderTopRadiusAnimated,
|
|
221
|
+
borderTopRightRadius: borderTopRadiusAnimated,
|
|
222
|
+
},
|
|
216
223
|
]}
|
|
217
224
|
>
|
|
218
225
|
<Animated.View
|
|
226
|
+
pointerEvents={!collapsed ? "auto" : "none"}
|
|
219
227
|
style={[
|
|
220
|
-
styles.
|
|
221
|
-
|
|
222
|
-
transform: [
|
|
223
|
-
{ translateX: xPosition },
|
|
224
|
-
{ translateY: yPosition },
|
|
225
|
-
{ scale: scalePosition },
|
|
226
|
-
],
|
|
227
|
-
},
|
|
228
|
+
pip ? styles.modalContentPiP : styles.modalContent,
|
|
229
|
+
directionStyles(isTabletPortrait),
|
|
228
230
|
]}
|
|
229
231
|
>
|
|
230
|
-
|
|
232
|
+
<Animated.View
|
|
233
|
+
style={[
|
|
234
|
+
styles.expandedContentContainer,
|
|
235
|
+
{
|
|
236
|
+
transform: [
|
|
237
|
+
{ translateX: xPosition },
|
|
238
|
+
{ translateY: yPosition },
|
|
239
|
+
{ scale: scalePosition },
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
]}
|
|
243
|
+
>
|
|
244
|
+
{content}
|
|
245
|
+
</Animated.View>
|
|
246
|
+
{extraContent ? (
|
|
247
|
+
<GestureAnimatedScrollView
|
|
248
|
+
ref={scrollViewRef}
|
|
249
|
+
contentContainerStyle={getExtraContentPadding(insets)}
|
|
250
|
+
bounces={false}
|
|
251
|
+
overScrollMode="never"
|
|
252
|
+
onLayout={onScrollViewLayout}
|
|
253
|
+
style={[
|
|
254
|
+
styles.extraContentScrollView,
|
|
255
|
+
{ opacity: expandedOpacity },
|
|
256
|
+
]}
|
|
257
|
+
>
|
|
258
|
+
<PlayerDetailsWrapperHeightContext.Provider
|
|
259
|
+
value={playerDetailsWrapperHeight}
|
|
260
|
+
>
|
|
261
|
+
{extraContent}
|
|
262
|
+
</PlayerDetailsWrapperHeightContext.Provider>
|
|
263
|
+
</GestureAnimatedScrollView>
|
|
264
|
+
) : null}
|
|
231
265
|
</Animated.View>
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
paddingBottom: insets.bottom,
|
|
237
|
-
}}
|
|
238
|
-
onLayout={onScrollViewLayout}
|
|
266
|
+
|
|
267
|
+
{!isFullScreenOrPIP ? (
|
|
268
|
+
<Animated.View
|
|
269
|
+
pointerEvents={collapsed ? "box-none" : "none"}
|
|
239
270
|
style={[
|
|
240
|
-
styles.
|
|
241
|
-
{ opacity:
|
|
271
|
+
styles.collapsedBarContainer,
|
|
272
|
+
{ opacity: collapsedOpacity },
|
|
242
273
|
]}
|
|
243
274
|
>
|
|
244
|
-
<
|
|
245
|
-
|
|
275
|
+
<Pressable
|
|
276
|
+
testID="collapsedBarWrapper"
|
|
277
|
+
onPress={expand}
|
|
278
|
+
style={styles.collapsedBarWrapper}
|
|
246
279
|
>
|
|
247
|
-
{
|
|
248
|
-
</
|
|
249
|
-
</
|
|
280
|
+
{collapsedContent}
|
|
281
|
+
</Pressable>
|
|
282
|
+
</Animated.View>
|
|
250
283
|
) : null}
|
|
251
284
|
</Animated.View>
|
|
252
|
-
|
|
253
|
-
{!isFullScreenOrPIP ? (
|
|
254
|
-
<Animated.View
|
|
255
|
-
pointerEvents={collapsed ? "box-none" : "none"}
|
|
256
|
-
style={[
|
|
257
|
-
styles.collapsedBarContainer,
|
|
258
|
-
{ opacity: collapsedOpacity },
|
|
259
|
-
]}
|
|
260
|
-
>
|
|
261
|
-
<Pressable
|
|
262
|
-
testID="collapsedBarWrapper"
|
|
263
|
-
onPress={expand}
|
|
264
|
-
style={styles.collapsedBarWrapper}
|
|
265
|
-
>
|
|
266
|
-
{collapsedContent}
|
|
267
|
-
</Pressable>
|
|
268
|
-
</Animated.View>
|
|
269
|
-
) : null}
|
|
270
285
|
</Animated.View>
|
|
271
|
-
</
|
|
286
|
+
</AnimatedSafeAreaView>
|
|
272
287
|
</PanGestureHandler>
|
|
273
288
|
);
|
|
274
289
|
}
|