diff --git a/src/lib/discovery-v2/DiscoveryView.svelte b/src/lib/discovery-v2/DiscoveryView.svelte index 97b6c2acc..64805df30 100644 --- a/src/lib/discovery-v2/DiscoveryView.svelte +++ b/src/lib/discovery-v2/DiscoveryView.svelte @@ -43,6 +43,7 @@ import { toggleArtistFavorite } from '$lib/stores/artistFavoritesStore'; import { invoke } from '@tauri-apps/api/core'; import { replacePlaybackQueue } from '$lib/services/queuePlaybackService'; + import { setPlaybackContext } from '$lib/stores/playbackContextStore'; import { playQueueIndex } from '$lib/stores/queueStore'; import type { BackendQueueTrack } from '$lib/stores/queueStore'; @@ -291,6 +292,61 @@ let spotlightTopTracksLoading = $state(false); let spotlightRadioLoading = $state(false); + async function handleContinueListeningTrackClick(track: DiscoveryTrackCard) { + const trackIndex = continueListening.findIndex((entry) => entry.trackId === track.trackId); + if (trackIndex < 0) return; + + const trackIds = continueListening.map((entry) => entry.trackId); + + await setPlaybackContext( + 'home_list', + 'home:continue_listening', + 'Continue Listening', + 'qobuz', + trackIds, + trackIndex, + ); + + try { + const queueTracks: BackendQueueTrack[] = continueListening.map((entry) => ({ + id: entry.trackId, + title: entry.title, + version: null, + artist: entry.artist, + album: entry.album, + duration_secs: entry.durationSeconds, + artwork_url: entry.artwork ?? null, + hires: entry.hires, + bit_depth: entry.bitDepth ?? null, + sample_rate: entry.samplingRate ?? null, + is_local: false, + album_id: entry.albumId ?? null, + artist_id: entry.artistId ?? null, + })); + await replacePlaybackQueue(queueTracks, trackIndex, { + debugLabel: 'discovery-v2:continue-listening', + }); + } catch (err) { + console.error('[discovery-v2] continue listening queue failed', err); + } + + onTrackPlay?.({ + id: track.trackId, + title: track.title, + artist: track.artist, + album: track.album, + albumId: track.albumId, + artistId: track.artistId, + albumArt: track.artwork, + duration: track.duration, + durationSeconds: track.durationSeconds, + hires: track.hires, + bitDepth: track.bitDepth, + samplingRate: track.samplingRate, + isrc: track.isrc, + }); + } + async function handleSpotlightTopTracks() { if (!spotlight || spotlightTopTracksLoading || spotlight.topTracks.length === 0) return; spotlightTopTracksLoading = true; @@ -455,15 +511,7 @@ artist={track.artist} artwork={track.artwork} isPlaying={track.trackId === activeTrackId && isPlaybackActive === true} - onClick={() => onTrackPlay?.({ - id: track.trackId, - title: track.title, - artist: track.artist, - album: track.album, - albumId: track.albumId, - artistId: track.artistId, - albumArt: track.artwork, - } as DisplayTrack)} + onClick={() => handleContinueListeningTrackClick(track)} onArtistClick={track.artistId !== undefined ? () => onTrackGoToArtist?.(track.artistId!) : undefined} diff --git a/src/lib/discovery-v2/data.ts b/src/lib/discovery-v2/data.ts index 8afdcaafd..f2db4784b 100644 --- a/src/lib/discovery-v2/data.ts +++ b/src/lib/discovery-v2/data.ts @@ -234,6 +234,12 @@ export interface DiscoveryTrackCard { albumId?: string; artistId?: number; artwork?: string; + duration: string; + durationSeconds: number; + hires: boolean; + bitDepth?: number; + samplingRate?: number; + isrc?: string; } export interface DiscoveryArtistTile { @@ -267,6 +273,12 @@ interface RecoTrackDisplayMeta { albumArt: string; albumId?: string; artistId?: number; + duration: string; + durationSeconds: number; + hires: boolean; + bitDepth?: number; + samplingRate?: number; + isrc?: string; } interface RecoArtistCardMeta { @@ -673,6 +685,12 @@ export async function fetchHomeResolved( albumId: track.albumId, artistId: track.artistId, artwork: track.albumArt || undefined, + duration: track.duration, + durationSeconds: track.durationSeconds, + hires: track.hires, + bitDepth: track.bitDepth, + samplingRate: track.samplingRate, + isrc: track.isrc, })), topArtists: resp.topArtists.slice(0, perSection).map((a) => ({ artistId: a.id,