playStatsTrack: fall back to streaming sources when not in library
The Top Tracks sidebar play button on the artist-detail page (and the same buttons on the Stats page) called /api/stats/resolve-track and gave up with a 'Track not found in library' toast on a miss. Now when the library lookup misses, falls through to /api/enhanced- search/stream-track — the same Soulseek/YouTube/streaming-source pipeline the search-results play button uses. So Last.fm popular tracks, recent plays, and stats artist top tracks all play even if you don't own the track yet. Library hit still wins (faster, full quality). Only on miss does it escalate to streaming. Final error toast updated to reflect both paths having been tried.
This commit is contained in:
parent
20dfcf10a5
commit
135f6b9ea1
1 changed files with 47 additions and 12 deletions
|
|
@ -464,6 +464,7 @@ function _renderDbStorageChart(tables, totalFileSize, method) {
|
|||
}
|
||||
|
||||
async function playStatsTrack(title, artist, album) {
|
||||
// 1. Try the library first — fastest and best quality if owned.
|
||||
try {
|
||||
const resp = await fetch('/api/stats/resolve-track', {
|
||||
method: 'POST',
|
||||
|
|
@ -471,22 +472,56 @@ async function playStatsTrack(title, artist, album) {
|
|||
body: JSON.stringify({ title, artist }),
|
||||
});
|
||||
const data = await resp.json();
|
||||
if (!data.success || !data.track) {
|
||||
showToast(data.error || 'Track not found in library', 'error');
|
||||
if (data.success && data.track) {
|
||||
const t = data.track;
|
||||
playLibraryTrack({
|
||||
id: t.id,
|
||||
title: t.title,
|
||||
file_path: t.file_path,
|
||||
bitrate: t.bitrate,
|
||||
artist_id: t.artist_id,
|
||||
album_id: t.album_id,
|
||||
_stats_image: t.image_url || null,
|
||||
}, t.album_title || album || '', t.artist_name || artist || '');
|
||||
return;
|
||||
}
|
||||
const t = data.track;
|
||||
playLibraryTrack({
|
||||
id: t.id,
|
||||
title: t.title,
|
||||
file_path: t.file_path,
|
||||
bitrate: t.bitrate,
|
||||
artist_id: t.artist_id,
|
||||
album_id: t.album_id,
|
||||
_stats_image: t.image_url || null,
|
||||
}, t.album_title || album || '', t.artist_name || artist || '');
|
||||
} catch (e) {
|
||||
console.debug('Library resolve failed, will try streaming fallback:', e);
|
||||
}
|
||||
|
||||
// 2. Library miss — fall back to streaming via the enhanced-search streamer
|
||||
// (Soulseek → YouTube → other configured sources, same pipeline used by
|
||||
// the search results' play button).
|
||||
if (typeof showLoadingOverlay === 'function') {
|
||||
showLoadingOverlay(`Searching for ${title}...`);
|
||||
}
|
||||
try {
|
||||
const streamResp = await fetch('/api/enhanced-search/stream-track', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
track_name: title,
|
||||
artist_name: artist,
|
||||
album_name: album || '',
|
||||
duration_ms: 0,
|
||||
}),
|
||||
});
|
||||
const streamData = await streamResp.json();
|
||||
if (typeof hideLoadingOverlay === 'function') hideLoadingOverlay();
|
||||
|
||||
if (streamData.success && streamData.result) {
|
||||
if (typeof startStream === 'function') {
|
||||
await startStream(streamData.result);
|
||||
} else {
|
||||
showToast('Streaming not available', 'error');
|
||||
}
|
||||
} else {
|
||||
showToast(streamData.error || 'Track not found in library or any source', 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
if (typeof hideLoadingOverlay === 'function') hideLoadingOverlay();
|
||||
showToast('Failed to play track', 'error');
|
||||
console.error('Stream fallback failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue