feat(queue): two-level deque model — PLAY prepends, add appends, last-track-end empties
Fixes five queue bugs: Playlist relabel, last-track-empties, dormant-seed-from-player on first add, immediate panel reactivity, and front/back deque semantics. Adds JumpTo for row jumps.
This commit is contained in:
@@ -45,7 +45,7 @@ else
|
||||
@* Fixed (embed) queue panel (§4 / AC5). A release embed shows the up-next inline below the
|
||||
controls as a read-only list (Editable=false → no drag handles, no remove buttons; C3).
|
||||
Jump-to-track is still allowed (OQ2) — routed through the same OnQueueJump as the docked
|
||||
overlay, which calls PlayRelease (clearing IsArmed if the embed was armed-but-not-started).
|
||||
overlay, which calls JumpTo (moves the pointer and streams the row, clearing IsArmed).
|
||||
Gated on ShowFixedPanel so a single-track embed (empty queue) stays panel-free (UC6). The
|
||||
Queue button collapses/expands this panel (OQ1 Option A); collapse hides it and posts the
|
||||
shrunken height to the host iframe. *@
|
||||
|
||||
@@ -85,7 +85,13 @@ public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
||||
// Gated on Fixed + non-empty so single-track embeds keep their compact, panel-free bar (UC6).
|
||||
private bool ShowFixedPanel => Fixed && HasQueue;
|
||||
|
||||
private IReadOnlyList<TrackDto> QueueItems => QueueService?.Items ?? [];
|
||||
// Snapshot the live queue into a NEW list every render. QueueService.Items returns the service's
|
||||
// backing list by reference, so passing it straight through means Blazor parameter diffing sees an
|
||||
// unchanged reference after an in-place Clear/remove/reorder and the child (QueueList /
|
||||
// MudDropContainer) keeps its stale snapshot until reopened (bug #4). Materializing a fresh list per
|
||||
// access forces the parameter to change identity on every mutation, so the panel re-flows immediately.
|
||||
private IReadOnlyList<TrackDto> QueueItems =>
|
||||
QueueService is null ? [] : QueueService.Items.ToList();
|
||||
private int QueueCurrentIndex => QueueService?.CurrentIndex ?? -1;
|
||||
|
||||
// Fixed-mode panel collapse state (OQ1 Option A). Default expanded so a release embed shows the
|
||||
@@ -189,12 +195,14 @@ public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
||||
|
||||
private void ClearUpcoming() => QueueService?.ClearUpcoming();
|
||||
|
||||
// Jump reuses the existing "play from index" semantics (OQ2). This is the one queue action that
|
||||
// touches playback — it streams the chosen track via the player.
|
||||
// Jump to a row already in the queue. Under the deque model PlayRelease prepends (it is a PLAY,
|
||||
// not an in-place seek), so a jump cannot route through it without duplicating the queue. JumpTo
|
||||
// moves the pointer to the chosen row and streams it once — preserving deque order. This is the one
|
||||
// queue action besides PLAY/skip that touches playback.
|
||||
private async Task OnQueueJump(int index)
|
||||
{
|
||||
if (QueueService == null) return;
|
||||
await QueueService.PlayRelease(QueueService.Items, index);
|
||||
await QueueService.JumpTo(index);
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
|
||||
Reference in New Issue
Block a user