Add queue Move/RemoveAt + dormant-Enqueue coherence and shared QueueList (Phase 17.1)

This commit is contained in:
daniel-c-harvey
2026-06-19 14:32:08 -04:00
parent ebbaa3f84f
commit f296bbdf00
4 changed files with 524 additions and 6 deletions
@@ -87,12 +87,45 @@ public interface IQueueService
/// </summary>
Task Start();
/// <summary>Appends a track to the end of the queue without changing what is currently playing.</summary>
/// <summary>
/// Appends a track to the end of the queue without changing what is currently playing.
/// Into a dormant queue (<see cref="CurrentIndex"/> == -1) the append leaves a coherent
/// <see cref="CurrentIndex"/> (the first appended track) so a subsequent play/skip is correct —
/// but it does NOT begin playback (add is not play). Interop-free; safe during prerender.
/// </summary>
void Enqueue(TrackDto track);
/// <summary>Appends tracks to the end of the queue without changing what is currently playing.</summary>
/// <summary>
/// Appends tracks to the end of the queue without changing what is currently playing.
/// Into a dormant queue (<see cref="CurrentIndex"/> == -1) the append leaves a coherent
/// <see cref="CurrentIndex"/> (the first appended track) so a subsequent play/skip is correct —
/// but it does NOT begin playback (add is not play). Interop-free; safe during prerender.
/// </summary>
void EnqueueRange(IEnumerable<TrackDto> tracks);
/// <summary>
/// Reorders the queue, moving the track at <paramref name="fromIndex"/> to
/// <paramref name="toIndex"/>, and re-emits <see cref="QueueChanged"/>. Adjusts
/// <see cref="CurrentIndex"/> so the <em>same track</em> stays current across the move — it does
/// not restart, re-stream, or interrupt the currently-playing track. Interop-free; safe during
/// prerender. No-op (no throw, no <see cref="QueueChanged"/>) when either index is out of range
/// or the indices are equal.
/// </summary>
void Move(int fromIndex, int toIndex);
/// <summary>
/// Removes the track at <paramref name="index"/> and re-emits <see cref="QueueChanged"/>. Does
/// not touch playback (the player stays a single-track device): removing the current track does
/// not stop it — the playing track runs to its natural end while <see cref="CurrentIndex"/>
/// resolves to the new occupant of that slot (the next track) so the next auto-advance/skip is
/// coherent. Removing a track before the current decrements <see cref="CurrentIndex"/> (the same
/// track stays current); removing after the current leaves it unchanged. Removing the last
/// remaining track empties the queue (<see cref="CurrentIndex"/> == -1, dormant). Interop-free;
/// safe during prerender. No-op (no throw, no <see cref="QueueChanged"/>) when
/// <paramref name="index"/> is out of range.
/// </summary>
void RemoveAt(int index);
/// <summary>
/// Advances to the next track and streams it. No-op when <see cref="HasNext"/> is false.
/// </summary>