feature: Auto next-up preview, skip to next in queue. (#96)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2024-11-01 15:52:54 +01:00 committed by GitHub
parent f72ae9e3ca
commit 66f2b6cd4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 971 additions and 137 deletions

View file

@ -1,86 +1,35 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class VideoPlayerSettingsModel {
final double? screenBrightness;
final BoxFit videoFit;
final bool fillScreen;
final bool hardwareAccel;
final bool useLibass;
final double internalVolume;
final String? audioDevice;
const VideoPlayerSettingsModel({
this.screenBrightness,
this.videoFit = BoxFit.contain,
this.fillScreen = false,
this.hardwareAccel = true,
this.useLibass = false,
this.internalVolume = 100,
this.audioDevice,
});
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:fladder/util/localization_helper.dart';
part 'video_player_settings.freezed.dart';
part 'video_player_settings.g.dart';
@freezed
class VideoPlayerSettingsModel with _$VideoPlayerSettingsModel {
const VideoPlayerSettingsModel._();
factory VideoPlayerSettingsModel({
double? screenBrightness,
@Default(BoxFit.contain) BoxFit videoFit,
@Default(false) bool fillScreen,
@Default(true) bool hardwareAccel,
@Default(false) bool useLibass,
@Default(100) double internalVolume,
@Default(AutoNextType.static) AutoNextType nextVideoType,
String? audioDevice,
}) = _VideoPlayerSettingsModel;
double get volume => switch (defaultTargetPlatform) {
TargetPlatform.android || TargetPlatform.iOS => 100,
_ => internalVolume,
};
VideoPlayerSettingsModel copyWith({
ValueGetter<double?>? screenBrightness,
BoxFit? videoFit,
bool? fillScreen,
bool? hardwareAccel,
bool? useLibass,
double? internalVolume,
ValueGetter<String?>? audioDevice,
}) {
return VideoPlayerSettingsModel(
screenBrightness: screenBrightness != null ? screenBrightness() : this.screenBrightness,
videoFit: videoFit ?? this.videoFit,
fillScreen: fillScreen ?? this.fillScreen,
hardwareAccel: hardwareAccel ?? this.hardwareAccel,
useLibass: useLibass ?? this.useLibass,
internalVolume: internalVolume ?? this.internalVolume,
audioDevice: audioDevice != null ? audioDevice() : this.audioDevice,
);
}
Map<String, dynamic> toMap() {
return {
'screenBrightness': screenBrightness,
'videoFit': videoFit.name,
'fillScreen': fillScreen,
'hardwareAccel': hardwareAccel,
'useLibass': useLibass,
'internalVolume': internalVolume,
'audioDevice': audioDevice,
};
}
factory VideoPlayerSettingsModel.fromMap(Map<String, dynamic> map) {
return VideoPlayerSettingsModel(
screenBrightness: map['screenBrightness']?.toDouble(),
videoFit: BoxFit.values.firstWhereOrNull((element) => element.name == map['videoFit']) ?? BoxFit.contain,
fillScreen: map['fillScreen'] ?? false,
hardwareAccel: map['hardwareAccel'] ?? false,
useLibass: map['useLibass'] ?? false,
internalVolume: map['internalVolume']?.toDouble() ?? 0.0,
audioDevice: map['audioDevice'],
);
}
String toJson() => json.encode(toMap());
factory VideoPlayerSettingsModel.fromJson(String source) => VideoPlayerSettingsModel.fromMap(json.decode(source));
@override
String toString() {
return 'VideoPlayerSettingsModel(screenBrightness: $screenBrightness, videoFit: $videoFit, fillScreen: $fillScreen, hardwareAccel: $hardwareAccel, useLibass: $useLibass, internalVolume: $internalVolume, audioDevice: $audioDevice)';
}
factory VideoPlayerSettingsModel.fromJson(Map<String, dynamic> json) => _$VideoPlayerSettingsModelFromJson(json);
bool playerSame(VideoPlayerSettingsModel other) {
return other.hardwareAccel == hardwareAccel && other.useLibass == useLibass;
@ -111,3 +60,23 @@ class VideoPlayerSettingsModel {
audioDevice.hashCode;
}
}
enum AutoNextType {
off,
smart,
static;
const AutoNextType();
String label(BuildContext context) => switch (this) {
AutoNextType.off => context.localized.off,
AutoNextType.smart => context.localized.autoNextOffSmartTitle,
AutoNextType.static => context.localized.autoNextOffStaticTitle,
};
String desc(BuildContext context) => switch (this) {
AutoNextType.off => context.localized.off,
AutoNextType.smart => context.localized.autoNextOffSmartDesc,
AutoNextType.static => context.localized.autoNextOffStaticDesc,
};
}

View file

@ -0,0 +1,319 @@
// 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 'video_player_settings.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');
VideoPlayerSettingsModel _$VideoPlayerSettingsModelFromJson(
Map<String, dynamic> json) {
return _VideoPlayerSettingsModel.fromJson(json);
}
/// @nodoc
mixin _$VideoPlayerSettingsModel {
double? get screenBrightness => throw _privateConstructorUsedError;
BoxFit get videoFit => throw _privateConstructorUsedError;
bool get fillScreen => throw _privateConstructorUsedError;
bool get hardwareAccel => throw _privateConstructorUsedError;
bool get useLibass => throw _privateConstructorUsedError;
double get internalVolume => throw _privateConstructorUsedError;
AutoNextType get nextVideoType => throw _privateConstructorUsedError;
String? get audioDevice => throw _privateConstructorUsedError;
/// Serializes this VideoPlayerSettingsModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of VideoPlayerSettingsModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$VideoPlayerSettingsModelCopyWith<VideoPlayerSettingsModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $VideoPlayerSettingsModelCopyWith<$Res> {
factory $VideoPlayerSettingsModelCopyWith(VideoPlayerSettingsModel value,
$Res Function(VideoPlayerSettingsModel) then) =
_$VideoPlayerSettingsModelCopyWithImpl<$Res, VideoPlayerSettingsModel>;
@useResult
$Res call(
{double? screenBrightness,
BoxFit videoFit,
bool fillScreen,
bool hardwareAccel,
bool useLibass,
double internalVolume,
AutoNextType nextVideoType,
String? audioDevice});
}
/// @nodoc
class _$VideoPlayerSettingsModelCopyWithImpl<$Res,
$Val extends VideoPlayerSettingsModel>
implements $VideoPlayerSettingsModelCopyWith<$Res> {
_$VideoPlayerSettingsModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of VideoPlayerSettingsModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? screenBrightness = freezed,
Object? videoFit = null,
Object? fillScreen = null,
Object? hardwareAccel = null,
Object? useLibass = null,
Object? internalVolume = null,
Object? nextVideoType = null,
Object? audioDevice = freezed,
}) {
return _then(_value.copyWith(
screenBrightness: freezed == screenBrightness
? _value.screenBrightness
: screenBrightness // ignore: cast_nullable_to_non_nullable
as double?,
videoFit: null == videoFit
? _value.videoFit
: videoFit // ignore: cast_nullable_to_non_nullable
as BoxFit,
fillScreen: null == fillScreen
? _value.fillScreen
: fillScreen // ignore: cast_nullable_to_non_nullable
as bool,
hardwareAccel: null == hardwareAccel
? _value.hardwareAccel
: hardwareAccel // ignore: cast_nullable_to_non_nullable
as bool,
useLibass: null == useLibass
? _value.useLibass
: useLibass // ignore: cast_nullable_to_non_nullable
as bool,
internalVolume: null == internalVolume
? _value.internalVolume
: internalVolume // ignore: cast_nullable_to_non_nullable
as double,
nextVideoType: null == nextVideoType
? _value.nextVideoType
: nextVideoType // ignore: cast_nullable_to_non_nullable
as AutoNextType,
audioDevice: freezed == audioDevice
? _value.audioDevice
: audioDevice // ignore: cast_nullable_to_non_nullable
as String?,
) as $Val);
}
}
/// @nodoc
abstract class _$$VideoPlayerSettingsModelImplCopyWith<$Res>
implements $VideoPlayerSettingsModelCopyWith<$Res> {
factory _$$VideoPlayerSettingsModelImplCopyWith(
_$VideoPlayerSettingsModelImpl value,
$Res Function(_$VideoPlayerSettingsModelImpl) then) =
__$$VideoPlayerSettingsModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{double? screenBrightness,
BoxFit videoFit,
bool fillScreen,
bool hardwareAccel,
bool useLibass,
double internalVolume,
AutoNextType nextVideoType,
String? audioDevice});
}
/// @nodoc
class __$$VideoPlayerSettingsModelImplCopyWithImpl<$Res>
extends _$VideoPlayerSettingsModelCopyWithImpl<$Res,
_$VideoPlayerSettingsModelImpl>
implements _$$VideoPlayerSettingsModelImplCopyWith<$Res> {
__$$VideoPlayerSettingsModelImplCopyWithImpl(
_$VideoPlayerSettingsModelImpl _value,
$Res Function(_$VideoPlayerSettingsModelImpl) _then)
: super(_value, _then);
/// Create a copy of VideoPlayerSettingsModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? screenBrightness = freezed,
Object? videoFit = null,
Object? fillScreen = null,
Object? hardwareAccel = null,
Object? useLibass = null,
Object? internalVolume = null,
Object? nextVideoType = null,
Object? audioDevice = freezed,
}) {
return _then(_$VideoPlayerSettingsModelImpl(
screenBrightness: freezed == screenBrightness
? _value.screenBrightness
: screenBrightness // ignore: cast_nullable_to_non_nullable
as double?,
videoFit: null == videoFit
? _value.videoFit
: videoFit // ignore: cast_nullable_to_non_nullable
as BoxFit,
fillScreen: null == fillScreen
? _value.fillScreen
: fillScreen // ignore: cast_nullable_to_non_nullable
as bool,
hardwareAccel: null == hardwareAccel
? _value.hardwareAccel
: hardwareAccel // ignore: cast_nullable_to_non_nullable
as bool,
useLibass: null == useLibass
? _value.useLibass
: useLibass // ignore: cast_nullable_to_non_nullable
as bool,
internalVolume: null == internalVolume
? _value.internalVolume
: internalVolume // ignore: cast_nullable_to_non_nullable
as double,
nextVideoType: null == nextVideoType
? _value.nextVideoType
: nextVideoType // ignore: cast_nullable_to_non_nullable
as AutoNextType,
audioDevice: freezed == audioDevice
? _value.audioDevice
: audioDevice // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// @nodoc
@JsonSerializable()
class _$VideoPlayerSettingsModelImpl extends _VideoPlayerSettingsModel
with DiagnosticableTreeMixin {
_$VideoPlayerSettingsModelImpl(
{this.screenBrightness,
this.videoFit = BoxFit.contain,
this.fillScreen = false,
this.hardwareAccel = true,
this.useLibass = false,
this.internalVolume = 100,
this.nextVideoType = AutoNextType.static,
this.audioDevice})
: super._();
factory _$VideoPlayerSettingsModelImpl.fromJson(Map<String, dynamic> json) =>
_$$VideoPlayerSettingsModelImplFromJson(json);
@override
final double? screenBrightness;
@override
@JsonKey()
final BoxFit videoFit;
@override
@JsonKey()
final bool fillScreen;
@override
@JsonKey()
final bool hardwareAccel;
@override
@JsonKey()
final bool useLibass;
@override
@JsonKey()
final double internalVolume;
@override
@JsonKey()
final AutoNextType nextVideoType;
@override
final String? audioDevice;
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return 'VideoPlayerSettingsModel(screenBrightness: $screenBrightness, videoFit: $videoFit, fillScreen: $fillScreen, hardwareAccel: $hardwareAccel, useLibass: $useLibass, internalVolume: $internalVolume, nextVideoType: $nextVideoType, audioDevice: $audioDevice)';
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty('type', 'VideoPlayerSettingsModel'))
..add(DiagnosticsProperty('screenBrightness', screenBrightness))
..add(DiagnosticsProperty('videoFit', videoFit))
..add(DiagnosticsProperty('fillScreen', fillScreen))
..add(DiagnosticsProperty('hardwareAccel', hardwareAccel))
..add(DiagnosticsProperty('useLibass', useLibass))
..add(DiagnosticsProperty('internalVolume', internalVolume))
..add(DiagnosticsProperty('nextVideoType', nextVideoType))
..add(DiagnosticsProperty('audioDevice', audioDevice));
}
/// Create a copy of VideoPlayerSettingsModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$VideoPlayerSettingsModelImplCopyWith<_$VideoPlayerSettingsModelImpl>
get copyWith => __$$VideoPlayerSettingsModelImplCopyWithImpl<
_$VideoPlayerSettingsModelImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$VideoPlayerSettingsModelImplToJson(
this,
);
}
}
abstract class _VideoPlayerSettingsModel extends VideoPlayerSettingsModel {
factory _VideoPlayerSettingsModel(
{final double? screenBrightness,
final BoxFit videoFit,
final bool fillScreen,
final bool hardwareAccel,
final bool useLibass,
final double internalVolume,
final AutoNextType nextVideoType,
final String? audioDevice}) = _$VideoPlayerSettingsModelImpl;
_VideoPlayerSettingsModel._() : super._();
factory _VideoPlayerSettingsModel.fromJson(Map<String, dynamic> json) =
_$VideoPlayerSettingsModelImpl.fromJson;
@override
double? get screenBrightness;
@override
BoxFit get videoFit;
@override
bool get fillScreen;
@override
bool get hardwareAccel;
@override
bool get useLibass;
@override
double get internalVolume;
@override
AutoNextType get nextVideoType;
@override
String? get audioDevice;
/// Create a copy of VideoPlayerSettingsModel
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$VideoPlayerSettingsModelImplCopyWith<_$VideoPlayerSettingsModelImpl>
get copyWith => throw _privateConstructorUsedError;
}

