@applicaster/quick-brick-player 14.0.0-alpha.3552323332 → 14.0.0-alpha.3890252181

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-alpha.3552323332",
3
+ "version": "14.0.0-alpha.3890252181",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -35,13 +35,12 @@
35
35
  },
36
36
  "homepage": "https://github.com/applicaster/quickbrick#readme",
37
37
  "dependencies": {
38
- "@applicaster/quick-brick-mobile-transport-controls": "14.0.0-alpha.3552323332",
39
- "@applicaster/quick-brick-tv-transport-controls": "14.0.0-rc.7",
40
- "@applicaster/zapp-react-native-tvos-app": "14.0.0-alpha.3552323332",
41
- "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.3552323332",
42
- "@applicaster/zapp-react-native-utils": "14.0.0-alpha.3552323332",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "14.0.0-rc.34",
39
+ "@applicaster/quick-brick-tv-transport-controls": "14.0.0-rc.34",
40
+ "@applicaster/zapp-react-native-tvos-app": "14.0.0-alpha.3890252181",
41
+ "@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.3890252181",
42
+ "@applicaster/zapp-react-native-utils": "14.0.0-alpha.3890252181",
43
43
  "query-string": "7.1.3",
44
- "react-native-web-linear-gradient": "1.1.2",
45
44
  "shaka-player": "4.3.5",
46
45
  "typeface-montserrat": "^0.0.54",
47
46
  "video.js": "7.14.3",
@@ -62,11 +61,9 @@
62
61
  "react": "*",
63
62
  "react-native": "*",
64
63
  "react-native-fs": "*",
65
- "react-native-gesture-handler": "*",
66
64
  "react-native-linear-gradient": "*",
67
65
  "react-native-safe-area-context": "*",
68
66
  "react-native-svg": "*",
69
- "react-native-web": "*",
70
67
  "react-native-webview": "*",
71
68
  "uglify-js": "*",
72
69
  "validate-color": "*",
@@ -22,6 +22,8 @@ import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks
22
22
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
23
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
24
24
  import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/utils";
25
+ import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
26
+ import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
25
27
 
26
28
  const bottomTabBarHeight = getTabBarHeight();
27
29
 
@@ -38,7 +40,6 @@ type Props = {
38
40
  ImageComponent?: React.ReactNode;
39
41
  isActiveGesture?: boolean;
40
42
  minimisedHeight: number;
41
- progressBarHeight: number;
42
43
  aspectRatio?: number;
43
44
  };
44
45
 
@@ -47,7 +48,7 @@ const styles = StyleSheet.create({
47
48
  flex: 1,
48
49
  flexDirection: "column",
49
50
  alignItems: "stretch",
50
- marginTop: 3, // from plugins/mobile-transport-controls/src/ProgressBar/layouts/DockedLayout.tsx
51
+ marginTop: PROGRESS_BAR_HEIGHT,
51
52
  },
52
53
  content: {
53
54
  flex: 1,
@@ -160,7 +161,7 @@ export const DockedControls = (props: Props) => {
160
161
  const {
161
162
  entry,
162
163
  layoutState,
163
- onPlayerSeek,
164
+ onPlayerSeek = noop,
164
165
  playNextData,
165
166
  ImageComponent,
166
167
  isActiveGesture = true,
@@ -210,8 +211,6 @@ export const DockedControls = (props: Props) => {
210
211
 
211
212
  const liveButton = Boolean(value("live_badge_enabled"));
212
213
 
213
- const startComponentsAnimation = () => {};
214
-
215
214
  const dockedBackgroundColor = value("docked_player_background_color");
216
215
 
217
216
  const insets = useSafeAreaInsets();
@@ -234,7 +233,7 @@ export const DockedControls = (props: Props) => {
234
233
  layoutState={layoutState}
235
234
  onPlayerSeek={onPlayerSeek}
236
235
  playerState={playerState}
237
- startComponentsAnimation={startComponentsAnimation}
236
+ startComponentsAnimation={noop}
238
237
  docked
239
238
  />
240
239
  ) : null}
@@ -4,7 +4,6 @@ import {
4
4
  useSafeAreaFrame,
5
5
  useSafeAreaInsets,
6
6
  } from "react-native-safe-area-context";
7
- import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
8
7
 
9
8
  import { MOBILE, NAVBAR_HEIGHT } from "./const";
10
9
  import { TransportInfo } from "./TransportInfo";
@@ -17,7 +16,7 @@ import {
17
16
  BottomDebugSquare,
18
17
  LeftDebugSquare,
19
18
  RightDebugSquare,
20
- } from "./Debug/index";
19
+ } from "./DebugComponent";
21
20
 
22
21
  import { Props } from "./types";
23
22
 
@@ -79,8 +78,6 @@ export function MobileLayout({
79
78
  onSpeedButtonPress,
80
79
  playbackSpeedName,
81
80
  configuration,
82
- dimensions,
83
- playNextData,
84
81
  title,
85
82
  summary,
86
83
  }: Props) {
@@ -88,12 +85,10 @@ export function MobileLayout({
88
85
 
89
86
  const { bottom: bottomInset, top: topInset } = useSafeAreaInsets();
90
87
  const { height: screenHeight } = useSafeAreaFrame();
91
- const { progressBarHeight } = useModalAnimationContext();
92
88
 
93
89
  const { imageSize } = useMobileLayoutImageSize();
94
90
 
95
- const { height: transportInfoHeight, onLayout: onTransportInfoLayout } =
96
- useTransportInfoHeight();
91
+ const { onLayout: onTransportInfoLayout } = useTransportInfoHeight();
97
92
 
98
93
  const controlsContainerHeight = React.useMemo(() => {
99
94
  return (
@@ -107,10 +102,6 @@ export function MobileLayout({
107
102
  );
108
103
  }, [screenHeight, topInset, imageSize, bottomInset]);
109
104
 
110
- const verticalOffsetForImage = React.useMemo(() => {
111
- return transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight;
112
- }, [transportInfoHeight, progressBarHeight]);
113
-
114
105
  return (
115
106
  <View
116
107
  style={[
@@ -162,18 +153,9 @@ export function MobileLayout({
162
153
  >
163
154
  <PlayerImage
164
155
  entry={entry}
165
- layoutState={layoutState}
166
- playerState={playerState}
167
- value={value}
168
- configuration={configuration}
169
- onPlayerSeek={onPlayerSeek}
170
- dimensions={dimensions}
171
- playNextData={playNextData}
172
- title={title}
173
- summary={summary}
174
- docked={docked}
156
+ docked={false}
175
157
  imageWidth={imageSize}
176
- verticalOffset={verticalOffsetForImage}
158
+ configuration={configuration}
177
159
  />
178
160
  </View>
179
161
  {/* PlayerImage */}
@@ -1,7 +1,16 @@
1
1
  import React, { PropsWithChildren } from "react";
2
2
  import { Image, Animated, StyleSheet, ImageStyle } from "react-native";
3
3
 
4
- import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
4
+ import {
5
+ useModalAnimationContext,
6
+ PlayerAnimationStateEnum,
7
+ DURATION_TO_MINIMIZE,
8
+ DURATION_TO_MAXIMIZE,
9
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
10
+ import { PlayerAnimationStateT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/ModalAnimationContext";
11
+ import { useBackgroundImage } from "@applicaster/zapp-react-native-utils/audioPlayerUtils";
12
+
13
+ import { useChangePlayerState } from "./hooks";
5
14
 
6
15
  const styles = StyleSheet.create({
7
16
  container: {
@@ -15,17 +24,48 @@ type Props = PropsWithChildren<{
15
24
  entry: ZappEntry;
16
25
  style?: ImageStyle | ImageStyle[];
17
26
  imageWidth: number;
27
+ docked: boolean;
18
28
  }>;
19
29
 
20
- export const AnimatedImage = ({ entry, style, imageWidth }: Props) => {
30
+ export const AnimatedImage = ({ entry, style, imageWidth, docked }: Props) => {
21
31
  const heightAnim = React.useRef(new Animated.Value(imageWidth)).current;
22
32
 
23
- const source = React.useMemo(
24
- () => ({ uri: imageSrcFromMediaItem(entry, undefined) }),
25
- [entry]
26
- );
33
+ const backgroundImageSource = useBackgroundImage(entry);
34
+
35
+ const { minimisedHeight } = useModalAnimationContext();
36
+
37
+ const changePlayerState$ = useChangePlayerState({ docked });
38
+
39
+ React.useEffect(() => {
40
+ const subscription = changePlayerState$.subscribe({
41
+ next: (nextPlayerState: PlayerAnimationStateT) => {
42
+ if (nextPlayerState === PlayerAnimationStateEnum.minimize) {
43
+ Animated.timing(heightAnim, {
44
+ toValue: minimisedHeight,
45
+ duration: DURATION_TO_MINIMIZE,
46
+ useNativeDriver: false, // width/height can't use native driver
47
+ }).start();
48
+ }
49
+
50
+ if (nextPlayerState === PlayerAnimationStateEnum.maximize) {
51
+ Animated.timing(heightAnim, {
52
+ toValue: imageWidth,
53
+ duration: DURATION_TO_MAXIMIZE,
54
+ useNativeDriver: false, // width/height can't use native driver
55
+ }).start();
56
+ }
57
+
58
+ if (nextPlayerState === PlayerAnimationStateEnum.appear_as_docked) {
59
+ // minimize image immediatly
60
+ heightAnim.setValue(minimisedHeight);
61
+ }
62
+ },
63
+ });
27
64
 
28
- if (!source) return null;
65
+ return () => {
66
+ subscription.unsubscribe();
67
+ };
68
+ }, [changePlayerState$, minimisedHeight, imageWidth]);
29
69
 
30
70
  return (
31
71
  <Animated.View
@@ -36,7 +76,7 @@ export const AnimatedImage = ({ entry, style, imageWidth }: Props) => {
36
76
  },
37
77
  ]}
38
78
  >
39
- <Image resizeMode="cover" style={style} source={source} />
79
+ <Image resizeMode="cover" style={style} source={backgroundImageSource} />
40
80
  </Animated.View>
41
81
  );
42
82
  };
@@ -1,7 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { Image, ImageStyle } from "react-native";
3
-
4
- import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
3
+ import { useBackgroundImage } from "@applicaster/zapp-react-native-utils/audioPlayerUtils";
5
4
 
6
5
  type Props = {
7
6
  entry: ZappEntry;
@@ -9,12 +8,9 @@ type Props = {
9
8
  };
10
9
 
11
10
  export const FlexImage = ({ entry, style }: Props) => {
12
- const source = React.useMemo(
13
- () => ({ uri: imageSrcFromMediaItem(entry, undefined) }),
14
- [entry]
15
- );
11
+ const backgroundImageSource = useBackgroundImage(entry);
16
12
 
17
- if (!source) return null;
18
-
19
- return <Image resizeMode="cover" style={style} source={source} />;
13
+ return (
14
+ <Image resizeMode="cover" style={style} source={backgroundImageSource} />
15
+ );
20
16
  };
@@ -53,6 +53,7 @@ export const PlayerImage = (props: Props) => {
53
53
  entry={entry}
54
54
  style={[styles.backgroundImageContainer, { borderRadius }]}
55
55
  imageWidth={imageWidth}
56
+ docked={docked}
56
57
  />
57
58
  )}
58
59
  </View>
@@ -1,11 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { StyleSheet, View } from "react-native";
3
- import {
4
- useSafeAreaFrame,
5
- useSafeAreaInsets,
6
- } from "react-native-safe-area-context";
7
- import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
8
- import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
3
+ import { useSafeAreaFrame } from "react-native-safe-area-context";
9
4
 
10
5
  import { TransportInfo } from "./TransportInfo";
11
6
  import { PlayerImage } from "./PlayerImage";
@@ -17,8 +12,6 @@ import { Props } from "./types";
17
12
  import { isSmallTabletHeight as getIsSmallTabletHeight } from "./utils";
18
13
  import { NAVBAR_HEIGHT, TABLET_LANDSCAPE } from "./const";
19
14
 
20
- const isIOS = isApplePlatform();
21
-
22
15
  const MIN_WIDTH = TABLET_LANDSCAPE.MIN_WIDTH; // Minimum width for the audio player container
23
16
  const MAX_SPACING = TABLET_LANDSCAPE.MARGIN_VERTICAL; // Maximum spacing for the audio player container
24
17
  const MIN_SPACING = TABLET_LANDSCAPE.MARGIN_VERTICAL_S; // Minimum spacing for the audio player container
@@ -68,22 +61,6 @@ const styles = StyleSheet.create({
68
61
  },
69
62
  });
70
63
 
71
- const isTabletWithHomeButton = (bottomInset: number): boolean =>
72
- bottomInset === 0;
73
-
74
- const withAdditionalOffset = ({ progressBarHeight, bottomInset }) => {
75
- if (isIOS && isTabletWithHomeButton(bottomInset)) {
76
- return progressBarHeight === 0 ? 8 : progressBarHeight + 2;
77
- }
78
-
79
- if (isIOS && !isTabletWithHomeButton(bottomInset)) {
80
- return progressBarHeight === 0 ? 4 : 1;
81
- }
82
-
83
- // android
84
- return progressBarHeight === 0 ? 4 : 0.5;
85
- };
86
-
87
64
  export function TabletLandscapeLayout({
88
65
  entry,
89
66
  layoutState,
@@ -96,21 +73,16 @@ export function TabletLandscapeLayout({
96
73
  onSkipStart,
97
74
  onSkipLive,
98
75
  onSpeedButtonPress,
99
- onCloseVideoModal,
100
76
  playbackSpeedName,
101
77
  configuration,
102
- dimensions,
103
- playNextData,
104
78
  title,
105
79
  summary,
106
80
  }: Props) {
107
81
  const [imageWidth, setImageWidth] = React.useState(0);
108
82
  const { docked } = layoutState;
109
83
 
110
- const { bottom: bottomInset } = useSafeAreaInsets();
111
84
  const { height: screenHeight } = useSafeAreaFrame();
112
85
  const isSmallScreen = getIsSmallTabletHeight(screenHeight);
113
- const { progressBarHeight } = useModalAnimationContext();
114
86
 
115
87
  const onLayoutImage = React.useCallback((e) => {
116
88
  setImageWidth(e.nativeEvent.layout.width);
@@ -149,20 +121,7 @@ export function TabletLandscapeLayout({
149
121
  <PlayerImage
150
122
  docked={false}
151
123
  entry={entry}
152
- layoutState={layoutState}
153
- playerState={playerState}
154
- value={value}
155
124
  configuration={configuration}
156
- onPlayerSeek={onPlayerSeek}
157
- onCloseVideoModal={onCloseVideoModal}
158
- dimensions={dimensions}
159
- playNextData={playNextData}
160
- title={title}
161
- summary={summary}
162
- verticalOffset={withAdditionalOffset({
163
- progressBarHeight,
164
- bottomInset,
165
- })}
166
125
  onLayoutImage={onLayoutImage}
167
126
  />
168
127
  ) : null}
@@ -4,8 +4,6 @@ import {
4
4
  useSafeAreaFrame,
5
5
  useSafeAreaInsets,
6
6
  } from "react-native-safe-area-context";
7
- import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
8
- import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
9
7
 
10
8
  import { withDebug } from "./debug";
11
9
  import { TABLET_PORTRAIT } from "./const";
@@ -15,7 +13,6 @@ import { PlayerImage } from "./PlayerImage";
15
13
  import { Controls } from "./Controls";
16
14
 
17
15
  import { useTabletLayoutImageSize } from "./hooks";
18
- import { DockedControls } from "./DockedControls";
19
16
  import { VerticalGutter } from "./VerticalGutter";
20
17
 
21
18
  import { Props } from "./types";
@@ -82,11 +79,8 @@ export function TabletPortraitLayout({
82
79
  onSkipStart,
83
80
  onSkipLive,
84
81
  onSpeedButtonPress,
85
- onCloseVideoModal,
86
82
  playbackSpeedName,
87
83
  configuration,
88
- dimensions,
89
- playNextData,
90
84
  title,
91
85
  summary,
92
86
  }: Props) {
@@ -94,7 +88,6 @@ export function TabletPortraitLayout({
94
88
 
95
89
  const { bottom: bottomInset, top: topInset } = useSafeAreaInsets();
96
90
  const { height: screenHeight } = useSafeAreaFrame();
97
- const { progressBarHeight } = useModalAnimationContext();
98
91
 
99
92
  const {
100
93
  imageSize,
@@ -153,21 +146,9 @@ export function TabletPortraitLayout({
153
146
  >
154
147
  <PlayerImage
155
148
  entry={entry}
156
- layoutState={layoutState}
157
- playerState={playerState}
158
- value={value}
159
149
  configuration={configuration}
160
- onPlayerSeek={onPlayerSeek}
161
- onCloseVideoModal={onCloseVideoModal}
162
- dimensions={dimensions}
163
- playNextData={playNextData}
164
- title={title}
165
- summary={summary}
166
150
  docked={docked}
167
151
  imageWidth={imageSize}
168
- verticalOffset={
169
- toNumberWithDefaultZero(topOffset) - progressBarHeight
170
- }
171
152
  />
172
153
  </View>
173
154
 
@@ -196,20 +177,6 @@ export function TabletPortraitLayout({
196
177
  </View>
197
178
  </View>
198
179
  </View>
199
- {/* PlayerImage */}
200
-
201
- <DockedControls
202
- entry={entry}
203
- layoutState={layoutState}
204
- playerState={playerState}
205
- value={value}
206
- dimensions={dimensions}
207
- onCloseVideoModal={onCloseVideoModal}
208
- onPlayerSeek={onPlayerSeek}
209
- playNextData={playNextData}
210
- title={title}
211
- summary={summary}
212
- />
213
180
  </View>
214
181
  );
215
182
  }
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import { compose, map, propOr, split, take, trim } from "ramda";
3
2
  import { LayoutChangeEvent, StyleSheet, View } from "react-native";
4
3
 
5
4
  import { TransportInfo as MobileTransportInfo } from "@applicaster/quick-brick-mobile-transport-controls";
@@ -13,6 +12,7 @@ import { NAVBAR_HEIGHT, TABLET_LANDSCAPE } from "../const";
13
12
  import { withDebug } from "../debug";
14
13
  import { useSafeAreaFrame } from "react-native-safe-area-context";
15
14
  import { isSmallTabletHeight } from "../utils";
15
+ import { getPlayerActionButtons } from "@applicaster/zapp-react-native-utils/playerUtils";
16
16
 
17
17
  const styles = StyleSheet.create({
18
18
  container: {
@@ -82,14 +82,8 @@ export const TransportInfo = ({
82
82
  );
83
83
 
84
84
  const actionButtons = React.useMemo(
85
- () =>
86
- compose(
87
- take(2),
88
- map(trim),
89
- split(","),
90
- propOr("", "player_action_buttons")
91
- )(configuration),
92
- [configuration.player_action_buttons]
85
+ () => getPlayerActionButtons(configuration),
86
+ [configuration]
93
87
  );
94
88
 
95
89
  return (
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { ModalHeader } from "@applicaster/zapp-react-native-ui-components/Components/ModalComponent/Header";
3
- import { isNil } from "lodash";
3
+ import { isNil } from "@applicaster/zapp-react-native-utils/utils";
4
4
 
5
5
  const formatTime = (milliseconds: number) => {
6
6
  const totalSeconds = Math.floor(milliseconds / 1000);
@@ -0,0 +1,7 @@
1
+ import { Animated } from "react-native";
2
+ import { createNativeWrapper } from "react-native-gesture-handler";
3
+
4
+ export const GestureAnimatedScrollView = createNativeWrapper(
5
+ Animated.ScrollView,
6
+ {}
7
+ );
@@ -51,14 +51,15 @@ export function AnimatedModal({
51
51
  <PanGestureHandler {...gestureHandlerProps}>
52
52
  <Animated.View
53
53
  pointerEvents={"auto"}
54
- // eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
55
- style={{
56
- backgroundColor: "black",
57
- borderTopLeftRadius: borderTopRadiusAnimated,
58
- borderTopRightRadius: borderTopRadiusAnimated,
59
- transform: [{ translateY }],
60
- height: SCREEN_HEIGHT,
61
- }}
54
+ style={[
55
+ styles.modalWrapper,
56
+ {
57
+ borderTopLeftRadius: borderTopRadiusAnimated,
58
+ borderTopRightRadius: borderTopRadiusAnimated,
59
+ transform: [{ translateY }],
60
+ height: SCREEN_HEIGHT,
61
+ },
62
+ ]}
62
63
  >
63
64
  <Animated.View
64
65
  style={[
@@ -95,9 +96,7 @@ export function AnimatedModal({
95
96
  >
96
97
  <Pressable
97
98
  testID="collapsedBarWrapper"
98
- onPress={() => {
99
- expand();
100
- }}
99
+ onPress={expand}
101
100
  style={styles.collapsedBarWrapper}
102
101
  >
103
102
  {collapsedContent}
@@ -1,24 +1,24 @@
1
1
  import React, { useRef, ReactElement } from "react";
2
2
 
3
3
  import { StyleSheet, Animated, Pressable, ViewStyle } from "react-native";
4
- import {
5
- createNativeWrapper,
6
- PanGestureHandler,
7
- } from "react-native-gesture-handler";
4
+ import { PanGestureHandler } from "react-native-gesture-handler";
8
5
  import { useStyles } from "./styles";
9
6
  import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/utils";
10
7
  import { useVideoModalState } from "./hooks";
11
8
  import {
12
9
  DEFAULT_IMAGE_RATIO_VIDEO,
10
+ MODAL_COLLAPSE_START,
13
11
  MODAL_RADIUS,
14
12
  SCREEN_HEIGHT,
15
13
  SCREEN_WIDTH,
14
+ VIDEO_TRANSITION_THRESHOLD,
16
15
  } from "./consts";
17
16
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
18
17
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
19
18
  import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/useModalAnimationContext";
20
19
  import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
21
20
  import { useSafeAreaInsets } from "react-native-safe-area-context";
21
+ import { GestureAnimatedScrollView } from "./GestureAnimatedScrollView";
22
22
 
23
23
  const orientationStyles = StyleSheet.create({
24
24
  landscape: { flexDirection: "row" },
@@ -29,8 +29,6 @@ const directionStyles = (isLandscape: boolean): ViewStyle => {
29
29
  return isLandscape ? orientationStyles.landscape : orientationStyles.portrait;
30
30
  };
31
31
 
32
- const GestureAnimatedScrollView = createNativeWrapper(Animated.ScrollView, {});
33
-
34
32
  type AnimatedModalProps = {
35
33
  enabled?: boolean;
36
34
  pip?: boolean;
@@ -52,6 +50,8 @@ type AnimatedModalProps = {
52
50
  };
53
51
  };
54
52
 
53
+ const height = SCREEN_HEIGHT;
54
+
55
55
  export function VideoPlayerModal({
56
56
  enabled = true,
57
57
  aspectRatio = DEFAULT_IMAGE_RATIO_VIDEO,
@@ -65,11 +65,9 @@ export function VideoPlayerModal({
65
65
  const isTablet = useIsTablet();
66
66
 
67
67
  let width = SCREEN_WIDTH;
68
- let height = SCREEN_HEIGHT;
69
68
 
70
69
  if (isTablet && !isTabletPortrait) {
71
70
  width = style?.tabletLandscapeWidth || width;
72
- height = SCREEN_HEIGHT; // Keep height consistent for landscape
73
71
  }
74
72
 
75
73
  const { minimised_height: minimisedHeight } = useConfiguration();
@@ -91,11 +89,11 @@ export function VideoPlayerModal({
91
89
 
92
90
  const SCALE_FACTOR = 1 / (width / aspectRatio / minimisedHeight); // Scale factor for expanded content
93
91
 
94
- const VIDEO_TRANSITION_THRESHOLD = 0.5; // Threshold for video transition
92
+ const insets = useSafeAreaInsets();
95
93
 
96
94
  // Interpolated opacities for smooth cross-fade
97
95
  const collapsedOpacity = translateY.interpolate({
98
- inputRange: [height * 0.8, height - collapsedHeight],
96
+ inputRange: [MODAL_COLLAPSE_START, height - collapsedHeight],
99
97
  outputRange: [0, 1],
100
98
  extrapolate: "clamp",
101
99
  });
@@ -108,17 +106,12 @@ export function VideoPlayerModal({
108
106
 
109
107
  const xPosition = translateY.interpolate({
110
108
  inputRange: [height * VIDEO_TRANSITION_THRESHOLD, height - collapsedHeight],
111
- outputRange: [
112
- 0,
113
- -(width - width * SCALE_FACTOR) / 2, // Adjust this range as needed (-(width * scale_factor))
114
- ], // Adjust this range as needed (-(width * scale_factor))
109
+ outputRange: [0, -(width - width * SCALE_FACTOR) / 2],
115
110
  extrapolate: "clamp",
116
111
  });
117
112
 
118
113
  const vidHeight = width / aspectRatio;
119
114
 
120
- const insets = useSafeAreaInsets();
121
-
122
115
  const yPosition = translateY.interpolate({
123
116
  inputRange: [height * VIDEO_TRANSITION_THRESHOLD, height - collapsedHeight],
124
117
  outputRange: [
@@ -135,7 +128,7 @@ export function VideoPlayerModal({
135
128
  (SCREEN_WIDTH / aspectRatio) * SCALE_FACTOR) /
136
129
  2
137
130
  ),
138
- ], // Adjust this range as needed (-(some_padding_top + (height * scale_factor)))
131
+ ],
139
132
  extrapolate: "clamp",
140
133
  });
141
134
 
@@ -144,7 +137,7 @@ export function VideoPlayerModal({
144
137
  SCREEN_HEIGHT * VIDEO_TRANSITION_THRESHOLD,
145
138
  SCREEN_HEIGHT - collapsedHeight,
146
139
  ],
147
- outputRange: [1, SCALE_FACTOR], // Adjust this range as needed
140
+ outputRange: [1, SCALE_FACTOR],
148
141
  extrapolate: "clamp",
149
142
  });
150
143
 
@@ -166,14 +159,15 @@ export function VideoPlayerModal({
166
159
  >
167
160
  <Animated.View
168
161
  pointerEvents={"auto"}
169
- // eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
170
- style={{
171
- backgroundColor: "black",
172
- borderTopLeftRadius: borderTopRadiusAnimated,
173
- borderTopRightRadius: borderTopRadiusAnimated,
174
- transform: [{ translateY }],
175
- height: SCREEN_HEIGHT,
176
- }}
162
+ style={[
163
+ styles.modalWrapper,
164
+ {
165
+ borderTopLeftRadius: borderTopRadiusAnimated,
166
+ borderTopRightRadius: borderTopRadiusAnimated,
167
+ transform: [{ translateY }],
168
+ height: SCREEN_HEIGHT,
169
+ },
170
+ ]}
177
171
  >
178
172
  <Animated.View
179
173
  pointerEvents={"auto"}
@@ -230,9 +224,7 @@ export function VideoPlayerModal({
230
224
  >
231
225
  <Pressable
232
226
  testID="collapsedBarWrapper"
233
- onPress={() => {
234
- expand();
235
- }}
227
+ onPress={expand}
236
228
  style={styles.collapsedBarWrapper}
237
229
  >
238
230
  {collapsedContent}
@@ -1,15 +1,29 @@
1
- import { Dimensions } from "react-native";
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";
2
7
 
3
8
  export const DOCKED_PROGRESSBAR_HEIGHT = 3; // Height of the docked progress bar plugins/mobile-transport-controls/src/ProgressBar/layouts/DockedLayout.tsx
4
9
 
5
- export const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } =
6
- Dimensions.get("window");
10
+ export const VIDEO_TRANSITION_THRESHOLD = 0.5; // Threshold for video transition
7
11
 
8
- export const MODAL_COLLAPSE_START = SCREEN_HEIGHT * 0.8; // 80% of screen height
12
+ const windowDimensions = Dimensions.get("window");
9
13
 
10
- export const DRAG_TO_COLLAPSE = 0.4; // 40% to collapse
14
+ const isOldAndroidDevice =
15
+ isAndroidPlatform() && !isAndroidVersionAtLeast(35) && !isAndroidTablet();
11
16
 
12
- export const DRAG_TO_EXPAND = 0.6; // 60% to expand
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
+ export const DRAG_TO_COLLAPSE = 0.02; // 2% to collapse
25
+
26
+ export const DRAG_TO_EXPAND = 0.02; // 2% to expand
13
27
 
14
28
  export const DEFAULT_IMAGE_RATIO_VIDEO = 16 / 9; // Default aspect ratio for video
15
29
 
@@ -31,6 +31,8 @@ export const useVideoModalState = (
31
31
  const collapsedHeight =
32
32
  minimisedHeight + bottom + bottomTabBarHeight + PROGRESS_BAR_HEIGHT;
33
33
 
34
+ const translateY = translateYRef.current;
35
+
34
36
  const handleExpand = useCallback(
35
37
  (toValue: number) => {
36
38
  return Animated.timing(translateYRef.current, {
@@ -53,17 +55,6 @@ export const useVideoModalState = (
53
55
  [translateYRef]
54
56
  );
55
57
 
56
- // setup translateY if not provided
57
- if (!translateYRef.current) {
58
- const initialTranslateY = handleExpand
59
- ? 0
60
- : SCREEN_HEIGHT - collapsedHeight;
61
-
62
- translateYRef.current.setValue(initialTranslateY);
63
- }
64
-
65
- const translateY = translateYRef.current;
66
-
67
58
  const offset = useRef(SCREEN_HEIGHT - collapsedHeight);
68
59
 
69
60
  // Gesture handler for modal
@@ -91,25 +82,27 @@ export const useVideoModalState = (
91
82
  newY = SCREEN_HEIGHT - collapsedHeight;
92
83
  }
93
84
 
94
- const shouldCollapse = translationY > SCREEN_HEIGHT * DRAG_TO_COLLAPSE;
95
- const shouldExpand = translationY < -SCREEN_HEIGHT * DRAG_TO_EXPAND;
85
+ const shouldCollapse =
86
+ translationY > (SCREEN_HEIGHT - collapsedHeight) * DRAG_TO_COLLAPSE;
87
+
88
+ const shouldExpand =
89
+ translationY < -(SCREEN_HEIGHT - collapsedHeight) * DRAG_TO_EXPAND;
96
90
 
97
91
  if (!collapsed && shouldCollapse) {
98
92
  // Collapse
99
93
  Animated.timing(translateY, {
100
94
  toValue: SCREEN_HEIGHT - collapsedHeight,
101
- duration: 250,
95
+ duration: ANIMATION_DURATION,
102
96
  useNativeDriver: true,
103
97
  }).start(() => {
104
98
  minimiseVideoModal();
105
99
  offset.current = SCREEN_HEIGHT - collapsedHeight;
106
- translateY.setValue(SCREEN_HEIGHT - collapsedHeight);
107
100
  });
108
101
  } else if (collapsed && shouldExpand) {
109
102
  // Expand
110
103
  Animated.timing(translateY, {
111
104
  toValue: 0,
112
- duration: 250,
105
+ duration: ANIMATION_DURATION,
113
106
  useNativeDriver: true,
114
107
  }).start(() => {
115
108
  maximiseVideoModal();
@@ -1,4 +1,3 @@
1
- /* eslint-disable react-native/no-color-literals */
2
1
  import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/utils";
3
2
  import {
4
3
  useIsTablet,
@@ -50,6 +49,9 @@ export const useStyles = ({ height }: { height: number }) => {
50
49
 
51
50
  const backgroundColor = useBackgroundColor();
52
51
 
52
+ const BG_COLOR_DEFAULT_BLACK = "black";
53
+ const BG_COLOR_DEFAULT_TRANSPARENT = "transparent";
54
+
53
55
  const styles = StyleSheet.create({
54
56
  modal: {
55
57
  position: "absolute",
@@ -61,8 +63,11 @@ export const useStyles = ({ height }: { height: number }) => {
61
63
  zIndex: 100,
62
64
  overflow: "hidden",
63
65
  },
66
+ modalWrapper: {
67
+ backgroundColor: BG_COLOR_DEFAULT_BLACK,
68
+ },
64
69
  collapsedModalBg: {
65
- backgroundColor: "black",
70
+ backgroundColor: BG_COLOR_DEFAULT_BLACK,
66
71
  },
67
72
  modalContent: {
68
73
  flex: 1,
@@ -70,12 +75,13 @@ export const useStyles = ({ height }: { height: number }) => {
70
75
  },
71
76
  expandedContentContainer: {
72
77
  justifyContent: "flex-start",
73
- backgroundColor: "transparent",
78
+ backgroundColor: BG_COLOR_DEFAULT_TRANSPARENT,
74
79
  zIndex: 1,
75
80
  flex: 0,
76
81
  },
77
82
  extraContentScrollView: {
78
- backgroundColor: "transparent",
83
+ width: "100%",
84
+ backgroundColor: BG_COLOR_DEFAULT_TRANSPARENT,
79
85
  },
80
86
  collapsedBarContainer: {
81
87
  ...StyleSheet.absoluteFillObject,
@@ -13,11 +13,10 @@ export const GenericTVPlayerView: React.FC<GenericTVPlayerViewProps> = ({
13
13
  audioPlayerProps,
14
14
  transportControls,
15
15
  entry,
16
- inline,
17
16
  }) => {
18
17
  return (
19
18
  <>
20
- {type === "audio" && inline ? (
19
+ {type === "audio" ? (
21
20
  <AudioPlayer
22
21
  audio_item={entry}
23
22
  plugin_configuration={pluginConfiguration}
@@ -61,6 +61,7 @@ const styles = StyleSheet.create({
61
61
  zIndex: 1,
62
62
  },
63
63
  playerSize: { width: "100%", height: "100%" },
64
+ flexImage: { height: "100%", aspectRatio: 1, flex: -1 },
64
65
  });
65
66
 
66
67
  const logger = createLogger({
@@ -1021,14 +1022,9 @@ export default class VideoPlayer extends React.Component<
1021
1022
  entry={entry}
1022
1023
  aspectRatio={1}
1023
1024
  layoutState={sharedWrapperViewProps.layoutState}
1024
- onPlayerSeek={() => {}}
1025
1025
  playNextData={sharedWrapperViewProps.playNextData}
1026
- progressBarHeight={4}
1027
1026
  ImageComponent={
1028
- <FlexImage
1029
- entry={entry}
1030
- style={{ height: "100%", aspectRatio: 1, flex: -1 }}
1031
- />
1027
+ <FlexImage entry={entry} style={styles.flexImage} />
1032
1028
  }
1033
1029
  />
1034
1030
  </View>
@@ -1140,9 +1136,7 @@ export default class VideoPlayer extends React.Component<
1140
1136
  entry={entry}
1141
1137
  aspectRatio={aspectRatio}
1142
1138
  layoutState={sharedWrapperViewProps.layoutState}
1143
- onPlayerSeek={() => {}}
1144
1139
  playNextData={sharedWrapperViewProps.playNextData}
1145
- progressBarHeight={4}
1146
1140
  />
1147
1141
  </View>
1148
1142
  )