@applicaster/quick-brick-player 15.0.0-alpha.6141436051 → 15.0.0-alpha.6203358875

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "15.0.0-alpha.6141436051",
3
+ "version": "15.0.0-alpha.6203358875",
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-alpha.6141436051",
39
- "@applicaster/quick-brick-tv-transport-controls": "15.0.0-rc.15",
40
- "@applicaster/zapp-react-native-tvos-app": "15.0.0-alpha.6141436051",
41
- "@applicaster/zapp-react-native-ui-components": "15.0.0-alpha.6141436051",
42
- "@applicaster/zapp-react-native-utils": "15.0.0-alpha.6141436051",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "15.0.0-rc.127",
39
+ "@applicaster/quick-brick-tv-transport-controls": "15.0.0-rc.116",
40
+ "@applicaster/zapp-react-native-tvos-app": "15.0.0-alpha.6203358875",
41
+ "@applicaster/zapp-react-native-ui-components": "15.0.0-alpha.6203358875",
42
+ "@applicaster/zapp-react-native-utils": "15.0.0-alpha.6203358875",
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 { isMenuVisible } from "@applicaster/zapp-react-native-ui-components/Components/Screen/navigationHandler";
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
 
@@ -90,7 +90,8 @@ const styles = StyleSheet.create({
90
90
  marginTop: { marginTop: PROGRESS_BAR_HEIGHT },
91
91
  });
92
92
 
93
- const getValue = (key: string, stylesObj: {}) => stylesObj?.[key] ?? null;
93
+ const getValue = (key: string, stylesObj: Record<string, any>) =>
94
+ stylesObj?.[key] ?? null;
94
95
 
95
96
  const controlButtons = (
96
97
  live: boolean,
@@ -166,7 +167,12 @@ export const DockedControls = (props: Props) => {
166
167
  const { currentRoute, screenData } = useNavigation();
167
168
 
168
169
  const plugins = usePlugins();
169
- const menuVisible = isMenuVisible(currentRoute, screenData, plugins);
170
+
171
+ const bottomTabsVisible = isBottomTabVisible(
172
+ currentRoute,
173
+ screenData,
174
+ plugins
175
+ );
170
176
 
171
177
  const { minimised_height: minimisedHeight } = useConfiguration();
172
178
 
@@ -208,7 +214,7 @@ export const DockedControls = (props: Props) => {
208
214
 
209
215
  const insets = useSafeAreaInsets();
210
216
 
211
- const progresBarLayoutState = React.useMemo(
217
+ const progressBarLayoutState = React.useMemo(
212
218
  () => ({
213
219
  inline: layoutState.inline,
214
220
  docked: true,
@@ -247,13 +253,13 @@ export const DockedControls = (props: Props) => {
247
253
  );
248
254
 
249
255
  const bottomSpacerStyle = React.useMemo(() => {
250
- const tabBarHeight = menuVisible ? bottomTabBarHeight : 0;
256
+ const tabBarHeight = bottomTabsVisible ? bottomTabBarHeight : 0;
251
257
  const safeAreaBottomInset = insets.bottom || 0;
252
258
 
253
259
  return {
254
260
  height: safeAreaBottomInset + tabBarHeight,
255
261
  };
256
- }, [menuVisible, insets.bottom]);
262
+ }, [bottomTabsVisible, insets.bottom]);
257
263
 
258
264
  const contentInfoContent = React.useMemo(
259
265
  () => ({ ...entry, title, summary }),
@@ -275,7 +281,7 @@ export const DockedControls = (props: Props) => {
275
281
  content={entry}
276
282
  value={value}
277
283
  visible
278
- layoutState={progresBarLayoutState}
284
+ layoutState={progressBarLayoutState}
279
285
  onPlayerSeek={onPlayerSeek}
280
286
  playerState={playerState}
281
287
  docked
@@ -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={[shouldShowShadow ? styles.shadow : undefined, { borderRadius }]}
58
+ style={[styles.defaultImageWrapperView, { borderRadius }]}
37
59
  >
38
- <View style={[styles.defaultImageWrapperView, { borderRadius }]}>
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
- borderColor: "transparent",
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 { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
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 { plugins } = usePickFromState(["plugins"]);
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 { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
9
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,22 +17,18 @@ export function AnimatedModal({
17
17
  content,
18
18
  collapsedContent,
19
19
  }: AnimatedModalProps) {
20
- const translateYRef = useModalAnimationContext().yTranslate;
20
+ const { translateY, collapsed, gestureHandlerProps, expand, offset } =
21
+ useVideoModalState();
21
22
 
22
- const {
23
- translateY,
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 styles = useStyles({ height: collapsedHeight, type: "audio" });
26
+ const height = getWindowHeight();
27
+ const heightAboveMinimised = height - collapsedHeight;
31
28
 
32
- const WINDOW_HEIGHT = getWindowHeight();
33
- const heightAboveMinimised = WINDOW_HEIGHT - collapsedHeight;
29
+ const styles = useStyles({ height: collapsedHeight, type: "audio" });
34
30
 
35
- const MODAL_COLLAPSE_START = WINDOW_HEIGHT * MODAL_COLLAPSE_RATIO;
31
+ const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
36
32
 
37
33
  // Interpolated opacities for smooth cross-fade
38
34
  const collapsedOpacity = translateY.interpolate({
@@ -63,7 +59,7 @@ export function AnimatedModal({
63
59
  borderTopLeftRadius: borderTopRadiusAnimated,
64
60
  borderTopRightRadius: borderTopRadiusAnimated,
65
61
  transform: [{ translateY }],
66
- height: WINDOW_HEIGHT,
62
+ height: height,
67
63
  },
68
64
  ]}
69
65
  >
@@ -73,7 +69,6 @@ export function AnimatedModal({
73
69
  {
74
70
  borderTopLeftRadius: borderTopRadiusAnimated,
75
71
  borderTopRightRadius: borderTopRadiusAnimated,
76
- height: WINDOW_HEIGHT,
77
72
  },
78
73
  ]}
79
74
  >
@@ -1,6 +1,6 @@
1
1
  import React, { ReactElement, useMemo, useRef } from "react";
2
2
 
3
- import { Animated, Pressable, StyleSheet, ViewStyle } from "react-native";
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 { useSafeAreaInsets } from "react-native-safe-area-context";
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 { getWindowHeight, getWindowWidth } from "./utils";
22
-
23
- const orientationStyles = StyleSheet.create({
24
- landscape: { flexDirection: "row" },
25
- portrait: { flexDirection: "column" },
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 directionStyles = (isLandscape: boolean): ViewStyle => {
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,44 +62,61 @@ export function VideoPlayerModal({
59
62
  const enabled = !!modal && !fullscreen;
60
63
  const isTablet = useIsTablet();
61
64
 
62
- const WINDOW_WIDTH = useMemo(() => getWindowWidth(), []); // remember initial width, ignore rotation changes
63
- const height = useMemo(() => getWindowHeight(), []); // remember initial height, ignore rotation changes
64
- const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
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
+ );
65
74
 
66
- let width = WINDOW_WIDTH;
75
+ const height = useMemo(
76
+ () => getWindowHeight(isTablet, !isTabletPortrait),
77
+ []
78
+ ); // remember initial height, ignore rotation changes
67
79
 
68
- if (isTablet && !isTabletPortrait) {
69
- width = style?.tabletLandscapeWidth || width;
70
- }
80
+ const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
71
81
 
72
82
  const { minimised_height: minimisedHeight } = useConfiguration();
73
83
  const scrollViewRef = useRef<typeof Animated.ScrollView | null>(null);
74
84
 
75
- const translateYRef = useModalAnimationContext().yTranslate;
76
- // used when modal is false, should not be used in animation
77
- const dummyRef = useRef(new Animated.Value(0));
85
+ const { translateY, collapsed, gestureHandlerProps, expand, offset } =
86
+ useVideoModalState();
78
87
 
79
- const {
80
- translateY,
81
- collapsed,
82
- collapsedHeight,
83
- gestureHandlerProps,
84
- expand,
85
- } = useVideoModalState(modal ? translateYRef : dummyRef);
88
+ const frame = useSafeAreaFrame();
89
+ const collapsedHeight = frame.height - offset.current;
86
90
 
87
91
  const heightAboveMinimised = height - collapsedHeight;
88
92
 
89
- const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
90
-
91
93
  const styles = useStyles({ height: collapsedHeight });
92
94
 
93
95
  const SCALE_FACTOR = 1 / (width / aspectRatio / minimisedHeight); // Scale factor for expanded content
94
96
 
95
97
  const insets = useSafeAreaInsets();
96
98
 
97
- const isFullScreenOrPIP = fullscreen || pip;
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;
98
118
 
99
- // Interpolated opacities for smooth cross-fade
119
+ // animated opacity for smooth cross-fade of collapsed content
100
120
  const collapsedOpacity = !isFullScreenOrPIP
101
121
  ? translateY.interpolate({
102
122
  inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
@@ -105,6 +125,7 @@ export function VideoPlayerModal({
105
125
  })
106
126
  : new Animated.Value(0);
107
127
 
128
+ // animated opacity for extra content
108
129
  const expandedOpacity = !isFullScreenOrPIP
109
130
  ? translateY.interpolate({
110
131
  inputRange: [0, heightAboveMinimised],
@@ -113,6 +134,7 @@ export function VideoPlayerModal({
113
134
  })
114
135
  : new Animated.Value(1);
115
136
 
137
+ // animated x position for video content
116
138
  const xPosition = !isFullScreenOrPIP
117
139
  ? translateY.interpolate({
118
140
  inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
@@ -121,27 +143,23 @@ export function VideoPlayerModal({
121
143
  })
122
144
  : new Animated.Value(0);
123
145
 
124
- const vidHeight = width / aspectRatio;
125
-
146
+ // animated y position for video content
126
147
  const yPosition = !isFullScreenOrPIP
127
148
  ? translateY.interpolate({
128
149
  inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
129
150
  outputRange: [
130
151
  0,
131
- isTablet && isTabletLandscape
132
- ? -((-PROGRESS_BAR_HEIGHT + height - vidHeight * SCALE_FACTOR) / 2)
133
- : -(
134
- PROGRESS_BAR_HEIGHT +
135
- insets.top / 2 +
136
- (WINDOW_WIDTH / aspectRatio -
137
- (WINDOW_WIDTH / aspectRatio) * SCALE_FACTOR) /
138
- 2
139
- ),
152
+ -(
153
+ PROGRESS_BAR_HEIGHT +
154
+ getInsetsOffset(insets, isTabletPortrait) +
155
+ getScaledPos(height, vidHeight, minimisedHeight, isTabletPortrait)
156
+ ),
140
157
  ],
141
158
  extrapolate: "clamp",
142
159
  })
143
160
  : new Animated.Value(0);
144
161
 
162
+ // animated position for video content
145
163
  const scalePosition = !isFullScreenOrPIP
146
164
  ? translateY.interpolate({
147
165
  inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
@@ -152,7 +170,7 @@ export function VideoPlayerModal({
152
170
 
153
171
  const borderTopRadiusAnimated = !isFullScreenOrPIP
154
172
  ? translateY.interpolate({
155
- inputRange: [0, height - collapsedHeight],
173
+ inputRange: [0, heightAboveMinimised],
156
174
  outputRange: [MODAL_RADIUS, 0],
157
175
  extrapolate: "clamp",
158
176
  })
@@ -176,90 +194,96 @@ export function VideoPlayerModal({
176
194
  <PanGestureHandler
177
195
  enabled={enabled}
178
196
  waitFor={scrollViewRef}
197
+ activeOffsetY={[-25, 25]}
198
+ activeOffsetX={[-25, 25]}
179
199
  {...gestureHandlerProps}
180
200
  >
181
- <Animated.View
182
- pointerEvents={"auto"}
183
- style={[
184
- styles.modalWrapper,
185
- {
186
- borderTopLeftRadius: borderTopRadiusAnimated,
187
- borderTopRightRadius: borderTopRadiusAnimated,
188
- transform: [{ translateY: isFullScreenOrPIP ? 0 : translateY }],
189
- height: height,
190
- },
191
- ]}
192
- >
201
+ <AnimatedSafeAreaView pointerEvents="box-none" edges={["bottom"]}>
193
202
  <Animated.View
194
203
  pointerEvents={"auto"}
195
204
  style={[
196
- styles.modal,
197
- collapsed ? styles.collapsedModalBg : null,
205
+ styles.modalWrapper,
198
206
  {
199
207
  borderTopLeftRadius: borderTopRadiusAnimated,
200
208
  borderTopRightRadius: borderTopRadiusAnimated,
201
- height: height,
209
+ transform: [{ translateY: isFullScreenOrPIP ? 0 : translateY }],
210
+ height: frame.height,
202
211
  },
203
212
  ]}
204
213
  >
205
214
  <Animated.View
206
- pointerEvents={!collapsed ? "auto" : "none"}
207
- style={[styles.modalContent, directionStyles(isTabletLandscape)]}
215
+ pointerEvents={"auto"}
216
+ style={[
217
+ styles.modal,
218
+ collapsed ? styles.collapsedModalBg : null,
219
+ {
220
+ borderTopLeftRadius: borderTopRadiusAnimated,
221
+ borderTopRightRadius: borderTopRadiusAnimated,
222
+ },
223
+ ]}
208
224
  >
209
225
  <Animated.View
226
+ pointerEvents={!collapsed ? "auto" : "none"}
210
227
  style={[
211
- styles.expandedContentContainer,
212
- {
213
- transform: [
214
- { translateX: xPosition },
215
- { translateY: yPosition },
216
- { scale: scalePosition },
217
- ],
218
- },
228
+ pip ? styles.modalContentPiP : styles.modalContent,
229
+ directionStyles(isTabletPortrait),
219
230
  ]}
220
231
  >
221
- {content}
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}
222
265
  </Animated.View>
223
- {extraContent ? (
224
- <GestureAnimatedScrollView
225
- ref={scrollViewRef}
226
- contentContainerStyle={{
227
- paddingBottom: insets.bottom,
228
- }}
229
- onLayout={onScrollViewLayout}
266
+
267
+ {!isFullScreenOrPIP ? (
268
+ <Animated.View
269
+ pointerEvents={collapsed ? "box-none" : "none"}
230
270
  style={[
231
- styles.extraContentScrollView,
232
- { opacity: expandedOpacity },
271
+ styles.collapsedBarContainer,
272
+ { opacity: collapsedOpacity },
233
273
  ]}
234
274
  >
235
- <PlayerDetailsWrapperHeightContext.Provider
236
- value={playerDetailsWrapperHeight}
275
+ <Pressable
276
+ testID="collapsedBarWrapper"
277
+ onPress={expand}
278
+ style={styles.collapsedBarWrapper}
237
279
  >
238
- {extraContent}
239
- </PlayerDetailsWrapperHeightContext.Provider>
240
- </GestureAnimatedScrollView>
280
+ {collapsedContent}
281
+ </Pressable>
282
+ </Animated.View>
241
283
  ) : null}
242
284
  </Animated.View>
243
-
244
- {!isFullScreenOrPIP ? (
245
- <Animated.View
246
- pointerEvents={collapsed ? "box-none" : "none"}
247
- style={[
248
- styles.collapsedBarContainer,
249
- { opacity: collapsedOpacity },
250
- ]}
251
- >
252
- <Pressable
253
- testID="collapsedBarWrapper"
254
- onPress={expand}
255
- style={styles.collapsedBarWrapper}
256
- >
257
- {collapsedContent}
258
- </Pressable>
259
- </Animated.View>
260
- ) : null}
261
285
  </Animated.View>
262
- </Animated.View>
286
+ </AnimatedSafeAreaView>
263
287
  </PanGestureHandler>
264
288
  );
265
289
  }