@applicaster/quick-brick-player 14.0.0-rc.77 → 14.0.0-rc.79

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": "14.0.0-rc.77",
3
+ "version": "14.0.0-rc.79",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -37,9 +37,9 @@
37
37
  "dependencies": {
38
38
  "@applicaster/quick-brick-mobile-transport-controls": "14.0.0-rc.67",
39
39
  "@applicaster/quick-brick-tv-transport-controls": "14.0.0-rc.71",
40
- "@applicaster/zapp-react-native-tvos-app": "14.0.0-rc.77",
41
- "@applicaster/zapp-react-native-ui-components": "14.0.0-rc.77",
42
- "@applicaster/zapp-react-native-utils": "14.0.0-rc.77",
40
+ "@applicaster/zapp-react-native-tvos-app": "14.0.0-rc.79",
41
+ "@applicaster/zapp-react-native-ui-components": "14.0.0-rc.79",
42
+ "@applicaster/zapp-react-native-utils": "14.0.0-rc.79",
43
43
  "query-string": "7.1.3",
44
44
  "shaka-player": "4.3.5",
45
45
  "typeface-montserrat": "^0.0.54",
@@ -99,11 +99,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
99
99
  );
100
100
 
101
101
  useEffect(() => {
102
- if (player) {
103
- setSpeedManager(new SpeedController(player));
104
- } else {
105
- setSpeedManager(null);
106
- }
102
+ setSpeedManager(player ? new SpeedController(player) : null);
107
103
  }, [player]);
108
104
 
109
105
  useEffect(() => {
@@ -217,7 +213,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
217
213
  items: speedOptions,
218
214
  current_selection: playbackSpeed,
219
215
  onPress: onSpeedSelect,
220
- title: configuration["playback_speed_title"],
216
+ title: configuration.playback_speed_title,
221
217
  itemProps: getBottomSheetModalItemProps,
222
218
  iconProps: getBottomSheetModalIconProps,
223
219
  labelProps: getBottomSheetModalLabelProps,
@@ -233,7 +229,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
233
229
  ],
234
230
  },
235
231
  });
236
- }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
232
+ }, [playbackSpeed, onSpeedSelect, configuration.playback_speed_title]);
237
233
 
