From 1c54782dd737be8cd0ebd40cd396010106e25edc Mon Sep 17 00:00:00 2001 From: Ultradesu Date: Mon, 8 Jun 2026 17:59:46 +0100 Subject: [PATCH] Fix queue display --- Cargo.lock | 2 +- templates/player/scripts.html | 54 ++++++++++++++++++++++++++++ templates/player/shell.html | 67 ++++++++++++++++++----------------- templates/player/styles.html | 43 ++++++++++++++++++++-- 4 files changed, 130 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6cc7114..386989e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1418,7 +1418,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "furumusic" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-trait", diff --git a/templates/player/scripts.html b/templates/player/scripts.html index 95fc091..53e22ba 100644 --- a/templates/player/scripts.html +++ b/templates/player/scripts.html @@ -822,6 +822,7 @@ document.addEventListener('alpine:init', () => { _playLocal(track, options = {}) { this.currentTrack = track; + Alpine.store('queue')?.syncCurrentIndexToTrack(track); this._localSourceTrackId = track.id; this._historyRecorded = false; this._resetPlaybackTracking(); @@ -1138,6 +1139,7 @@ document.addEventListener('alpine:init', () => { _mirrorRemoteTrack(track, playing, positionSeconds = null) { if (!track) return; this.currentTrack = track; + Alpine.store('queue')?.syncCurrentIndexToTrack(track); this.isPlaying = !!playing; if (positionSeconds !== null) this.currentTime = Math.max(0, Number(positionSeconds || 0)); this.duration = Number(track.duration_seconds || this.duration || 0); @@ -1158,6 +1160,7 @@ document.addEventListener('alpine:init', () => { const track = state.track || queue?.tracks?.[queue.currentIndex] || null; if (track) { this.currentTrack = track; + queue?.syncCurrentIndexToTrack(track); } this.shuffle = !!state.shuffle; this.repeatMode = state.repeat_mode || 'off'; @@ -1359,6 +1362,7 @@ document.addEventListener('alpine:init', () => { : tracks[idx]; if (currentTrack) { this.currentTrack = currentTrack; + queue.syncCurrentIndexToTrack(currentTrack); this._localSourceTrackId = currentTrack.id; this._historyRecorded = false; this._resetPlaybackTracking(); @@ -1976,6 +1980,56 @@ document.addEventListener('alpine:init', () => { return this.tracks.slice(start, start + limit); }, + effectiveCurrentIndex() { + const currentTrack = Alpine.store('player')?.currentTrack || null; + if (currentTrack?.id) { + return this.tracks.findIndex(track => Number(track?.id) === Number(currentTrack.id)); + } + if (!this.tracks.length) return -1; + return Math.max(0, Math.min(Number(this.currentIndex || 0), this.tracks.length - 1)); + }, + + queueItemState(index) { + const current = this.effectiveCurrentIndex(); + if (current < 0) return 'upcoming'; + if (index < current) return 'played'; + if (index === current) return 'current'; + return 'upcoming'; + }, + + displayItems() { + const current = this.effectiveCurrentIndex(); + const playerTrack = Alpine.store('player')?.currentTrack || null; + const items = this.tracks.map((track, index) => ({ + track, + index, + key: `${index}-${track?.id || 'track'}`, + state: current >= 0 + ? (index < current ? 'played' : (index === current ? 'current' : 'upcoming')) + : 'upcoming', + synthetic: false, + })); + + if (playerTrack?.id && current < 0) { + items.unshift({ + track: playerTrack, + index: -1, + key: `current-${playerTrack.id}`, + state: 'current', + synthetic: true, + }); + } + + return items; + }, + + syncCurrentIndexToTrack(track) { + if (!track?.id || !this.tracks.length) return -1; + const index = this.tracks.findIndex(item => Number(item?.id) === Number(track.id)); + if (index >= 0) this.currentIndex = index; + return index; + }, + addToEnd(tracks) { const items = this._tracksForQueueAdd(tracks); if (!items.length) return; diff --git a/templates/player/shell.html b/templates/player/shell.html index a31a50e..6f6d72e 100644 --- a/templates/player/shell.html +++ b/templates/player/shell.html @@ -959,42 +959,43 @@
-