@applicaster/quick-brick-player 13.0.0-alpha.1512623290 → 13.0.0-alpha.1545345200

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 +9 -10
  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 -89
  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 +100 -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 +39 -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.1512623290",
3
+ "version": "13.0.0-alpha.1545345200",
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,13 +35,13 @@
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.46",
40
- "@applicaster/quick-brick-tv-transport-controls": "13.0.0-alpha.1512623290",
41
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.1512623290",
42
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.1512623290",
43
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.1512623290",
44
- "keymirror": "^0.1.1",
38
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.1545345200",
39
+ "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.56",
40
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.1545345200",
41
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.1545345200",
42
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.1545345200",
45
43
  "query-string": "7.1.3",
44
+ "react-native-web-linear-gradient": "1.1.2",
46
45
  "shaka-player": "4.3.5",
47
46
  "typeface-montserrat": "^0.0.54",
48
47
  "video.js": "7.14.3",
@@ -60,15 +59,15 @@
60
59
  "@applicaster/zapp-react-native-tvos-ui-components": "*",
61
60
  "@babel/runtime": "*",
62
61
  "@react-native-community/netinfo": "*",
63
- "@types/node": "*",
64
- "@types/react-native": "0.69.6",
65
62
  "immer": "*",
66
63
  "react": "*",
67
64
  "react-native": "*",
68
65
  "react-native-fs": "*",
66
+ "react-native-gesture-handler": "*",
69
67
  "react-native-linear-gradient": "*",
70
68
  "react-native-safe-area-context": "*",
71
69
  "react-native-svg": "*",
70
+ "react-native-web": "*",
72
71
  "react-native-webview": "*",
73
72
  "uglify-js": "*",
74
73
  "validate-color": "*",
@@ -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 { getSleepTimerOptions } 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,43 @@ 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
- items: [
310
- {
311
- label: configuration["playback_sleep_off_label"],
312
- value: 0,
313
- },
314
- ].concat(sleeps),
277
+ items: getSleepTimerOptions(configuration),
315
278
  current_selection: sleepTimerState.timer,
316
279
  onPress: onSleepSelect,
317
280
  title: configuration["playback_sleep_title"],
281
+ itemProps: getBottomSheetModalItemProps,
282
+ iconProps: getBottomSheetModalIconProps,
283
+ labelProps: getBottomSheetModalLabelProps,
284
+ getSelectedItemIcon: getBottomSheetModalSelectedItemIcon,
285
+ iconPlacement: "right",
318
286
  },
319
287
  options: {
320
288
  supportedOrientations: ["portrait"],
321
289
  },
322
290
  });
323
291
  }, [
324
- navigator,
325
292
  sleepTimerState.timer,
326
293
  configuration["playback_sleep_title"],
327
294
  configuration["playback_sleep_off_label"],
@@ -355,13 +322,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
355
322
  player?.seekTo(0);
356
323
  }, [player]);
357
324
 
358
- const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
359
-
360
- const ContainerView = SafeAreaView;
361
-
362
325
  const MainContent = React.useMemo(() => {
363
326
  return (
364
- <ContainerView style={Styles.mainContainer(style)} edges={edges}>
327
+ <SafeAreaView style={[style, Styles.playerContainer]} edges={edges}>
365
328
  <AnimationComponent
366
329
  animationType={ComponentAnimationType.moveUpComponent}
367
330
  additionalData={{ saveArea: true }}
@@ -405,18 +368,18 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
405
368
  animationType={ComponentAnimationType.componentFade}
406
369
  >
407
370
  <PlayerDetails
371
+ isAudioPlayer
408
372
  configuration={configuration}
409
373
  style={Styles.playerDetails}
410
374
  entry={entry}
411
375
  isTabletLandscape={isTabletLandscape}
412
- isAudioPlayer={true}
413
376
  />
414
377
  </AnimationComponent>
415
378
  </View>
416
379
  </View>
417
380
  </AnimatedScrollModal>
418
381
  </AnimationComponent>
419
- </ContainerView>
382
+ </SafeAreaView>
420
383
  );
421
384
  }, [
422
385
  docked,
@@ -442,21 +405,26 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
442
405
  ]);
443
406
 
444
407
  if (configuration.magic_background) {
445
- const baseUrl = entry?.extensions?.audio_player_background_image ?? "";
408
+ const baseUrl = imageSrcFromMediaItem(entry, null);
446
409
 
447
410
  const queryParamName =
448
411
  configuration.audio_player_background_image_query || "width";
449
412
 
413
+ const defaultBackgroundColor =
414
+ configuration.audio_player_background_image_default_color ||
415
+ theme?.app_background_color;
416
+
450
417
  const queryParamValue = 15;
451
418
 
452
- const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
419
+ const url =
420
+ baseUrl && addQueryParam(baseUrl, queryParamName, queryParamValue);
453
421
 
454
422
  return (
455
423
  <MagicBG
456
424
  image={url}
457
425
  fallbackUrl={baseUrl}
458
426
  colors={entry?.extensions?.backgroundColors}
459
- defaultColor="#000000"
427
+ defaultColor={defaultBackgroundColor}
460
428
  >
461
429
  {MainContent}
462
430
  </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
+ };