238
234
  const onPlayerSeek = React.useCallback(
239
235
  (targetTime: number) => {
@@ -33,16 +33,10 @@ const bottomTabBarHeight = getTabBarHeight();
33
33
  type Props = {
34
34
  entry: ZappEntry;
35
35
  layoutState: QuickBrickPlayer.LayoutState;
36
- playerState: QuickBrickPlayer.PlayerState;
37
- value: GetValue;
38
- onCloseVideoModal: () => void;
39
- onPlayerSeek: (targetTime: number) => void;
36
+ onPlayerSeek?: (targetTime: number) => void;
40
37
  playNextData: PlayNextData;
41
- title: string | number;
42
- summary: string | number;
43
38
  ImageComponent?: React.ReactNode;
44
39
  isActiveGesture?: boolean;
45
- minimisedHeight: number;
46
40
  aspectRatio?: number;
47
41
  };
48
42
 
@@ -4,8 +4,9 @@ import { Animated, Pressable } from "react-native";
4
4
  import { PanGestureHandler } from "react-native-gesture-handler";
5
5
  import { useStyles } from "./styles";
6
6
  import { useVideoModalState } from "./hooks";
7
- import { MODAL_COLLAPSE_START, MODAL_RADIUS, SCREEN_HEIGHT } from "./consts";
7
+ import { MODAL_COLLAPSE_RATIO, MODAL_RADIUS } from "./consts";
8
8
  import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
9
+ import { getWindowHeight } from "./utils";
9
10
 
10
11
  type AnimatedModalProps = {
11
12
  content?: ReactElement;
@@ -28,21 +29,26 @@ export function AnimatedModal({
28
29
 
29
30
  const styles = useStyles({ height: collapsedHeight, type: "audio" });
30
31
 
32
+ const WINDOW_HEIGHT = getWindowHeight();
33
+ const heightAboveMinimised = WINDOW_HEIGHT - collapsedHeight;
34
+
35
+ const MODAL_COLLAPSE_START = WINDOW_HEIGHT * MODAL_COLLAPSE_RATIO;
36
+
31
37
  // Interpolated opacities for smooth cross-fade
32
38
  const collapsedOpacity = translateY.interpolate({
33
- inputRange: [MODAL_COLLAPSE_START, SCREEN_HEIGHT - collapsedHeight],
39
+ inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
34
40
  outputRange: [0, 1],
35
41
  extrapolate: "clamp",
36
42
  });
37
43
 
38
44
  const expandedOpacity = translateY.interpolate({
39
- inputRange: [0, SCREEN_HEIGHT - collapsedHeight],
45
+ inputRange: [0, heightAboveMinimised],
40
46
  outputRange: [1, 0],
41
47
  extrapolate: "clamp",
42
48
  });
43
49
 
44
50
  const borderTopRadiusAnimated = translateY.interpolate({
45
- inputRange: [0, SCREEN_HEIGHT - collapsedHeight],
51
+ inputRange: [0, heightAboveMinimised],
46
52
  outputRange: [MODAL_RADIUS, 0],
47
53
  extrapolate: "clamp",
48
54
  });
@@ -57,7 +63,7 @@ export function AnimatedModal({
57
63
  borderTopLeftRadius: borderTopRadiusAnimated,
58
64
  borderTopRightRadius: borderTopRadiusAnimated,
59
65
  transform: [{ translateY }],
60
- height: SCREEN_HEIGHT,
66
+ height: WINDOW_HEIGHT,
61
67
  },
62
68
  ]}
63
69
  >
@@ -67,7 +73,7 @@ export function AnimatedModal({
67
73
  {
68
74
  borderTopLeftRadius: borderTopRadiusAnimated,
69
75
  borderTopRightRadius: borderTopRadiusAnimated,
70
- height: SCREEN_HEIGHT,
76
+ height: WINDOW_HEIGHT,
71
77
  },
72
78
  ]}
73
79
  >
@@ -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 { 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,11 @@ 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 MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
65
+
66
+ let width = WINDOW_WIDTH;
66
67
 
67
68
  if (isTablet && !isTabletPortrait) {
68
69
  width = style?.tabletLandscapeWidth || width;
@@ -83,6 +84,8 @@ export function VideoPlayerModal({
83
84
  expand,
84
85
  } = useVideoModalState(modal ? translateYRef : dummyRef);
85
86
 
87
+ const heightAboveMinimised = height - collapsedHeight;
88
+
86
89
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
87
90
 
88
91
  const styles = useStyles({ height: collapsedHeight });
@@ -96,7 +99,7 @@ export function VideoPlayerModal({
96
99
  // Interpolated opacities for smooth cross-fade
97
100
  const collapsedOpacity = !isFullScreenOrPIP
98
101
  ? translateY.interpolate({
99
- inputRange: [MODAL_COLLAPSE_START, height - collapsedHeight],
102
+ inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
100
103
  outputRange: [0, 1],
101
104
  extrapolate: "clamp",
102
105
  })
@@ -104,7 +107,7 @@ export function VideoPlayerModal({
104
107
 
105
108
  const expandedOpacity = !isFullScreenOrPIP
106
109
  ? translateY.interpolate({
107
- inputRange: [0, height - collapsedHeight],
110
+ inputRange: [0, heightAboveMinimised],
108
111
  outputRange: [1, 0],
109
112
  extrapolate: "clamp",
110
113
  })
@@ -112,10 +115,7 @@ export function VideoPlayerModal({
112
115
 
113
116
  const xPosition = !isFullScreenOrPIP
114
117
  ? translateY.interpolate({
115
- inputRange: [
116
- height * VIDEO_TRANSITION_THRESHOLD,
117
- height - collapsedHeight,
118
- ],
118
+ inputRange: [height * VIDEO_TRANSITION_THRESHOLD, heightAboveMinimised],
119
119
  outputRange: [0, -(width - width * SCALE_FACTOR) / 2],
120
120
  extrapolate: "clamp",
121
121
  })
@@ -136,8 +136,8 @@ export function VideoPlayerModal({
136
136
  : -(
137
137
  PROGRESS_BAR_HEIGHT +
138
138
  insets.top / 2 +
139
- (SCREEN_WIDTH / aspectRatio -
140
- (SCREEN_WIDTH / aspectRatio) * SCALE_FACTOR) /
139
+ (WINDOW_WIDTH / aspectRatio -
140
+ (WINDOW_WIDTH / aspectRatio) * SCALE_FACTOR) /
141
141
  2
142
142
  ),
143
143
  ],
@@ -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
@@ -12,10 +12,10 @@ import {
12
12
  ANIMATION_DURATION,
13
13
  DRAG_TO_COLLAPSE,
14
14
  DRAG_TO_EXPAND,
15
- SCREEN_HEIGHT,
16
15
  } from "../consts";
17
16
  import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
18
17
  import { usePlugins } from "@applicaster/zapp-react-native-redux";
18
+ import { getWindowHeight } from "../utils";
19
19
 
20
20
  const bottomTabBarHeight = getTabBarHeight();
21
21
 
@@ -24,6 +24,8 @@ export const useVideoModalState = (
24
24
  ) => {
25
25
  const { minimised_height: minimisedHeight } = useConfiguration();
26
26
 
27
+ const WINDOW_HEIGHT = getWindowHeight();
28
+
27
29
  const {
28
30
  maximiseVideoModal,
29
31
  minimiseVideoModal,
@@ -36,7 +38,9 @@ export const useVideoModalState = (
36
38
 
37
39
  const menuVisible = isMenuVisible(currentRoute, screenData, plugins);
38
40
 
39
- const collapsed = videoModalState.mode === VideoModalMode.MINIMIZED;
41
+ const collapsed =
42
+ videoModalState.visible &&
43
+ videoModalState.mode === VideoModalMode.MINIMIZED;
40
44
 
41
45
  const { bottom } = useSafeAreaInsets();
42
46
 
@@ -48,6 +52,8 @@ export const useVideoModalState = (
48
52
  (menuVisible ? bottomTabBarHeight : 0) +
49
53
  PROGRESS_BAR_HEIGHT;
50
54
 
55
+ const heightAboveMinimised = WINDOW_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,18 +164,20 @@ 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
182
  }, [videoModalState.visible, videoModalState.mode, collapsedHeight]);
175
183
 
@@ -0,0 +1,29 @@
1
+ import { StatusBar, Dimensions } from "react-native";
2
+
3
+ import {
4
+ isAndroidPlatform,
5
+ isAndroidVersionAtLeast,
6
+ } from "@applicaster/zapp-react-native-utils/reactUtils";
7
+ import { isAndroidTablet } from "@applicaster/zapp-react-native-utils/reactHooks/layout/isTablet";
8
+
9
+ const MIN_SUPPORTED_ANDROID_API = 34;
10
+
11
+ const isOldAndroidDevice =
12
+ isAndroidPlatform() &&
13
+ !isAndroidVersionAtLeast(MIN_SUPPORTED_ANDROID_API) &&
14
+ !isAndroidTablet();
15
+
16
+ export const getWindowHeight = (): number => {
17
+ const windowDimensions = Dimensions.get("window");
18
+
19
+ return (
20
+ windowDimensions.height +
21
+ (isOldAndroidDevice ? (StatusBar.currentHeight ?? 0) : 0)
22
+ );
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