@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 +6 -6
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +115 -90
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +2 -2
- package/src/Player/AudioLayer/Layout/defaultLayoutsConts.ts +2 -2
- package/src/Player/index.tsx +2 -2
- package/src/Player/AudioLayer/SleepTimerManager.ts +0 -136
- package/src/Player/AudioLayer/SpeedManager.ts +0 -51
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-player",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
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-
|
|
40
|
-
"@applicaster/quick-brick-tv-transport-controls": "13.0.0-rc.
|
|
41
|
-
"@applicaster/zapp-react-native-tvos-app": "13.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.
|
|
43
|
-
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.
|
|
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 {
|
|
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"]
|
|
143
|
-
{ asset: configuration["speed_1"]
|
|
144
|
-
{ asset: configuration["speed_1_2"]
|
|
145
|
-
{ asset: configuration["speed_1_5"]
|
|
146
|
-
{ asset: configuration["speed_2"]
|
|
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 [
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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 [
|
|
182
|
-
|
|
162
|
+
const [sleepTimer, setSleepTimer] = useState({
|
|
163
|
+
label: "playback_sleep_off_label",
|
|
164
|
+
value: 0,
|
|
165
|
+
});
|
|
183
166
|
|
|
184
|
-
const [
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
sleepTimerManager?.sleepTimerState$.subscribe(setSleepTimerState);
|
|
192
|
+
const cancelSleepTimer = async () => {
|
|
193
|
+
player?.cancelSleepTimer();
|
|
214
194
|
|
|
215
|
-
|
|
216
|
-
|
|
195
|
+
setSleepTimer({
|
|
196
|
+
label: "playback_sleep_off_label",
|
|
197
|
+
value: 0,
|
|
198
|
+
});
|
|
217
199
|
|
|
218
|
-
|
|
219
|
-
sleepSubscription?.unsubscribe();
|
|
220
|
-
speedSubscription?.unsubscribe();
|
|
221
|
-
};
|
|
222
|
-
}, [sleepTimerManager, speedManager]);
|
|
200
|
+
setSleepTimerDate(0);
|
|
223
201
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
|
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
|
-
|
|
310
|
+
setPlaybackSpeed(item);
|
|
311
|
+
player.setPlaybackRate(item.value);
|
|
312
|
+
await localStorage.setItem("speed", item, NAMESPACE);
|
|
275
313
|
},
|
|
276
|
-
[
|
|
314
|
+
[player, setPlaybackSpeed]
|
|
277
315
|
);
|
|
278
316
|
|
|
279
317
|
const onSleepSelect = React.useCallback(
|
|
280
318
|
async (item) => {
|
|
281
|
-
|
|
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
|
-
[
|
|
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:
|
|
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
|
-
|
|
383
|
-
? "sleep_timer"
|
|
384
|
-
: "sleep_timer_active"
|
|
409
|
+
sleepTimer.value === 0 ? "sleep_timer" : "sleep_timer_active"
|
|
385
410
|
}
|
|
386
|
-
sleepTimerDate={
|
|
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
|
-
|
|
437
|
-
|
|
461
|
+
sleepTimer.value,
|
|
462
|
+
sleepTimerDate,
|
|
438
463
|
]);
|
|
439
464
|
|
|
440
465
|
if (configuration.magic_background) {
|
package/src/Player/index.tsx
CHANGED
|
@@ -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
|
-
|
|
922
|
-
|
|
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
|
-
}
|