@applicaster/quick-brick-player 15.0.0-rc.5 → 15.0.0-rc.50

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.
Files changed (32) hide show
  1. package/package.json +6 -6
  2. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +20 -8
  3. package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +78 -65
  4. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +1 -6
  5. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +27 -25
  6. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +6 -1
  7. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +5 -8
  8. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +1 -6
  9. package/src/Player/AudioLayer/utils.ts +1 -27
  10. package/src/Player/PlayNextOverlay/index.tsx +2 -2
  11. package/src/Player/PlayerModal/PlayerModal.tsx +16 -15
  12. package/src/Player/PlayerModal/VideoPlayerModal.tsx +138 -120
  13. package/src/Player/PlayerModal/consts/index.ts +2 -19
  14. package/src/Player/PlayerModal/hooks/index.ts +115 -139
  15. package/src/Player/PlayerModal/styles.ts +5 -0
  16. package/src/Player/PlayerModal/utils/index.ts +111 -0
  17. package/src/Player/PlayerView/types.ts +1 -2
  18. package/src/Player/Utils/index.tsx +9 -9
  19. package/src/Player/hooks/progressStates/__tests__/utils.test.ts +23 -0
  20. package/src/Player/hooks/progressStates/useLiveProgressState.tsx +78 -0
  21. package/src/Player/hooks/progressStates/useProgressState.tsx +30 -0
  22. package/src/Player/hooks/progressStates/useVodProgressState.tsx +115 -0
  23. package/src/Player/hooks/progressStates/utils.ts +33 -0
  24. package/src/Player/index.tsx +559 -357
  25. package/src/utils/dimensions.ts +29 -0
  26. package/src/utils/index.ts +12 -0
  27. package/src/utils/logger.ts +6 -0
  28. package/src/utils/playerHelpers.ts +11 -0
  29. package/src/utils/playerStyles.ts +50 -0
  30. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +0 -82
  31. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +0 -1
  32. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +0 -99
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "15.0.0-rc.5",
3
+ "version": "15.0.0-rc.50",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -35,11 +35,11 @@
35
35
  },
36
36
  "homepage": "https://github.com/applicaster/quickbrick#readme",
37
37
  "dependencies": {
38
- "@applicaster/quick-brick-mobile-transport-controls": "14.0.0-rc.56",
39
- "@applicaster/quick-brick-tv-transport-controls": "14.0.0-rc.60",
40
- "@applicaster/zapp-react-native-tvos-app": "15.0.0-rc.5",
41
- "@applicaster/zapp-react-native-ui-components": "15.0.0-rc.5",
42
- "@applicaster/zapp-react-native-utils": "15.0.0-rc.5",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "15.0.0-rc.50",
39
+ "@applicaster/quick-brick-tv-transport-controls": "15.0.0-rc.45",
40
+ "@applicaster/zapp-react-native-tvos-app": "15.0.0-rc.50",
41
+ "@applicaster/zapp-react-native-ui-components": "15.0.0-rc.50",
42
+ "@applicaster/zapp-react-native-utils": "15.0.0-rc.50",
43
43
  "query-string": "7.1.3",
44
44
  "shaka-player": "4.3.5",
45
45
  "typeface-montserrat": "^0.0.54",
@@ -61,6 +61,7 @@ type Props = {
61
61
  inline: boolean;
62
62
  docked: boolean;
63
63
  isModal: boolean;
64
+ pip: boolean;
64
65
  };
65
66
  playNextData: PlayNextData;
66
67
  isTabletPortrait?: boolean;
@@ -99,11 +100,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
99
100
  );
100
101
 
101
102
  useEffect(() => {
102
- if (player) {
103
- setSpeedManager(new SpeedController(player));
104
- } else {
105
- setSpeedManager(null);
106
- }
103
+ setSpeedManager(player ? new SpeedController(player) : null);
107
104
  }, [player]);
108
105
 
109
106
  useEffect(() => {
@@ -217,7 +214,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
217
214
  items: speedOptions,
218
215
  current_selection: playbackSpeed,
219
216
  onPress: onSpeedSelect,
220
- title: configuration["playback_speed_title"],
217
+ title: configuration.playback_speed_title,
221
218
  itemProps: getBottomSheetModalItemProps,
222
219
  iconProps: getBottomSheetModalIconProps,
223
220
  labelProps: getBottomSheetModalLabelProps,
@@ -233,7 +230,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
233
230
  ],
234
231
  },
