@applicaster/quick-brick-player 13.0.0-alpha.8490438700 → 13.0.0-alpha.9103242840

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": "13.0.0-alpha.8490438700",
3
+ "version": "13.0.0-alpha.9103242840",
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": "13.0.0-rc.28",
40
- "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.26",
41
- "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.8490438700",
42
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.8490438700",
43
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.8490438700",
39
+ "@applicaster/quick-brick-mobile-transport-controls": "13.0.0-alpha.9103242840",
40
+ "@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.19",
41
+ "@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.9103242840",
42
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.9103242840",
43
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.9103242840",
44
44
  "keymirror": "^0.1.1",
45
45
  "query-string": "7.1.3",
46
46
  "react-native-web-linear-gradient": "1.1.2",
@@ -17,7 +17,13 @@ import { PlayerDetails } from "@applicaster/zapp-react-native-ui-components/Comp
17
17
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
18
18
  import { useEffect, useState } from "react";
19
19
  import { MagicBG } from "./MagicBG";
20
- import { formatSpeed } from "./utils";
20
+ import {
21
+ formatSpeed,
22
+ hasDatePassed,
23
+ loadItemsFromStorage,
24
+ NAMESPACE,
25
+ } from "./utils";
26
+ import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
21
27
  import { addQueryParam, getLiveUrl } from "../Utils";
22
28
  import { useTitleSummaryOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerTitleSummaryOverlay";
23
29
  import {
@@ -27,19 +33,6 @@ import {
27
33
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
28
34
  import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
29
35
  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
- import {
38
- SleepTimerController,
39
- SleepTimerState,
40
- SLEEP_TIMER_OFF,
41
- } from "./SleepTimerManager";
42
- import { SpeedController, PlaybackSpeed, DEFAULT_SPEED } from "./SpeedManager";
43
36
 
44
37
  const { log_debug } = createLogger({
45
38
  subsystem: "UIComponent",
@@ -139,11 +132,11 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
139
132
  } = props;
140
133
 
141
134
  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 },
135
+ { asset: configuration["speed_0_8"], value: 0.8 },
136
+ { asset: configuration["speed_1"], value: 1.0 },
137
+ { asset: configuration["speed_1_2"], value: 1.2 },
138
+ { asset: configuration["speed_1_5"], value: 1.5 },
139
+ { asset: configuration["speed_2"], value: 2.0 },
147
140
  ];
148
141
 
149
142
  const isTablet = useIsTablet();
@@ -161,29 +154,17 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
161
154
  configuration?.audio_live_player_update_interval
162
155
  );
163
156
 
164
- const [sleepTimerManager, setSleepTimerManager] =
165
- useState<SleepTimerController | null>(null);
166
-
167
- const [speedManager, setSpeedManager] = useState<SpeedController | null>(
168
- null
169
- );
170
-
171
- useEffect(() => {
172
- if (player) {
173
- setSleepTimerManager(new SleepTimerController(player));
174
- setSpeedManager(new SpeedController(player));
175
- } else {
176
- setSleepTimerManager(null);
177
- setSpeedManager(null);
178
- }
179
- }, [player]);
157
+ const [playbackSpeed, setPlaybackSpeed] = useState({
158
+ asset: configuration["speed_1"],
159
+ value: 1.0,
160
+ });
180
161
 
181
- const [playbackSpeed, setPlaybackSpeed] =
182
- useState<PlaybackSpeed>(DEFAULT_SPEED);
162
+ const [sleepTimer, setSleepTimer] = useState({
163
+ label: "playback_sleep_off_label",
164
+ value: 0,
165
+ });
183
166
 
184
- const [sleepTimerState, setSleepTimerState] = useState<SleepTimerState>(
185
- new SleepTimerState(SLEEP_TIMER_OFF, 0)
186
- );
167
+ const [sleepTimerDate, setSleepTimerDate] = useState(0);
187
168
 
188
169
  const [defaultDimensions, setDefaultDimensions] =
189
170
  React.useState<Dimensions>(undefined);
@@ -208,27 +189,82 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
208
189
  if (!defaultDimensions) setDefaultDimensions({ width, height });
209
190
  };
