@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.
- package/package.json +5 -5
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +20 -8
- package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +71 -63
- package/src/Player/AudioLayer/Layout/MobileLayout.tsx +1 -6
- package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +5 -23
- package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +5 -8
- package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +1 -6
- package/src/Player/AudioLayer/utils.ts +1 -27
- package/src/Player/PlayerModal/PlayerModal.tsx +13 -6
- package/src/Player/PlayerModal/VideoPlayerModal.tsx +30 -27
- package/src/Player/PlayerModal/consts/index.ts +2 -19
- package/src/Player/PlayerModal/hooks/index.ts +44 -31
- package/src/Player/PlayerModal/styles.ts +4 -0
- package/src/Player/PlayerModal/utils/index.ts +29 -0
- package/src/Player/PlayerView/types.ts +1 -2
- package/src/Player/index.tsx +547 -356
- package/src/utils/dimensions.ts +29 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/logger.ts +6 -0
- package/src/utils/playerHelpers.ts +11 -0
- package/src/utils/playerStyles.ts +50 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +0 -82
- package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +0 -1
- package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +0 -99
|
@@ -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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
-
? -(
|
|
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
|
-
(
|
|
140
|
-
(
|
|
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:
|
|
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:
|
|
207
|
+
height: screenHeight,
|
|
208
208
|
},
|
|
209
209
|
]}
|
|
210
210
|
>
|
|
211
211
|
<Animated.View
|
|
212
212
|
pointerEvents={!collapsed ? "auto" : "none"}
|
|
213
|
-
style={[
|
|
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 {
|
|
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 =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
const collapsed =
|
|
43
|
+
videoModalState.visible &&
|
|
44
|
+
videoModalState.mode === VideoModalMode.MINIMIZED;
|
|
42
45
|
|
|
43
|
-
const
|
|
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(
|
|
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 >
|
|
86
|
-
newY =
|
|
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 >
|
|
103
|
-
newY =
|
|
108
|
+
if (newY > heightAboveMinimised) {
|
|
109
|
+
newY = heightAboveMinimised;
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
const shouldCollapse =
|
|
107
|
-
translationY >
|
|
113
|
+
translationY > heightAboveMinimised * DRAG_TO_COLLAPSE;
|
|
108
114
|
|
|
109
115
|
const shouldExpand =
|
|
110
|
-
translationY < -
|
|
116
|
+
translationY < -heightAboveMinimised * DRAG_TO_EXPAND;
|
|
111
117
|
|
|
112
118
|
if (!collapsed && shouldCollapse) {
|
|
113
119
|
// Collapse
|
|
114
120
|
Animated.timing(translateY, {
|
|
115
|
-
toValue:
|
|
121
|
+
toValue: heightAboveMinimised,
|
|
116
122
|
duration: ANIMATION_DURATION,
|
|
117
123
|
useNativeDriver: true,
|
|
118
124
|
}).start(() => {
|
|
119
125
|
minimiseVideoModal();
|
|
120
|
-
offset.current =
|
|
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 ?
|
|
142
|
+
toValue: collapsed ? heightAboveMinimised : 0,
|
|
137
143
|
useNativeDriver: true,
|
|
138
144
|
}).start(() => {
|
|
139
|
-
offset.current = collapsed ?
|
|
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.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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
|
-
}, [
|
|
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
|
+
};
|