@applicaster/quick-brick-player 13.0.0-alpha.7223526501 → 13.0.0-alpha.7586259907

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,11 +1,10 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "13.0.0-alpha.7223526501",
3
+ "version": "13.0.0-alpha.7586259907",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
7
7
  "scripts": {
8
- "test": "jest -w=2",
9
8
  "build": "echo 'skipping ts build for core packages'"
10
9
  },
11
10
  "files": [
@@ -36,11 +35,11 @@
36
35
  },
37
36
  "homepage": "https://github.com/applicaster/quickbrick#readme",
38
37
  "dependencies": {
39
- "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.7223526501",
40
- "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.46",
41
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.7223526501",
42
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.7223526501",
43
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7223526501",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-rc.88",
39
+ "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.7586259907",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.7586259907",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7586259907",
44
43
  "keymirror": "^0.1.1",
45
44
  "query-string": "7.1.3",
46
45
  "react-native-web-linear-gradient": "1.1.2",
@@ -61,11 +60,8 @@
61
60
  "@applicaster/zapp-react-native-tvos-ui-components": "*",
62
61
  "@babel/runtime": "*",
63
62
  "@react-native-community/netinfo": "*",
64
- "@types/node": "*",
65
- "@types/react-native": "0.69.6",
66
63
  "immer": "*",
67
64
  "react": "*",
68
- "react-hot-loader": "*",
69
65
  "react-native": "*",
70
66
  "react-native-fs": "*",
71
67
  "react-native-gesture-handler": "*",
@@ -41,6 +41,7 @@ import {
41
41
  } from "./SleepTimerManager";
42
42
  import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
43
43
  import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
44
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
44
45
 
45
46
  const { log_debug } = createLogger({
46
47
  subsystem: "UIComponent",
@@ -58,6 +59,7 @@ type Configuration = {
58
59
  [key: string]: any;
59
60
  magic_background?: boolean;
60
61
  audio_player_background_image_query?: string;
62
+ audio_player_background_image_default_color?: string;
61
63
  tablet_landscape_sidebar_width?: string;
62
64
  tablet_landscape_player_container_background_color?: string;
63
65
  };
@@ -127,9 +129,12 @@ const sleeps = [
127
129
  { label: "2 hours", value: 120 },
128
130
  ];
129
131
 
132
+ const edges: Edge[] = ["right", "left", "top"];
133
+
130
134
  export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
131
135
  const player = usePlayer();
132
136
  const playerState = usePlayerState("audio-player-wrapper");
137
+ const theme = useTheme();
133
138
 
134
139
  const {
135
140
  docked,
@@ -359,8 +364,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
359
364
  player?.seekTo(0);
360
365
  }, [player]);
361
366
 
362
- const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
363
-
364
367
  const ContainerView = SafeAreaView;
365
368
 
366
369
  const MainContent = React.useMemo(() => {
@@ -451,16 +454,21 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
451
454
  const queryParamName =
452
455
  configuration.audio_player_background_image_query || "width";
453
456
 
457
+ const defaultBackgroundColor =
458
+ configuration.audio_player_background_image_default_color ||
459
+ theme?.app_background_color;
460
+
454
461
  const queryParamValue = 15;
455
462
 
456
- const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
463
+ const url =
464
+ baseUrl && addQueryParam(baseUrl, queryParamName, queryParamValue);
457
465
 
458
466
  return (
459
467
  <MagicBG
460
468
  image={url}
461
469
  fallbackUrl={baseUrl}
462
470
  colors={entry?.extensions?.backgroundColors}
463
- defaultColor="#000000"
471
+ defaultColor={defaultBackgroundColor}
464
472
  >
465
473
  {MainContent}
466
474
  </MagicBG>
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { useEffect, useMemo, useState } from "react";
3
3
  import * as R from "ramda";
4
- import { View } from "react-native";
4
+ import { View, Dimensions as ScreenDimensions } from "react-native";
5
5
  import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
6
6
 
7
7
  import {
@@ -33,8 +33,13 @@ import {
33
33
  ComponentAnimationType,
34
34
  useModalAnimationContext,
35
35
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
36
+ import { PlayerAnimationStateT } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/ModalAnimationContext";
36
37
  import DockedLayout from "./DockedLayout";
37
38
  import { isValidDate } from "../../Utils";
39
+ import { calculateBorderRadius } from "../utils";
40
+
41
+ const getAudioPlayerWidthForTablet = (isPortraitMode: boolean) =>
42
+ isPortraitMode ? 463 : 350;
38
43
 
39
44
  type Dimensions = {
40
45
  width: number;
@@ -79,6 +84,9 @@ type LayoutProps = {
79
84
  defaultDimensions: Dimensions;
80
85
  };
81
86
 
87
+ const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } =
88
+ ScreenDimensions.get("screen");
89
+
82
90
  const Styles = {
83
91
  container: { flex: 1 },
84
92
  tabletContainer: (isPortraitMode: boolean) => ({
@@ -86,42 +94,63 @@ const Styles = {
86
94
  alignItems: "center",
87
95
  justifyContent: isPortraitMode ? "center" : "flex-start",
88
96
  }),
89
- playerImageWrapper: {
97
+ playerImageWrapper: (docked: boolean) => ({
90
98
  width: "100%",
91
99
  maxHeight: 750,
92
- marginTop: 80,
100
+ marginTop: docked ? 80 : 20,
101
+ }),
102
+ playerInfoWrapper: {
103
+ flex: 1,
104
+ alignItems: "center",
105
+ justifyContent: "space-between",
93
106
  },
94
- tabletLayout: {
95
- width: 463,
107
+ tabletLayout: (isPortraitMode: boolean) => ({
108
+ width: getAudioPlayerWidthForTablet(isPortraitMode),
96
109
  marginBottom: 80,
97
- },
110
+ paddingHorizontal: undefined, // override paddingHorizontal
111
+ }),
98
112
  controls: (isTablet: boolean, isLiveShowFullControls: boolean) => ({
99
113
  height: isTablet ? 64 : 50,
100
- marginHorizontal: 10,
114
+ marginHorizontal: isTablet ? undefined : 10,
101
115
  justifyContent: isLiveShowFullControls ? "space-between" : "space-evenly",
102
116
  }),
103
- backgroundImageContainer: (dimensions: Dimensions, isTablet: boolean) => {
104
- const mobileValue = dimensions.width
117
+ backgroundImageContainer: (
118
+ dimensions: Dimensions,
119
+ isTablet: boolean,
120
+ isPortraitMode: boolean
121
+ ) => {
122
+ if (isTablet) {
123
+ const size = getAudioPlayerWidthForTablet(isPortraitMode);
124
+
125
+ return {
126
+ width: size,
127
+ height: size,
128
+ };
129
+ }
130
+
131
+ const mobileValue = dimensions?.width
105
132
  ? dimensions.width - PADDING_HORIZONTAL * 2
106
- : 330;
133
+ : SCREEN_WIDTH - PADDING_HORIZONTAL * 2;
107
134
 
108
135
  return {
109
- width: isTablet ? 463 : mobileValue,
110
- height: isTablet ? 463 : mobileValue,
136
+ width: mobileValue,
137
+ height: mobileValue,
111
138
  };
112
139
  },
113
140
  backgroundImageContainerImageStyle: (
114
141
  isTablet: boolean,
115
142
  docked: boolean,
116
143
  startComponentsAnimation: boolean,
117
- isActiveGesture: boolean
144
+ isActiveGesture: boolean,
145
+ playerAnimationState: PlayerAnimationStateT
118
146
  ) => ({
119
- borderRadius:
120
- (startComponentsAnimation && isActiveGesture) || docked
121
- ? 0
122
- : isTablet
123
- ? 24
124
- : 10,
147
+ borderRadius: calculateBorderRadius(
148
+ isTablet,
149
+ docked,
150
+ startComponentsAnimation,
151
+ isActiveGesture,
152
+ playerAnimationState
153
+ ),
125
154
  }),
126
155
 
127
156
  paddingHorizontal: {
@@ -173,8 +202,7 @@ export default function DefaultLayout(props: LayoutProps) {
173
202
  } = props;
174
203
 
175
204
  const isTablet = useIsTablet();
176
- const { width, height } = dimensions;
177
- const isPortraitMode = width < height;
205
+ const isPortraitMode = SCREEN_WIDTH < SCREEN_HEIGHT;
178
206
  const isLiveContent = playerState.isLive;
179
207
  const docked = layoutState.docked;
180
208
 
@@ -330,12 +358,15 @@ export default function DefaultLayout(props: LayoutProps) {
330
358
 
331
359
  const defaultImageDimensions = React.useMemo(
332
360
  () =>
333
- defaultDimensions &&
334
- Styles.backgroundImageContainer(defaultDimensions, isTablet),
335
- [defaultDimensions, isTablet]
361
+ Styles.backgroundImageContainer(
362
+ defaultDimensions,
363
+ isTablet,
364
+ isPortraitMode
365
+ ),
366
+ [defaultDimensions, isTablet, isPortraitMode]
336
367
  );
337
368
 
338
- const { isActiveGesture, startComponentsAnimation } =
369
+ const { isActiveGesture, startComponentsAnimation, playerAnimationState } =
339
370
  useModalAnimationContext();
340
371
 
341
372
  return (
@@ -344,7 +375,10 @@ export default function DefaultLayout(props: LayoutProps) {
344
375
  isTablet ? Styles.tabletContainer(isPortraitMode) : Styles.container
345
376
  }
346
377
  >
347
- <AnimationComponent animationType={ComponentAnimationType.componentFade}>
378
+ <AnimationComponent
379
+ animationType={ComponentAnimationType.componentFade}
380
+ style={isTablet ? Styles.playerInfoWrapper : undefined}
381
+ >
348
382
  <TransportInfo
349
383
  content={entry}
350
384
  value={value}
@@ -356,13 +390,16 @@ export default function DefaultLayout(props: LayoutProps) {
356
390
  </AnimationComponent>
357
391
  <AnimationComponent
358
392
  animationType={ComponentAnimationType.moveUpComponent}
359
- style={isTablet ? Styles.playerImageWrapper : undefined}
393
+ style={isTablet ? Styles.playerImageWrapper(docked) : undefined}
360
394
  >
361
395
  <AnimationComponent
362
396
  animationType={ComponentAnimationType.moveComponentHorizontal}
363
397
  additionalData={{
364
398
  disableAnimatedComponent: !isTablet,
365
- moveValue: (dimensions.width - 463) / 2,
399
+ moveValue:
400
+ (dimensions.width -
401
+ getAudioPlayerWidthForTablet(isPortraitMode)) /
402
+ 2,
366
403
  extraAnimation: !isTablet
367
404
  ? {
368
405
  [ComponentAnimationType.audioPlayerPaddingHorizontal]: {
@@ -375,13 +412,17 @@ export default function DefaultLayout(props: LayoutProps) {
375
412
  >
376
413
  <PlayerImageBackground
377
414
  entry={entry}
378
- docked={docked}
379
- style={Styles.backgroundImageContainer(dimensions, isTablet)}
415
+ style={Styles.backgroundImageContainer(
416
+ dimensions,
417
+ isTablet,
418
+ isPortraitMode
419
+ )}
380
420
  imageStyle={Styles.backgroundImageContainerImageStyle(
381
421
  isTablet,
382
422
  docked,
383
423
  startComponentsAnimation,
384
- isActiveGesture
424
+ isActiveGesture,
425
+ playerAnimationState
385
426
  )}
386
427
  defaultImageDimensions={defaultImageDimensions}
387
428
  />
@@ -392,7 +433,7 @@ export default function DefaultLayout(props: LayoutProps) {
392
433
  <View
393
434
  style={[
394
435
  Styles.paddingHorizontal,
395
- isTablet ? Styles.tabletLayout : undefined,
436
+ isTablet ? Styles.tabletLayout(isPortraitMode) : undefined,
396
437
  ]}
397
438
  >
398
439
  {!docked && (
@@ -409,6 +450,7 @@ export default function DefaultLayout(props: LayoutProps) {
409
450
  {needsToShowProgressBar ? (
410
451
  <View>
411
452
  <ProgressBar
453
+ name={"audio-default-layout"}
412
454
  content={entry}
413
455
  value={value}
414
456
  visible={true}
@@ -19,6 +19,7 @@ import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Compo
19
19
  import {
20
20
  AnimationComponent,
21
21
  ComponentAnimationType,
22
+ defaultAspectRatioWidth,
22
23
  PlayerAnimationStateEnum,
23
24
  useModalAnimationContext,
24
25
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
@@ -113,7 +114,7 @@ const playerDimensionsStyle = (
113
114
  minimisedHeight: number,
114
115
  addPadding: boolean
115
116
  ): ViewStyle => ({
116
- paddingLeft: addPadding ? minimisedHeight || 100 : 0,
117
+ paddingLeft: addPadding ? defaultAspectRatioWidth(minimisedHeight) || 100 : 0,
117
118
  });
118
119
 
119
120
  const animatedContainerStyle = (docked: boolean): ViewStyle => ({
@@ -133,24 +134,11 @@ const backgroundImageStyle = (
133
134
  });
134
135
 
135
136
  const controlButtons = (
136
- isPlayNextEnabled: boolean,
137
137
  live: boolean,
138
138
  paused: boolean,
139
139
  buffering: boolean,
140
140
  playerId: string
141
141
  ): Array<ControlsButton> => {
142
- if (isPlayNextEnabled) {
143
- return [
144
- {
145
- size: "medium",
146
- name: "play_next",
147
- icon: "play_next",
148
- preferredFocus: true,
149
- style: styles.buttons,
150
- },
151
- ];
152
- }
153
-
154
142
  if (buffering) {
155
143
  return [
156
144
  {
@@ -230,7 +218,7 @@ export default function DockedLayout(props: LayoutProps) {
230
218
  } = useModalAnimationContext();
231
219
 
232
220
  const maximazeVideoModal = React.useCallback(
233
- () => setPlayerAnimationState(PlayerAnimationStateEnum.maximaze),
221
+ () => setPlayerAnimationState(PlayerAnimationStateEnum.maximize),
234
222
  []
235
223
  );
236
224
 
@@ -247,6 +235,7 @@ export default function DockedLayout(props: LayoutProps) {
247
235
  {!playerState.isLive &&
248
236
  (layoutState.docked || startComponentsAnimation) ? (
249
237
  <ProgressBar
238
+ name={"audio-docked-layout"}
250
239
  content={entry}
251
240
  value={value}
252
241
  visible={visible}
@@ -302,7 +291,6 @@ export default function DockedLayout(props: LayoutProps) {
302
291
  value={value}
303
292
  visible={visible}
304
293
  buttons={R.partial(controlButtons, [
305
- playNextData,
306
294
  playerState.isLive && liveButton,
307
295
  ])}
308
296
  style={styles.playPauseButton}
@@ -17,7 +17,7 @@ const playbackButtonMargins = (
17
17
  isTablet: boolean,
18
18
  isLiveShowFullControls: boolean
19
19
  ): number =>
20
- isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? 95 : 40;
20
+ isLiveShowFullControls ? (isTablet ? 65 : 10) : isTablet ? undefined : 40;
21
21
 
22
22
  export const PADDING_HORIZONTAL = 15;
23
23
 
@@ -47,7 +47,7 @@ const fetchPaletteAndDominantColor = async (imageUrl: string) => {
47
47
  const dominant = await getDominantColor(imageUrl);
48
48
  const dominantColor = `rgb(${dominant.r}, ${dominant.g}, ${dominant.b})`;
49
49
 
50
- return { gradientColors: colors.slice(0, 2), dominantColor };
50
+ return { gradientColors: colors.slice(0, 2).reverse(), dominantColor };
51
51
  };
52
52
 
53
53
  export const MagicBG: React.FC<MagicBGProps> = ({
@@ -1,4 +1,8 @@
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
  import { parseJsonIfNeeded } from "@applicaster/zapp-react-native-utils/functionUtils";
3
7
 
4
8
  export const NAMESPACE = "audio-player";
@@ -31,3 +35,23 @@ export const formatSpeed = (value: number) => {
31
35
  // Return the formatted string with "speed_" prefix
32
36
  return `speed_${formattedValue}`;
33
37
  };
38
+
39
+ export const calculateBorderRadius = (
40
+ isTablet: boolean,
41
+ docked: boolean,
42
+ startComponentsAnimation: boolean,
43
+ isActiveGesture: boolean,
44
+ playerAnimationState: PlayerAnimationStateT
45
+ ): number => {
46
+ const shouldRemoveBorderRadius =
47
+ (startComponentsAnimation &&
48
+ isActiveGesture &&
49
+ playerAnimationState !== PlayerAnimationStateEnum.maximize) ||
50
+ docked;
51
+
52
+ if (shouldRemoveBorderRadius) {
53
+ return 0;
54
+ }
55
+
56
+ return isTablet ? 24 : 10;
57
+ };
@@ -721,7 +721,7 @@ export default class VideoPlayer extends React.Component<
721
721
 
722
722
  const isAudioItem =
723
723
  entry?.content?.type?.includes?.("audio") ||
724
- entry?.type?.value === "audio";
724
+ entry?.type?.value?.includes?.("audio");
725
725
 
726
726
  const getStyle = (dimensions) => {
727
727
  const generalStyles = isAudioItem ? styles.audio : styles.video;
@@ -791,8 +791,13 @@ export default class VideoPlayer extends React.Component<
791
791
  controls: shouldUseNativeControls,
792
792
  };
793
793
 
794
+ const isFullScreenAudioPlayer =
795
+ this.getPluginConfiguration()?.["full_screen_audio_player"] || false;
796
+
797
+ const isAudioPlayer = isFullScreenAudioPlayer && isAudioItem;
798
+
794
799
  const pictureInPictureEnabled =
795
- this.props.pluginConfiguration?.pictureInPictureEnabled;
800
+ this.props.pluginConfiguration?.pictureInPictureEnabled && !isAudioPlayer;
796
801
 
797
802
  const nativeProps = {
798
803
  entry, // Must be passed first in list
@@ -966,9 +971,6 @@ export default class VideoPlayer extends React.Component<
966
971
  ) : null;
967
972
  };
968
973
 
969
- const isFullScreenAudioPlayer =
970
- this.getPluginConfiguration()?.["full_screen_audio_player"] || false;
971
-
972
974
  const sharedWrapperViewProps = {
973
975
  style,
974
976
  entry,
@@ -995,7 +997,8 @@ export default class VideoPlayer extends React.Component<
995
997
 
996
998
  const renderMobilePlayer = () => {
997
999
  return isFullScreenAudioPlayer && isAudioItem ? (
998
- <View style={containerStyle}>
1000
+ // Ensure the View remains in the native hierarchy for proper rendering and interaction
1001
+ <View collapsable={false} style={containerStyle}>
999
1002
  {!castAction?.state?.connected || supportNativeCast ? (
1000
1003
  <this.props.PlayerComponent
1001
1004
  ref={this._assignRoot}