@applicaster/quick-brick-player 12.0.0-alpha.5251355865 → 12.0.0-alpha.5335460000

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": "12.0.0-alpha.5251355865",
3
+ "version": "12.0.0-alpha.5335460000",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "homepage": "https://github.com/applicaster/quickbrick#readme",
38
38
  "dependencies": {
39
- "@applicaster/quick-brick-mobile-transport-controls": "12.0.0-alpha.5251355865",
40
- "@applicaster/quick-brick-tv-transport-controls": "11.0.0-rc.133",
41
- "@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.5251355865",
42
- "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5251355865",
43
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5251355865",
39
+ "@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.96",
40
+ "@applicaster/quick-brick-tv-transport-controls": "12.0.0-rc.100",
41
+ "@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.5335460000",
42
+ "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5335460000",
43
+ "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5335460000",
44
44
  "keymirror": "^0.1.1",
45
45
  "query-string": "7.1.3",
46
46
  "react-native-web-linear-gradient": "1.1.2",
@@ -1,74 +1,85 @@
1
1
  import React, { useEffect, useState } from "react";
2
- import { Image, StyleSheet, View } from "react-native";
2
+ import { StyleSheet, View } from "react-native";
3
3
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
4
4
  import { MUTED_USAGE } from "../const";
5
5
  import { LiveImageManager } from "@applicaster/zapp-react-native-ui-components/Components/VideoLive/LiveImageManager";
6
+ import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
6
7
 
7
8
  type Asset = string | undefined;
8
9
 
9
10
  const isCurrentPlayer = (playerId) =>
10
11
  LiveImageManager.instance.getCurrentlyPlaying()?.playerId === playerId;
11
12
 
13
+ const liveImageButtonsListenerKey = "live-image-buttons";
14
+
12
15
  const usePlayPauseListeners = (playerId, player, asset, setImageUri) =>
13
16
  useEffect(() => {
14
17
  if (playerId && player) {
15
- if (player.playerState.isReadyToPlay) {
16
- if (player.playerState.isPaused) {
17
- setImageUri(asset.active);
18
- } else {
19
- setImageUri(asset.inactive);
20
- }
18
+ setImageUri(null);
19
+
20
+ return;
21
+ }
22
+
23
+ if (player.playerState.isReadyToPlay) {
24
+ if (player.playerState.isPaused) {
25
+ setImageUri(asset.active);
26
+ } else {
27
+ setImageUri(asset.inactive);
21
28
  }
29
+ }
22
30
 
23
- return player.addListener({
24
- id: "live-image-buttons",
25
- listener: {
26
- onPlayerResume: () => {
27
- setImageUri(asset.inactive);
28
- },
29
- onPlayerPause: () => {
30
- setImageUri(asset.active);
31
- },
32
- onPlayerClose: () => {
33
- setImageUri(null);
34
- },
35
- onLoad() {
36
- setImageUri(asset.inactive);
37
- },
31
+ return player.addListener({
32
+ id: liveImageButtonsListenerKey,
33
+ listener: {
34
+ onPlayerResume: () => {
35
+ setImageUri(asset.inactive);
38
36
  },
39
- });
40
- }
37
+ onPlayerPause: () => {
38
+ setImageUri(asset.active);
39
+ },
40
+ onPlayerClose: () => {
41
+ setImageUri(null);
42
+ },
43
+ onLoad() {
44
+ setImageUri(asset.inactive);
45
+ },
46
+ },
47
+ });
41
48
  }, [player, playerId, asset]);
42
49
 
43
50
  const useMuteUnmuteListeners = (playerId, player, asset, setImageUri) =>
44
51
  useEffect(() => {
45
- if (playerId && player) {
46
- // active action = muted, inactive = unmuted
47
- return player.addListener({
48
- id: "live-image-buttons",
49
- listener: {
50
- onPlayerMute: () => {
51
- if (isCurrentPlayer(playerId)) {
52
- setImageUri(asset.active);
53
- }
54
- },
55
- onPlayerUnmute: () => {
56
- if (isCurrentPlayer(playerId)) {
57
- setImageUri(asset.inactive);
58
- }
59
- },
60
- onLoad() {
61
- setImageUri(player?.getIsMuted() ? asset.active : asset.inactive);
62
- },
63
- onPlayerClose: () => {
64
- setImageUri(null);
65
- },
66
- onVideoEnd: () => {
67
- setImageUri(null);
68
- },
69
- },
70
- });
52
+ if (!player || !playerId) {
53
+ setImageUri(null);
54
+
55
+ return;
71
56
  }
57
+
58
+ // active action = muted, inactive = unmuted
59
+ return player.addListener({
60
+ id: liveImageButtonsListenerKey,
61
+ listener: {
62
+ onPlayerMute: () => {
63
+ if (isCurrentPlayer(playerId)) {
64
+ setImageUri(asset.active);
65
+ }
66
+ },
67
+ onPlayerUnmute: () => {
68
+ if (isCurrentPlayer(playerId)) {
69
+ setImageUri(asset.inactive);
70
+ }
71
+ },
72
+ onLoad() {
73
+ setImageUri(player?.getIsMuted() ? asset.active : asset.inactive);
74
+ },
75
+ onPlayerClose: () => {
76
+ setImageUri(null);
77
+ },
78
+ onVideoEnd: () => {
79
+ setImageUri(null);
80
+ },
81
+ },
82
+ });
72
83
  }, [player, playerId, asset]);
73
84
 
74
85
  const useListeners = MUTED_USAGE
@@ -21,7 +21,7 @@ const playActionCallback = (player) => {
21
21
  }
22
22
  };
23
23
 
24
- const invokeAction = () => {
24
+ const invokeAction = (_item: ZappEntry, _object) => {
25
25
  const actionCallback = MUTED_USAGE ? muteActionCallback : playActionCallback;
26
26
  // We only allow one player to be present at a time
27
27
  const player = LiveImageManager.instance.getCurrentlyPlaying()?.player;
@@ -29,6 +29,54 @@ const invokeAction = () => {
29
29
  actionCallback(player);
30
30
  };
31
31
 
32
+ // Not exported because currently the is no way
33
+ // to subscribe to the action availability change.
34
+ // We currently return a null state to disable the action.
35
+ // eslint-disable-next-line unused-imports/no-unused-vars
36
+ const isActionAvailable = (item: ZappEntry) => {
37
+ return (
38
+ LiveImageManager.instance.getCurrentlyPlaying()?.getPlayer().entry.id ===
39
+ item.id
40
+ );
41
+ };
42
+
43
+ const addListener = (
44
+ entryId: string,
45
+ listener: CellActionStateListenerFunction
46
+ ) => {
47
+ const callback = (event: Record<string, any>) => {
48
+ if (event.entry?.id !== entryId) {
49
+ return;
50
+ }
51
+
52
+ const player = LiveImageManager.instance.getCurrentlyPlaying()?.getPlayer();
53
+
54
+ if (!player || player.entry?.id !== entryId) {
55
+ listener(null);
56
+
57
+ return;
58
+ }
59
+
60
+ const actionState = MUTED_USAGE ? player.getIsMuted() : player.isPaused();
61
+
62
+ listener({
63
+ state: actionState ? 1 : 0,
64
+ label: "",
65
+ asset: AssetComponent,
66
+ });
67
+ };
68
+
69
+ return LiveImageManager.instance.addListener({
70
+ id: `cell-player-${entryId}`,
71
+ listener: {
72
+ onEnd: callback,
73
+ onStart: callback,
74
+ onError: callback,
75
+ onDestroy: callback,
76
+ },
77
+ });
78
+ };
79
+
32
80
  const emptyState = [];
33
81
 
34
82
  const initialEntryState = () => ({
@@ -46,6 +94,7 @@ export function ContextProvider(Component: ReactComponent<any>) {
46
94
  state: emptyState,
47
95
  invokeAction,
48
96
  initialEntryState,
97
+ addListener,
49
98
  }),
50
99
  [invokeAction, initialEntryState]
51
100
  );
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { ViewStyle, View, ScrollView } from "react-native";
2
+ import { ViewStyle, View } from "react-native";
3
3
 
4
4
  import { SafeAreaView, Edge } from "react-native-safe-area-context";
5
5
  import { usePlayerState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState";
@@ -24,8 +24,15 @@ import {
24
24
  NAMESPACE,
25
25
  } from "./utils";
26
26
  import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
27
- import { getLiveUrl } from "../Utils";
27
+ import { addQueryParam, getLiveUrl } from "../Utils";
28
28
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
29
+ import {
30
+ AnimationComponent,
31
+ ComponentAnimationType,
32
+ AnimatedScrollModal,
33
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
34
+ import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
35
+ import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
29
36
 
30
37
  const { log_debug } = createLogger({
31
38
  subsystem: "UIComponent",
@@ -68,29 +75,20 @@ export const defaultAspectRatioWidth = (height: number): number =>
68
75
  (height / 9) * 16;
69
76
 
70
77
  const Styles = {
71
- mainContainer: (docked: boolean, style: ViewStyle) => {
78
+ mainContainer: (style: ViewStyle) => {
72
79
  const combinedStyle: ViewStyle = {
73
80
  flex: 1,
74
81
  };
75
82
 
76
- if (!docked) {
77
- style.paddingTop = 0;
78
- style.paddingHorizontal = 15;
79
- }
80
-
81
- return { ...combinedStyle, ...style };
82
- },
83
- playerContainer: (docked: boolean, style: ViewStyle) => {
84
- const combinedStyle: ViewStyle = {
85
- flex: 1,
83
+ return {
84
+ ...combinedStyle,
85
+ ...style,
86
86
  };
87
-
88
- if (docked) {
89
- combinedStyle.height = style.height;
90
- }
91
-
92
- return combinedStyle;
93
87
  },
88
+ playerContainer: {
89
+ flex: 1,
90
+ },
91
+ paddingHorizontal: { paddingTop: 0, paddingHorizontal: PADDING_HORIZONTAL },
94
92
 
95
93
  controlsMobile: {
96
94
  height: 50,
@@ -168,6 +166,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
168
166
 
169
167
  const [sleepTimerDate, setSleepTimerDate] = useState(0);
170
168
 
169
+ const [defaultDimensions, setDefaultDimensions] =
170
+ React.useState<Dimensions>(undefined);
171
+
171
172
  const [dimensions, setDimensions] = React.useState<Dimensions>({
172
173
  width: 0,
173
174
  height: 0,
@@ -181,9 +182,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
181
182
  const { width, height } = event.nativeEvent.layout;
182
183
 
183
184
  setDimensions({
184
- width: docked ? defaultAspectRatioWidth(height) : width,
185
+ width,
185
186
  height,
186
187
  });
188
+
189
+ if (!defaultDimensions) setDefaultDimensions({ width, height });
187
190
  };
188
191
 
189
192
  const cancelSleepTimer = async () => {
@@ -195,7 +198,6 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
195
198
  });
196
199
 
197
200
  setSleepTimerDate(0);
198
- player?.pause();
199
201
 
200
202
  await localStorage.removeItem("sleep", NAMESPACE);
201
203
  };
@@ -293,7 +295,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
293
295
  playerState.isPaused ? player?.play() : player.pause();
294
296
  }, [playerState, player]);
295
297
 
296
- const seekDuration = Number(value("seek_duration"));
298
+ const seekDuration = toNumberWithDefault(10, value("seek_duration"));
297
299
 
298
300
  const onRewindButtonPress = React.useCallback(() => {
299
301
  player?.rewind(seekDuration);
@@ -376,58 +378,65 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
376
378
  player?.seekTo(0);
377
379
  }, [player]);
378
380
 
379
- const edges = React.useMemo<Edge[]>(
380
- () => (docked ? [] : ["right", "left", "top"]),
381
- [docked]
382
- );
381
+ const edges = React.useMemo<Edge[]>(() => ["right", "left", "top"], [docked]);
383
382
 
384
- const ContainerView = docked ? View : SafeAreaView;
383
+ const ContainerView = SafeAreaView;
385
384
 
386
385
  const MainContent = React.useMemo(() => {
387
386
  return (
388
- <ContainerView style={Styles.mainContainer(docked, style)} edges={edges}>
389
- <ScrollView
390
- style={Styles.playerContainer(docked, style)}
391
- onLayout={onLayout}
387
+ <ContainerView style={Styles.mainContainer(style)} edges={edges}>
388
+ <AnimationComponent
389
+ animationType={ComponentAnimationType.moveUpComponent}
390
+ additionalData={{ saveArea: true }}
391
+ style={Styles.playerContainer}
392
392
  >
393
- <Layout
394
- entry={entry}
395
- playerState={playerState}
396
- layoutState={layoutState}
397
- value={value}
398
- onPlaybackButtonPress={onPlaybackButtonPress}
399
- onRewindButtonPress={onRewindButtonPress}
400
- onForwardButtonPress={onForwardButtonPress}
401
- onPlayerSeek={onPlayerSeek}
402
- onSkipStart={onSkipStart}
403
- onSpeedButtonPress={onSpeedButtonPress}
404
- onSleepButtonPress={onSleepButtonPress}
405
- playbackSpeedName={formatSpeed(playbackSpeed.value)}
406
- playbackSleepName={
407
- sleepTimer.value === 0 ? "sleep_timer" : "sleep_timer_active"
408
- }
409
- sleepTimerDate={sleepTimerDate}
410
- cancelSleepTimer={cancelSleepTimer}
411
- onSkipLive={onSkipLive}
412
- onCloseVideoModal={onCloseVideoModal}
413
- maximiseVideoModal={maximiseVideoModal}
414
- configuration={configuration}
415
- dimensions={dimensions}
416
- playNextData={playNextData}
417
- title={title}
418
- summary={summary}
419
- />
420
- {children}
421
- {!docked && (
422
- <PlayerDetails
423
- configuration={configuration}
424
- style={Styles.playerDetails}
425
- entry={entry}
426
- isTabletLandscape={isTabletLandscape}
427
- isAudioPlayer={true}
428
- />
429
- )}
430
- </ScrollView>
393
+ <AnimatedScrollModal>
394
+ <View style={Styles.playerContainer} onLayout={onLayout}>
395
+ <Layout
396
+ entry={entry}
397
+ playerState={playerState}
398
+ layoutState={layoutState}
399
+ value={value}
400
+ onPlaybackButtonPress={onPlaybackButtonPress}
401
+ onRewindButtonPress={onRewindButtonPress}
402
+ onForwardButtonPress={onForwardButtonPress}
403
+ onPlayerSeek={onPlayerSeek}
404
+ onSkipStart={onSkipStart}
405
+ onSpeedButtonPress={onSpeedButtonPress}
406
+ onSleepButtonPress={onSleepButtonPress}
407
+ playbackSpeedName={formatSpeed(playbackSpeed.value)}
408
+ playbackSleepName={
409
+ sleepTimer.value === 0 ? "sleep_timer" : "sleep_timer_active"
410
+ }
411
+ sleepTimerDate={sleepTimerDate}
412
+ cancelSleepTimer={cancelSleepTimer}
413
+ onSkipLive={onSkipLive}
414
+ onCloseVideoModal={onCloseVideoModal}
415
+ maximiseVideoModal={maximiseVideoModal}
416
+ configuration={configuration}
417
+ dimensions={dimensions}
418
+ playNextData={playNextData}
419
+ title={title}
420
+ summary={summary}
421
+ defaultDimensions={defaultDimensions}
422
+ />
423
+ <View style={Styles.paddingHorizontal}>
424
+ {children}
425
+ <AnimationComponent
426
+ animationType={ComponentAnimationType.componentFade}
427
+ >
428
+ <PlayerDetails
429
+ configuration={configuration}
430
+ style={Styles.playerDetails}
431
+ entry={entry}
432
+ isTabletLandscape={isTabletLandscape}
433
+ isAudioPlayer={true}
434
+ />
435
+ </AnimationComponent>
436
+ </View>
437
+ </View>
438
+ </AnimatedScrollModal>
439
+ </AnimationComponent>
431
440
  </ContainerView>
432
441
  );
433
442
  }, [
@@ -456,17 +465,20 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
456
465
  if (configuration.magic_background) {
457
466
  const baseUrl = entry?.extensions?.audio_player_background_image ?? "";
458
467
 
459
- // TODO: To be added when background is ready
468
+ const queryParamName =
469
+ configuration.audio_player_background_image_query || "width";
470
+
471
+ const queryParamValue = 15;
460
472
 
461
- // const queryParamName =
462
- // configuration.audio_player_background_image_query || "width";
463
- //
464
- // const queryParamValue = 15;
465
- //
466
- // const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
473
+ const url = addQueryParam(baseUrl, queryParamName, queryParamValue);
467
474
 
468
475
  return (
469
- <MagicBG image={baseUrl} fallbackUrl={baseUrl} defaultColor="#000000">
476
+ <MagicBG
477
+ image={url}
478
+ fallbackUrl={baseUrl}
479
+ colors={entry?.extensions?.backgroundColors}
480
+ defaultColor="#000000"
481
+ >
470
482
  {MainContent}
471
483
  </MagicBG>
472
484
  );