@applicaster/quick-brick-player 15.0.0-rc.3 → 15.0.0-rc.30

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.
@@ -1,34 +1,34 @@
1
- import React, { ReactElement, useRef } from "react";
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";
7
7
  import { useVideoModalState } from "./hooks";
8
8
  import {
9
9
  DEFAULT_IMAGE_RATIO_VIDEO,
10
- MODAL_COLLAPSE_START,
10
+ MODAL_COLLAPSE_RATIO,
11
11
  MODAL_RADIUS,
12
- SCREEN_HEIGHT,
13
- SCREEN_WIDTH,
14
12
  VIDEO_TRANSITION_THRESHOLD,
15
13
  } from "./consts";
16
14
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
17
- import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
18
15
  import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/useModalAnimationContext";
19
16
  import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
20
- import { useSafeAreaInsets } from "react-native-safe-area-context";
17
+ import {
18
+ SafeAreaView,
19
+ useSafeAreaFrame,
20
+ useSafeAreaInsets,
21
+ } from "react-native-safe-area-context";
21
22
  import { GestureAnimatedScrollView } from "./GestureAnimatedScrollView";
22
23
  import { PlayerDetailsWrapperHeightContext } from "./context";
23
-
24
- const orientationStyles = StyleSheet.create({
25
- landscape: { flexDirection: "row" },
26
- portrait: { flexDirection: "column" },
27
- });
28
-
29
- const directionStyles = (isLandscape: boolean): ViewStyle => {
30
- return isLandscape ? orientationStyles.landscape : orientationStyles.portrait;
31
- };
24
+ import {
25
+ getInsetsOffset,
26
+ getWindowHeight,
27
+ getWindowWidth,
28
+ directionStyles,
29
+ getScaledPos,
30
+ getExtraContentPadding,
31
+ } from "./utils";
32
32
 
33
33
  type AnimatedModalProps = {
34
34
  pip?: boolean;
@@ -46,8 +46,6 @@ type AnimatedModalProps = {
46
46
  };
47
47
  };
48
48
 
