diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index e2c4df6..f4882f7 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -121,6 +121,7 @@ pub fn run() { title TEXT NOT NULL, artist_name TEXT NOT NULL, album_title TEXT, + album_picture TEXT, duration INTEGER DEFAULT 0, track_number INTEGER, cached_at INTEGER NOT NULL, diff --git a/src/lib/library/deezer-database.ts b/src/lib/library/deezer-database.ts index 8f880ae..f274537 100644 --- a/src/lib/library/deezer-database.ts +++ b/src/lib/library/deezer-database.ts @@ -36,6 +36,7 @@ export interface DeezerTrack { title: string; artist_name: string; album_title: string; + album_picture?: string | null; duration: number; cached_at: number; } @@ -47,6 +48,7 @@ export interface DeezerPlaylistTrack { title: string; artist_name: string; album_title: string; + album_picture: string | null; duration: number; track_number: number | null; cached_at: number; @@ -292,15 +294,21 @@ export async function upsertPlaylistTracks(playlistId: string, tracks: any[]): P // Insert new tracks for (let i = 0; i < tracks.length; i++) { const track = tracks[i]; + // Convert ALB_PICTURE hash to full URL + const albumPictureUrl = track.ALB_PICTURE + ? `https://e-cdns-images.dzcdn.net/images/cover/${track.ALB_PICTURE}/500x500-000000-80-0-0.jpg` + : null; + await database.execute( - `INSERT INTO deezer_playlist_tracks (playlist_id, track_id, title, artist_name, album_title, duration, track_number, cached_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, + `INSERT INTO deezer_playlist_tracks (playlist_id, track_id, title, artist_name, album_title, album_picture, duration, track_number, cached_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, [ playlistId, String(track.SNG_ID), track.SNG_TITLE || '', track.ART_NAME || 'Unknown', track.ALB_TITLE || '', + albumPictureUrl, track.DURATION || 0, track.TRACK_NUMBER || i + 1, now diff --git a/src/lib/library/playlist.ts b/src/lib/library/playlist.ts index 7ad45c1..6ea593d 100644 --- a/src/lib/library/playlist.ts +++ b/src/lib/library/playlist.ts @@ -1,6 +1,7 @@ import { readTextFile, exists, readDir } from '@tauri-apps/plugin-fs'; import { invoke } from '@tauri-apps/api/core'; import type { Track, AudioFormat, PlaylistWithTracks, TrackMetadata } from '$lib/types/track'; +import { findAlbumArt } from './album'; /** * Get audio format from file extension @@ -210,6 +211,40 @@ export async function findPlaylistArt(playlistPath: string): Promise { + for (const track of tracks) { + const album = track.metadata.album; + const albumArtist = track.metadata.albumArtist || track.metadata.artist; + + if (!album || !albumArtist) { + continue; // Skip tracks without album metadata + } + + // Construct album folder path following the same structure as downloader + const albumPath = `${musicFolder}/${albumArtist}/${album}`; + + try { + // Check if album folder exists and has cover art + const coverArtPath = await findAlbumArt(albumPath); + if (coverArtPath) { + return coverArtPath; + } + } catch (error) { + // Album folder doesn't exist or can't be read, continue to next track + continue; + } + } + + return undefined; +} + /** * Load playlist with track information */ diff --git a/src/routes/playlists/[name]/+page.svelte b/src/routes/playlists/[name]/+page.svelte index ed0b299..781c977 100644 --- a/src/routes/playlists/[name]/+page.svelte +++ b/src/routes/playlists/[name]/+page.svelte @@ -3,7 +3,7 @@ import { page } from '$app/stores'; import { settings, loadSettings } from '$lib/stores/settings'; import { scanPlaylists } from '$lib/library/scanner'; - import { loadPlaylistTracks, findPlaylistArt } from '$lib/library/playlist'; + import { loadPlaylistTracks, findPlaylistArt, findPlaylistCoverFallback } from '$lib/library/playlist'; import CollectionView from '$lib/components/CollectionView.svelte'; import type { Track, PlaylistWithTracks } from '$lib/types/track'; @@ -58,6 +58,11 @@ playlistData = tracksData; coverArtPath = coverPath; + // If no cover art found, try fallback from first track's album + if (!coverArtPath && playlistData.tracks.length > 0) { + coverArtPath = await findPlaylistCoverFallback(playlistData.tracks, $settings.musicFolder); + } + loading = false; } catch (e) { error = 'Error loading playlist: ' + (e as Error).message; diff --git a/src/routes/services/deezer/playlists/[id]/+page.svelte b/src/routes/services/deezer/playlists/[id]/+page.svelte index cce0774..963657c 100644 --- a/src/routes/services/deezer/playlists/[id]/+page.svelte +++ b/src/routes/services/deezer/playlists/[id]/+page.svelte @@ -1,6 +1,7 @@