Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add sleep timer for videos #606

Merged
merged 3 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1374,5 +1374,10 @@
"serverUnreachable": "Server is unreachable, or is not a valid invidious server",
"copyToDownloadFolder": "Copy to download folder",
"fileCopiedToDownloadFolder": "File copied to download folder",
"videoDeleted": "Video deleted"
"videoDeleted": "Video deleted",
"sleepTimer": "Sleep timer",
"stopTheVideo": "Stop the video",
"stopTheVideoExplanation": "If enabled, the video will be closed, if disabled the video will be simply paused",
"setTimer": "Set timer",
"cancelSleepTimer": "Cancel sleep timer"
}
6 changes: 3 additions & 3 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@
"@videoAddedToQueue": {
"description": "Pop up message when a video was added at the end of the video queue"
},
"shareLinkWithTimestamp": "Ajouter l'horodatage",
"shareLinkWithTimestamp": "Ajouter l''horodatage",
"@shareLinkWithTimestamp": {
"description": "asking user to share link along with timestamp"
},
Expand Down Expand Up @@ -1361,7 +1361,7 @@
"@refresh": {},
"wrongThumbnailConfiguration": "Le serveur est joignable mais mal configurée, les vidéos ainsi que les photo de profile des chaînes risquent de ne pas apparaitre proprement. Désactivez le test de la configuration si cela vous convient, sinon réglez le serveur",
"@wrongThumbnailConfiguration": {},
"addBasicAuth": "ajouter une méthode d'autentification basique",
"addBasicAuth": "ajouter une méthode d''autentification basique",
"@addBasicAuth": {},
"value": "Valeur",
"@value": {},
Expand All @@ -1381,7 +1381,7 @@
"@alsoTestServerConfig": {},
"serverAlreadyExists": "Ce serveur existe déjà dans les paramètres",
"@serverAlreadyExists": {},
"openWikiLink": "Ouvrir le Wiki pour avoir de l'aide",
"openWikiLink": "Ouvrir le Wiki pour avoir de l''aide",
"@openWikiLink": {},
"serverUnreachable": "Le serveur n'est pas joignable, ou ceci n'est pas un serveur invidious valide",
"@serverUnreachable": {},
Expand Down
2 changes: 1 addition & 1 deletion lib/l10n/app_sv.arb
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@
"@sponsorBlockCategoryIntroDescription": {
"description": "Sponsorblock 'Intro' Category description"
},
"sponsorBlockCategoryOutroDescription": "Eftertexter eller när YouTube's slutbild visas. Ej för sammanfattning med information.",
"sponsorBlockCategoryOutroDescription": "Eftertexter eller när YouTube''s slutbild visas. Ej för sammanfattning med information.",
"@sponsorBlockCategoryOutroDescription": {
"description": "Outro block 'Outro' Category description"
},
Expand Down
11 changes: 11 additions & 0 deletions lib/player/models/sleep_timer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:freezed_annotation/freezed_annotation.dart';

part 'sleep_timer.freezed.dart';

@freezed
class SleepTimer with _$SleepTimer {
const factory SleepTimer({
@Default(Duration(minutes: 5)) Duration duration,
@Default(true) bool stopVideo,
}) = _SleepTimer;
}
165 changes: 165 additions & 0 deletions lib/player/models/sleep_timer.freezed.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark

part of 'sleep_timer.dart';

// **************************************************************************
// FreezedGenerator
// **************************************************************************

T _$identity<T>(T value) => value;

final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');

/// @nodoc
mixin _$SleepTimer {
Duration get duration => throw _privateConstructorUsedError;
bool get stopVideo => throw _privateConstructorUsedError;

/// Create a copy of SleepTimer
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$SleepTimerCopyWith<SleepTimer> get copyWith =>
throw _privateConstructorUsedError;
}

/// @nodoc
abstract class $SleepTimerCopyWith<$Res> {
factory $SleepTimerCopyWith(
SleepTimer value, $Res Function(SleepTimer) then) =
_$SleepTimerCopyWithImpl<$Res, SleepTimer>;
@useResult
$Res call({Duration duration, bool stopVideo});
}