210
191
 
211
- useEffect(() => {
212
- const sleepSubscription =
213
- sleepTimerManager?.sleepTimerState$.subscribe(setSleepTimerState);
192
+ const cancelSleepTimer = async () => {
193
+ player?.cancelSleepTimer();
214
194
 
215
- const speedSubscription =
216
- speedManager?.playbackSpeed$.subscribe(setPlaybackSpeed);
195
+ setSleepTimer({
196
+ label: "playback_sleep_off_label",
197
+ value: 0,
198
+ });
217
199
 
218
- return () => {
219
- sleepSubscription?.unsubscribe();
220
- speedSubscription?.unsubscribe();
221
- };
222
- }, [sleepTimerManager, speedManager]);
200
+ setSleepTimerDate(0);
223
201
 
224
- useEffect(() => {
225
- if (!playerState.isReadyToPlay) {
226
- return;
202
+ await localStorage.removeItem("sleep", NAMESPACE);
203
+ };
204
+
205
+ const startSleepTimer = (timerValue: number) => {
206
+ try {
207
+ const currentDate = new Date();
208
+ const futureDate = new Date(currentDate.getTime() + timerValue * 60000);
209
+ const futureSleepDate = futureDate.getTime();
210
+
211
+ player?.cancelSleepTimer();
212
+
213
+ player?.startSleepTimer(futureSleepDate);
214
+
215
+ return futureSleepDate;
216
+ } catch (e) {
217
+ return 0;
227
218
  }
219
+ };
220
+
221
+ const handleSleep = async (
222
+ timerValue: number,
223
+ currentFutureSleepDate = null
224
+ ) => {
225
+ if (currentFutureSleepDate) {
226
+ if (hasDatePassed(currentFutureSleepDate)) {
227
+ await cancelSleepTimer();
228
228
 
229
- void speedManager?.loadSpeed();
230
- void sleepTimerManager?.loadSleep();
231
- }, [playerState.isReadyToPlay, speedManager, sleepTimerManager]);
229
+ return 0;
230
+ }
231
+
232
+ return currentFutureSleepDate;
233
+ }
234
+
235
+ if (timerValue === 0) {
236
+ await cancelSleepTimer();
237
+
238
+ return timerValue;
239
+ }
240
+
241
+ return startSleepTimer(timerValue);
242
+ };
243
+
244
+ useEffect(() => {
245
+ const loadSpeed = async () => {
246
+ const speed = await loadItemsFromStorage("speed");
247
+
248
+ if (playerState.isReadyToPlay && speed) {
249
+ setPlaybackSpeed(speed);
250
+ player?.setPlaybackRate(speed.value);
251
+ }
252
+ };
253
+
254
+ const loadSleep = async () => {
255
+ const sleep = await loadItemsFromStorage("sleep");
256
+
257
+ if (playerState.isReadyToPlay && sleep) {
258
+ const { futureSleepDate, ...rest } = sleep;
259
+ setSleepTimer(rest);
260
+ const sleepTimerDate = await handleSleep(sleep.value, futureSleepDate);
261
+ setSleepTimerDate(sleepTimerDate);
262
+ }
263
+ };
264
+
265
+ loadSpeed().then();
266
+ loadSleep().then();
267
+ }, [playerState.isReadyToPlay]);
232
268
 
233
269
  const getValue = (key: string, stylesObj: {}) =>
234
270
  R.propOr(null, key, stylesObj);
@@ -256,7 +292,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
256
292
 
257
293
  const onPlaybackButtonPress = React.useCallback(() => {
258
294
  if (playerState.isBuffering) return;
259
- playerState.isPaused ? player?.play() : player?.pause();
295
+ playerState.isPaused ? player?.play() : player.pause();
260
296
  }, [playerState, player]);
261
297
 
262
298
  const seekDuration = toNumberWithDefault(10, value("seek_duration"));
@@ -271,16 +307,26 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
271
307
 
272
308
  const onSpeedSelect = React.useCallback(
273
309
  async (item) => {
274
- await speedManager?.setPlaybackSpeed(item);
310
+ setPlaybackSpeed(item);
311
+ player.setPlaybackRate(item.value);
312
+ await localStorage.setItem("speed", item, NAMESPACE);
275
313
  },
276
- [speedManager]
314
+ [player, setPlaybackSpeed]
277
315
  );
278
316
 
279
317
  const onSleepSelect = React.useCallback(
280
318
  async (item) => {
281
- await sleepTimerManager?.setSleepTimer(item);
319
+ setSleepTimer(item);
320
+ const futureSleepDate = await handleSleep(item.value);
321
+ setSleepTimerDate(futureSleepDate);
322
+
323
+ await localStorage.setItem(
324
+ "sleep",
325
+ { ...item, futureSleepDate },
326
+ NAMESPACE
327
+ );
282
328
  },
283
- [sleepTimerManager]
329
+ [player, setSleepTimer]
284
330
  );
285
331
 
286
332
  const onSpeedButtonPress = React.useCallback(() => {
@@ -295,24 +341,15 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
295
341
  supportedOrientations: ["portrait"],
296
342
  },
297
343
  });