View file

@ -0,0 +1,52 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'video_player_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$VideoPlayerSettingsModelImpl _$$VideoPlayerSettingsModelImplFromJson(
Map<String, dynamic> json) =>
_$VideoPlayerSettingsModelImpl(
screenBrightness: (json['screenBrightness'] as num?)?.toDouble(),
videoFit: $enumDecodeNullable(_$BoxFitEnumMap, json['videoFit']) ??
BoxFit.contain,
fillScreen: json['fillScreen'] as bool? ?? false,
hardwareAccel: json['hardwareAccel'] as bool? ?? true,
useLibass: json['useLibass'] as bool? ?? false,
internalVolume: (json['internalVolume'] as num?)?.toDouble() ?? 100,
nextVideoType:
$enumDecodeNullable(_$AutoNextTypeEnumMap, json['nextVideoType']) ??
AutoNextType.static,
audioDevice: json['audioDevice'] as String?,
);
Map<String, dynamic> _$$VideoPlayerSettingsModelImplToJson(
_$VideoPlayerSettingsModelImpl instance) =>
<String, dynamic>{
'screenBrightness': instance.screenBrightness,
'videoFit': _$BoxFitEnumMap[instance.videoFit]!,
'fillScreen': instance.fillScreen,
'hardwareAccel': instance.hardwareAccel,
'useLibass': instance.useLibass,
'internalVolume': instance.internalVolume,
'nextVideoType': _$AutoNextTypeEnumMap[instance.nextVideoType]!,
'audioDevice': instance.audioDevice,
};
const _$BoxFitEnumMap = {
BoxFit.fill: 'fill',
BoxFit.contain: 'contain',
BoxFit.cover: 'cover',
BoxFit.fitWidth: 'fitWidth',
BoxFit.fitHeight: 'fitHeight',
BoxFit.none: 'none',
BoxFit.scaleDown: 'scaleDown',
};
const _$AutoNextTypeEnumMap = {
AutoNextType.off: 'off',
AutoNextType.smart: 'smart',
AutoNextType.static: 'static',
};