#867 UX: open Tidal discovery modal instantly instead of blocking ~10s on a track pre-fetch
Clicking Discover on a fresh Tidal card awaited /api/tidal/playlist/<id> (which paginates Tidal with a 1s sleep per page + rate-limit throttle, ~10s for a large playlist) BEFORE opening the modal — and the backend discovery worker then re-fetched the same playlist anyway. Now that the modal builds its rows from the backend discovery results (#867), open it immediately and let discovery populate it: no blocking pre-fetch, no redundant double-fetch of the playlist.
This commit is contained in:
parent
846a9c75a0
commit
77829622a7
1 changed files with 11 additions and 34 deletions
|
|
@ -150,42 +150,19 @@ async function handleTidalCardClick(playlistId) {
|
||||||
console.log(`🎵 [Card Click] Tidal card clicked: ${playlistId}, Phase: ${state.phase}`);
|
console.log(`🎵 [Card Click] Tidal card clicked: ${playlistId}, Phase: ${state.phase}`);
|
||||||
|
|
||||||
if (state.phase === 'fresh') {
|
if (state.phase === 'fresh') {
|
||||||
// Fetch tracks if not yet loaded (metadata-only listing doesn't include them)
|
// Open the modal IMMEDIATELY — don't block on a slow Tidal track fetch.
|
||||||
if (!state.playlist.tracks || state.playlist.tracks.length === 0) {
|
// The old flow awaited /api/tidal/playlist/<id> (which paginates with a
|
||||||
console.log(`🎵 Fetching tracks for Tidal playlist: ${state.playlist.name}`);
|
// 1s sleep per page + rate-limit throttle, ~10s for a big playlist)
|
||||||
showLoadingOverlay(`Loading ${state.playlist.name}...`);
|
// before the modal appeared, then the backend re-fetched the same
|
||||||
try {
|
// playlist when discovery started. Now the backend discovery fetch is
|
||||||
const resp = await fetch(`/api/tidal/playlist/${playlistId}`);
|
// the single source of truth and the modal builds its rows from those
|
||||||
if (resp.ok) {
|
// results as they stream in (#867), so we open right away. If the
|
||||||
const fullData = await resp.json();
|
// background loader already cached the track list, the rows seed
|
||||||
if (fullData.tracks && fullData.tracks.length > 0) {
|
// instantly; otherwise the discovery poll fills them in. (#867 UX)
|
||||||
// Convert to Track-like objects for the discovery modal
|
if (!Array.isArray(state.playlist.tracks)) {
|
||||||
state.playlist.tracks = fullData.tracks.map(t => ({
|
state.playlist.tracks = [];
|
||||||
id: t.id, name: t.name, artists: t.artists || [],
|
|
||||||
album: t.album || '', duration_ms: t.duration_ms || 0,
|
|
||||||
track_number: t.track_number || 0
|
|
||||||
}));
|
|
||||||
// Update card count
|
|
||||||
const countEl = document.querySelector(`#tidal-card-${playlistId} .playlist-card-track-count`);
|
|
||||||
if (countEl) countEl.textContent = `${state.playlist.tracks.length} tracks`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Failed to fetch Tidal playlist tracks: ${e}`);
|
|
||||||
hideLoadingOverlay();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.playlist.tracks || state.playlist.tracks.length === 0) {
|
|
||||||
hideLoadingOverlay();
|
|
||||||
showToast('Could not load tracks for this playlist', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hideLoadingOverlay();
|
|
||||||
console.log(`🎵 Ready with ${state.playlist.tracks.length} Tidal tracks for discovery`);
|
|
||||||
|
|
||||||
// Open discovery modal - phase will be updated when discovery actually starts
|
|
||||||
openTidalDiscoveryModal(playlistId, state.playlist);
|
openTidalDiscoveryModal(playlistId, state.playlist);
|
||||||
|
|
||||||
} else if (state.phase === 'discovering' || state.phase === 'discovered' || state.phase === 'syncing' || state.phase === 'sync_complete') {
|
} else if (state.phase === 'discovering' || state.phase === 'discovered' || state.phase === 'syncing' || state.phase === 'sync_complete') {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue