@applicaster/quick-brick-player 13.0.0-alpha.5771418585 → 13.0.0-alpha.5790181722

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.
Files changed (33) hide show
  1. package/package.json +8 -13
  2. package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
  3. package/src/Player/AudioLayer/AudioDescription.tsx +4 -6
  4. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +57 -84
  5. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +27 -0
  6. package/src/Player/AudioLayer/Layout/Controls/index.tsx +305 -0
  7. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +3 -13
  8. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +30 -53
  9. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +212 -0
  10. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +83 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +32 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +95 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +17 -0
  14. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +214 -0
  15. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +224 -0
  16. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +102 -0
  17. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  18. package/src/Player/AudioLayer/Layout/const.ts +20 -0
  19. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  20. package/src/Player/AudioLayer/Layout/hooks/index.ts +3 -0
  21. package/src/Player/AudioLayer/Layout/hooks/useImageSize.ts +101 -0
  22. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  23. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  24. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  25. package/src/Player/AudioLayer/MagicBG/index.tsx +1 -1
  26. package/src/Player/AudioLayer/utils.ts +27 -0
  27. package/src/Player/Const/sleepTimerOptions.ts +10 -0
  28. package/src/Player/Const/speedOptions.ts +4 -0
  29. package/src/Player/Utils/Utils.ts +0 -5
  30. package/src/Player/Utils/index.tsx +117 -0
  31. package/src/Player/index.tsx +21 -9
  32. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
  33. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "13.0.0-alpha.5771418585",
3
+ "version": "13.0.0-alpha.5790181722",
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,12 +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.42",
40
- "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.42",
41
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.5771418585",
42
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.5771418585",
43
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.5771418585",
44
- "keymirror": "^0.1.1",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-rc.95",
39
+ "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.5790181722",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.5790181722",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.5790181722",
45
43
  "query-string": "7.1.3",
46
44
  "react-native-web-linear-gradient": "1.1.2",
47
45
  "shaka-player": "4.3.5",
@@ -61,12 +59,9 @@
61
59
  "@applicaster/zapp-react-native-tvos-ui-components": "*",
62
60
  "@babel/runtime": "*",
63
61
  "@react-native-community/netinfo": "*",
64
- "@types/node": "*",
65
- "@types/react-native": "0.69.6",
66
62
  "immer": "*",
67
- "react": "17.0.2",
68
- "react-hot-loader": "*",
69
- "react-native": "0.68.6",
63
+ "react": "*",
64
+ "react-native": "*",
70
65
  "react-native-fs": "*",
71
66
  "react-native-gesture-handler": "*",
72
67
  "react-native-linear-gradient": "*",
@@ -55,6 +55,11 @@ const useMuteUnmuteListeners = (playerId, player, asset, setImageUri) =>
55
55
  return;
56
56
  }
57
57
 
58
+ // initial state setup - show correct mute/unmute icon based on current state
59
+ if (player?.playerState?.isReadyToPlay) {
60
+ setImageUri(player.getIsMuted() ? asset.active : asset.inactive);
61
+ }
62
+
58
63
  // active action = muted, inactive = unmuted
59
64
  return player.addListener({
60
65
  id: liveImageButtonsListenerKey,
@@ -73,10 +78,17 @@ const useMuteUnmuteListeners = (playerId, player, asset, setImageUri) =>
73
78
  setImageUri(player?.getIsMuted() ? asset.active : asset.inactive);
74
79
  },
75
80
  onPlayerClose: () => {
76
- setImageUri(null);
81
+ if (isCurrentPlayer(playerId)) {
82
+ setImageUri(null);
83
+ }
77
84
  },
78
85
  onVideoEnd: () => {
79
- setImageUri(null);
86
+ if (isCurrentPlayer(playerId)) {
87
+ setImageUri(null);
88
+ }
89
+ },
90
+ onPlayerResume: () => {
91
+ setImageUri(player?.getIsMuted() ? asset.active : asset.inactive);
80
92
  },
81
93
  },
82
94
  });
@@ -93,7 +105,7 @@ const styles = StyleSheet.create({
93
105
  },
94
106
  });
95
107
 
96
- export function AssetComponent(props: CellActionAssetComponentProps) {
108
+ function AssetImage(props: CellActionAssetComponentProps) {
97
109
  const { cellUUID: playerId, asset } = props;
98
110
  const [imageUri, setImageUri] = useState<Asset>(null);
99
111
 
@@ -108,3 +120,5 @@ export function AssetComponent(props: CellActionAssetComponentProps) {
108
120
 
109
121
  return <View />;
110
122
  }
123
+
124
+ export const AssetComponent = React.memo(AssetImage);
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { Text, TextStyle, View } from "react-native";
2
+ import { Text, TextStyle } from "react-native";
3
3
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
4
4
 
5
5
  type AudioDescriptionProps = {
@@ -13,8 +13,6 @@ type AudioDescriptionProps = {
13
13
  value: GetValue;
14
14
  };
15
15
 
16
- const containerStyles = { paddingTop: 32, paddingBottom: 12 };
17
-
18
16
  const titleStyles = (value: GetValue, prefix: string): TextStyle => ({
19
17
  textAlign: "left",
20
18
  color: value(`${prefix}title_color`),
@@ -83,13 +81,13 @@ export const AudioDescription = (props: AudioDescriptionProps) => {
83
81
  const prefix = layoutState.docked ? "docked_player_" : "";
84
82
 
85
83
  return (
86
- <View style={containerStyles}>
84
+ <>
87
85
  <Text style={titleStyles(value, prefix)} numberOfLines={1}>
88
86
  {title}
89
87
  </Text>
90
- <Text style={summaryStyles(value, prefix)} numberOfLines={2}>
88
+ <Text style={summaryStyles(value, prefix)} numberOfLines={1}>
91
89
  {summary}
92
90
  </Text>
93
- </View>
91
+ </>
94
92
  );
95
93
  };
@@ -1,5 +1,10 @@
1
1
  import * as React from "react";
2
- import { ViewStyle, View } 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,28 +23,33 @@ 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
+ } from "../Utils";
22
34
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
35
  import {
24
36
  AnimationComponent,
25
37
  ComponentAnimationType,
26
38
  AnimatedScrollModal,
27
39
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
28
- import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
40
+ import { PADDING_HORIZONTAL } from "./Layout/const";
29
41
  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
42
  import {
38
43
  SleepTimerController,
39
44
  SleepTimerState,
40
45
  SLEEP_TIMER_OFF,
41
46
  } from "./SleepTimerManager";
42
47
  import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
48
+ import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
49
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
50
+ import { openBottomSheetModal } from "@applicaster/zapp-react-native-utils/modalState";
51
+ import { sleepTimerOptions } from "../Const/sleepTimerOptions";
52
+ import { speedOptions } from "../Const/speedOptions";
43
53
 
44
54
  const { log_debug } = createLogger({
45
55
  subsystem: "UIComponent",
@@ -57,6 +67,7 @@ type Configuration = {
57
67
  [key: string]: any;
58
68
  magic_background?: boolean;
59
69
  audio_player_background_image_query?: string;
70
+ audio_player_background_image_default_color?: string;
60
71
  tablet_landscape_sidebar_width?: string;
61
72
  tablet_landscape_player_container_background_color?: string;
62
73
  };
@@ -78,54 +89,26 @@ type Props = {
78
89
  isTabletPortrait?: boolean;
79
90
  };
80
91
 
81
- export const defaultAspectRatioWidth = (height: number): number =>
82
- (height / 9) * 16;
92
+ const { width: SCREEN_WIDTH } = ScreenDimensions.get("screen");
83
93
 
84
- const Styles = {
85
- mainContainer: (style: ViewStyle) => {
86
- const combinedStyle: ViewStyle = {
87
- flex: 1,
88
- };
89
-
90
- return {
91
- ...combinedStyle,
92
- ...style,
93
- };
94
- },
94
+ const Styles = StyleSheet.create({
95
95
  playerContainer: {
96
96
  flex: 1,
97
97
  },
98
98
  paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
99
-
100
- controlsMobile: {
101
- height: 50,
102
- marginHorizontal: 24,
103
- },
104
- controlsTablet: {
105
- height: 96,
106
- marginHorizontal: 24,
107
- },
108
- playerDetails: { marginTop: 60 },
109
-
110
- linearGradient: {
111
- flex: 1,
99
+ playerDetails: {
100
+ marginTop: 60,
101
+ alignSelf: "center",
102
+ width: SCREEN_WIDTH - PADDING_HORIZONTAL * 2,
112
103
  },
113
- };
104
+ });
114
105
 
115
- const sleeps = [
116
- // { label: "End of episode", value: "episode" },
117
- { label: "5 minutes", value: 5 },
118
- { label: "10 minutes", value: 10 },
119
- { label: "15 minutes", value: 15 },
120
- { label: "30 minutes", value: 30 },
121
- { label: "45 minutes", value: 45 },
122
- { label: "1 hour", value: 60 },
123
- { label: "2 hours", value: 120 },
124
- ];
106
+ const edges: Edge[] = ["right", "left", "top"];
125
107
 
126
108
  export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
127
109
  const player = usePlayer();
128
110
  const playerState = usePlayerState("audio-player-wrapper");
111
+ const theme = useTheme();
129
112
 
130
113
  const {
131
114
  docked,
@@ -138,24 +121,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
138
121
  isTabletPortrait,
139
122
  } = props;
140
123
 
141
- const speeds = [
142
- { asset: configuration["speed_0_8"] || speed_0_8, value: 0.8 },
143
- { asset: configuration["speed_1"] || speed_1, value: 1.0 },
144
- { asset: configuration["speed_1_2"] || speed_1_2, value: 1.2 },
145
- { asset: configuration["speed_1_5"] || speed_1_5, value: 1.5 },
146
- { asset: configuration["speed_2"] || speed_2, value: 2.0 },
147
- ];
148
-
149
124
  const isTablet = useIsTablet();
150
125
 
151
126
  const isTabletLandscape = !isTV() && isTablet && !isTabletPortrait;
152
127
 
153
- // TODO: Have generic place for live url from configuration. Currently its hardcoded for client.
154
-
155
- const feedUrl = getLiveUrl(entry?.extensions?.live?.channel_src ?? "");
156
-
157
128
  const { title, summary } = useTitleSummaryOverlay(
158
- feedUrl,
159
129
  entry,
160
130
  playerState?.isLive,
161
131
  configuration?.audio_live_player_update_interval
@@ -193,8 +163,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
193
163
  height: 0,
194
164
  });
195
165
 
196
- const navigator = useNavigation();
197
-
198
166
  const { maximiseVideoModal } = useNavigation();
199
167
 
200
168
  const onLayout = (event: any) => {
@@ -284,44 +252,48 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
284
252
  );
285
253
 
286
254
  const onSpeedButtonPress = React.useCallback(() => {
287
- navigator.openModalBottomSheet({
255
+ openBottomSheetModal({
288
256
  modalBottomSheetContentProps: {
289
- items: speeds,
257
+ items: speedOptions,
290
258
  current_selection: playbackSpeed,
291
259
  onPress: onSpeedSelect,
292
260
  title: configuration["playback_speed_title"],
261
+ itemProps: getBottomSheetModalItemProps,
262
+ iconProps: getBottomSheetModalIconProps,
263
+ labelProps: getBottomSheetModalLabelProps,
264
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
265
+ getDefaultItemIcon: getBottomSheetModalDefaultItemIcon,
266
+ iconPlacement: "right",
293
267
  },
294
268
  options: {
295
269
  supportedOrientations: ["portrait"],
296
270
  },
297
271
  });
298
- }, [
299
- playbackSpeed,
300
- setPlaybackSpeed,
301
- navigator,
302
- onSpeedSelect,
303
- configuration["playback_speed_title"],
304
- ]);
272
+ }, [playbackSpeed, onSpeedSelect, configuration["playback_speed_title"]]);
305
273
 
306
274
  const onSleepButtonPress = React.useCallback(() => {
307
- navigator.openModalBottomSheet({
275
+ openBottomSheetModal({
308
276
  modalBottomSheetContentProps: {
309
277
  items: [
310
278
  {
311
279
  label: configuration["playback_sleep_off_label"],
312
280
  value: 0,
313
281
  },
314
- ].concat(sleeps),
282
+ ].concat(sleepTimerOptions),
315
283
  current_selection: sleepTimerState.timer,
316
284
  onPress: onSleepSelect,
317
285
  title: configuration["playback_sleep_title"],
286
+ itemProps: getBottomSheetModalItemProps,
287
+ iconProps: getBottomSheetModalIconProps,
288
+ labelProps: getBottomSheetModalLabelProps,
289
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
290
+ iconPlacement: "right",
318
291
  },
319
292
  options: {
320
293
  supportedOrientations: ["portrait"],
321
294
  },
322
295
  });
323
296
  }, [
324
- navigator,
325
297
  sleepTimerState.timer,
326
298
  configuration["playback_sleep_title"],
327
299
  configuration["playback_sleep_off_label"],
@@ -355,13 +327,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
355
327
  player?.seekTo(0);
356
328
  }, [player]);
357
329
 
358
- const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
359
-
360
- const ContainerView = SafeAreaView;
361
-
362
330
  const MainContent = React.useMemo(() => {
363
331
  return (
364
- <ContainerView style={Styles.mainContainer(style)} edges={edges}>
332
+ <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
365
333
  <AnimationComponent
366
334
  animationType={ComponentAnimationType.moveUpComponent}
367
335
  additionalData={{ saveArea: true }}
@@ -405,18 +373,18 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
405
373
  animationType={ComponentAnimationType.componentFade}
406
374
  >
407
375
  <PlayerDetails
376
+ isAudioPlayer
408
377
  configuration={configuration}
409
378
  style={Styles.playerDetails}
410
379
  entry={entry}
411
380
  isTabletLandscape={isTabletLandscape}
412
- isAudioPlayer={true}
413
381
  />
414
382
  </AnimationComponent>
415
383
  </View>
416
384
  </View>
417
385
  </AnimatedScrollModal>
418
386
  </AnimationComponent>
419
- </ContainerView>
387
+ </SafeAreaView>
420
388
  );
421
389
  }, [
422
390
  docked,
@@ -442,21 +410,26 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
442
410
  ]);
443
411
 
444
412
  if (configuration.magic_background) {
445
- const baseUrl = entry?.extensions?.audio_player_background_image ?? "";
413
+ const baseUrl = imageSrcFromMediaItem(entry, null);
446
414
 
447
415
  const queryParamName =
448
416
  configuration.audio_player_background_image_query || "width";
449
417
 
418
+ const defaultBackgroundColor =
419
+ configuration.audio_player_background_image_default_color ||
420
+ theme?.app_background_color;
421
+
450
422
  const queryParamValue = 15;
451
423
 
452
- const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
424
+ const url =
425
+ baseUrl && addQueryParam(baseUrl, queryParamName, queryParamValue);
453
426
 
454
427
  return (
455
428
  <MagicBG
456
429
  image={url}
457
430
  fallbackUrl={baseUrl}
458
431
  colors={entry?.extensions?.backgroundColors}
459
- defaultColor="#000000"
432
+ defaultColor={defaultBackgroundColor}
460
433
  >
461
434
  {MainContent}
462
435
  </MagicBG>
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+
4
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+
6
+ import { TABLET_VERTICAL_SEPARATOR_HEIGHT } from "../const";
7
+
8
+ import { withDebug } from "../debug";
9
+
10
+ const styles = StyleSheet.create({
11
+ flexingHeight: {
12
+ flex: 1,
13
+
14
+ ...withDebug({ backgroundColor: "red" }),
15
+ },
16
+ fixedHeight: {
17
+ height: TABLET_VERTICAL_SEPARATOR_HEIGHT,
18
+
19
+ ...withDebug({ backgroundColor: "red" }),
20
+ },
21
+ });
22
+
23
+ export const VerticalGutter = () => {
24
+ const isTablet = useIsTablet();
25
+
26
+ return <View style={isTablet ? styles.fixedHeight : styles.flexingHeight} />;
27
+ };