@applicaster/quick-brick-player 15.0.0-alpha.3514407021 → 15.0.0-alpha.4368022015

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,4 +1,4 @@
1
- import React, { ReactElement, useRef } from "react";
1
+ import React, { ReactElement, useMemo, useRef } from "react";
2
2
 
3
3
  import { Animated, Pressable, StyleSheet, ViewStyle } from "react-native";
4
4
  import { PanGestureHandler } from "react-native-gesture-handler";
@@ -7,10 +7,8 @@ import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/C
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";
@@ -20,6 +18,7 @@ import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-component
20
18
  import { useSafeAreaInsets } from "react-native-safe-area-context";
21
19
  import { GestureAnimatedScrollView } from "./GestureAnimatedScrollView";
22
20
  import { PlayerDetailsWrapperHeightContext } from "./context";
21
+ import { getScreenHeight, getWindowHeight, getWindowWidth } from "./utils";
23
22
 
24
23
  const orientationStyles = StyleSheet.create({
25
24
  landscape: { flexDirection: "row" },
@@ -46,8 +45,6 @@ type AnimatedModalProps = {
46
45
  };
47
46
  };
48
47
 
49
- const height = SCREEN_HEIGHT;
50
-
51
48
  export function VideoPlayerModal({
52
49
  aspectRatio = DEFAULT_IMAGE_RATIO_VIDEO,
53
50
  content,
@@ -62,7 +59,12 @@ export function VideoPlayerModal({
62
59
  const enabled = !!modal && !fullscreen;
63
60
  const isTablet = useIsTablet();
64
61
 
65
- let width = SCREEN_WIDTH;
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;
66
+
67
+ let width = WINDOW_WIDTH;
66
68
 
67
69
  if (isTablet && !isTabletPortrait) {
68
70
  width = style?.tabletLandscapeWidth || width;
@@ -83,6 +85,8 @@ export function VideoPlayerModal({
83
85
  expand,
84
86
  } = useVideoModalState(modal ? translateYRef : dummyRef);
85
87
 
88
+ const heightAboveMinimised = height - collapsedHeight;
89
+
86
90
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
87
91
 
88
92
  const styles = useStyles({ height: collapsedHeight });
@@ -96,7 +100,7 @@ export function VideoPlayerModal({
96
100
  // Interpolated opacities for smooth cross-fade
97
101
  const collapsedOpacity = !isFullScreenOrPIP
98
102
  ? translateY.interpolate({
99
- inputRange: [MODAL_COLLAPSE_START, height - collapsedHeight],
103
+ inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
100
104
  outputRange: [0, 1],
101
105
  extrapolate: "clamp",
102
106
  })
@@ -104,7 +108,7 @@ export function VideoPlayerModal({
104
108
 
105
109
  const expandedOpacity = !isFullScreenOrPIP
106
110
  ? translateY.interpolate({
107
- inputRange: [0, height - collapsedHeight],
111
+ inputRange: [0, heightAboveMinimised],
108
112
  outputRange: [1, 0],
109
113
  extrapolate: "clamp",
110
114
  })
@@ -112,10 +116,7 @@ export function VideoPlayerModal({
112
116
 
113
117
  const xPosition = !isFullScreenOrPIP
114
118
  ? translateY.interpolate({
115
- inputRange: [
116
- height * VIDEO_TRANSITION_THRESHOLD,
117
- height - collapsedHeight,
118
- ],
119
+ inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
119
120
  outputRange: [0, -(width - width * SCALE_FACTOR) / 2],
120
121
  extrapolate: "clamp",
121
122
  })
@@ -125,19 +126,21 @@ export function VideoPlayerModal({
125
126
 
126
127
  const yPosition = !isFullScreenOrPIP
127
128
  ? translateY.interpolate({
128
- inputRange: [
129
- height * VIDEO_TRANSITION_THRESHOLD,
130
- height - collapsedHeight,
131
- ],
129
+ inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
132
130
  outputRange: [
133
131
  0,
134
132
  isTablet && isTabletLandscape
135
- ? -((-PROGRESS_BAR_HEIGHT + height - vidHeight * SCALE_FACTOR) / 2)
133
+ ? -(
134
+ (-PROGRESS_BAR_HEIGHT +
135
+ screenHeight -
136
+ vidHeight * SCALE_FACTOR) /
137
+ 2
138
+ )
136
139
  : -(
137
140
  PROGRESS_BAR_HEIGHT +
138
141
  insets.top / 2 +
139
- (SCREEN_WIDTH / aspectRatio -
140
- (SCREEN_WIDTH / aspectRatio) * SCALE_FACTOR) /
142
+ (WINDOW_WIDTH / aspectRatio -
143
+ (WINDOW_WIDTH / aspectRatio) * SCALE_FACTOR) /
141
144
  2
142
145
  ),
143
146
  ],
@@ -147,10 +150,7 @@ export function VideoPlayerModal({
147
150
 
148
151
  const scalePosition = !isFullScreenOrPIP
149
152
  ? translateY.interpolate({
150
- inputRange: [
151
- height * VIDEO_TRANSITION_THRESHOLD,
152
- height - collapsedHeight,
153
- ],
153
+ inputRange: [height * VIDEO_TRANSITION_THRESHOLD, MODAL_COLLAPSE_START],
154
154
  outputRange: [1, SCALE_FACTOR],
155
155
  extrapolate: "clamp",
156
156
  })
@@ -192,7 +192,7 @@ export function VideoPlayerModal({
192
192
  borderTopLeftRadius: borderTopRadiusAnimated,
193
193
  borderTopRightRadius: borderTopRadiusAnimated,
194
194
  transform: [{ translateY: isFullScreenOrPIP ? 0 : translateY }],
195
- height: height,
195
+ height: screenHeight,
196
196
  },
197
197
  ]}
198
198
  >
@@ -204,13 +204,16 @@ export function VideoPlayerModal({
204
204
  {
205
205
  borderTopLeftRadius: borderTopRadiusAnimated,
206
206
  borderTopRightRadius: borderTopRadiusAnimated,
207
- height: height,
207
+ height: screenHeight,
208
208
  },
209
209
  ]}
210
210
  >
211
211
  <Animated.View
212
212
  pointerEvents={!collapsed ? "auto" : "none"}
213
- style={[styles.modalContent, directionStyles(isTabletLandscape)]}
213
+ style={[
214
+ pip ? styles.modalContentPiP : styles.modalContent,
215
+ directionStyles(isTabletLandscape),
216
+ ]}
214
217
  >
215
218
  <Animated.View
216
219
  style={[
@@ -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) +
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
  () => ({
@@ -75,6 +75,10 @@ export const useStyles = ({ height }: { height: number }) => {
75
75
  flex: 1,
76
76
  alignItems: "center",
77
77
  },
78
+ modalContentPiP: {
79
+ flex: 1,
80
+ alignItems: "flex-start",
81
+ },
78
82
  expandedContentContainer: {
79
83
  justifyContent: "flex-start",
80
84
  backgroundColor: BG_COLOR_DEFAULT_TRANSPARENT,
@@ -0,0 +1,29 @@
1
+ import { Dimensions } from "react-native";
2
+
3
+ import {
4
+ isAndroidPlatform,
5
+ isAndroidVersionAtLeast,
6
+ } from "@applicaster/zapp-react-native-utils/reactUtils";
7
+
8
+ const MIN_SUPPORTED_ANDROID_API = 34;
9
+
10
+ export const isOldAndroidDevice =
11
+ isAndroidPlatform() && !isAndroidVersionAtLeast(MIN_SUPPORTED_ANDROID_API);
12
+
13
+ export const getWindowHeight = (): number => {
14
+ const windowDimensions = Dimensions.get("window");
15
+
16
+ return windowDimensions.height;
17
+ };
18
+
19
+ export const getScreenHeight = (): number => {
20
+ const screenDimensions = Dimensions.get("screen");
21
+
22
+ return screenDimensions.height;
23
+ };
24
+
25
+ export const getWindowWidth = (): number => {
26
+ const windowDimensions = Dimensions.get("window");
27
+
28
+ return windowDimensions.width;
29
+ };
@@ -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