Collapse duplicated setup across the suite into six shared helpers under
test/test_helpers/ and rewrite the 28 suites that were open-coding it:
http_fixtures.dart jsonResponse() for http.Response JSON stubs
library_tab_scaffold.dart pumps library tabs under their required ancestors
multi_server_fixtures.dart MultiServerProvider wiring for widget tests
playback_report_fakes.dart PlaybackReportCall + fake report sinks
profile_stack.dart production-shaped profile dependency graph
theme.dart testMonoTokens for fast-settling widget tests
Net -1245 lines with no change in coverage or assertions.
All timed presets shared one 'timed' bool, so arming any of 15/30/60
minutes checkmarked all three. The service now retains the armed
duration (sleepTimerDuration) and the menu marks the matching preset.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A queue edit can un-arm the next entry in the same instant mpv rolls
into it; the resulting transition was dropped as unexpected, leaving the
UI and progress reporting on the finished track for the entire next
file. Remember the cleared arm (generation-gated) so the transition is
still adopted, and handle the armed track no longer being in the queue:
advance to the queue's real next, or park when nothing follows. Also
fixes the latent fallthrough that left the cursor on the finished track
when the armed track vanished from the queue.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The platforms advertise stop, skip forward/backward, and playback-rate
commands by default, but both the music and video handlers silently
dropped them (Android Auto/Bluetooth stop and FF/rewind did nothing;
iOS/macOS showed a dead rate control). setControlsEnabled now manages
those controls: music handles Stop and in-track skips and stops
advertising a speed control; video handles Stop (exit, matching the
companion remote), skips via a shared relative-seek helper, and rate
changes through player.setRate. Skip commands stay off on iOS/macOS
where they would displace the next/previous lock-screen buttons.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Audio-only mpv core on every platform (dedicated
com.plezy/mpv_audio_player channels): parameterized android/windows/
linux mpv plugins and a new apple MpvAudioPlayerCore, all skipping
video/window paths (vid=no, audio-display=no, gapless-audio=weak).
MusicPlaybackService drives an in-memory queue with shuffle/repeat,
file-loaded-event gapless arming (property edges coalesce and the
android bridge drops them), per-track progress reporting, OS media
controls, audio focus, sleep timer, and error auto-skip.
PlaybackCoordinator enforces one live native player: starting video
disposes the audio core first.