@applicaster/quick-brick-player 13.0.6-alpha.4390983410 → 13.0.6-alpha.5144834334

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": "13.0.6-alpha.4390983410",
3
+ "version": "13.0.6-alpha.5144834334",
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": "13.0.6-alpha.4390983410",
39
- "@applicaster/quick-brick-tv-transport-controls": "13.0.6-alpha.4390983410",
40
- "@applicaster/zapp-react-native-tvos-app": "13.0.6-alpha.4390983410",
41
- "@applicaster/zapp-react-native-ui-components": "13.0.6-alpha.4390983410",
42
- "@applicaster/zapp-react-native-utils": "13.0.6-alpha.4390983410",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.2",
39
+ "@applicaster/quick-brick-tv-transport-controls": "13.0.4",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.6-alpha.5144834334",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.6-alpha.5144834334",
42
+ "@applicaster/zapp-react-native-utils": "13.0.6-alpha.5144834334",
43
43
  "query-string": "7.1.3",
44
44
  "react-native-web-linear-gradient": "1.1.2",
45
45
  "shaka-player": "4.3.5",
@@ -1,6 +1,11 @@
1
1
  import * as React from "react";
2
2
  import { useEffect, useState } from "react";
3
- import { StyleSheet, View, ViewStyle } from "react-native";
3
+ import {
4
+ Dimensions as ScreenDimensions,
5
+ StyleSheet,
6
+ View,
7
+ ViewStyle,
8
+ } from "react-native";
4
9
 
5
10
  import { Edge, SafeAreaView } from "react-native-safe-area-context";
6
11
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
@@ -8,9 +13,14 @@ import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerM
8
13
  import * as R from "ramda";
9
14
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
10
15
  import Layout from "./Layout";
11
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
16
+ import {
17
+ useIsTablet,
18
+ useNavigation,
19
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
12
20
  import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
13
21
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
22
+ import { PlayerDetails } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/PlayerDetails";
23
+ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
14
24
  import { formatSpeed } from "./utils";
15
25
  import {
16
26
  getBottomSheetModalDefaultItemIcon,
@@ -20,7 +30,12 @@ import {
20
30
  getBottomSheetModalSelectedItemIcon,
21
31
  } from "../Utils";
22
32
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
-
33
+ import {
34
+ AnimatedScrollModal,
35
+ AnimationComponent,
36
+ ComponentAnimationType,
37
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
38
+ import { PADDING_HORIZONTAL } from "./Layout/const";
24
39
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
25
40
 
26
41
  import { DEFAULT_SPEED, PlaybackSpeed, SpeedController } from "./SpeedManager";
@@ -66,10 +81,18 @@ type Props = {
66
81
  isTabletPortrait?: boolean;
67
82
  };
68
83
 
84
+ const { width: SCREEN_WIDTH } = ScreenDimensions.get("screen");
85
+
69
86
  const Styles = StyleSheet.create({
70
87
  playerContainer: {
71
88
  flex: 1,
72
89
  },
90
+ paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
91
+ playerDetails: {
92
+ marginTop: 60,
93
+ alignSelf: "center",
94
+ width: SCREEN_WIDTH - PADDING_HORIZONTAL * 2,
95
+ },
73
96
  });
74
97
 
75
98
  const edges: Edge[] = ["right", "left", "top"];
@@ -84,10 +107,16 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
84
107
  configuration,
85
108
  style,
86
109
  entry,
110
+ children,
87
111
  layoutState,
88
112
  playNextData = null,
113
+ isTabletPortrait,
89
114
  } = props;
90
115
 
116
+ const isTablet = useIsTablet();
117
+
118
+ const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
119
+
91
120
  const { title, summary } = useTitleSummaryOverlay(
92
121
  entry,
93
122
  playerState?.isLive,
@@ -235,6 +264,10 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
235
264
  });
236
265
  }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
237
266
 
