feat: scrobbling, genre grid redesign with detail view + play button
- Scrobble to Navidrome on auto-advance (Android) and track end (web) so type=recent and type=frequent are accurate for the hero card - Genre section: pill chips → grid cards with colored left bars - Top 15 genres shown by default (sorted by song count), expand toggle - Genre card: click → genre detail page with full song list - Genre card: hover play button → shuffle-play without navigating - Genre detail page reuses album-detail layout (back btn, stats, song list) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
d3a1bf6a82
commit
f79817410b
5 files changed
+115
-19
No files matched your search
@@ -189,6 +189,10 @@ window.NSPlayer = {
|
||||
// doesn't match what native is actually playing, the queues are mismatched.
|
||||
// Allow through if reason='queue' (we triggered a setQueue) or if no IDs to compare.
|
||||
if (liveId && S.queue[idx]?.id && String(liveId) !== String(S.queue[idx].id) && p.reason !== 'queue') return;
|
||||
// Scrobble the track that just finished (auto-advance = it played to completion).
|
||||
if (p.reason === 'auto' && S.queue[S.qIdx]?.id) {
|
||||
api('scrobble', `&id=${S.queue[S.qIdx].id}&time=${Date.now()}`).catch(() => {});
|
||||
}
|
||||
const indexChanged = (idx !== S.qIdx);
|
||||
S.qIdx = idx;
|
||||
const s = S.queue[S.qIdx];
|
||||
@@ -614,6 +618,8 @@ export function nextSong() {
|
||||
|
||||
export function onEnded() {
|
||||
if(S.repeat === 'one') { S.audio.currentTime = 0; S.audio.play(); return; }
|
||||
// Scrobble the track that just finished (web path).
|
||||
if (S.queue[S.qIdx]?.id) api('scrobble', `&id=${S.queue[S.qIdx].id}&time=${Date.now()}`).catch(() => {});
|
||||
nextSong();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user