@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "15.0.0-alpha.4368022015",
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.27",
39
- "@applicaster/quick-brick-tv-transport-controls": "15.0.0-rc.15",
40
- "@applicaster/zapp-react-native-tvos-app": "15.0.0-alpha.4368022015",
41
- "@applicaster/zapp-react-native-ui-components": "15.0.0-alpha.4368022015",
42
- "@applicaster/zapp-react-native-utils": "15.0.0-alpha.4368022015",
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 { 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
 
@@ -167,7 +167,12 @@ export const DockedControls = (props: Props) => {
167
167
  const { currentRoute, screenData } = useNavigation();
168
168
 
169
169
  const plugins = usePlugins();
170
- const menuVisible = isMenuVisible(currentRoute, screenData, plugins);
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 = menuVisible ? bottomTabBarHeight : 0;
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
- }, [menuVisible, insets.bottom]);
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={[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
- import { getScreenHeight, getWindowHeight } from "./utils";
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 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;
34
- const screenHeight = getScreenHeight();
29
+ const styles = useStyles({ height: collapsedHeight, type: "audio" });
35
30
 
36
- const MODAL_COLLAPSE_START = WINDOW_HEIGHT * MODAL_COLLAPSE_RATIO;
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: screenHeight,
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, 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 { getScreenHeight, 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,45 +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 screenHeight = useMemo(() => getScreenHeight(), []); // remember initial height, ignore rotation changes
65
- 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
+ );
66
74
 
67
- let width = WINDOW_WIDTH;
75
+ const height = useMemo(
76
+ () => getWindowHeight(isTablet, !isTabletPortrait),
77
+ []
78
+ ); // remember initial height, ignore rotation changes
68
79
 
69
- if (isTablet && !isTabletPortrait) {
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 translateYRef = useModalAnimationContext().yTranslate;
77
- // used when modal is false, should not be used in animation
78
- const dummyRef = useRef(new Animated.Value(0));
85
+ const { translateY, collapsed, gestureHandlerProps, expand, offset } =
86
+ useVideoModalState();
79
87
 
80
- const {
81
- translateY,
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 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;
99
118
 
100
- // Interpolated opacities for smooth cross-fade
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
- const vidHeight = width / aspectRatio;
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
- isTablet && isTabletLandscape
133
- ? -(
134
- (-PROGRESS_BAR_HEIGHT +
135
- screenHeight -
136
- vidHeight * SCALE_FACTOR) /
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, height - collapsedHeight],
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
- <Animated.View
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.modal,
203
- collapsed ? styles.collapsedModalBg : null,
205
+ styles.modalWrapper,
204
206
  {
205
207
  borderTopLeftRadius: borderTopRadiusAnimated,
206
208
  borderTopRightRadius: borderTopRadiusAnimated,
207
- height: screenHeight,
209
+ transform: [{ translateY: isFullScreenOrPIP ? 0 : translateY }],
210
+ height: frame.height,
208
211
  },
209
212
  ]}
210
213
  >
211
214
  <Animated.View
212
- pointerEvents={!collapsed ? "auto" : "none"}
215
+ pointerEvents={"auto"}
213
216
  style={[
214
- pip ? styles.modalContentPiP : styles.modalContent,
215
- directionStyles(isTabletLandscape),
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.expandedContentContainer,
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
- {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}
231
265
  </Animated.View>
232
- {extraContent ? (
233
- <GestureAnimatedScrollView
234
- ref={scrollViewRef}
235
- contentContainerStyle={{
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.extraContentScrollView,
241
- { opacity: expandedOpacity },
271
+ styles.collapsedBarContainer,
272
+ { opacity: collapsedOpacity },
242
273
  ]}
243
274
  >
244
- <PlayerDetailsWrapperHeightContext.Provider
245
- value={playerDetailsWrapperHeight}
275
+ <Pressable
276
+ testID="collapsedBarWrapper"
277
+ onPress={expand}
278
+ style={styles.collapsedBarWrapper}
246
279
  >
247
- {extraContent}
248
- </PlayerDetailsWrapperHeightContext.Provider>
249
- </GestureAnimatedScrollView>
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
- </Animated.View>
286
+ </AnimatedSafeAreaView>
272
287
  </PanGestureHandler>
273
288
  );
274
289
  }