@applicaster/quick-brick-player 13.0.0-alpha.6179233127 → 13.0.0-alpha.6400875052

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.6179233127",
3
+ "version": "13.0.0-alpha.6400875052",
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-rc.66",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-rc.88",
40
39
  "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
41
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.6179233127",
42
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.6179233127",
43
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.6179233127",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.6400875052",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.6400875052",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.6400875052",
44
43
  "keymirror": "^0.1.1",
45
44
  "query-string": "7.1.3",
46
45
  "react-native-web-linear-gradient": "1.1.2",
@@ -1,5 +1,10 @@
1
1
  import * as React from "react";
2
- import { ViewStyle, View, Dimensions as ScreenDimensions } from "react-native";
2
+ import {
3
+ StyleSheet,
4
+ ViewStyle,
5
+ View,
6
+ Dimensions as ScreenDimensions,
7
+ } from "react-native";
3
8
 
4
9
  import { SafeAreaView, Edge } from "react-native-safe-area-context";
5
10
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
@@ -18,7 +23,15 @@ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
18
23
  import { useEffect, useState } from "react";
19
24
  import { MagicBG } from "./MagicBG";
20
25
  import { formatSpeed } from "./utils";
21
- import { addQueryParam, getLiveUrl } from "../Utils";
26
+ import {
27
+ addQueryParam,
28
+ getBottomSheetModalDefaultItemIcon,
29
+ getBottomSheetModalIconProps,
30
+ getBottomSheetModalItemProps,
31
+ getBottomSheetModalLabelProps,
32
+ getBottomSheetModalSelectedItemIcon,
33
+ getLiveUrl,
34
+ } from "../Utils";
22
35
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
36
  import {
24
37
  AnimationComponent,
@@ -27,13 +40,6 @@ import {
27
40
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
28
41
  import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
29
42
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
30
- import {
31
- speed_0_8,
32
- speed_1,
33
- speed_1_2,
34
- speed_1_5,
35
- speed_2,
36
- } from "@applicaster/quick-brick-mobile-transport-controls";
37
43
  import {
38
44
  SleepTimerController,
39
45
  SleepTimerState,
@@ -42,6 +48,9 @@ import {
42
48
  import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
43
49
  import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
44
50
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
51
+ import { openBottomSheetModal } from "@applicaster/zapp-react-native-utils/modalState";
52
+ import { sleepTimerOptions } from "../Const/sleepTimerOptions";
53
+ import { speedOptions } from "../Const/speedOptions";
45
54
 
46
55
  const { log_debug } = createLogger({
47
56
  subsystem: "UIComponent",
@@ -83,51 +92,17 @@ type Props = {
83
92
 
84
93
  const { width: SCREEN_WIDTH } = ScreenDimensions.get("screen");
85
94
 
86
- const Styles = {
87
- mainContainer: (style: ViewStyle) => {
88
- const combinedStyle: ViewStyle = {
89
- flex: 1,
90
- };
91
-
92
- return {
93
- ...combinedStyle,
94
- ...style,
95
- };
96
- },
95
+ const Styles = StyleSheet.create({
97
96
  playerContainer: {
98
97
  flex: 1,
99
98
  },
100
99
  paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
101
-
102
- controlsMobile: {
103
- height: 50,
104
- marginHorizontal: 24,
105
- },
106
- controlsTablet: {
107
- height: 96,
108
- marginHorizontal: 24,
109
- },
110
100
  playerDetails: {
111
101
  marginTop: 60,
112
102
  alignSelf: "center",
113
103
  width: SCREEN_WIDTH - PADDING_HORIZONTAL * 2,
114
104
  },
115
-
116
- linearGradient: {
117
- flex: 1,
118
- },
119
- };
120
-
121
- const sleeps = [
122
- // { label: "End of episode", value: "episode" },
123
- { label: "5 minutes", value: 5 },
124
- { label: "10 minutes", value: 10 },
125
- { label: "15 minutes", value: 15 },
126
- { label: "30 minutes", value: 30 },
127
- { label: "45 minutes", value: 45 },
128
- { label: "1 hour", value: 60 },
129
- { label: "2 hours", value: 120 },
130
- ];
105
+ });
131
106
 
132
107
  const edges: Edge[] = ["right", "left", "top"];
133
108
 
@@ -147,14 +122,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
147
122
  isTabletPortrait,
148
123
  } = props;
149
124
 
150
- const speeds = [
151
- { asset: configuration["speed_0_8"] || speed_0_8, value: 0.8 },
152
- { asset: configuration["speed_1"] || speed_1, value: 1.0 },
153
- { asset: configuration["speed_1_2"] || speed_1_2, value: 1.2 },
154
- { asset: configuration["speed_1_5"] || speed_1_5, value: 1.5 },
155
- { asset: configuration["speed_2"] || speed_2, value: 2.0 },
156
- ];
157
-
158
125
  const isTablet = useIsTablet();
159
126
 
160
127
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
@@ -202,8 +169,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
202
169
  height: 0,
203
170
  });
204
171
 
205
- const navigator = useNavigation();
206
-
207
172
  const { maximiseVideoModal } = useNavigation();
208
173
 
209
174
  const onLayout = (event: any) => {
@@ -293,44 +258,48 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
293
258
  );
294
259
 
295
260
  const onSpeedButtonPress = React.useCallback(() => {
296
- navigator.openModalBottomSheet({
261
+ openBottomSheetModal({
297
262
  modalBottomSheetContentProps: {
298
- items: speeds,
263
+ items: speedOptions,
299
264
  current_selection: playbackSpeed,
300
265
  onPress: onSpeedSelect,
301
266
  title: configuration["playback_speed_title"],
267
+ itemProps: getBottomSheetModalItemProps,
268
+ iconProps: getBottomSheetModalIconProps,
269
+ labelProps: getBottomSheetModalLabelProps,
270
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
271
+ getDefaultItemIcon: getBottomSheetModalDefaultItemIcon,
272
+ iconPlacement: "right",
302
273
  },
303
274
  options: {
304
275
  supportedOrientations: ["portrait"],
305
276
  },
306
277
  });
307
- }, [
308
- playbackSpeed,
309
- setPlaybackSpeed,
310
- navigator,
311
- onSpeedSelect,
312
- configuration["playback_speed_title"],
313
- ]);
278
+ }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
314
279
 
315
280
  const onSleepButtonPress = React.useCallback(() => {
316
- navigator.openModalBottomSheet({
281
+ openBottomSheetModal({
317
282
  modalBottomSheetContentProps: {
318
283
  items: [
319
284
  {
320
285
  label: configuration["playback_sleep_off_label"],
321
286
  value: 0,
322
287
  },
323
- ].concat(sleeps),
288
+ ].concat(sleepTimerOptions),
324
289
  current_selection: sleepTimerState.timer,
325
290
  onPress: onSleepSelect,
326
291
  title: configuration["playback_sleep_title"],
292
+ itemProps: getBottomSheetModalItemProps,
293
+ iconProps: getBottomSheetModalIconProps,
294
+ labelProps: getBottomSheetModalLabelProps,
295
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
296
+ iconPlacement: "right",
327
297
  },
328
298
  options: {
329
299
  supportedOrientations: ["portrait"],
330
300
  },
331
301
  });
332
302
  }, [
333
- navigator,
334
303
  sleepTimerState.timer,
335
304
  configuration["playback_sleep_title"],
336
305
  configuration["playback_sleep_off_label"],
@@ -368,7 +337,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
368
337
 
369
338
  const MainContent = React.useMemo(() => {
370
339
  return (
371
- <ContainerView style={Styles.mainContainer(style)} edges={edges}>
340
+ <ContainerView style={[style, Styles.playerContainer]} edges={edges}>
372
341
  <AnimationComponent
373
342
  animationType={ComponentAnimationType.moveUpComponent}
374
343
  additionalData={{ saveArea: true }}
@@ -412,11 +381,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
412
381
  animationType={ComponentAnimationType.componentFade}
413
382
  >
414
383
  <PlayerDetails
384
+ isAudioPlayer
415
385
  configuration={configuration}
416
386
  style={Styles.playerDetails}
417
387
  entry={entry}
418
388
  isTabletLandscape={isTabletLandscape}
419
- isAudioPlayer={true}
420
389
  />
421
390
  </AnimationComponent>
422
391
  </View>
@@ -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
  {
@@ -303,7 +291,6 @@ export default function DockedLayout(props: LayoutProps) {
303
291
  value={value}
304
292
  visible={visible}
305
293
  buttons={R.partial(controlButtons, [
306
- playNextData,
307
294
  playerState.isLive && liveButton,
308
295
  ])}
309
296
  style={styles.playPauseButton}
@@ -0,0 +1,10 @@
1
+ export const sleepTimerOptions = [
2
+ // { label: "End of episode", value: "episode" },
3
+ { label: "5 minutes", value: 5 },
4
+ { label: "10 minutes", value: 10 },
5
+ { label: "15 minutes", value: 15 },
6
+ { label: "30 minutes", value: 30 },
7
+ { label: "45 minutes", value: 45 },
8
+ { label: "1 hour", value: 60 },
9
+ { label: "2 hours", value: 120 },
10
+ ];
@@ -0,0 +1,4 @@
1
+ export const speedOptions = [0.8, 1, 1.2, 1.5, 2].map((v) => ({
2
+ label: v + "x",
3
+ value: v,
4
+ }));
@@ -1 +1,118 @@
1
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
2
+
1
3
  export * from "./Utils";
4
+
5
+ export const getBottomSheetModalIconProps = (theme) => ({
6
+ height: theme["audio_modal_bottom_sheet_item_icon_height"],
7
+ width: theme["audio_modal_bottom_sheet_item_icon_width"],
8
+ marginBottom: theme["audio_modal_bottom_sheet_item_icon_margin_bottom"],
9
+ marginLeft: theme["audio_modal_bottom_sheet_item_icon_margin_left"],
10
+ marginRight: theme["audio_modal_bottom_sheet_item_icon_margin_right"],
11
+ marginTop: theme["audio_modal_bottom_sheet_item_icon_margin_top"],
12
+ flavour: theme["modal_bottom_sheet_item_icon_flavour"],
13
+ });
14
+
15
+ export const getBottomSheetModalLabelProps = (theme, width: number) => {
16
+ const {
17
+ audio_modal_bottom_sheet_item_label_android_letter_spacing,
18
+ audio_modal_bottom_sheet_item_label_ios_letter_spacing,
19
+ audio_modal_bottom_sheet_item_label_family_ios_font_selector,
20
+ audio_modal_bottom_sheet_item_label_family_android_font_selector,
21
+ audio_modal_bottom_sheet_item_label_focus_font_color,
22
+ audio_modal_bottom_sheet_item_label_font_color,
23
+ audio_modal_bottom_sheet_item_label_selected_font_color,
24
+ audio_modal_bottom_sheet_item_label_hover_selected_font_color,
25
+ audio_modal_bottom_sheet_item_label_font_size,
26
+ audio_modal_bottom_sheet_item_label_line_height,
27
+ audio_modal_bottom_sheet_item_label_margin_bottom,
28
+ audio_modal_bottom_sheet_item_label_margin_top,
29
+ audio_modal_bottom_sheet_item_label_margin_left,
30
+ audio_modal_bottom_sheet_item_label_margin_right,
31
+ audio_modal_bottom_sheet_item_label_transform,
32
+ audio_modal_bottom_sheet_item_icon_width,
33
+ audio_modal_bottom_sheet_item_icon_margin_left,
34
+ audio_modal_bottom_sheet_item_icon_margin_right,
35
+ audio_modal_bottom_sheet_item_margin_left,
36
+ audio_modal_bottom_sheet_item_margin_right,
37
+ audio_modal_bottom_sheet_item_padding_left,
38
+ audio_modal_bottom_sheet_item_padding_right,
39
+ } = theme;
40
+
41
+ const maxWidth =
42
+ width -
43
+ (audio_modal_bottom_sheet_item_icon_width +
44
+ audio_modal_bottom_sheet_item_icon_margin_left +
45
+ audio_modal_bottom_sheet_item_icon_margin_right +
46
+ audio_modal_bottom_sheet_item_margin_left +
47
+ audio_modal_bottom_sheet_item_margin_right +
48
+ audio_modal_bottom_sheet_item_padding_left +
49
+ audio_modal_bottom_sheet_item_padding_right);
50
+
51
+ return {
52
+ fontFamily: platformSelect({
53
+ ios: audio_modal_bottom_sheet_item_label_family_ios_font_selector,
54
+ android: audio_modal_bottom_sheet_item_label_family_android_font_selector,
55
+ }),
56
+ letterSpacing: platformSelect({
57
+ ios: audio_modal_bottom_sheet_item_label_ios_letter_spacing,
58
+ android: audio_modal_bottom_sheet_item_label_android_letter_spacing,
59
+ }),
60
+ fontSize: audio_modal_bottom_sheet_item_label_font_size,
61
+ color: audio_modal_bottom_sheet_item_label_font_color,
62
+ focusColor: audio_modal_bottom_sheet_item_label_focus_font_color,
63
+ hoverSelectedColor:
64
+ audio_modal_bottom_sheet_item_label_hover_selected_font_color,
65
+ selectedColor: audio_modal_bottom_sheet_item_label_selected_font_color,
66
+ lineHeight: audio_modal_bottom_sheet_item_label_line_height,
67
+ marginBottom: audio_modal_bottom_sheet_item_label_margin_bottom,
68
+ marginTop: audio_modal_bottom_sheet_item_label_margin_top,
69
+ marginLeft: audio_modal_bottom_sheet_item_label_margin_left,
70
+ marginRight: audio_modal_bottom_sheet_item_label_margin_right,
71
+ transform: audio_modal_bottom_sheet_item_label_transform,
72
+ maxWidth,
73
+ };
74
+ };
75
+
76
+ export const getBottomSheetModalItemProps = (theme, width: number) => {
77
+ const {
78
+ audio_modal_bottom_sheet_item_background_color,
79
+ audio_modal_bottom_sheet_item_focus_background_color,
80
+ audio_modal_bottom_sheet_item_selected_background_color,
81
+ audio_modal_bottom_sheet_item_focusected_background_color,
82
+ audio_modal_bottom_sheet_item_corner_radius,
83
+ audio_modal_bottom_sheet_item_margin_bottom,
84
+ audio_modal_bottom_sheet_item_margin_left,
85
+ audio_modal_bottom_sheet_item_margin_right,
86
+ audio_modal_bottom_sheet_item_margin_top,
87
+ audio_modal_bottom_sheet_item_padding_bottom,
88
+ audio_modal_bottom_sheet_item_padding_left,
89
+ audio_modal_bottom_sheet_item_padding_right,
90
+ audio_modal_bottom_sheet_item_padding_top,
91
+ } = theme;
92
+
93
+ return {
94
+ backgroundColor: audio_modal_bottom_sheet_item_background_color,
95
+ focusedBackgroundColor:
96
+ audio_modal_bottom_sheet_item_focus_background_color,
97
+ selectedBackgroundColor:
98
+ audio_modal_bottom_sheet_item_selected_background_color,
99
+ focusectedBackgroundColor:
100
+ audio_modal_bottom_sheet_item_focusected_background_color,
101
+ borderRadius: audio_modal_bottom_sheet_item_corner_radius,
102
+ marginBottom: audio_modal_bottom_sheet_item_margin_bottom,
103
+ marginTop: audio_modal_bottom_sheet_item_margin_top,
104
+ marginLeft: audio_modal_bottom_sheet_item_margin_left,
105
+ marginRight: audio_modal_bottom_sheet_item_margin_right,
106
+ paddingTop: audio_modal_bottom_sheet_item_padding_top,
107
+ paddingBottom: audio_modal_bottom_sheet_item_padding_bottom,
108
+ paddingRight: audio_modal_bottom_sheet_item_padding_right,
109
+ paddingLeft: audio_modal_bottom_sheet_item_padding_left,
110
+ maxWidth: width,
111
+ };
112
+ };
113
+
114
+ export const getBottomSheetModalSelectedItemIcon = (theme) =>
115
+ theme["audio_modal_bottom_sheet_item_selected_icon"] || null;
116
+
117
+ export const getBottomSheetModalDefaultItemIcon = (theme) =>
118
+ theme["audio_modal_bottom_sheet_item_default_icon"] || null;
@@ -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}
@@ -1051,7 +1054,10 @@ export default class VideoPlayer extends React.Component<
1051
1054
  {!castAction?.state?.connected || supportNativeCast ? (
1052
1055
  <AnimationComponent
1053
1056
  animationType={ComponentAnimationType.player}
1054
- additionalData={playerDimensions}
1057
+ additionalData={{
1058
+ ...playerDimensions,
1059
+ disableAnimatedComponent: isAudioItem,
1060
+ }}
1055
1061
  style={getStyle(playerDimensions)}
1056
1062
  >
1057
1063
  <this.props.PlayerComponent