@applicaster/quick-brick-player 13.0.8-alpha.4915596275 → 13.0.8-alpha.8384339831

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.8-alpha.4915596275",
3
+ "version": "13.0.8-alpha.8384339831",
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.8-alpha.4915596275",
39
- "@applicaster/quick-brick-tv-transport-controls": "13.0.8-alpha.4915596275",
40
- "@applicaster/zapp-react-native-tvos-app": "13.0.8-alpha.4915596275",
41
- "@applicaster/zapp-react-native-ui-components": "13.0.8-alpha.4915596275",
42
- "@applicaster/zapp-react-native-utils": "13.0.8-alpha.4915596275",
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.8-alpha.8384339831",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.8-alpha.8384339831",
42
+ "@applicaster/zapp-react-native-utils": "13.0.8-alpha.8384339831",
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,16 +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
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
22
28
  import { getTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/getTabBarHeight";
23
- import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
24
- import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
25
- import { useConfiguration } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/utils";
26
- import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
27
- 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";
29
29
 
30
30
  const bottomTabBarHeight = getTabBarHeight();
31
31
 
@@ -34,15 +34,13 @@ type Props = {
34
34
  layoutState: QuickBrickPlayer.LayoutState;
35
35
  playerState: QuickBrickPlayer.PlayerState;
36
36
  value: GetValue;
37
+ dimensions: QuickBrickPlayer.AudioPlayerProps["dimensions"];
37
38
  onCloseVideoModal: () => void;
38
39
  onPlayerSeek: (targetTime: number) => void;
39
40
  playNextData: PlayNextData;
40
41
  title: string | number;
41
42
  summary: string | number;
42
43
  ImageComponent?: React.ReactNode;
43
- isActiveGesture?: boolean;
44
- minimisedHeight: number;
45
- aspectRatio?: number;
46
44
  };
47
45
 
48
46
  const styles = StyleSheet.create({
@@ -50,7 +48,6 @@ const styles = StyleSheet.create({
50
48
  flex: 1,
51
49
  flexDirection: "column",
52
50
  alignItems: "stretch",
53
- marginTop: PROGRESS_BAR_HEIGHT,
54
51
  },
55
52
  content: {
56
53
  flex: 1,
@@ -102,6 +99,26 @@ const playerDimensionsStyle = (
102
99
  width: addPadding ? toNumberWithDefault(100, minimisedHeight) : 0,
103
100
  });
104
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
+
105
122
  const controlButtons = (
106
123
  live: boolean,
107
124
  paused: boolean,
@@ -163,118 +180,107 @@ export const DockedControls = (props: Props) => {
163
180
  const {
164
181
  entry,
165
182
  layoutState,
166
- onPlayerSeek = noop,
183
+ playerState,
184
+ value,
185
+ dimensions,
186
+ onCloseVideoModal,
187
+ onPlayerSeek,
167
188
  playNextData,
189
+ title,
190
+ summary,
168
191
  ImageComponent,
169
- isActiveGesture = true,
170
- aspectRatio,
171
192
  } = props;
172
193
 
173
- const onCloseVideoModal = React.useCallback(() => {
174
- playerManager.close();
175
- }, []);
176
-
177
- const { currentRoute, screenData } = useNavigation();
178
-
179
- const menuVisible = isMenuVisible(currentRoute, screenData);
180
-
181
- const { minimised_height: minimisedHeight } = useConfiguration();
182
-
183
- const configuration = useZStore("playerConfiguration")();
184
- const playerState = usePlayerState("shared-player-wrapper-docked");
185
-
186
- const getValue = (key: string, stylesObj: {}) =>
187
- R.propOr(null, key, stylesObj);
188
-
189
- const value = React.useCallback(
190
- (key: string) => {
191
- const retVal = getValue(key, configuration);
192
-
193
- const minimumAllowedSeekableDurationInSeconds = getValue(
194
- "minimumAllowedSeekableDurationInSeconds",
195
- configuration
196
- );
194
+ const isTablet = useIsTablet();
197
195
 
198
- if (key === "liveSeekingEnabled") {
199
- return playerState.seekableDuration <
200
- minimumAllowedSeekableDurationInSeconds || playerManager.isCasting()
201
- ? false
202
- : retVal;
203
- }
196
+ const liveButton = Boolean(value("live_badge_enabled"));
204
197
 
205
- return retVal;
206
- },
207
- [...Object.values(configuration), playerState]
208
- );
198
+ const {
199
+ isActiveGesture,
200
+ setPlayerAnimationState,
201
+ startComponentsAnimation,
202
+ minimisedHeight,
203
+ progressBarHeight,
204
+ } = useModalAnimationContext();
209
205
 
210
- const { title, summary } = useTitleSummaryOverlay(
211
- entry,
212
- playerState?.isLive,
213
- configuration?.audio_live_player_update_interval
206
+ const maximazeVideoModal = React.useCallback(
207
+ () => setPlayerAnimationState(PlayerAnimationStateEnum.maximize),
208
+ []
214
209
  );
215
210
 
216
- const isTablet = useIsTablet();
217
-
218
- const liveButton = Boolean(value("live_badge_enabled"));
219
-
220
211
  const dockedBackgroundColor = value("docked_player_background_color");
221
212
 
222
213
  const insets = useSafeAreaInsets();
223
214
 
215
+ if (!layoutState.docked && !startComponentsAnimation) return null;
216
+
224
217
  return (
225
- <View
218
+ <AnimationComponent
219
+ animationType={ComponentAnimationType.componentAppears}
226
220
  style={[
227
221
  styles.container,
222
+ animatedContainerStyle(
223
+ isActiveGesture || layoutState.docked,
224
+ progressBarHeight
225
+ ),
228
226
  {
229
- height:
230
- minimisedHeight +
231
- (menuVisible ? bottomTabBarHeight : 0) +
232
- insets.bottom,
227
+ height: minimisedHeight + bottomTabBarHeight + insets.bottom,
233
228
  },
234
229
  ]}
235
230
  >
236
- {!playerState.isLive ? (
231
+ {!playerState.isLive &&
232
+ (layoutState.docked || startComponentsAnimation) ? (
237
233
  <ProgressBar
238
- name={"shared-docked-layout"}
234
+ name={"audio-docked-layout"}
239
235
  content={entry}
240
236
  value={value}
241
237
  visible
242
238
  layoutState={layoutState}
243
239
  onPlayerSeek={onPlayerSeek}
244
240
  playerState={playerState}
245
- startComponentsAnimation={noop}
241
+ startComponentsAnimation={startComponentsAnimation}
246
242
  docked
247
243
  />
248
244
  ) : null}
249
245
 
250
246
  <View style={styles.content}>
251
- <View style={styles.touchableArea}>
252
- {isActiveGesture || layoutState.docked ? (
253
- <View style={{ aspectRatio: aspectRatio, height: minimisedHeight }}>
254
- {ImageComponent || null}
255
- </View>
256
- ) : (
257
- <View
258
- style={playerDimensionsStyle(
259
- minimisedHeight,
260
- isActiveGesture || layoutState.docked
261
- )}
262
- />
247
+ <View
248
+ style={backgroundImageStyle(
249
+ dimensions,
250
+ minimisedHeight,
251
+ isActiveGesture
263
252
  )}
264
- <View
265
- testID="content-info"
266
- style={[
267
- styles.contentInfo,
268
- { backgroundColor: dockedBackgroundColor },
269
- ]}
270
- >
271
- <ContentInfo
272
- content={{ ...entry, title, summary }}
273
- value={value}
274
- docked
275
- />
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>
276
282
  </View>
277
- </View>
283
+ </TouchableWithoutFeedback>
278
284
  <View
279
285
  style={[
280
286
  isTablet
@@ -304,10 +310,10 @@ export const DockedControls = (props: Props) => {
304
310
  </View>
305
311
  <View
306
312
  style={{
307
- height: insets.bottom + (menuVisible ? bottomTabBarHeight : 0),
313
+ height: insets.bottom + bottomTabBarHeight,
308
314
  backgroundColor: dockedBackgroundColor,
309
315
  }}
310
316
  />
311
- </View>
317
+ </AnimationComponent>
312
318
  );
313
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
  }