267
+ const onCloseVideoModal = React.useCallback(() => {
268
+ playerManager.close();
269
+ }, [playerManager]);
270
+
238
271
  const onPlayerSeek = React.useCallback(
239
272
  (targetTime: number) => {
240
273
  player?.seekTo(targetTime);
@@ -252,28 +285,51 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
252
285
 
253
286
  return (
254
287
  <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
255
- <View style={Styles.playerContainer} onLayout={onLayout}>
256
- <Layout
257
- entry={entry}
258
- playerState={playerState}
259
- layoutState={layoutState}
260
- value={value}
261
- onPlaybackButtonPress={onPlaybackButtonPress}
262
- onRewindButtonPress={onRewindButtonPress}
263
- onForwardButtonPress={onForwardButtonPress}
264
- onPlayerSeek={onPlayerSeek}
265
- onSkipStart={onSkipStart}
266
- onSpeedButtonPress={onSpeedButtonPress}
267
- playbackSpeedName={formatSpeed(playbackSpeed.value)}
268
- onSkipLive={onSkipLive}
269
- maximiseVideoModal={maximiseVideoModal}
270
- configuration={configuration}
271
- dimensions={dimensions}
272
- playNextData={playNextData}
273
- title={title}
274
- summary={summary}
275
- />
276
- </View>
288
+ <AnimationComponent
289
+ animationType={ComponentAnimationType.moveUpComponent}
290
+ additionalData={{ saveArea: true }}
291
+ style={Styles.playerContainer}
292
+ >
293
+ <AnimatedScrollModal>
294
+ <View style={Styles.playerContainer} onLayout={onLayout}>
295
+ <Layout
296
+ entry={entry}
297
+ playerState={playerState}
298
+ layoutState={layoutState}
299
+ value={value}
300
+ onPlaybackButtonPress={onPlaybackButtonPress}
301
+ onRewindButtonPress={onRewindButtonPress}
302
+ onForwardButtonPress={onForwardButtonPress}
303
+ onPlayerSeek={onPlayerSeek}
304
+ onSkipStart={onSkipStart}
305
+ onSpeedButtonPress={onSpeedButtonPress}
306
+ playbackSpeedName={formatSpeed(playbackSpeed.value)}
307
+ onSkipLive={onSkipLive}
308
+ onCloseVideoModal={onCloseVideoModal}
309
+ maximiseVideoModal={maximiseVideoModal}
310
+ configuration={configuration}
311
+ dimensions={dimensions}
312
+ playNextData={playNextData}
313
+ title={title}
314
+ summary={summary}
315
+ />
316
+ <View style={Styles.paddingHorizontal}>
317
+ {children}
318
+ <AnimationComponent
319
+ animationType={ComponentAnimationType.componentFade}
320
+ >
321
+ <PlayerDetails
322
+ isAudioPlayer
323
+ configuration={configuration}
324
+ style={Styles.playerDetails}
325
+ entry={entry}
326
+ isTabletLandscape={isTabletLandscape}
327
+ />
328
+ </AnimationComponent>
329
+ </View>
330
+ </View>
331
+ </AnimatedScrollModal>
332
+ </AnimationComponent>
277
333
  </SafeAreaView>
278
334
  );
279
335
  };
@@ -1,11 +1,12 @@
1
1
  import * as React from "react";
2
- import { StyleSheet, View, ViewStyle } from "react-native";
3
- import * as R from "ramda";
4
2
  import {
5
- useIsTablet,
6
- useZStore,
7
- } from "@applicaster/zapp-react-native-utils/reactHooks";
8
- import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
3
+ StyleSheet,
4
+ TouchableWithoutFeedback,
5
+ View,
6
+ ViewStyle,
7
+ } from "react-native";
8
+ import * as R from "ramda";
9
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
9
10
 