/// @nodoc
class _$SleepTimerCopyWithImpl<$Res, $Val extends SleepTimer>
implements $SleepTimerCopyWith<$Res> {
_$SleepTimerCopyWithImpl(this._value, this._then);

// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;

/// Create a copy of SleepTimer
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? duration = null,
Object? stopVideo = null,
}) {
return _then(_value.copyWith(
duration: null == duration
? _value.duration
: duration // ignore: cast_nullable_to_non_nullable
as Duration,
stopVideo: null == stopVideo
? _value.stopVideo
: stopVideo // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
}
}

/// @nodoc
abstract class _$$SleepTimerImplCopyWith<$Res>
implements $SleepTimerCopyWith<$Res> {
factory _$$SleepTimerImplCopyWith(
_$SleepTimerImpl value, $Res Function(_$SleepTimerImpl) then) =
__$$SleepTimerImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({Duration duration, bool stopVideo});
}

/// @nodoc
class __$$SleepTimerImplCopyWithImpl<$Res>
extends _$SleepTimerCopyWithImpl<$Res, _$SleepTimerImpl>
implements _$$SleepTimerImplCopyWith<$Res> {
__$$SleepTimerImplCopyWithImpl(
_$SleepTimerImpl _value, $Res Function(_$SleepTimerImpl) _then)
: super(_value, _then);

/// Create a copy of SleepTimer
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? duration = null,
Object? stopVideo = null,
}) {
return _then(_$SleepTimerImpl(
duration: null == duration
? _value.duration
: duration // ignore: cast_nullable_to_non_nullable
as Duration,
stopVideo: null == stopVideo
? _value.stopVideo
: stopVideo // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}

/// @nodoc

class _$SleepTimerImpl implements _SleepTimer {
const _$SleepTimerImpl(
{this.duration = const Duration(minutes: 5), this.stopVideo = true});

@override
@JsonKey()
final Duration duration;
@override
@JsonKey()
final bool stopVideo;

@override
String toString() {
return 'SleepTimer(duration: $duration, stopVideo: $stopVideo)';
}

@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SleepTimerImpl &&
(identical(other.duration, duration) ||
other.duration == duration) &&
(identical(other.stopVideo, stopVideo) ||
other.stopVideo == stopVideo));
}

@override
int get hashCode => Object.hash(runtimeType, duration, stopVideo);

/// Create a copy of SleepTimer
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$SleepTimerImplCopyWith<_$SleepTimerImpl> get copyWith =>
__$$SleepTimerImplCopyWithImpl<_$SleepTimerImpl>(this, _$identity);
}

abstract class _SleepTimer implements SleepTimer {
const factory _SleepTimer({final Duration duration, final bool stopVideo}) =
_$SleepTimerImpl;

@override
Duration get duration;
@override
bool get stopVideo;

/// Create a copy of SleepTimer
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$SleepTimerImplCopyWith<_$SleepTimerImpl> get copyWith =>
throw _privateConstructorUsedError;
}
24 changes: 24 additions & 0 deletions lib/player/states/player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:audio_service/audio_service.dart';
import 'package:audio_session/audio_session.dart';
import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:bloc/bloc.dart';
import 'package:clipious/player/models/sleep_timer.dart';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -240,6 +241,7 @@ class PlayerCubit extends Cubit<PlayerState> with WidgetsBindingObserver {
type: MediaEventType.miniDisplayChanged,
value: state.isMini);
emit(state.copyWith(isClosing: true));
cancelSleep();
Future.delayed(
animationDuration * 1.5,
() {
Expand Down Expand Up @@ -965,6 +967,27 @@ class PlayerCubit extends Cubit<PlayerState> with WidgetsBindingObserver {
setFullScreen(FullScreenState.fullScreen);
}
}

void sleep(SleepTimer sleepTimer) {
emit(state.copyWith(hasTimer: true));

EasyDebounce.debounce(
'video-sleep-timer',
sleepTimer.duration,
() {
emit(state.copyWith(hasTimer: false));
pause();
if (sleepTimer.stopVideo && !isClosed) {
hide();
}
},
);
}

void cancelSleep() {
emit(state.copyWith(hasTimer: false));
EasyDebounce.cancel('video-sleep-timer');
}
}

@freezed
Expand All @@ -973,6 +996,7 @@ class PlayerState with _$PlayerState {
{
// player display properties
@Default(true) bool isMini,
@Default(false) bool hasTimer,
double? top,
@Default(false) bool isDragging,
@Default(0) int selectedFullScreenIndex,
Expand Down
Loading
Loading