298
- }, [
299
- playbackSpeed,
300
- setPlaybackSpeed,
301
- navigator,
302
- onSpeedSelect,
303
- configuration["playback_speed_title"],
304
- ]);
344
+ }, [playbackSpeed, setPlaybackSpeed]);
305
345
 
306
346
  const onSleepButtonPress = React.useCallback(() => {
307
347
  navigator.openModalBottomSheet({
308
348
  modalBottomSheetContentProps: {
309
349
  items: [
310
- {
311
- label: configuration["playback_sleep_off_label"],
312
- value: 0,
313
- },
350
+ { label: configuration["playback_sleep_off_label"], value: 0 },
314
351
  ].concat(sleeps),
315
- current_selection: sleepTimerState.timer,
352
+ current_selection: sleepTimer,
316
353
  onPress: onSleepSelect,
317
354
  title: configuration["playback_sleep_title"],
318
355
  },
@@ -320,17 +357,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
320
357
  supportedOrientations: ["portrait"],
321
358
  },
322
359
  });
323
- }, [
324
- navigator,
325
- sleepTimerState.timer,
326
- configuration["playback_sleep_title"],
327
- configuration["playback_sleep_off_label"],
328
- onSleepSelect,
329
- ]);
330
-
331
- const cancelSleepTimer = React.useCallback(() => {
332
- sleepTimerManager?.cancelSleepTimer();
333
- }, [sleepTimerManager]);
360
+ }, [sleepTimer, setSleepTimer, configuration]);
334
361
 
335
362
  const onCloseVideoModal = React.useCallback(() => {
336
363
  playerManager.close();
@@ -379,11 +406,9 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
379
406
  onSleepButtonPress={onSleepButtonPress}
380
407
  playbackSpeedName={formatSpeed(playbackSpeed.value)}
381
408
  playbackSleepName={
382
- sleepTimerState.timer.value === 0
383
- ? "sleep_timer"
384
- : "sleep_timer_active"
409
+ sleepTimer.value === 0 ? "sleep_timer" : "sleep_timer_active"
385
410
  }
386
- sleepTimerDate={sleepTimerState.timerDate}
411
+ sleepTimerDate={sleepTimerDate}
387
412
  cancelSleepTimer={cancelSleepTimer}
388
413
  onSkipLive={onSkipLive}
389
414
  onCloseVideoModal={onCloseVideoModal}
@@ -433,8 +458,8 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
433
458
  playNextData,
434
459
  onSkipStart,
435
460
  onSkipLive,
436
- sleepTimerState.timer.value,
437
- sleepTimerState.timerDate,
461
+ sleepTimer.value,
462
+ sleepTimerDate,
438
463
  ]);
