Now you can line up videos. Long-press → "Play next" inserts right
after the current playing item; "Add to queue" appends to the back.
Media3 auto-advances through the queue when each item ends.
Implementation:
* feature/player/Queue.kt — process-wide MutableStateFlow<List<
NowPlayingItem>> that mirrors the controller's MediaItem list
1:1 by index. Append, insertAt, setAll mutators match how the
controller's media items get mutated.
* StrawMediaController.enqueueNext / enqueueLast — build the
MediaItem (same shape as setPlayingFrom), insert into Queue at
the corresponding index, then controller.addMediaItem. Empty-
queue fallback: route through setPlayingFrom (starts playback
immediately) so the user doesn't get a silent no-op.
* PlaybackService Player.Listener.onMediaItemTransition — on auto-
advance, look up the new index in Queue, push the matching
NowPlayingItem into NowPlaying via claim(). Minibar + the SB
skip-loop (both reactive to NowPlaying.current) reflect the
new track without any extra wiring.
* feature/detail/StreamResolution.kt — extracted the
resolveStreamPlayback function out of VideoDetailViewModel so
the queue path can call it for each new item.
* VideoActionsSheet wires Play next / Add to queue rows that
launch into StrawApp.globalScope (process-scoped) — sheet
dismisses immediately for snappy UX, but the strawcore network
resolve lives in a scope that outlives the sheet. Toast on
completion.
* StrawApp exposes appScope via a companion `globalScope` for
fire-and-forget work that needs to outlive Composition.
Known limitation:
* SponsorBlock segments are not fetched for queued items — they
play through without skips. The originally-played item (added
via setPlayingFrom) still gets SB. Folding in lazy per-item SB
fetch on transition is a follow-up.