sleeptimer

This commit is contained in:
Dr-Blank 2024-06-06 15:35:30 -04:00
parent d372a6b096
commit b98188d7fb
No known key found for this signature in database
GPG key ID: 7452CC63F210A266
17 changed files with 1262 additions and 363 deletions

View file

@ -0,0 +1,89 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:just_audio/just_audio.dart';
import 'package:whispering_pages/features/player/core/audiobook_player.dart';
/// this timer pauses the music player after a certain duration
///
/// watches the state of the music player and pauses it when the timer is up
/// timer is cancelled when the music player is paused or stopped
class SleepTimer {
/// The duration after which the music player will be paused
final Duration duration;
/// The player to be paused
final AudiobookPlayer player;
/// The timer that will pause the player
Timer? timer;
/// for internal use only
/// when the timer was started
DateTime? startedAt;
SleepTimer({required this.duration, required this.player}) {
player.playbackEventStream.listen((event) {
if (event.processingState == ProcessingState.completed ||
event.processingState == ProcessingState.idle) {
reset();
}
});
/// pause the player when the timer is up
player.playerStateStream.listen((state) {
if (state.playing && timer == null) {
startTimer();
} else if (!state.playing) {
reset();
}
});
debugPrint('SleepTimer created with duration: $duration');
}
/// resets the timer
void reset() {
if (timer != null) {
timer!.cancel();
debugPrint(
'SleepTimer cancelled timer, remaining time: $remainingTime, duration: $duration',
);
timer = null;
}
}
/// starts the timer
void startTimer() {
reset();
timer = Timer(duration, () {
player.pause();
reset();
debugPrint('SleepTimer paused player after $duration');
});
startedAt = DateTime.now();
debugPrint('SleepTimer started for $duration at $startedAt');
}
Duration get remainingTime {
if (timer == null) {
return Duration.zero;
}
final elapsed = DateTime.now().difference(startedAt!);
return duration - elapsed;
}
/// a stream that emits the remaining time every second
Stream<Duration> get remainingTimeStream async* {
while (timer != null) {
yield remainingTime;
await Future.delayed(0.5.seconds);
}
}
/// dispose the timer
void dispose() {
reset();
debugPrint('SleepTimer disposed');
}
}

View file

@ -0,0 +1,19 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:whispering_pages/features/player/providers/audiobook_player.dart';
import 'package:whispering_pages/features/sleep_timer/core/sleep_timer.dart';
import 'package:whispering_pages/settings/app_settings_provider.dart';
part 'sleep_timer_provider.g.dart';
@Riverpod(keepAlive: true)
SleepTimer? sleepTimer(SleepTimerRef ref) {
final appSettings = ref.watch(appSettingsProvider);
final sleepTimerSettings = appSettings.playerSettings.sleepTimerSettings;
var sleepTimer = SleepTimer(
// duration: sleepTimerSettings.defaultDuration,
duration: const Duration(seconds: 5),
player: ref.watch(simpleAudiobookPlayerProvider),
);
ref.onDispose(sleepTimer.dispose);
return sleepTimer;
}

View file

@ -0,0 +1,24 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'sleep_timer_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$sleepTimerHash() => r'79646b12412f3300166db29328664a5e58e405bd';
/// See also [sleepTimer].
@ProviderFor(sleepTimer)
final sleepTimerProvider = Provider<SleepTimer?>.internal(
sleepTimer,
name: r'sleepTimerProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$sleepTimerHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef SleepTimerRef = ProviderRef<SleepTimer?>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member