49
- const height = SCREEN_HEIGHT;
50
-
51
49
  export function VideoPlayerModal({
52
50
  aspectRatio = DEFAULT_IMAGE_RATIO_VIDEO,
53
51
  content,
@@ -62,11 +60,18 @@ export function VideoPlayerModal({
62
60
  const enabled = !!modal && !fullscreen;
63
61
  const isTablet = useIsTablet();
64
62
 
65
- let width = SCREEN_WIDTH;
63
+ // remember initial width, ignore rotation changes
64
+ const width = useMemo(
65
+ () =>
66
+ isTablet && !isTabletPortrait
67
+ ? style.tabletLandscapeWidth
68
+ : getWindowWidth(),
69
+ // eslint-disable-next-line react-hooks/exhaustive-deps
70
+ []
71
+ );
66
72
 
67
- if (isTablet && !isTabletPortrait) {
68
- width = style?.tabletLandscapeWidth || width;
69
- }
73
+ const height = useMemo(() => getWindowHeight(), []); // remember initial height, ignore rotation changes
74
+ const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
70
75
 
71
76
  const { minimised_height: minimisedHeight } = useConfiguration();
72
77
  const scrollViewRef = useRef<typeof Animated.ScrollView | null>(null);
@@ -83,7 +88,9 @@ export function VideoPlayerModal({
83
88
  expand,
84
89
  } = useVideoModalState(modal ? translateYRef : dummyRef);
85
90
 
86
- const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
91
+ const frame = useSafeAreaFrame();
92
+
93
+ const heightAboveMinimised = height - collapsedHeight;
87
94
 
88
95
  const styles = useStyles({ height: collapsedHeight });
89
96
 
@@ -96,7 +103,7 @@ export function VideoPlayerModal({
96
103
  // Interpolated opacities for smooth cross-fade
97
104
  const collapsedOpacity = !isFullScreenOrPIP
98
105
  ? translateY.interpolate({
99
- inputRange: [MODAL_COLLAPSE_START, height - collapsedHeight],
106
+ inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
100
107
  outputRange: [0, 1],
101
108
  extrapolate: "clamp",
102
109
  })
@@ -104,18 +111,16 @@ export function VideoPlayerModal({
104
111
 
105
112
  const expandedOpacity = !isFullScreenOrPIP
106
113
  ? translateY.interpolate({
107
- inputRange: [0, height - collapsedHeight],
114
+ inputRange: [0, heightAboveMinimised],
108
115
  outputRange: [1, 0],
109
116
  extrapolate: "clamp",
110
117
  })
111
118
  : new Animated.Value(1);
112
119
 
120
+ // animated position for video content during modal transition
113
121
  const xPosition = !isFullScreenOrPIP
114
122
  ? translateY.interpolate({
115
- inputRange: [
116
- height * VIDEO_TRANSITION_THRESHOLD,
117
- height - collapsedHeight,
118
- ],
123
+ inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
119
124
  outputRange: [0, -(width - width * SCALE_FACTOR) / 2],
120
125
  extrapolate: "clamp",
121
126
  })
@@ -123,34 +128,26 @@ export function VideoPlayerModal({
123
128
 
124
129
  const vidHeight = width / aspectRatio;
125
130
 
131
+ // animated position for video content during modal transition
126
132
  const yPosition = !isFullScreenOrPIP
127
133
  ? translateY.interpolate({
128
- inputRange: [
129
- height * VIDEO_TRANSITION_THRESHOLD,
130
- height - collapsedHeight,
131
- ],
134
+ inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
132
135
  outputRange: [
133
136
  0,
134
- isTablet && isTabletLandscape
135
- ? -((-PROGRESS_BAR_HEIGHT + height - vidHeight * SCALE_FACTOR) / 2)
136
- : -(
137
- PROGRESS_BAR_HEIGHT +
138
- insets.top / 2 +
139
- (SCREEN_WIDTH / aspectRatio -
140
- (SCREEN_WIDTH / aspectRatio) * SCALE_FACTOR) /
141
- 2
142
- ),
137
+ -(
138
+ PROGRESS_BAR_HEIGHT +
139
+ getInsetsOffset(insets, isTabletPortrait) +
140
+ getScaledPos(height, vidHeight, minimisedHeight, isTabletPortrait)
141
+ ),
143
142
  ],
144
143
  extrapolate: "clamp",
145
144
  })
146
145
  : new Animated.Value(0);
147
146
 
147
+ // animated position for video content during modal transition
148
148
  const scalePosition = !isFullScreenOrPIP
149
149
  ? translateY.interpolate({
150
- inputRange: [
151
- height * VIDEO_TRANSITION_THRESHOLD,
152
- height - collapsedHeight,
153
- ],
150
+ inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
154
151
  outputRange: [1, SCALE_FACTOR],
155
152
  extrapolate: "clamp",
156
153
  })
@@ -158,7 +155,7 @@ export function VideoPlayerModal({
158
155
 
159
156
  const borderTopRadiusAnimated = !isFullScreenOrPIP
160
157
  ? translateY.interpolate({
161
- inputRange: [0, height - collapsedHeight],
158
+ inputRange: [0, heightAboveMinimised],
162
159
  outputRange: [MODAL_RADIUS, 0],
163
160
  extrapolate: "clamp",
164
161
  })
@@ -184,88 +181,92 @@ export function VideoPlayerModal({
184
181
  waitFor={scrollViewRef}
185
182
  {...gestureHandlerProps}
186
183
  >
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: height,
196
- },
197
- ]}
198
- >
184
+ <SafeAreaView pointerEvents="box-none" edges={["bottom"]}>
199
185
  <Animated.View
200
186
  pointerEvents={"auto"}
201
187
  style={[
202
- styles.modal,
203
- collapsed ? styles.collapsedModalBg : null,
188
+ styles.modalWrapper,
204
189
  {
205
190
  borderTopLeftRadius: borderTopRadiusAnimated,
206
191
  borderTopRightRadius: borderTopRadiusAnimated,
207
- height: height,
192
+ transform: [{ translateY: isFullScreenOrPIP ? 0 : translateY }],
193
+ height: frame.height,
208
194
  },
209
195
  ]}
210
196
  >
211
197
  <Animated.View
212
- pointerEvents={!collapsed ? "auto" : "none"}
213
- style={[styles.modalContent, directionStyles(isTabletLandscape)]}
198
+ pointerEvents={"auto"}
199
+ style={[
200
+ styles.modal,
201
+ collapsed ? styles.collapsedModalBg : null,
202
+ {
203
+ borderTopLeftRadius: borderTopRadiusAnimated,
204
+ borderTopRightRadius: borderTopRadiusAnimated,
205
+ },
206
+ ]}
214
207
  >
215
208
  <Animated.View
209
+ pointerEvents={!collapsed ? "auto" : "none"}
216
210
  style={[
217
- styles.expandedContentContainer,
218
- {
219
- transform: [
220
- { translateX: xPosition },
221
- { translateY: yPosition },
222
- { scale: scalePosition },
223
- ],
224
- },
211
+ pip ? styles.modalContentPiP : styles.modalContent,
212
+ directionStyles(isTabletPortrait),
225
213
  ]}
226
214
  >
227
- {content}
215
+ <Animated.View
216
+ style={[
217
+ styles.expandedContentContainer,
218
+ {
219
+ transform: [
220
+ { translateX: xPosition },
221
+ { translateY: yPosition },
222
+ { scale: scalePosition },
223
+ ],
224
+ },
225
+ ]}
226
+ >
227
+ {content}
228
+ </Animated.View>
229
+ {extraContent ? (
230
+ <GestureAnimatedScrollView
231
+ ref={scrollViewRef}
232
+ contentContainerStyle={getExtraContentPadding(insets)}
233
+ bounces={false}
234
+ overScrollMode="never"
235
+ onLayout={onScrollViewLayout}
236
+ style={[
237
+ styles.extraContentScrollView,
238
+ { opacity: expandedOpacity },
239
+ ]}
240
+ >
241
+ <PlayerDetailsWrapperHeightContext.Provider
242
+ value={playerDetailsWrapperHeight}
243
+ >
244
+ {extraContent}
245
+ </PlayerDetailsWrapperHeightContext.Provider>
246
+ </GestureAnimatedScrollView>
247
+ ) : null}
228
248
  </Animated.View>
229
- {extraContent ? (
230
- <GestureAnimatedScrollView
231
- ref={scrollViewRef}
232
- contentContainerStyle={{
233
- paddingBottom: insets.bottom,
234
- }}
235
- onLayout={onScrollViewLayout}
249
+
250
+ {!isFullScreenOrPIP ? (
251
+ <Animated.View
252
+ pointerEvents={collapsed ? "box-none" : "none"}
236
253
  style={[
237
- styles.extraContentScrollView,
238
- { opacity: expandedOpacity },
254
+ styles.collapsedBarContainer,
255
+ { opacity: collapsedOpacity },
239
256
  ]}
240
257
  >
241
- <PlayerDetailsWrapperHeightContext.Provider
242
- value={playerDetailsWrapperHeight}
258
+ <Pressable
259
+ testID="collapsedBarWrapper"
260
+ onPress={expand}
261
+ style={styles.collapsedBarWrapper}
243
262
  >
244
- {extraContent}
245
- </PlayerDetailsWrapperHeightContext.Provider>
246
- </GestureAnimatedScrollView>
263
+ {collapsedContent}
264
+ </Pressable>
265
+ </Animated.View>
247
266
  ) : null}
248
267
  </Animated.View>
249
-
250
- {!isFullScreenOrPIP ? (
251
- <Animated.View
252
- pointerEvents={collapsed ? "box-none" : "none"}
253
- style={[
254
- styles.collapsedBarContainer,
255
- { opacity: collapsedOpacity },
256
- ]}
257
- >
258
- <Pressable
259
- testID="collapsedBarWrapper"
260
- onPress={expand}
261
- style={styles.collapsedBarWrapper}
262
- >
263
- {collapsedContent}
264
- </Pressable>
265
- </Animated.View>
266
- ) : null}
267
268
  </Animated.View>
268
- </Animated.View>
269
+ </SafeAreaView>
269
270
  </PanGestureHandler>
270
271
  );
271
272
  }
@@ -1,26 +1,7 @@
1
- import { isAndroidTablet } from "@applicaster/zapp-react-native-utils/reactHooks/layout/isTablet";
2
- import {
3
- isAndroidPlatform,
4
- isAndroidVersionAtLeast,
5
- } from "@applicaster/zapp-react-native-utils/reactUtils";
6
- import { Dimensions, StatusBar } from "react-native";
7
-
8
1
  export const DOCKED_PROGRESSBAR_HEIGHT = 3; // Height of the docked progress bar plugins/mobile-transport-controls/src/ProgressBar/layouts/DockedLayout.tsx
9
2
 
10
3
  export const VIDEO_TRANSITION_THRESHOLD = 0.5; // Threshold for video transition
11
4
 
12
- const windowDimensions = Dimensions.get("window");
13
-
14
- const isOldAndroidDevice =
15
- isAndroidPlatform() && !isAndroidVersionAtLeast(34) && !isAndroidTablet();
16
-
17
- export const SCREEN_WIDTH = windowDimensions.width;
18
-
19
- export const SCREEN_HEIGHT =
20
- windowDimensions.height + (isOldAndroidDevice ? StatusBar.currentHeight : 0);
21
-
22
- export const MODAL_COLLAPSE_START = SCREEN_HEIGHT * 0.7; // 70% of screen height
23
-
24
5
  export const DRAG_TO_COLLAPSE = 0.02; // 2% to collapse
25
6
 
26
7
  export const DRAG_TO_EXPAND = 0.02; // 2% to expand
@@ -32,3 +13,5 @@ export const DEFAULT_IMAGE_RATIO_AUDIO = 1; // Default aspect ratio for audio
32
13
  export const ANIMATION_DURATION = 250; // Default animation duration in milliseconds
33
14
 
34
15
  export const MODAL_RADIUS = 16; // Default border radius for modal
16
+
17
+ export const MODAL_COLLAPSE_RATIO = 0.7; // 70% of the screen height
@@ -1,5 +1,8 @@
1
1
  import { useCallback, useEffect, useMemo, useRef } from "react";
2
- import { useSafeAreaInsets } from "react-native-safe-area-context";
2
+ import {
3
+ useSafeAreaFrame,
4
+ useSafeAreaInsets,
5
+ } from "react-native-safe-area-context";
3
6
  import { State } from "react-native-gesture-handler";
4
7
  import { Animated } from "react-native";
5
8
 
@@ -12,10 +15,10 @@ import {
12
15
  ANIMATION_DURATION,
13
16
  DRAG_TO_COLLAPSE,
14
17
  DRAG_TO_EXPAND,
15
- SCREEN_HEIGHT,
16
18
  } from "../consts";
17
19
  import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
18
20
  import { usePlugins } from "@applicaster/zapp-react-native-redux";
21
+ import { isOldAndroidDevice } from "../utils";
19
22
 
20
23
  const bottomTabBarHeight = getTabBarHeight();
21
24
 
@@ -36,18 +39,21 @@ export const useVideoModalState = (
36
39
 
37
40
  const menuVisible = isMenuVisible(currentRoute, screenData, plugins);
38
41
 
39
- const collapsed = videoModalState.mode === VideoModalMode.MINIMIZED;
40
-
41
- const { bottom } = useSafeAreaInsets();
42
+ const collapsed =
43
+ videoModalState.visible &&
44
+ videoModalState.mode === VideoModalMode.MINIMIZED;
42
45
 
43
- const initialBottomOffset = useRef(bottom).current;
46
+ const frame = useSafeAreaFrame();
47
+ const insets = useSafeAreaInsets();
44
48
 
45
49
  const collapsedHeight =
46
50
  minimisedHeight +
47
- initialBottomOffset +
48
51
  (menuVisible ? bottomTabBarHeight : 0) +
52
+ (isOldAndroidDevice ? 0 : insets.bottom) + // insets.bottom is added to properly display docked modal
49
53
  PROGRESS_BAR_HEIGHT;
50
54
 
55
+ const heightAboveMinimised = frame.height - collapsedHeight;
56
+
51
57
  const translateY = translateYRef.current;
52
58
 
53
59
  const handleExpand = useCallback(
@@ -72,7 +78,7 @@ export const useVideoModalState = (
72
78
  [translateYRef]
73
79
  );
74
80
 
75
- const offset = useRef(SCREEN_HEIGHT - collapsedHeight);
81
+ const offset = useRef(heightAboveMinimised);
76
82
 
77
83
  // Gesture handler for modal
78
84
  const onGestureEvent = useCallback(
@@ -82,8 +88,8 @@ export const useVideoModalState = (
82
88
  let newY = offset.current + y;
83
89
  if (newY < 0) newY = 0;
84
90
 
85
- if (newY > SCREEN_HEIGHT - collapsedHeight) {
86
- newY = SCREEN_HEIGHT - collapsedHeight;
91
+ if (newY > heightAboveMinimised) {
92
+ newY = heightAboveMinimised;
87
93
  }
88
94
 
89
95
  translateY.setValue(newY);
@@ -99,25 +105,25 @@ export const useVideoModalState = (
99
105
  let newY = offset.current + translationY;
100
106
  if (newY < 0) newY = 0;
101
107
 
102
- if (newY > SCREEN_HEIGHT - collapsedHeight) {
103
- newY = SCREEN_HEIGHT - collapsedHeight;
108
+ if (newY > heightAboveMinimised) {
109
+ newY = heightAboveMinimised;
104
110
  }
105
111
 
106
112
  const shouldCollapse =
107
- translationY > (SCREEN_HEIGHT - collapsedHeight) * DRAG_TO_COLLAPSE;
113
+ translationY > heightAboveMinimised * DRAG_TO_COLLAPSE;
108
114
 
109
115
  const shouldExpand =
110
- translationY < -(SCREEN_HEIGHT - collapsedHeight) * DRAG_TO_EXPAND;
116
+ translationY < -heightAboveMinimised * DRAG_TO_EXPAND;
111
117
 
112
118
  if (!collapsed && shouldCollapse) {
113
119
  // Collapse
114
120
  Animated.timing(translateY, {
115
- toValue: SCREEN_HEIGHT - collapsedHeight,
121
+ toValue: heightAboveMinimised,
116
122
  duration: ANIMATION_DURATION,
117
123
  useNativeDriver: true,
118
124
  }).start(() => {
119
125
  minimiseVideoModal();
120
- offset.current = SCREEN_HEIGHT - collapsedHeight;
126
+ offset.current = heightAboveMinimised;
121
127
  });
122
128
  } else if (collapsed && shouldExpand) {
123
129
  // Expand
@@ -133,10 +139,10 @@ export const useVideoModalState = (
133
139
  } else {
134
140
  // Snap back to current state
135
141
  Animated.spring(translateY, {
136
- toValue: collapsed ? SCREEN_HEIGHT - collapsedHeight : 0,
142
+ toValue: collapsed ? heightAboveMinimised : 0,
137
143
  useNativeDriver: true,
138
144
  }).start(() => {
139
- offset.current = collapsed ? SCREEN_HEIGHT - collapsedHeight : 0;
145
+ offset.current = collapsed ? heightAboveMinimised : 0;
140
146
  translateY.setValue(offset.current);
141
147
  });
142
148
  }
@@ -158,20 +164,27 @@ export const useVideoModalState = (
158
164
  }, [onGestureEvent, onHandlerStateChange]);
159
165
 
160
166
  useEffect(() => {
161
- if (videoModalState.mode === VideoModalMode.MAXIMIZED) {
162
- handleExpand(0).start(() => {
163
- maximiseVideoModal();
164
- offset.current = 0;
165
- translateY.setValue(0);
166
- });
167
- } else if (videoModalState.mode === VideoModalMode.MINIMIZED) {
168
- handleCollapse(SCREEN_HEIGHT - collapsedHeight).start(() => {
169
- minimiseVideoModal();
170
- offset.current = SCREEN_HEIGHT - collapsedHeight;
171
- translateY.setValue(SCREEN_HEIGHT - collapsedHeight);
172
- });
167
+ if (videoModalState.visible) {
168
+ if (videoModalState.mode === VideoModalMode.MAXIMIZED) {
169
+ handleExpand(0).start(() => {
170
+ maximiseVideoModal();
171
+ offset.current = 0;
172
+ translateY.setValue(0);
173
+ });
174
+ } else if (videoModalState.mode === VideoModalMode.MINIMIZED) {
175
+ handleCollapse(heightAboveMinimised).start(() => {
176
+ minimiseVideoModal();
177
+ offset.current = heightAboveMinimised;
178
+ translateY.setValue(heightAboveMinimised);
179
+ });
180
+ }
173
181
  }
174
- }, [videoModalState.visible, videoModalState.mode, collapsedHeight]);
182
+ }, [
183
+ videoModalState.visible,
184
+ videoModalState.mode,
185
+ collapsedHeight,
186
+ heightAboveMinimised,
187
+ ]);
175
188
 
176
189
  return useMemo(
177
190
  () => ({
@@ -63,6 +63,7 @@ export const useStyles = ({ height }: { height: number }) => {
63
63
  backgroundColor,
64
64
  elevation: 10,
65
65
  zIndex: 100,
66
+ height: "100%",
66
67
  overflow: "hidden",
67
68
  },
68
69
  modalWrapper: {
@@ -75,6 +76,10 @@ export const useStyles = ({ height }: { height: number }) => {
75
76
  flex: 1,
76
77
  alignItems: "center",
77
78
  },
79
+ modalContentPiP: {
80
+ flex: 1,
81
+ alignItems: "flex-start",
82
+ },
78
83
  expandedContentContainer: {
79
84
  justifyContent: "flex-start",
80
85
  backgroundColor: BG_COLOR_DEFAULT_TRANSPARENT,
@@ -0,0 +1,92 @@
1
+ import { StyleSheet, Dimensions, ViewStyle } from "react-native";
2
+
3
+ import {
4
+ isAndroidPlatform,
5
+ isAndroidVersionAtLeast,
6
+ isTV,
7
+ } from "@applicaster/zapp-react-native-utils/reactUtils";
8
+ import {
9
+ isTablet,
10
+ useIsTablet as getIsTablet,
11
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
12
+
13
+ const SAFE_AREA_BREAKING_API_VERSION = 35;
14
+
15
+ export const isOldAndroidDevice =
16
+ isAndroidPlatform() &&
17
+ !isAndroidVersionAtLeast(SAFE_AREA_BREAKING_API_VERSION);
18
+
19
+ export const getWindowHeight = (): number => {
20
+ const windowDimensions = Dimensions.get("window");
21
+
22
+ return windowDimensions.height;
23
+ };
24
+
25
+ export const getScreenHeight = (): number => {
26
+ const screenDimensions = Dimensions.get("screen");
27
+
28
+ return screenDimensions.height;
29
+ };
30
+
31
+ export const getWindowWidth = (): number => {
32
+ const windowDimensions = Dimensions.get("window");
33
+
34
+ return windowDimensions.width;
35
+ };
36
+
37
+ const getIsTabletLandscape = (isTabletPortrait: boolean): boolean => {
38
+ return !isTV() && isTablet() && !isTabletPortrait;
39
+ };
40
+
41
+ export const getInsetsOffset = (
42
+ insets: { top: number; bottom: number },
43
+ isTabletPortrait: boolean
44
+ ): number => {
45
+ const isTabletLandscape = getIsTabletLandscape(isTabletPortrait);
46
+
47
+ return isTablet() && isTabletLandscape
48
+ ? isOldAndroidDevice
49
+ ? insets.top / 2
50
+ : 0
51
+ : insets.top / 2;
52
+ };
53
+
54
+ const orientationStyles = StyleSheet.create({
55
+ landscape: { flexDirection: "row" },
56
+ portrait: { flexDirection: "column" },
57
+ });
58
+
59
+ export const directionStyles = (isTabletPortrait: boolean): ViewStyle => {
60
+ const isTabletLandscape = getIsTabletLandscape(isTabletPortrait);
61
+
62
+ return isTabletLandscape
63
+ ? orientationStyles.landscape
64
+ : orientationStyles.portrait;
65
+ };
66
+
67
+ export const getScaledPos = (
68
+ height,
69
+ vidHeight,
70
+ minimisedHeight,
71
+ isTabletPortrait
72
+ ) => {
73
+ const isTabletLandscape = getIsTabletLandscape(isTabletPortrait);
74
+
75
+ const SCALE_FACTOR = minimisedHeight / vidHeight; // Scale factor for expanded content
76
+
77
+ return (
78
+ ((isTabletLandscape ? height : vidHeight) - vidHeight * SCALE_FACTOR) / 2
79
+ );
80
+ };
81
+
82
+ export const getExtraContentPadding = (insets: {
83
+ top: number;
84
+ bottom: number;
85
+ }): ViewStyle => {
86
+ const isTablet = getIsTablet(); // not a hook, just a utility function
87
+
88
+ return {
89
+ paddingTop: isTablet ? insets.top : 0,
90
+ paddingBottom: insets.bottom,
91
+ };
92
+ };
@@ -10,9 +10,8 @@ export interface PlayNextOverlayProps {
10
10
  }
11
11
 
12
12
  export interface PlayerComponentProps {
13
- ref: React.RefObject<any>;
13
+ ref: React.Ref<any>;
14
14
  listener: Record<string, any>;
15
- configuration: Record<string, any>;
16
15
  style: ViewStyle;
17
16
  }
18
17