@applicaster/quick-brick-player 15.0.0-alpha.5170277721 → 15.0.0-alpha.5587607173

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": "15.0.0-alpha.5170277721",
3
+ "version": "15.0.0-alpha.5587607173",
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": "15.0.0-rc.8",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "15.0.0-alpha.5587607173",
39
39
  "@applicaster/quick-brick-tv-transport-controls": "15.0.0-rc.15",
40
- "@applicaster/zapp-react-native-tvos-app": "15.0.0-alpha.5170277721",
41
- "@applicaster/zapp-react-native-ui-components": "15.0.0-alpha.5170277721",
42
- "@applicaster/zapp-react-native-utils": "15.0.0-alpha.5170277721",
40
+ "@applicaster/zapp-react-native-tvos-app": "15.0.0-alpha.5587607173",
41
+ "@applicaster/zapp-react-native-ui-components": "15.0.0-alpha.5587607173",
42
+ "@applicaster/zapp-react-native-utils": "15.0.0-alpha.5587607173",
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;
@@ -246,13 +247,28 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
246
247
  player?.seekTo(0);
247
248
  }, [player]);
248
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
+
249
265
  return (
250
266
  <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
251
267
  <View style={Styles.playerContainer} onLayout={onLayout}>
252
268
  <Layout
253
269
  entry={entry}
254
270
  playerState={playerState}
255
- layoutState={layoutState}
271
+ layoutState={layoutStateMemo}
256
272
  value={value}
257
273
  onPlaybackButtonPress={onPlaybackButtonPress}
258
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";
@@ -27,6 +25,7 @@ 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
26
  import { isMenuVisible } 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
 
@@ -45,7 +44,6 @@ const styles = StyleSheet.create({
45
44
  flex: 1,
46
45
  flexDirection: "column",
47
46
  alignItems: "stretch",
48
- marginTop: PROGRESS_BAR_HEIGHT,
49
47
  },
50
48
  content: {
51
49
  flex: 1,
@@ -88,14 +86,12 @@ const styles = StyleSheet.create({
88
86
  buttons: {
89
87
  marginVertical: 10,
90
88
  },
89
+ liveMarginTop: { marginTop: 0 },
90
+ marginTop: { marginTop: PROGRESS_BAR_HEIGHT },
91
91
  });
92
92
 
93
- const playerDimensionsStyle = (
94
- minimisedHeight: number,
95
- addPadding: boolean
96
- ): ViewStyle => ({
97
- width: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
98
- });
93
+ const getValue = (key: string, stylesObj: Record<string, any>) =>
94
+ stylesObj?.[key] ?? null;
99
95
 
100
96
  const controlButtons = (
101
97
  live: boolean,
@@ -161,7 +157,6 @@ export const DockedControls = (props: Props) => {
161
157
  onPlayerSeek = noop,
162
158
  playNextData,
163
159
  ImageComponent,
164
- isActiveGesture = true,
165
160
  aspectRatio,
166
161
  } = props;
167
162
 
@@ -179,11 +174,6 @@ export const DockedControls = (props: Props) => {
179
174
  const configuration = useZStore("playerConfiguration")();
180
175
  const playerState = usePlayerState("shared-player-wrapper-docked");
181
176
 
182
- const getValue = React.useCallback(
183
- (key: string, stylesObj: {}) => R.propOr(null, key, stylesObj),
184
- []
185
- );
186
-
187
177
  const value = React.useCallback(
188
178
  (key: string) => {
189
179
  const retVal = getValue(key, configuration);
@@ -202,7 +192,7 @@ export const DockedControls = (props: Props) => {
202
192
 
203
193
  return retVal;
204
194
  },
205
- [...Object.values(configuration), playerState.seekableDuration, getValue]
195
+ [...Object.values(configuration), playerState.seekableDuration]
206
196
  );
207
197
 
208
198
  const { title, summary } = useTitleSummaryOverlay(
@@ -219,15 +209,65 @@ export const DockedControls = (props: Props) => {
219
209
 
220
210
  const insets = useSafeAreaInsets();
221
211
 
212
+ const progressBarLayoutState = React.useMemo(
213
+ () => ({
214
+ inline: layoutState.inline,
215
+ docked: true,
216
+ isModal: layoutState.isModal,
217
+ pip: layoutState.pip,
218
+ }),
219
+ [layoutState.inline, layoutState.isModal, layoutState.pip]
220
+ );
221
+
222
+ const _controlButtons = React.useMemo(
223
+ () => partial(controlButtons, playerState.isLive && liveButton),
224
+ [playerState.isLive, liveButton]
225
+ );
226
+
227
+ const containerStyles = React.useMemo(
228
+ () => ({
229
+ height: minimisedHeight,
230
+ maxHeight: minimisedHeight,
231
+ }),
232
+ [minimisedHeight]
233
+ );
234
+
235
+ const imageComponentWrapperStyles = React.useMemo(
236
+ () => ({
237
+ aspectRatio: aspectRatio,
238
+ height: minimisedHeight,
239
+ }),
240
+ [aspectRatio, minimisedHeight]
241
+ );
242
+
243
+ const backgroundColorStyle = React.useMemo(
244
+ () => ({
245
+ backgroundColor: dockedBackgroundColor,
246
+ }),
247
+ [dockedBackgroundColor]
248
+ );
249
+
250
+ const bottomSpacerStyle = React.useMemo(() => {
251
+ const tabBarHeight = menuVisible ? bottomTabBarHeight : 0;
252
+ const safeAreaBottomInset = insets.bottom || 0;
253
+
254
+ return {
255
+ height: safeAreaBottomInset + tabBarHeight,
256
+ };
257
+ }, [menuVisible, insets.bottom]);
258
+
259
+ const contentInfoContent = React.useMemo(
260
+ () => ({ ...entry, title, summary }),
261
+ [title, summary, entry]
262
+ );
263
+
222
264
  return (
223
265
  <>
224
266
  <View
225
267
  style={[
226
268
  styles.container,
227
- {
228
- height: minimisedHeight,
229
- maxHeight: minimisedHeight,
230
- },
269
+ containerStyles,
270
+ playerState.isLive ? styles.liveMarginTop : styles.marginTop,
231
271
  ]}
232
272
  >
233
273
  {!playerState.isLive ? (
@@ -236,42 +276,23 @@ export const DockedControls = (props: Props) => {
236
276
  content={entry}
237
277
  value={value}
238
278
  visible
239
- layoutState={layoutState}
279
+ layoutState={progressBarLayoutState}
240
280
  onPlayerSeek={onPlayerSeek}
241
281
  playerState={playerState}
242
- startComponentsAnimation={noop}
243
282
  docked
244
283
  />
245
284
  ) : null}
246
285
 
247
286
  <View style={styles.content}>
248
287
  <View style={styles.touchableArea}>
249
- {isActiveGesture || layoutState.docked ? (
250
- <View
251
- style={{ aspectRatio: aspectRatio, height: minimisedHeight }}
252
- >
253
- {ImageComponent || null}
254
- </View>
255
- ) : (
256
- <View
257
- style={playerDimensionsStyle(
258
- minimisedHeight,
259
- isActiveGesture || layoutState.docked
260
- )}
261
- />
262
- )}
288
+ <View style={imageComponentWrapperStyles}>
289
+ {ImageComponent || null}
290
+ </View>
263
291
  <View
264
292
  testID="content-info"
265
- style={[
266
- styles.contentInfo,
267
- { backgroundColor: dockedBackgroundColor },
268
- ]}
293
+ style={[styles.contentInfo, backgroundColorStyle]}
269
294
  >
270
- <ContentInfo
271
- content={{ ...entry, title, summary }}
272
- value={value}
273
- docked
274
- />
295
+ <ContentInfo content={contentInfoContent} value={value} docked />
275
296
  </View>
276
297
  </View>
277
298
  <View
@@ -279,15 +300,13 @@ export const DockedControls = (props: Props) => {
279
300
  isTablet
280
301
  ? styles.controlsContainerForTablet
281
302
  : styles.controlsContainerForMobile,
282
- { backgroundColor: dockedBackgroundColor },
303
+ backgroundColorStyle,
283
304
  ]}
284
305
  >
285
306
  <Controls
286
307
  value={value}
287
308
  visible
288
- buttons={R.partial(controlButtons, [
289
- playerState.isLive && liveButton,
290
- ])}
309
+ buttons={_controlButtons}
291
310
  style={styles.playPauseButton}
292
311
  playNextData={playNextData}
293
312
  playerState={playerState}
@@ -302,12 +321,7 @@ export const DockedControls = (props: Props) => {
302
321
  </View>
303
322
  </View>
304
323
  </View>
305
- <View
306
- style={{
307
- height: insets.bottom + (menuVisible ? bottomTabBarHeight : 0),
308
- backgroundColor: dockedBackgroundColor,
309
- }}
310
- />
324
+ <View style={[bottomSpacerStyle, backgroundColorStyle]} />
311
325
  </>
312
326
  );
313
327
  };
@@ -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
- };
@@ -5,8 +5,8 @@ import { PanGestureHandler } from "react-native-gesture-handler";
5
5
  import { useStyles } from "./styles";
6
6
  import { useVideoModalState } from "./hooks";
7
7
  import { MODAL_COLLAPSE_RATIO, MODAL_RADIUS } from "./consts";
8
- import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
9
8
  import { getWindowHeight } from "./utils";
9
+ import { useSafeAreaFrame } from "react-native-safe-area-context";
10
10
 
11
11
  type AnimatedModalProps = {
12
12
  content?: ReactElement;
@@ -17,22 +17,18 @@ export function AnimatedModal({
17
17
  content,
18
18
  collapsedContent,
19
19
  }: AnimatedModalProps) {
20
- const translateYRef = useModalAnimationContext().yTranslate;
20
+ const { translateY, collapsed, gestureHandlerProps, expand, offset } =
21
+ useVideoModalState();
21
22
 
22
- const {
23
- translateY,
24
- collapsed,
25
- collapsedHeight,
26
- gestureHandlerProps,
27
- expand,
28
- } = useVideoModalState(translateYRef);
23
+ const frame = useSafeAreaFrame();
24
+ const collapsedHeight = frame.height - offset.current;
29
25
 
30
- const styles = useStyles({ height: collapsedHeight, type: "audio" });
26
+ const height = getWindowHeight();
27
+ const heightAboveMinimised = height - collapsedHeight;
31
28
 
32
- const WINDOW_HEIGHT = getWindowHeight();
33
- const heightAboveMinimised = WINDOW_HEIGHT - collapsedHeight;
29
+ const styles = useStyles({ height: collapsedHeight, type: "audio" });
34
30
 
35
- const MODAL_COLLAPSE_START = WINDOW_HEIGHT * MODAL_COLLAPSE_RATIO;
31
+ const MODAL_COLLAPSE_START = height * MODAL_COLLAPSE_RATIO;
36
32
 
37
33
  // Interpolated opacities for smooth cross-fade
38
34
  const collapsedOpacity = translateY.interpolate({
@@ -63,7 +59,7 @@ export function AnimatedModal({
63
59
  borderTopLeftRadius: borderTopRadiusAnimated,
64
60
  borderTopRightRadius: borderTopRadiusAnimated,
65
61
  transform: [{ translateY }],
66
- height: WINDOW_HEIGHT,
62
+ height: height,
67
63
  },
68
64
  ]}
69
65
  >
@@ -73,7 +69,6 @@ export function AnimatedModal({
73
69
  {
74
70
  borderTopLeftRadius: borderTopRadiusAnimated,
75
71
  borderTopRightRadius: borderTopRadiusAnimated,
76
- height: WINDOW_HEIGHT,
77
72
  },
78
73
  ]}
79
74
  >