|
1 | | -import { peek, tick } from 'maverick.js'; |
| 1 | +import { tick, untrack } from 'maverick.js'; |
2 | 2 | import { DOMEvent, type InferEventDetail } from 'maverick.js/std'; |
3 | 3 |
|
4 | 4 | import type { MediaContext } from '../api/media-context'; |
@@ -37,64 +37,71 @@ export class MediaPlayerDelegate { |
37 | 37 | ) { |
38 | 38 | if (__SERVER__) return; |
39 | 39 |
|
40 | | - const { $state, logger } = this._media; |
| 40 | + return untrack(async () => { |
| 41 | + const { logger } = this._media, |
| 42 | + { autoplay, canPlay, started, duration, seekable, buffered, remotePlaybackInfo } = |
| 43 | + this._media.$state; |
41 | 44 |
|
42 | | - if (peek($state.canPlay)) return; |
| 45 | + if (canPlay()) return; |
43 | 46 |
|
44 | | - const detail = { |
45 | | - duration: info?.duration ?? peek($state.duration), |
46 | | - seekable: info?.seekable ?? peek($state.seekable), |
47 | | - buffered: info?.buffered ?? peek($state.buffered), |
48 | | - provider: peek(this._media.$provider)!, |
49 | | - }; |
| 47 | + const detail = { |
| 48 | + duration: info?.duration ?? duration(), |
| 49 | + seekable: info?.seekable ?? seekable(), |
| 50 | + buffered: info?.buffered ?? buffered(), |
| 51 | + provider: this._media.$provider()!, |
| 52 | + }; |
50 | 53 |
|
51 | | - this._notify('can-play', detail, trigger); |
| 54 | + this._notify('can-play', detail, trigger); |
52 | 55 |
|
53 | | - tick(); |
| 56 | + tick(); |
54 | 57 |
|
55 | | - if (__DEV__) { |
56 | | - logger |
57 | | - ?.infoGroup('-~-~-~-~-~-~- ✅ MEDIA READY -~-~-~-~-~-~-') |
58 | | - .labelledLog('Media Store', { ...$state }) |
59 | | - .labelledLog('Trigger Event', trigger) |
60 | | - .dispatch(); |
61 | | - } |
| 58 | + if (__DEV__) { |
| 59 | + logger |
| 60 | + ?.infoGroup('-~-~-~-~-~-~- ✅ MEDIA READY -~-~-~-~-~-~-') |
| 61 | + .labelledLog('Media', this._media) |
| 62 | + .labelledLog('Trigger Event', trigger) |
| 63 | + .dispatch(); |
| 64 | + } |
62 | 65 |
|
63 | | - const provider = peek(this._media.$provider), |
64 | | - { storage } = this._media, |
65 | | - { muted, volume, playsinline, clipStartTime } = this._media.$props, |
66 | | - { remotePlaybackInfo } = this._media.$state, |
67 | | - remotePlaybackTime = remotePlaybackInfo()?.savedState?.currentTime, |
68 | | - wasRemotePlaying = remotePlaybackInfo()?.savedState?.paused === false, |
69 | | - startTime = remotePlaybackTime ?? storage.data.time ?? clipStartTime(), |
70 | | - shouldAutoPlay = wasRemotePlaying || $state.autoplay(); |
71 | | - |
72 | | - if (provider) { |
73 | | - provider.setVolume(storage.data.volume ?? peek(volume)); |
74 | | - provider.setMuted(storage.data.muted ?? peek(muted)); |
75 | | - provider.setPlaysinline?.(peek(playsinline)); |
76 | | - if (startTime > 0) provider.setCurrentTime(startTime); |
77 | | - } |
| 66 | + let provider = this._media.$provider(), |
| 67 | + { storage } = this._media, |
| 68 | + { muted, volume, playsinline, clipStartTime } = this._media.$props; |
78 | 69 |
|
79 | | - if ($state.canPlay() && shouldAutoPlay && !$state.started()) { |
80 | | - await this._attemptAutoplay(trigger); |
81 | | - } |
| 70 | + const remotePlaybackTime = remotePlaybackInfo()?.savedState?.currentTime, |
| 71 | + wasRemotePlaying = remotePlaybackInfo()?.savedState?.paused === false, |
| 72 | + startTime = remotePlaybackTime ?? (await storage?.getTime()) ?? clipStartTime(), |
| 73 | + shouldAutoPlay = wasRemotePlaying || autoplay(); |
| 74 | + |
| 75 | + if (provider) { |
| 76 | + provider.setVolume((await storage?.getVolume()) ?? volume()); |
| 77 | + provider.setMuted((await storage?.getMuted()) ?? muted()); |
| 78 | + provider.setPlaysinline?.(playsinline()); |
| 79 | + if (startTime > 0) provider.setCurrentTime(startTime); |
| 80 | + } |
| 81 | + |
| 82 | + if (canPlay() && shouldAutoPlay && !started()) { |
| 83 | + await this._attemptAutoplay(trigger); |
| 84 | + } |
82 | 85 |
|
83 | | - remotePlaybackInfo.set(null); |
| 86 | + remotePlaybackInfo.set(null); |
| 87 | + }); |
84 | 88 | } |
85 | 89 |
|
86 | 90 | private async _attemptAutoplay(trigger?: Event) { |
87 | | - const { player, $state } = this._media; |
| 91 | + const { |
| 92 | + player, |
| 93 | + $state: { autoPlaying, muted }, |
| 94 | + } = this._media; |
88 | 95 |
|
89 | | - $state.autoPlaying.set(true); |
| 96 | + autoPlaying.set(true); |
90 | 97 |
|
91 | 98 | const attemptEvent = new DOMEvent<void>('autoplay-attempt', { trigger }); |
92 | 99 |
|
93 | 100 | try { |
94 | 101 | await player.play(attemptEvent); |
95 | 102 | } catch (error) { |
96 | 103 | if (__DEV__ && !seenAutoplayWarning) { |
97 | | - const muteMsg = !$state.muted() |
| 104 | + const muteMsg = !muted() |
98 | 105 | ? ' Attempting with volume muted will most likely resolve the issue.' |
99 | 106 | : ''; |
100 | 107 |
|
|
0 commit comments