using DeepDrftModels.DTOs; namespace DeepDrftPublic.Client.Services; /// /// Orchestrates ordered playback ("what plays next") above the single-slot /// . The player stays a single-track device; the queue owns the /// track list, the current position, skip-forward/back, and auto-advance on natural track end. It /// drives playback solely through the player's existing /// — it adds no new playback semantics. /// /// /// Extension posture (open/closed): future shuffle, repeat modes, reordering, and persistence are /// expected. They are additive — a shuffle/repeat strategy slots in behind / /// as the "which index is next" decision; reordering mutates /// and re-emits ; persistence snapshots/restores + /// . None of those require changing this interface's existing members, only /// adding new ones — so consumers written against today's surface keep working. /// /// /// /// With an empty queue ( == -1) the queue is dormant: it drives nothing and /// auto-advances nothing, so direct single-track play through the player behaves exactly as it did /// before the queue existed. /// /// public interface IQueueService { /// The ordered tracks currently queued. Empty when nothing is enqueued. IReadOnlyList Items { get; } /// /// Index into of the track the queue considers current, or -1 when the /// queue is empty. Always a valid index into when non-negative. /// int CurrentIndex { get; } /// The current track, or null when the queue is empty. TrackDto? Current { get; } /// True when there is a track after to advance to. bool HasNext { get; } /// True when there is a track before to step back to. bool HasPrevious { get; } /// /// Raised whenever the queue's contents or current position change. The player bar subscribes /// to re-render its skip-forward/back affordances. Fires on enqueue, advance, step-back, and clear. /// event Action? QueueChanged; /// /// Replaces the queue with (in the order given) and begins streaming /// the track at . This is the "play album" entry point the Cuts /// detail page consumes: pass the release's tracks in ordinal order. A header Play uses /// startIndex: 0; a mid-album row play passes that row's index so the queue continues to /// the end from there. No-op when is empty. /// Task PlayRelease(IEnumerable tracks, int startIndex = 0); /// Appends a track to the end of the queue without changing what is currently playing. void Enqueue(TrackDto track); /// Appends tracks to the end of the queue without changing what is currently playing. void EnqueueRange(IEnumerable tracks); /// /// Advances to the next track and streams it. No-op when is false. /// Task Next(); /// /// Steps back to the previous track and streams it. No-op when is false. /// Task Previous(); /// Empties the queue and resets the position. Does not stop the player. void Clear(); }