235
232
  });
236
- }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
233
+ }, [playbackSpeed, onSpeedSelect, configuration.playback_speed_title]);
237
234
 
238
235
  const onPlayerSeek = React.useCallback(
239
236
  (targetTime: number) => {
@@ -250,13 +247,28 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
250
247
  player?.seekTo(0);
251
248
  }, [player]);
252
249
 
250
+ const layoutStateMemo = React.useMemo(
251
+ () => ({
252
+ inline: layoutState.inline,
253
+ docked: layoutState.docked,
254
+ isModal: layoutState.isModal,
255
+ pip: layoutState.pip,
256
+ }),
257
+ [
258
+ layoutState.inline,
259
+ layoutState.docked,
260
+ layoutState.isModal,
261
+ layoutState.pip,
262
+ ]
263
+ );
264
+
253
265
  return (
254
266
  <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
255
267
  <View style={Styles.playerContainer} onLayout={onLayout}>
256
268
  <Layout
257
269
  entry={entry}
258
270
  playerState={playerState}
259
- layoutState={layoutState}
271
+ layoutState={layoutStateMemo}
260
272
  value={value}
261
273
  onPlaybackButtonPress={onPlaybackButtonPress}
262
274
  onRewindButtonPress={onRewindButtonPress}
@@ -1,6 +1,5 @@
1
1
  import * as React from "react";
2
- import { StyleSheet, View, ViewStyle } from "react-native";
3
- import * as R from "ramda";
2
+ import { StyleSheet, View } from "react-native";
4
3
  import {
5
4
  useIsTablet,
6
5
  useZStore,
@@ -16,7 +15,6 @@ import {
16
15
 
17
16
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
18
17
 
19
- import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
20
18
  import { useSafeAreaInsets } from "react-native-safe-area-context";
21
19
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
22
20
  import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/getTabBarHeight";
@@ -25,24 +23,19 @@ import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/pl
25
23
  import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/utils";
26
24
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
27
25
  import { PROGRESS_BAR_HEIGHT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/utils";
28
- import { isMenuVisible } from "@applicaster/zapp-react-native-ui-components/Components/Screen/navigationHandler";
26
+ import { isBottomTabVisible } from "@applicaster/zapp-react-native-ui-components/Components/Screen/navigationHandler";
29
27
  import { usePlugins } from "@applicaster/zapp-react-native-redux";
28
+ import { partial } from "@applicaster/zapp-react-native-utils/utils";
30
29
 
31
30
  const bottomTabBarHeight = getTabBarHeight();
32
31
 
33
32
  type Props = {
34
33
  entry: ZappEntry;
35
34
  layoutState: QuickBrickPlayer.LayoutState;
36
- playerState: QuickBrickPlayer.PlayerState;
37
- value: GetValue;
38
- onCloseVideoModal: () => void;
39
- onPlayerSeek: (targetTime: number) => void;
35
+ onPlayerSeek?: (targetTime: number) => void;
40
36
  playNextData: PlayNextData;
41
- title: string | number;
42
- summary: string | number;
43
37
  ImageComponent?: React.ReactNode;
44
38
  isActiveGesture?: boolean;
45
- minimisedHeight: number;
46
39
  aspectRatio?: number;
47
40
  };
48
41
 
@@ -51,7 +44,6 @@ const styles = StyleSheet.create({
51
44
  flex: 1,
52
45
  flexDirection: "column",
53
46
  alignItems: "stretch",
54
- marginTop: PROGRESS_BAR_HEIGHT,
55
47
  },
56
48
  content: {
57
49
  flex: 1,
@@ -94,14 +86,12 @@ const styles = StyleSheet.create({
94
86
  buttons: {
95
87
  marginVertical: 10,
96
88
  },
89
+ liveMarginTop: { marginTop: 0 },
90
+ marginTop: { marginTop: PROGRESS_BAR_HEIGHT },
97
91
  });
98
92
 
99
- const playerDimensionsStyle = (
100
- minimisedHeight: number,
101
- addPadding: boolean
102
- ): ViewStyle => ({
103
- width: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
104
- });
93
+ const getValue = (key: string, stylesObj: Record<string, any>) =>
94
+ stylesObj?.[key] ?? null;
105
95
 
106
96
  const controlButtons = (
107
97
  live: boolean,
@@ -167,7 +157,6 @@ export const DockedControls = (props: Props) => {
167
157
  onPlayerSeek = noop,
168
158
  playNextData,
169
159
  ImageComponent,
170
- isActiveGesture = true,
171
160
  aspectRatio,
172
161
  } = props;
173
162
 
@@ -178,18 +167,18 @@ export const DockedControls = (props: Props) => {
178
167
  const { currentRoute, screenData } = useNavigation();
179
168
 
180
169
  const plugins = usePlugins();
181
- const menuVisible = isMenuVisible(currentRoute, screenData, plugins);
170
+
171
+ const bottomTabsVisible = isBottomTabVisible(
172
+ currentRoute,
173
+ screenData,
174
+ plugins
175
+ );
182
176
 
183
177
  const { minimised_height: minimisedHeight } = useConfiguration();
184
178
 
185
179
  const configuration = useZStore("playerConfiguration")();
186
180
  const playerState = usePlayerState("shared-player-wrapper-docked");
187
181
 
188
- const getValue = React.useCallback(
189
- (key: string, stylesObj: {}) => R.propOr(null, key, stylesObj),
190
- []
191
- );
192
-
193
182
  const value = React.useCallback(
194
183
  (key: string) => {
195
184
  const retVal = getValue(key, configuration);
@@ -208,7 +197,7 @@ export const DockedControls = (props: Props) => {
208
197
 
209
198
  return retVal;
210
199
  },
211
- [...Object.values(configuration), playerState.seekableDuration, getValue]
200
+ [...Object.values(configuration), playerState.seekableDuration]
212
201
  );
213
202
 
214
203
  const { title, summary } = useTitleSummaryOverlay(
@@ -225,15 +214,65 @@ export const DockedControls = (props: Props) => {
225
214
 
226
215
  const insets = useSafeAreaInsets();
227
216
 
217
+ const progressBarLayoutState = React.useMemo(
218
+ () => ({
219
+ inline: layoutState.inline,
220
+ docked: true,
221
+ isModal: layoutState.isModal,
222
+ pip: layoutState.pip,
223
+ }),
224
+ [layoutState.inline, layoutState.isModal, layoutState.pip]
225
+ );
226
+
227
+ const _controlButtons = React.useMemo(
228
+ () => partial(controlButtons, playerState.isLive && liveButton),
229
+ [playerState.isLive, liveButton]
230
+ );
231
+
232
+ const containerStyles = React.useMemo(
233
+ () => ({
234
+ height: minimisedHeight,
235
+ maxHeight: minimisedHeight,
236
+ }),
237
+ [minimisedHeight]
238
+ );
239
+
240
+ const imageComponentWrapperStyles = React.useMemo(
241
+ () => ({
242
+ aspectRatio: aspectRatio,
243
+ height: minimisedHeight,
244
+ }),
245
+ [aspectRatio, minimisedHeight]
246
+ );
247
+
248
+ const backgroundColorStyle = React.useMemo(
249
+ () => ({
250
+ backgroundColor: dockedBackgroundColor,
251
+ }),
252
+ [dockedBackgroundColor]
253
+ );
254
+
255
+ const bottomSpacerStyle = React.useMemo(() => {
256
+ const tabBarHeight = bottomTabsVisible ? bottomTabBarHeight : 0;
257
+ const safeAreaBottomInset = insets.bottom || 0;
258
+
259
+ return {
260
+ height: safeAreaBottomInset + tabBarHeight,
261
+ };
262
+ }, [bottomTabsVisible, insets.bottom]);
263
+
264
+ const contentInfoContent = React.useMemo(
265
+ () => ({ ...entry, title, summary }),
266
+ [title, summary, entry]
267
+ );
268
+
228
269
  return (
229
270
  <>
230
271
  <View
231
272
  style={[
232
273
  styles.container,
233
- {
234
- height: minimisedHeight,
235
- maxHeight: minimisedHeight,
236
- },
274
+ containerStyles,
275
+ playerState.isLive ? styles.liveMarginTop : styles.marginTop,
237
276
  ]}
238
277
  >
239
278
  {!playerState.isLive ? (
@@ -242,42 +281,23 @@ export const DockedControls = (props: Props) => {
242
281
  content={entry}
243
282
  value={value}
244
283
  visible
245
- layoutState={layoutState}
284
+ layoutState={progressBarLayoutState}
246
285
  onPlayerSeek={onPlayerSeek}
247
286
  playerState={playerState}
248
- startComponentsAnimation={noop}
249
287
  docked
250
288
  />
251
289
  ) : null}
252
290
 
253
291
  <View style={styles.content}>
254
292
  <View style={styles.touchableArea}>
255
- {isActiveGesture || layoutState.docked ? (
256
- <View
257
- style={{ aspectRatio: aspectRatio, height: minimisedHeight }}
258
- >
259
- {ImageComponent || null}
260
- </View>
261
- ) : (
262
- <View
263
- style={playerDimensionsStyle(
264
- minimisedHeight,
265
- isActiveGesture || layoutState.docked
266
- )}
267
- />
268
- )}
293
+ <View style={imageComponentWrapperStyles}>
294
+ {ImageComponent || null}
295
+ </View>
269
296
  <View
270
297
  testID="content-info"
271
- style={[
272
- styles.contentInfo,
273
- { backgroundColor: dockedBackgroundColor },
274
- ]}
298
+ style={[styles.contentInfo, backgroundColorStyle]}
275
299
  >
276
- <ContentInfo
277
- content={{ ...entry, title, summary }}
278
- value={value}
279
- docked
280
- />
300
+ <ContentInfo content={contentInfoContent} value={value} docked />
281
301
  </View>
282
302
  </View>
283
303
  <View
@@ -285,15 +305,13 @@ export const DockedControls = (props: Props) => {
285
305
  isTablet
286
306
  ? styles.controlsContainerForTablet
287
307
  : styles.controlsContainerForMobile,
288
- { backgroundColor: dockedBackgroundColor },
308
+ backgroundColorStyle,
289
309
  ]}
290
310
  >
291
311
  <Controls
292
312
  value={value}
293
313
  visible
294
- buttons={R.partial(controlButtons, [
295
- playerState.isLive && liveButton,
296
- ])}
314
+ buttons={_controlButtons}
297
315
  style={styles.playPauseButton}
298
316
  playNextData={playNextData}
299
317
  playerState={playerState}
@@ -308,12 +326,7 @@ export const DockedControls = (props: Props) => {
308
326
  </View>
309
327
  </View>
310
328
  </View>
311
- <View
312
- style={{
313
- height: insets.bottom + (menuVisible ? bottomTabBarHeight : 0),
314
- backgroundColor: dockedBackgroundColor,
315
- }}
316
- />
329
+ <View style={[bottomSpacerStyle, backgroundColorStyle]} />
317
330
  </>
318
331
  );
319
332
  };
@@ -151,12 +151,7 @@ export function MobileLayout({
151
151
  },
152
152
  ]}
153
153
  >
154
- <PlayerImage
155
- entry={entry}
156
- docked={false}
157
- imageWidth={imageSize}
158
- configuration={configuration}
159
- />
154
+ <PlayerImage entry={entry} configuration={configuration} />
160
155
  </View>
161
156
  {/* PlayerImage */}
162
157
 
@@ -1,31 +1,24 @@
1
1
  import * as React from "react";
2
- import { LayoutChangeEvent, View } from "react-native";
2
+ import { Animated, LayoutChangeEvent, View } from "react-native";
3
3
 
4
4
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
5
5
  import { toBooleanWithDefaultTrue } from "@applicaster/zapp-react-native-utils/booleanUtils";
6
6
 
7
- import { AnimatedImage } from "./AnimatedImage";
8
7
  import { FlexImage } from "./FlexImage";
9
8
 
10
9
  import { styles } from "./styles";
11
10
  import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
11
+ import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
12
12
 
13
13
  type Props = {
14
14
  entry: ZappEntry;
15
15
  configuration: QuickBrickPlayer.AudioPlayerProps["configuration"];
16
- docked: boolean;
17
- imageWidth?: Option<number>;
16
+ docked?: boolean;
18
17
  onLayoutImage?: (event: LayoutChangeEvent) => void;
19
18
  };
20
19
 
21
20
  export const PlayerImage = (props: Props) => {
22
- const {
23
- entry,
24
- docked,
25
- imageWidth,
26
- configuration,
27
- onLayoutImage = noop,
28
- } = props;
21
+ const { entry, docked = false, configuration, onLayoutImage = noop } = props;
29
22
 
30
23
  const isShadowEnabled = toBooleanWithDefaultTrue(
31
24
  configuration?.audio_player_artwork_shadow_enabled
@@ -37,25 +30,34 @@ export const PlayerImage = (props: Props) => {
37
30
  configuration.audio_player_artwork_border_radius
38
31
  );
39
32
 
33
+ const { yTranslate } = useModalAnimationContext();
34
+
35
+ const isModalExpanded = yTranslate.current.interpolate({
36
+ inputRange: [0, 1], // this should be end with `1` only when it's in initial state ( 0pos), otherwise `0`
37
+ outputRange: [1, 0],
38
+ });
39
+
40
+ // do not use styles.shadow when isModalExpanded is 0
41
+
42
+ const animatedStyle = {
43
+ opacity: isModalExpanded,
44
+ };
45
+
40
46
  return (
41
47
  <View style={styles.alignItemsCenter}>
48
+ {/* Using an Animated.View to apply shadow to the image */}
49
+ <Animated.View
50
+ style={[
51
+ animatedStyle,
52
+ shouldShowShadow ? styles.shadow : undefined,
53
+ { borderRadius },
54
+ ]}
55
+ />
42
56
  <View
43
57
  onLayout={onLayoutImage}
44
- style={[shouldShowShadow ? styles.shadow : undefined, { borderRadius }]}
58
+ style={[styles.defaultImageWrapperView, { borderRadius }]}
45
59
  >
46
- {!imageWidth ? (
47
- <View style={[styles.defaultImageWrapperView, { borderRadius }]}>
48
- <FlexImage entry={entry} style={styles.backgroundImageContainer} />
49
- </View>
50
- ) : (
51
- // we have imageSize here and now we could animate resizing of this image
52
- <AnimatedImage
53
- entry={entry}
54
- style={[styles.backgroundImageContainer, { borderRadius }]}
55
- imageWidth={imageWidth}
56
- docked={docked}
57
- />
58
- )}
60
+ <FlexImage entry={entry} style={styles.backgroundImageContainer} />
59
61
  </View>
60
62
  </View>
61
63
  );
@@ -23,7 +23,12 @@ export const styles = StyleSheet.create({
23
23
  overflow: "hidden",
24
24
  },
25
25
  shadow: {
26
- borderColor: "transparent",
26
+ zIndex: 0,
27
+ position: "absolute",
28
+ top: 0,
29
+ left: 0,
30
+ right: 0,
31
+ bottom: 0,
27
32
  shadowColor: SHADOW_COLOR,
28
33
  shadowOffset: { width: 0, height: 24 },
29
34
  shadowOpacity: platformSelect({
@@ -117,14 +117,11 @@ export function TabletLandscapeLayout({
117
117
  <View style={[styles.flex, styles.audioPlayerContainerHeightLimit]}>
118
118
  {/* PlayerImage non-docked */}
119
119
  <View style={[styles.flex, withDebug(styles.debugYellow)]}>
120
- {!docked ? (
121
- <PlayerImage
122
- docked={false}
123
- entry={entry}
124
- configuration={configuration}
125
- onLayoutImage={onLayoutImage}
126
- />
127
- ) : null}
120
+ <PlayerImage
121
+ entry={entry}
122
+ configuration={configuration}
123
+ onLayoutImage={onLayoutImage}
124
+ />
128
125
  </View>
129
126
  {/* PlayerImage */}
130
127
 
@@ -144,12 +144,7 @@ export function TabletPortraitLayout({
144
144
  ]}
145
145
  onLayout={onLayout}
146
146
  >
147
- <PlayerImage
148
- entry={entry}
149
- configuration={configuration}
150
- docked={docked}
151
- imageWidth={imageSize}
152
- />
147
+ <PlayerImage entry={entry} configuration={configuration} />
153
148
  </View>
154
149
 
155
150
  <View
@@ -1,10 +1,6 @@
1
1
  import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
2
- import {
3
- PlayerAnimationStateEnum,
4
- PlayerAnimationStateT,
5
- } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/ModalAnimationContext";
2
+
6
3
  import { parseJsonIfNeeded } from "@applicaster/zapp-react-native-utils/functionUtils";
7
- import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
8
4
 
9
5
  export const NAMESPACE = "audio-player";
10
6
 
@@ -36,25 +32,3 @@ export const formatSpeed = (value: number) => {
36
32
  // Return the formatted string with "speed_" prefix
37
33
  return `speed_${formattedValue}`;
38
34
  };
39
-
40
- export const calculateBorderRadius = (
41
- docked: boolean,
42
- startComponentsAnimation: boolean,
43
- isActiveGesture: boolean,
44
- playerAnimationState: PlayerAnimationStateT,
45
- configuration: Record<string, any>
46
- ): number => {
47
- const shouldRemoveBorderRadius =
48
- (startComponentsAnimation &&
49
- isActiveGesture &&
50
- playerAnimationState !== PlayerAnimationStateEnum.maximize) ||
51
- docked;
52
-
53
- if (shouldRemoveBorderRadius) {
54
- return 0;
55
- }
56
-
57
- return toNumberWithDefaultZero(
58
- configuration.audio_player_artwork_border_radius
59
- );
60
- };
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import * as R from "ramda";
3
3
 
4
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
4
+ import { usePlugins } from "@applicaster/zapp-react-native-redux";
5
5
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
6
6
 
7
7
  type Props = {
@@ -32,7 +32,7 @@ export const PlayNextOverlay = ({
32
32
  playNextData,
33
33
  setNextVideoPreloadThresholdPercentage,
34
34
  }: Props) => {
35
- const { plugins } = usePickFromState(["plugins"]);
35
+ const plugins = usePlugins();
36
36
 
37
37
  const OverlayPlugin = getOverlayPlugin(plugins);
38
38
 
@@ -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";
8
- import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
7
+ import { MODAL_COLLAPSE_RATIO, MODAL_RADIUS } from "./consts";
8
+ import { getWindowHeight } from "./utils";
9
+ import { useSafeAreaFrame } from "react-native-safe-area-context";
9
10
 
10
11
  type AnimatedModalProps = {
11
12
  content?: ReactElement;
@@ -16,33 +17,34 @@ export function AnimatedModal({
16
17
  content,
17
18
  collapsedContent,
18
19
  }: AnimatedModalProps) {
19
- const translateYRef = useModalAnimationContext().yTranslate;
20
+ const { translateY, collapsed, gestureHandlerProps, expand, offset } =
21
+ useVideoModalState();
20
22
 
21
- const {
22
- translateY,
23
- collapsed,
24
- collapsedHeight,
25
- gestureHandlerProps,
26
- expand,
27
- } = useVideoModalState(translateYRef);
23
+ const frame = useSafeAreaFrame();
24
+ const collapsedHeight = frame.height - offset.current;
25
+
26
+ const height = getWindowHeight();
27
+ const heightAboveMinimised = height - collapsedHeight;
28
28
 
29
29
  const styles = useStyles({ height: collapsedHeight, type: "audio" });
30
30
 
31
+ const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
32
+
31
33
  // Interpolated opacities for smooth cross-fade
32
34
  const collapsedOpacity = translateY.interpolate({
33
- inputRange: [MODAL_COLLAPSE_START, SCREEN_HEIGHT - collapsedHeight],
35
+ inputRange: [MODAL_COLLAPSE_START, heightAboveMinimised],
34
36
  outputRange: [0, 1],
35
37
  extrapolate: "clamp",
36
38
  });
37
39
 
38
40
  const expandedOpacity = translateY.interpolate({
39
- inputRange: [0, SCREEN_HEIGHT - collapsedHeight],
41
+ inputRange: [0, heightAboveMinimised],
40
42
  outputRange: [1, 0],
41
43
  extrapolate: "clamp",
42
44
  });
43
45
 
44
46
  const borderTopRadiusAnimated = translateY.interpolate({
45
- inputRange: [0, SCREEN_HEIGHT - collapsedHeight],
47
+ inputRange: [0, heightAboveMinimised],
46
48
  outputRange: [MODAL_RADIUS, 0],
47
49
  extrapolate: "clamp",
48
50
  });
@@ -57,7 +59,7 @@ export function AnimatedModal({
57
59
  borderTopLeftRadius: borderTopRadiusAnimated,
58
60
  borderTopRightRadius: borderTopRadiusAnimated,
59
61
  transform: [{ translateY }],
60
- height: SCREEN_HEIGHT,
62
+ height: height,
61
63
  },
62
64
  ]}
63
65
  >
@@ -67,7 +69,6 @@ export function AnimatedModal({
67
69
  {
68
70
  borderTopLeftRadius: borderTopRadiusAnimated,
69
71
  borderTopRightRadius: borderTopRadiusAnimated,
70
- height: SCREEN_HEIGHT,
71
72
  },
72
73
  ]}
73
74
  >