10
11
  import {
11
12
  Button,
@@ -16,14 +17,15 @@ import {
16
17
 
17
18
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
18
19
 
20
+ import {
21
+ AnimationComponent,
22
+ ComponentAnimationType,
23
+ PlayerAnimationStateEnum,
24
+ useModalAnimationContext,
25
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
19
26
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
20
27
  import { useSafeAreaInsets } from "react-native-safe-area-context";
21
28
  import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/getTabBarHeight";
22
- import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
- import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
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";
27
29
 
28
30
  const bottomTabBarHeight = getTabBarHeight();
29
31
 
@@ -32,15 +34,13 @@ type Props = {
32
34
  layoutState: QuickBrickPlayer.LayoutState;
33
35
  playerState: QuickBrickPlayer.PlayerState;
34
36
  value: GetValue;
37
+ dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
35
38
  onCloseVideoModal: () => void;
36
39
  onPlayerSeek: (targetTime: number) => void;
37
40
  playNextData: PlayNextData;
38
41
  title: string | number;
39
42
  summary: string | number;
40
43
  ImageComponent?: React.ReactNode;
41
- isActiveGesture?: boolean;
42
- minimisedHeight: number;
43
- aspectRatio?: number;
44
44
  };
45
45
 
46
46
  const styles = StyleSheet.create({
@@ -48,7 +48,6 @@ const styles = StyleSheet.create({
48
48
  flex: 1,
49
49
  flexDirection: "column",
50
50
  alignItems: "stretch",
51
- marginTop: PROGRESS_BAR_HEIGHT,
52
51
  },
53
52
  content: {
54
53
  flex: 1,
@@ -100,6 +99,26 @@ const playerDimensionsStyle = (
100
99
  width: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
101
100
  });
102
101
 
102
+ const animatedContainerStyle = (
103
+ docked: boolean,
104
+ progressBarHeight: number
105
+ ): ViewStyle => ({
106
+ top: progressBarHeight,
107
+ position: "absolute",
108
+ width: "100%",
109
+ zIndex: docked ? 1 : -1,
110
+ });
111
+
112
+ const backgroundImageStyle = (
113
+ dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"],
114
+ minimisedHeight: number,
115
+ isActiveGesture: boolean
116
+ ): ViewStyle => ({
117
+ height: isActiveGesture ? minimisedHeight : dimensions.height,
118
+ aspectRatio: 1,
119
+ position: "absolute",
120
+ });
121
+
103
122
  const controlButtons = (
104
123
  live: boolean,
105
124
  paused: boolean,
@@ -161,111 +180,107 @@ export const DockedControls = (props: Props) => {
161
180
  const {
162
181
  entry,
163
182
  layoutState,
164
- onPlayerSeek = noop,
183
+ playerState,
184
+ value,
185
+ dimensions,
186
+ onCloseVideoModal,
187
+ onPlayerSeek,
165
188
  playNextData,
189
+ title,
190
+ summary,
166
191
  ImageComponent,
167
- isActiveGesture = true,
168
- aspectRatio,
169
192
  } = props;
170
193
 
171
- const onCloseVideoModal = React.useCallback(() => {
172
- playerManager.close();
173
- }, []);
174
-
175
- const { minimised_height: minimisedHeight } = useConfiguration();
176
-
177
- const configuration = useZStore("playerConfiguration")();
178
- const playerState = usePlayerState("shared-player-wrapper-docked");
179
-
180
- const getValue = (key: string, stylesObj: {}) =>
181
- R.propOr(null, key, stylesObj);
182
-
183
- const value = React.useCallback(
184
- (key: string) => {
185
- const retVal = getValue(key, configuration);
186
-
187
- const minimumAllowedSeekableDurationInSeconds = getValue(
188
- "minimumAllowedSeekableDurationInSeconds",
189
- configuration
190
- );
194
+ const isTablet = useIsTablet();
191
195
 
192
- if (key === "liveSeekingEnabled") {
193
- return playerState.seekableDuration <
194
- minimumAllowedSeekableDurationInSeconds || playerManager.isCasting()
195
- ? false
196
- : retVal;
197
- }
196
+ const liveButton = Boolean(value("live_badge_enabled"));
198
197
 
199
- return retVal;
200
- },
201
- [...Object.values(configuration), playerState]
202
- );
198
+ const {
199
+ isActiveGesture,
200
+ setPlayerAnimationState,
201
+ startComponentsAnimation,
202
+ minimisedHeight,
203
+ progressBarHeight,
204
+ } = useModalAnimationContext();
203
205
 
204
- const { title, summary } = useTitleSummaryOverlay(
205
- entry,
206
- playerState?.isLive,
207
- configuration?.audio_live_player_update_interval
206
+ const maximazeVideoModal = React.useCallback(
207
+ () => setPlayerAnimationState(PlayerAnimationStateEnum.maximize),
208
+ []
208
209
  );
209
210
 
210
- const isTablet = useIsTablet();
211
-
212
- const liveButton = Boolean(value("live_badge_enabled"));
213
-
214
211
  const dockedBackgroundColor = value("docked_player_background_color");
215
212
 
216
213
  const insets = useSafeAreaInsets();
217
214
 
215
+ if (!layoutState.docked && !startComponentsAnimation) return null;
216
+
218
217
  return (
219
- <View
218
+ <AnimationComponent
219
+ animationType={ComponentAnimationType.componentAppears}
220
220
  style={[
221
221
  styles.container,
222
+ animatedContainerStyle(
223
+ isActiveGesture || layoutState.docked,
224
+ progressBarHeight
225
+ ),
222
226
  {
223
227
  height: minimisedHeight + bottomTabBarHeight + insets.bottom,
224
228
  },
225
229
  ]}
226
230
  >
227
- {!playerState.isLive ? (
231
+ {!playerState.isLive &&
232
+ (layoutState.docked || startComponentsAnimation) ? (
228
233
  <ProgressBar
229
- name={"shared-docked-layout"}
234
+ name={"audio-docked-layout"}
230
235
  content={entry}
231
236
  value={value}
232
237
  visible
233
238
  layoutState={layoutState}
234
239
  onPlayerSeek={onPlayerSeek}
235
240
  playerState={playerState}
236
- startComponentsAnimation={noop}
241
+ startComponentsAnimation={startComponentsAnimation}
237
242
  docked
238
243
  />
239
244
  ) : null}
240
245
 
241
246
  <View style={styles.content}>
242
- <View style={styles.touchableArea}>
243
- {isActiveGesture || layoutState.docked ? (
244
- <View style={{ aspectRatio: aspectRatio, height: minimisedHeight }}>
245
- {ImageComponent || null}
246
- </View>
247
- ) : (
248
- <View
249
- style={playerDimensionsStyle(
250
- minimisedHeight,
251
- isActiveGesture || layoutState.docked
252
- )}
253
- />
247
+ <View
248
+ style={backgroundImageStyle(
249
+ dimensions,
250
+ minimisedHeight,
251
+ isActiveGesture
254
252
  )}
255
- <View
256
- testID="content-info"
257
- style={[
258
- styles.contentInfo,
259
- { backgroundColor: dockedBackgroundColor },
260
- ]}
261
- >
262
- <ContentInfo
263
- content={{ ...entry, title, summary }}
264
- value={value}
265
- docked
266
- />
253
+ />
254
+ <TouchableWithoutFeedback onPress={maximazeVideoModal}>
255
+ <View style={styles.touchableArea}>
256
+ {isActiveGesture || layoutState.docked ? (
257
+ <View
258
+ style={{ width: toNumberWithDefault(100, minimisedHeight) }}
259
+ >
260
+ {ImageComponent || null}
261
+ </View>
262
+ ) : (
263
+ <View
264
+ style={playerDimensionsStyle(
265
+ minimisedHeight,
266
+ isActiveGesture || layoutState.docked
267
+ )}
268
+ />
269
+ )}
270
+ <View
271
+ style={[
272
+ styles.contentInfo,
273
+ { backgroundColor: dockedBackgroundColor },
274
+ ]}
275
+ >
276
+ <ContentInfo
277
+ content={{ ...entry, title, summary }}
278
+ value={value}
279
+ docked
280
+ />
281
+ </View>
267
282
  </View>
268
- </View>
283
+ </TouchableWithoutFeedback>
269
284
  <View
270
285
  style={[
271
286
  isTablet
@@ -299,6 +314,6 @@ export const DockedControls = (props: Props) => {
299
314
  backgroundColor: dockedBackgroundColor,
300
315
  }}
301
316
  />
302
- </View>
317
+ </AnimationComponent>
303
318
  );
304
319
  };
@@ -4,6 +4,7 @@ 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";
7
8
 
8
9
  import { MOBILE, NAVBAR_HEIGHT } from "./const";
9
10
  import { TransportInfo } from "./TransportInfo";
@@ -11,6 +12,7 @@ import { PlayerImage } from "./PlayerImage";
11
12
  import { Controls } from "./Controls";
12
13
 
13
14
  import { useMobileLayoutImageSize, useTransportInfoHeight } from "./hooks";
15
+ import { DockedControls } from "./DockedControls";
14
16
  import { DEBUG, withDebug } from "./debug";
15
17
  import {
16
18
  BottomDebugSquare,
@@ -54,7 +56,6 @@ const mobileStyles = ({
54
56
  imageSize,
55
57
  }): ViewStyle => ({
56
58
  height: screenHeight - topInset - bottomInset,
57
- width: "100%",
58
59
 
59
60
  opacity: imageSize ? 1 : 0, // hide content until imageSize is calculated
60
61
 
@@ -76,8 +77,11 @@ export function MobileLayout({
76
77
  onSkipStart,
77
78
  onSkipLive,
78
79
  onSpeedButtonPress,
80
+ onCloseVideoModal,
79
81
  playbackSpeedName,
80
82
  configuration,
83
+ dimensions,
84
+ playNextData,
81
85
  title,
82
86
  summary,
83
87
  }: Props) {
@@ -85,10 +89,12 @@ export function MobileLayout({
85
89
 
86
90
  const { bottom: bottomInset, top: topInset } = useSafeAreaInsets();
87
91
  const { height: screenHeight } = useSafeAreaFrame();
92
+ const { progressBarHeight } = useModalAnimationContext();
88
93
 
89
94
  const { imageSize } = useMobileLayoutImageSize();
90
95
 
91
- const { onLayout: onTransportInfoLayout } = useTransportInfoHeight();
96
+ const { height: transportInfoHeight, onLayout: onTransportInfoLayout } =
97
+ useTransportInfoHeight();
92
98
 
93
99
  const controlsContainerHeight = React.useMemo(() => {
94
100
  return (
@@ -102,6 +108,10 @@ export function MobileLayout({
102
108
  );
103
109
  }, [screenHeight, topInset, imageSize, bottomInset]);
104
110
 
111
+ const verticalOffsetForImage = React.useMemo(() => {
112
+ return transportInfoHeight + MOBILE.MARGIN_TOP - progressBarHeight;
113
+ }, [transportInfoHeight, progressBarHeight]);
114
+
105
115
  return (
106
116
  <View
107
117
  style={[
@@ -153,9 +163,19 @@ export function MobileLayout({
153
163
  >
154
164
  <PlayerImage
155
165
  entry={entry}
156
- docked={false}
157
- imageWidth={imageSize}
166
+ layoutState={layoutState}
167
+ playerState={playerState}
168
+ value={value}
158
169
  configuration={configuration}
170
+ onPlayerSeek={onPlayerSeek}
171
+ onCloseVideoModal={onCloseVideoModal}
172
+ dimensions={dimensions}
173
+ playNextData={playNextData}
174
+ title={title}
175
+ summary={summary}
176
+ docked={docked}
177
+ imageWidth={imageSize}
178
+ verticalOffset={verticalOffsetForImage}
159
179
  />
160
180
  </View>
161
181
  {/* PlayerImage */}
@@ -184,6 +204,19 @@ export function MobileLayout({
184
204
  />
185
205
  </View>
186
206
  </View>
207
+
208
+ <DockedControls
209
+ entry={entry}
210
+ layoutState={layoutState}
211
+ playerState={playerState}
212
+ value={value}
213
+ dimensions={dimensions}
214
+ onCloseVideoModal={onCloseVideoModal}
215
+ onPlayerSeek={onPlayerSeek}
216
+ playNextData={playNextData}
217
+ title={title}
218
+ summary={summary}
219
+ />
187
220
  </View>
188
221
  );
189
222
  }