From e535fdb4bc0c94ca5fdcc34539ad362831d8139e Mon Sep 17 00:00:00 2001 From: Markury Date: Sat, 4 Oct 2025 16:21:33 -0400 Subject: [PATCH] refactor(ui): housekeeping --- src/lib/components/ContextMenu.svelte | 9 +++++ src/lib/components/NowPlayingPanel.svelte | 14 +++++-- .../components/TriangleVolumeSlider.svelte | 3 ++ src/lib/stores/playback.ts | 2 + .../deezer/playlists/[id]/+page.svelte | 37 +++++++++++-------- 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/lib/components/ContextMenu.svelte b/src/lib/components/ContextMenu.svelte index fdf7318..10bd463 100644 --- a/src/lib/components/ContextMenu.svelte +++ b/src/lib/components/ContextMenu.svelte @@ -48,6 +48,13 @@ onClose(); } } + + function handleKeyDown(e: KeyboardEvent, item: MenuItem) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + handleItemClick(item); + } + }
handleItemClick(item)} + onkeydown={(e) => handleKeyDown(e, item)} + tabindex="0" > {item.label} diff --git a/src/lib/components/NowPlayingPanel.svelte b/src/lib/components/NowPlayingPanel.svelte index 955ceb8..8a33876 100644 --- a/src/lib/components/NowPlayingPanel.svelte +++ b/src/lib/components/NowPlayingPanel.svelte @@ -4,6 +4,14 @@ import LyricsDisplay from '$lib/components/LyricsDisplay.svelte'; import TriangleVolumeSlider from '$lib/components/TriangleVolumeSlider.svelte'; + // Local volume state that syncs with the store + let volume = $state($playback.volume); + + // Sync local volume with store volume + $effect(() => { + volume = $playback.volume; + }); + function handlePlayPause() { playback.togglePlayPause(); } @@ -23,8 +31,8 @@ playback.setCurrentTime(time); } - function handleVolumeChange(volume: number) { - playback.setVolume(volume); + function handleVolumeChange(newVolume: number) { + playback.setVolume(newVolume); } function formatTime(seconds: number): string { @@ -127,7 +135,7 @@
- +
diff --git a/src/lib/components/TriangleVolumeSlider.svelte b/src/lib/components/TriangleVolumeSlider.svelte index 0cd2117..6d93337 100644 --- a/src/lib/components/TriangleVolumeSlider.svelte +++ b/src/lib/components/TriangleVolumeSlider.svelte @@ -148,6 +148,9 @@ bind:this={volumeThumb} onmousedown={handleThumbMouseDown} ontouchstart={handleThumbTouchStart} + role="button" + tabindex="-1" + aria-label="Volume slider thumb" >
diff --git a/src/lib/stores/playback.ts b/src/lib/stores/playback.ts index 17cf5cd..49a98b8 100644 --- a/src/lib/stores/playback.ts +++ b/src/lib/stores/playback.ts @@ -46,6 +46,8 @@ function createPlaybackStore(): PlaybackStore { return { subscribe, + set, + update, // Queue management playTrack(track: Track) { diff --git a/src/routes/services/deezer/playlists/[id]/+page.svelte b/src/routes/services/deezer/playlists/[id]/+page.svelte index 963657c..ded2608 100644 --- a/src/routes/services/deezer/playlists/[id]/+page.svelte +++ b/src/routes/services/deezer/playlists/[id]/+page.svelte @@ -98,24 +98,29 @@ // If we have cached album picture, use it if (cachedTracks[0].album_picture) { playlistPicture = cachedTracks[0].album_picture; - } else if ($deezerAuth.arl && cachedTracks[0].track_id) { - // Fetch album data from API to get cover - try { - deezerAPI.setArl($deezerAuth.arl); - const trackData = await deezerAPI.getTrackData(cachedTracks[0].track_id); - if (trackData && trackData.ALB_PICTURE) { - const albumCoverUrl = `https://e-cdns-images.dzcdn.net/images/cover/${trackData.ALB_PICTURE}/500x500-000000-80-0-0.jpg`; - playlistPicture = albumCoverUrl; + } else if ($deezerAuth.arl) { + // Get the track ID - handle both DeezerTrack (has 'id') and DeezerPlaylistTrack (has 'track_id') + const trackId = 'track_id' in cachedTracks[0] ? cachedTracks[0].track_id : cachedTracks[0].id; - // Update cache with the album picture - const database = await import('$lib/library/deezer-database').then(m => m.initDeezerDatabase()); - await database.execute( - 'UPDATE deezer_playlist_tracks SET album_picture = $1 WHERE track_id = $2', - [albumCoverUrl, cachedTracks[0].track_id] - ); + if (trackId) { + // Fetch album data from API to get cover + try { + deezerAPI.setArl($deezerAuth.arl); + const trackData = await deezerAPI.getTrack(trackId); + if (trackData && trackData.ALB_PICTURE) { + const albumCoverUrl = `https://e-cdns-images.dzcdn.net/images/cover/${trackData.ALB_PICTURE}/500x500-000000-80-0-0.jpg`; + playlistPicture = albumCoverUrl; + + // Update cache with the album picture + const database = await import('$lib/library/deezer-database').then(m => m.initDeezerDatabase()); + await database.execute( + 'UPDATE deezer_playlist_tracks SET album_picture = $1 WHERE track_id = $2', + [albumCoverUrl, trackId] + ); + } + } catch (err) { + console.error('Failed to fetch album cover:', err); } - } catch (err) { - console.error('Failed to fetch album cover:', err); } } }