Add sleep timer feature

Timer stops playback (pause) after 5/10/15/30/60 min. Wall-clock
deadline is self-correcting against OS throttling; 1Hz tick drives
the countdown UI. Cancelled in stop() so no timer resurrects a paused
player after teardown.

- sleep_timer.dart: isolated time logic, injectable clock for testing
- audio_handler.dart: sleepTimer field + cancel() in stop()
- now_playing_screen.dart: AppBar button + bottom sheet
- 10 unit tests via mocked clock

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dustin-Mike Jens Hähnel
2026-08-16 20:06:08 +02:00
co-authored by Claude Opus 4.8
parent 78f4b55e68
commit 51c2229148
4 changed files with 271 additions and 0 deletions
+4
View File
@@ -1,12 +1,15 @@
import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';
import 'sleep_timer.dart';
/// Kern der Wiedergabe: kapselt just_audio hinter audio_service,
/// damit Hintergrund-Wiedergabe + Lockscreen/Notification funktionieren.
class MeloAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
final AudioPlayer _player = AudioPlayer();
late final SleepTimer sleepTimer;
MeloAudioHandler() {
sleepTimer = SleepTimer(onElapsed: pause);
// just_audio-Events → audio_service PlaybackState
_player.playbackEventStream.map(_transformEvent).pipe(playbackState);
@@ -46,6 +49,7 @@ class MeloAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
@override
Future<void> stop() async {
sleepTimer.cancel();
await _player.stop();
await super.stop();
}