439
464
 
440
465
  if (configuration.magic_background) {
@@ -120,8 +120,8 @@ const Styles = {
120
120
  (startComponentsAnimation && isActiveGesture) || docked
121
121
  ? 0
122
122
  : isTablet
123
- ? 24
124
- : 10,
123
+ ? 24
124
+ : 10,
125
125
  }),
126
126
 
127
127
  paddingHorizontal: {
@@ -37,8 +37,8 @@ export const playbackButton = ({
37
37
  const icon = playerState.isPaused
38
38
  ? "play"
39
39
  : playerState.isLive && liveButton
40
- ? "stop"
41
- : "pause";
40
+ ? "stop"
41
+ : "pause";
42
42
 
43
43
  return {
44
44
  size: playbackButtonSize(isTablet),
@@ -918,8 +918,8 @@ export default class VideoPlayer extends React.Component<
918
918
  const playerContainerStyles = isApplePlatform()
919
919
  ? styles.playerContainerBlack
920
920
  : isTV() && isAudioItem
921
- ? styles.playerContainerTransparent
922
- : styles.playerContainerBlack;
921
+ ? styles.playerContainerTransparent
922
+ : styles.playerContainerBlack;
923
923
 
924
924
  const isInline = () => {
925
925
  if (isTV()) {
@@ -1,136 +0,0 @@
1
- import { BehaviorSubject } from "rxjs";
2
- import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
3
- import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
4
- import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
5
- import { hasDatePassed, NAMESPACE } from "./utils";
6
-
7
- const { log_debug, log_error } = createLogger({
8
- subsystem: "Player",
9
- category: "SleepTimerManager",
10
- });
11
-
12
- export type SleepTimer = {
13
- label: string;
14
- // interval in minutes for UI at the moment when timer was first started
15
- value: number;
16
- };
17
-
18
- export const SLEEP_TIMER_OFF: SleepTimer = {
19
- label: "playback_sleep_off_label",
20
- value: 0,
21
- };
22
-
23
- export class SleepTimerState {
24
- constructor(
25
- public timer: SleepTimer,
26
- public timerDate: number
27
- ) {}
28
- }
29
-
30
- const SLEEP_PREFERENCE_KEY = "sleep";
31
-
32
- export class SleepTimerController {
33
- private sleepTimerStateSubject = new BehaviorSubject<SleepTimerState>(
34
- new SleepTimerState(SLEEP_TIMER_OFF, 0)
35
- );
36
-
37
- constructor(private player: Player) {}
38
-
39
- get sleepTimerState$() {
40
- return this.sleepTimerStateSubject.asObservable();
41
- }
42
-
43
- async cancelSleepTimer() {
44
- this.player.cancelSleepTimer?.();
45
-
46
- await localStorage.removeItem(SLEEP_PREFERENCE_KEY, NAMESPACE);
47
-
48
- this.sleepTimerStateSubject.next(new SleepTimerState(SLEEP_TIMER_OFF, 0));
49
- }
50
-
51
- private async startSleepTimer(futureSleepDate: number) {
52
- try {
53
- log_debug(`Starting sleep timer at ${futureSleepDate}`);
54
- this.player.cancelSleepTimer?.();
55
- this.player.startSleepTimer?.(futureSleepDate);
56
-
57
- return futureSleepDate;
58
- } catch (e) {
59
- log_error("Failed to start sleep timer", { error: e.message });
60
-
61
- return 0;
62
- }
63
- }
64
-
65
- private async handleSleep(timerValue: number, currentFutureSleepDate = null) {
66
- log_debug("Handling sleep interval", {
67
- timerValue,
68
- currentFutureSleepDate,
69
- });
70
-
71
- if (timerValue === 0) {
72
- await this.cancelSleepTimer();
73
-
74
- return timerValue;
75
- }
76
-
77
- // starting a new timer
78
- if (currentFutureSleepDate == null) {
79
- log_debug(`Starting sleep timer in ${timerValue} minutes`);
80
- const futureSleepDate = Date.now() + timerValue * 60000;
81
-
82
- return this.startSleepTimer(futureSleepDate);
83
- }
84
-
85
- // restoring previous timer (leftover time interval)
86
- if (hasDatePassed(currentFutureSleepDate)) {
87
- log_debug("Sleep date has already passed");
88
- await this.cancelSleepTimer();
89
-
90
- return 0;
91
- }
92
-
93
- log_debug(`Starting sleep timer at ${timerValue}`);
94
-
95
- return this.startSleepTimer(currentFutureSleepDate);
96
- }
97
-
98
- async loadSleep() {
99
- const sleep = await localStorage.getItem(SLEEP_PREFERENCE_KEY, NAMESPACE);
100
-
101
- if (sleep) {
102
- const { futureSleepDate, ...rest } = sleep;
103
-
104
- const sleepTimerDate = await this.handleSleep(
105
- sleep.value,
106
- futureSleepDate
107
- );
108
-
109
- this.sleepTimerStateSubject.next(
110
- new SleepTimerState(rest as SleepTimer, sleepTimerDate)
111
- );
112
-
113
- log_debug(`Sleep state restored, will go to sleep at ${futureSleepDate}`);
114
- }
115
- }
116
-
117
- async setSleepTimer(item: SleepTimer) {
118
- const futureSleepDate = await this.handleSleep(item.value);
119
-
120
- await localStorage.setItem(
121
- SLEEP_PREFERENCE_KEY,
122
- { ...item, futureSleepDate },
123
- NAMESPACE
124
- );
125
-
126
- this.sleepTimerStateSubject.next(
127
- new SleepTimerState(item, futureSleepDate)
128
- );
129
- }
130
-
131
- // TODO: check if it will be called on Android when we need.
132
- // Probably we will have to handle it on native instead.
133
- public static async onPlayerDestroy() {
134
- await localStorage.removeItem(SLEEP_PREFERENCE_KEY, NAMESPACE);
135
- }
136
- }
@@ -1,51 +0,0 @@
1
- import { BehaviorSubject } from "rxjs";
2
- import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
3
- import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
4
- import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
5
- import { NAMESPACE } from "./utils";
6
-
7
- const { log_debug } = createLogger({
8
- subsystem: "Player",
9
- category: "PlaybackSpeedManager",
10
- });
11
-
12
- export type PlaybackSpeed = {
13
- asset: string;
14
- value: number;
15
- };
16
-
17
- const SPEED_PREFERENCE_KEY = "speed";
18
-
19
- export const DEFAULT_SPEED: PlaybackSpeed = {
20
- asset: "speed_1",
21
- value: 1.0,
22
- };
23
-
24
- export class SpeedController {
25
- private playbackSpeedSubject = new BehaviorSubject<PlaybackSpeed>(
26
- DEFAULT_SPEED
27
- );
28
-
29
- constructor(private player: Player) {}
30
-
31
- get playbackSpeed$() {
32
- return this.playbackSpeedSubject.asObservable();
33
- }
34
-
35
- async loadSpeed() {
36
- const speed = await localStorage.getItem(SPEED_PREFERENCE_KEY, NAMESPACE);
37
-
38
- // checking for value in case we will pull empty or broken object
39
- if (speed && speed.value) {
40
- this.playbackSpeedSubject.next(speed);
41
- this.player.setPlaybackRate?.(speed.value);
42
- log_debug(`Speed loaded: ${speed}`);
43
- }
44
- }
45
-
46
- async setPlaybackSpeed(speed: PlaybackSpeed) {
47
- await localStorage.setItem(SPEED_PREFERENCE_KEY, speed, NAMESPACE);
48
- this.playbackSpeedSubject.next(speed);
49
- this.player.setPlaybackRate?.(speed.value);
50
- }
51
- }