fix(music): mark only the active sleep timer preset selected

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>
This commit is contained in:
edde746
2026-07-06 15:31:29 +02:00
co-authored by Claude Fable 5
parent 32c4810c21
commit 226be37f85
4 changed files with 33 additions and 1 deletions
@@ -117,6 +117,10 @@ abstract class MusicPlaybackService extends ChangeNotifier {
/// inactive.
DateTime? get sleepTimerEndsAt;
/// The duration the timed sleep timer was armed with (for marking the
/// chosen preset); null in end-of-track mode or when inactive.
Duration? get sleepTimerDuration;
/// Whether the sleep timer pauses at the end of the current track instead
/// of after a fixed duration.
bool get sleepTimerEndOfTrack;
@@ -233,6 +237,9 @@ class StubMusicPlaybackService extends MusicPlaybackService {
@override
DateTime? get sleepTimerEndsAt => null;
@override
Duration? get sleepTimerDuration => null;
@override
bool get sleepTimerEndOfTrack => false;
@@ -129,6 +129,7 @@ class MusicPlaybackServiceImpl extends MusicPlaybackService with WidgetsBindingO
Timer? _sleepTimer;
DateTime? _sleepTimerEndsAt;
Duration? _sleepTimerDuration;
bool _sleepTimerEndOfTrack = false;
final StreamController<Duration> _positionController = StreamController<Duration>.broadcast();
@@ -186,6 +187,9 @@ class MusicPlaybackServiceImpl extends MusicPlaybackService with WidgetsBindingO
@override
DateTime? get sleepTimerEndsAt => _sleepTimerEndsAt;
@override
Duration? get sleepTimerDuration => _sleepTimerDuration;
@override
bool get sleepTimerEndOfTrack => _sleepTimerEndOfTrack;
@@ -932,10 +936,12 @@ class MusicPlaybackServiceImpl extends MusicPlaybackService with WidgetsBindingO
_sleepTimer?.cancel();
_sleepTimer = null;
_sleepTimerEndsAt = null;
_sleepTimerDuration = null;
final hadEndOfTrack = _sleepTimerEndOfTrack;
_sleepTimerEndOfTrack = endOfTrack;
if (!endOfTrack && duration != null) {
_sleepTimerEndsAt = DateTime.now().add(duration);
_sleepTimerDuration = duration;
_sleepTimer = Timer(duration, _onSleepTimerFired);
}
// End-of-track mode suppresses gapless arming (and leaving it restores
@@ -949,6 +955,7 @@ class MusicPlaybackServiceImpl extends MusicPlaybackService with WidgetsBindingO
void _onSleepTimerFired() {
_sleepTimer = null;
_sleepTimerEndsAt = null;
_sleepTimerDuration = null;
unawaited(pause());
notifyListeners();
}
@@ -957,6 +964,7 @@ class MusicPlaybackServiceImpl extends MusicPlaybackService with WidgetsBindingO
_sleepTimer?.cancel();
_sleepTimer = null;
_sleepTimerEndsAt = null;
_sleepTimerDuration = null;
_sleepTimerEndOfTrack = false;
}