feat(web): scroll-row arrows + stable desktop media tile
Home rows get hover left/right arrows that only show for the scrollable direction (enhanceScrollRow + initScrollRows, called from startApp); visibility recomputed on scroll/resize/content-load. Fix the OS media tile flicker when skipping on desktop PWA: mutate the existing MediaMetadata in place instead of assigning a new one each track (the replacement made Windows tear down and rebuild the tile). Action handlers are now set once. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
7498e45b16
commit
d65fbcd11e
5 files changed
+98
-9
No files matched your search
+24
-9
@@ -1019,23 +1019,38 @@ export function setVolume(v) {
|
||||
|
||||
// ─── MEDIA SESSION ────────────────────────────────────────────────────────
|
||||
|
||||
let _msHandlersSet = false;
|
||||
export function updateMediaSession(s) {
|
||||
// When native is active, Media3 owns the system notification — don't touch it.
|
||||
if (HAS_BRIDGE) return;
|
||||
if(!navigator.mediaSession) return;
|
||||
const ms = navigator.mediaSession;
|
||||
if(!ms) return;
|
||||
const artwork = s.coverArt ? [
|
||||
{ src: _cachedCoverUrl(s.coverArt, 256), sizes:'256x256', type:'image/jpeg' },
|
||||
{ src: _cachedCoverUrl(s.coverArt, 512), sizes:'512x512', type:'image/jpeg' },
|
||||
{ src: _cachedCoverUrl(s.coverArt, 1024), sizes:'1024x1024', type:'image/jpeg' },
|
||||
] : [];
|
||||
navigator.mediaSession.metadata = new MediaMetadata({ title:s.title, artist:s.artist||'', album:s.album||'', artwork });
|
||||
navigator.mediaSession.setActionHandler('play', togglePlay);
|
||||
navigator.mediaSession.setActionHandler('pause', togglePlay);
|
||||
navigator.mediaSession.setActionHandler('previoustrack', prevSong);
|
||||
navigator.mediaSession.setActionHandler('nexttrack', nextSong);
|
||||
navigator.mediaSession.setActionHandler('seekbackward', d => { S.audio.currentTime = Math.max(0, S.audio.currentTime-(d.seekOffset||10)); });
|
||||
navigator.mediaSession.setActionHandler('seekforward', d => { S.audio.currentTime = Math.min(S.audio.duration||0, S.audio.currentTime+(d.seekOffset||10)); });
|
||||
navigator.mediaSession.setActionHandler('seekto', d => { if(d.seekTime!=null) S.audio.currentTime = d.seekTime; });
|
||||
// Mutate the existing metadata in place rather than assigning a new MediaMetadata —
|
||||
// replacing the object makes Windows tear down & rebuild the media tile (visible
|
||||
// flicker when skipping). Spotify-style: keep one object, just update its fields.
|
||||
if (ms.metadata) {
|
||||
ms.metadata.title = s.title;
|
||||
ms.metadata.artist = s.artist || '';
|
||||
ms.metadata.album = s.album || '';
|
||||
ms.metadata.artwork = artwork;
|
||||
} else {
|
||||
ms.metadata = new MediaMetadata({ title:s.title, artist:s.artist||'', album:s.album||'', artwork });
|
||||
}
|
||||
// Action handlers are stable — set them once, not on every track change.
|
||||
if (_msHandlersSet) return;
|
||||
_msHandlersSet = true;
|
||||
ms.setActionHandler('play', togglePlay);
|
||||
ms.setActionHandler('pause', togglePlay);
|
||||
ms.setActionHandler('previoustrack', prevSong);
|
||||
ms.setActionHandler('nexttrack', nextSong);
|
||||
ms.setActionHandler('seekbackward', d => { S.audio.currentTime = Math.max(0, S.audio.currentTime-(d.seekOffset||10)); });
|
||||
ms.setActionHandler('seekforward', d => { S.audio.currentTime = Math.min(S.audio.duration||0, S.audio.currentTime+(d.seekOffset||10)); });
|
||||
ms.setActionHandler('seekto', d => { if(d.seekTime!=null) S.audio.currentTime = d.seekTime; });
|
||||
}
|
||||
|
||||
export function syncMediaSessionPosition() {
|
||||
|
||||
Reference in new issue
Block a user