102 lines
2.8 KiB
Dart
102 lines
2.8 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/foundation.dart';
|
|
import '../utils/app_logger.dart';
|
|
|
|
/// Service to manage sleep timer functionality
|
|
/// Allows setting a timer to pause/stop playback after a specified duration
|
|
class SleepTimerService extends ChangeNotifier {
|
|
static final SleepTimerService _instance = SleepTimerService._internal();
|
|
factory SleepTimerService() => _instance;
|
|
SleepTimerService._internal();
|
|
|
|
Timer? _timer;
|
|
DateTime? _endTime;
|
|
Duration? _duration;
|
|
VoidCallback? _onTimerComplete;
|
|
|
|
/// Whether a timer is currently active
|
|
bool get isActive => _timer != null && _timer!.isActive;
|
|
|
|
/// The time when the timer will complete
|
|
DateTime? get endTime => _endTime;
|
|
|
|
/// The original duration of the timer
|
|
Duration? get duration => _duration;
|
|
|
|
/// Remaining time on the timer
|
|
Duration? get remainingTime {
|
|
if (_endTime == null) return null;
|
|
final remaining = _endTime!.difference(DateTime.now());
|
|
return remaining.isNegative ? Duration.zero : remaining;
|
|
}
|
|
|
|
/// Start a sleep timer with the specified duration
|
|
/// [duration] - How long until the timer completes
|
|
/// [onComplete] - Callback to execute when timer completes
|
|
void startTimer(Duration duration, VoidCallback onComplete) {
|
|
// Cancel any existing timer
|
|
cancelTimer();
|
|
|
|
_duration = duration;
|
|
_endTime = DateTime.now().add(duration);
|
|
_onTimerComplete = onComplete;
|
|
|
|
appLogger.d('Sleep timer started: ${duration.inMinutes} minutes');
|
|
|
|
// Create a periodic timer to update remaining time
|
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
final remaining = remainingTime;
|
|
|
|
if (remaining == null || remaining.inSeconds <= 0) {
|
|
appLogger.d('Sleep timer completed');
|
|
_executeCallback();
|
|
cancelTimer();
|
|
} else {
|
|
// Notify listeners to update UI
|
|
notifyListeners();
|
|
}
|
|
});
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
/// Cancel the active timer
|
|
void cancelTimer() {
|
|
if (_timer != null) {
|
|
appLogger.d('Sleep timer cancelled');
|
|
_timer?.cancel();
|
|
_timer = null;
|
|
_endTime = null;
|
|
_duration = null;
|
|
_onTimerComplete = null;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
/// Extend the current timer by the specified duration
|
|
void extendTimer(Duration additionalTime) {
|
|
if (_endTime != null) {
|
|
_endTime = _endTime!.add(additionalTime);
|
|
_duration = _duration != null ? _duration! + additionalTime : additionalTime;
|
|
appLogger.d('Sleep timer extended by ${additionalTime.inMinutes} minutes');
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
void _executeCallback() {
|
|
if (_onTimerComplete != null) {
|
|
try {
|
|
_onTimerComplete!();
|
|
} catch (e) {
|
|
appLogger.e('Error executing sleep timer callback', error: e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_timer?.cancel();
|
|
super.dispose();
|
|
}
|
|
}
|