mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 13:38:13 -08:00
feature: Add support for mediaSegments (#138)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
36758bd508
commit
5c560e54b5
28 changed files with 6823 additions and 8312 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -4,7 +4,8 @@
|
|||
"jellyfin",
|
||||
"Jellyfin",
|
||||
"LTRB",
|
||||
"LTWH"
|
||||
"LTWH",
|
||||
"outro"
|
||||
],
|
||||
"dart.flutterSdkPath": ".fvm/versions/3.24.3",
|
||||
"search.exclude": {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,6 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
enum AnalysisMode {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('Introduction')
|
||||
introduction('Introduction'),
|
||||
@JsonValue('Credits')
|
||||
credits('Credits');
|
||||
|
||||
final String? value;
|
||||
|
||||
const AnalysisMode(this.value);
|
||||
}
|
||||
|
||||
enum AudioSpatialFormat {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
|
@ -313,6 +299,20 @@ enum DayPattern {
|
|||
const DayPattern(this.value);
|
||||
}
|
||||
|
||||
enum DeinterlaceMethod {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('yadif')
|
||||
yadif('yadif'),
|
||||
@JsonValue('bwdif')
|
||||
bwdif('bwdif');
|
||||
|
||||
final String? value;
|
||||
|
||||
const DeinterlaceMethod(this.value);
|
||||
}
|
||||
|
||||
enum DlnaProfileType {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
|
@ -342,7 +342,11 @@ enum DownMixStereoAlgorithms {
|
|||
@JsonValue('Dave750')
|
||||
dave750('Dave750'),
|
||||
@JsonValue('NightmodeDialogue')
|
||||
nightmodedialogue('NightmodeDialogue');
|
||||
nightmodedialogue('NightmodeDialogue'),
|
||||
@JsonValue('Rfc7845')
|
||||
rfc7845('Rfc7845'),
|
||||
@JsonValue('Ac4')
|
||||
ac4('Ac4');
|
||||
|
||||
final String? value;
|
||||
|
||||
|
|
@ -397,6 +401,38 @@ enum EmbeddedSubtitleOptions {
|
|||
const EmbeddedSubtitleOptions(this.value);
|
||||
}
|
||||
|
||||
enum EncoderPreset {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('auto')
|
||||
auto('auto'),
|
||||
@JsonValue('placebo')
|
||||
placebo('placebo'),
|
||||
@JsonValue('veryslow')
|
||||
veryslow('veryslow'),
|
||||
@JsonValue('slower')
|
||||
slower('slower'),
|
||||
@JsonValue('slow')
|
||||
slow('slow'),
|
||||
@JsonValue('medium')
|
||||
medium('medium'),
|
||||
@JsonValue('fast')
|
||||
fast('fast'),
|
||||
@JsonValue('faster')
|
||||
faster('faster'),
|
||||
@JsonValue('veryfast')
|
||||
veryfast('veryfast'),
|
||||
@JsonValue('superfast')
|
||||
superfast('superfast'),
|
||||
@JsonValue('ultrafast')
|
||||
ultrafast('ultrafast');
|
||||
|
||||
final String? value;
|
||||
|
||||
const EncoderPreset(this.value);
|
||||
}
|
||||
|
||||
enum EncodingContext {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
|
@ -705,28 +741,30 @@ enum GroupUpdateType {
|
|||
const GroupUpdateType(this.value);
|
||||
}
|
||||
|
||||
enum HardwareEncodingType {
|
||||
enum HardwareAccelerationType {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('AMF')
|
||||
amf('AMF'),
|
||||
@JsonValue('QSV')
|
||||
qsv('QSV'),
|
||||
@JsonValue('NVENC')
|
||||
nvenc('NVENC'),
|
||||
@JsonValue('V4L2M2M')
|
||||
v4l2m2m('V4L2M2M'),
|
||||
@JsonValue('VAAPI')
|
||||
vaapi('VAAPI'),
|
||||
@JsonValue('VideoToolBox')
|
||||
videotoolbox('VideoToolBox'),
|
||||
@JsonValue('RKMPP')
|
||||
rkmpp('RKMPP');
|
||||
@JsonValue('none')
|
||||
none('none'),
|
||||
@JsonValue('amf')
|
||||
amf('amf'),
|
||||
@JsonValue('qsv')
|
||||
qsv('qsv'),
|
||||
@JsonValue('nvenc')
|
||||
nvenc('nvenc'),
|
||||
@JsonValue('v4l2m2m')
|
||||
v4l2m2m('v4l2m2m'),
|
||||
@JsonValue('vaapi')
|
||||
vaapi('vaapi'),
|
||||
@JsonValue('videotoolbox')
|
||||
videotoolbox('videotoolbox'),
|
||||
@JsonValue('rkmpp')
|
||||
rkmpp('rkmpp');
|
||||
|
||||
final String? value;
|
||||
|
||||
const HardwareEncodingType(this.value);
|
||||
const HardwareAccelerationType(this.value);
|
||||
}
|
||||
|
||||
enum ImageFormat {
|
||||
|
|
@ -1199,6 +1237,28 @@ enum MediaProtocol {
|
|||
const MediaProtocol(this.value);
|
||||
}
|
||||
|
||||
enum MediaSegmentType {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('Unknown')
|
||||
unknown('Unknown'),
|
||||
@JsonValue('Commercial')
|
||||
commercial('Commercial'),
|
||||
@JsonValue('Preview')
|
||||
preview('Preview'),
|
||||
@JsonValue('Recap')
|
||||
recap('Recap'),
|
||||
@JsonValue('Outro')
|
||||
outro('Outro'),
|
||||
@JsonValue('Intro')
|
||||
intro('Intro');
|
||||
|
||||
final String? value;
|
||||
|
||||
const MediaSegmentType(this.value);
|
||||
}
|
||||
|
||||
enum MediaSourceType {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
|
@ -2011,6 +2071,68 @@ enum TaskState {
|
|||
const TaskState(this.value);
|
||||
}
|
||||
|
||||
enum TonemappingAlgorithm {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('none')
|
||||
none('none'),
|
||||
@JsonValue('clip')
|
||||
clip('clip'),
|
||||
@JsonValue('linear')
|
||||
linear('linear'),
|
||||
@JsonValue('gamma')
|
||||
gamma('gamma'),
|
||||
@JsonValue('reinhard')
|
||||
reinhard('reinhard'),
|
||||
@JsonValue('hable')
|
||||
hable('hable'),
|
||||
@JsonValue('mobius')
|
||||
mobius('mobius'),
|
||||
@JsonValue('bt2390')
|
||||
bt2390('bt2390');
|
||||
|
||||
final String? value;
|
||||
|
||||
const TonemappingAlgorithm(this.value);
|
||||
}
|
||||
|
||||
enum TonemappingMode {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('auto')
|
||||
auto('auto'),
|
||||
@JsonValue('max')
|
||||
max('max'),
|
||||
@JsonValue('rgb')
|
||||
rgb('rgb'),
|
||||
@JsonValue('lum')
|
||||
lum('lum'),
|
||||
@JsonValue('itp')
|
||||
itp('itp');
|
||||
|
||||
final String? value;
|
||||
|
||||
const TonemappingMode(this.value);
|
||||
}
|
||||
|
||||
enum TonemappingRange {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('auto')
|
||||
auto('auto'),
|
||||
@JsonValue('tv')
|
||||
tv('tv'),
|
||||
@JsonValue('pc')
|
||||
pc('pc');
|
||||
|
||||
final String? value;
|
||||
|
||||
const TonemappingRange(this.value);
|
||||
}
|
||||
|
||||
enum TranscodeReason {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
|
@ -2064,7 +2186,9 @@ enum TranscodeReason {
|
|||
@JsonValue('DirectPlayError')
|
||||
directplayerror('DirectPlayError'),
|
||||
@JsonValue('VideoRangeTypeNotSupported')
|
||||
videorangetypenotsupported('VideoRangeTypeNotSupported');
|
||||
videorangetypenotsupported('VideoRangeTypeNotSupported'),
|
||||
@JsonValue('VideoCodecTagNotSupported')
|
||||
videocodectagnotsupported('VideoCodecTagNotSupported');
|
||||
|
||||
final String? value;
|
||||
|
||||
|
|
@ -2138,7 +2262,9 @@ enum TranscodingInfoTranscodeReasons {
|
|||
@JsonValue('DirectPlayError')
|
||||
directplayerror('DirectPlayError'),
|
||||
@JsonValue('VideoRangeTypeNotSupported')
|
||||
videorangetypenotsupported('VideoRangeTypeNotSupported');
|
||||
videorangetypenotsupported('VideoRangeTypeNotSupported'),
|
||||
@JsonValue('VideoCodecTagNotSupported')
|
||||
videocodectagnotsupported('VideoCodecTagNotSupported');
|
||||
|
||||
final String? value;
|
||||
|
||||
|
|
@ -5023,62 +5149,6 @@ enum SessionsSessionIdViewingPostItemType {
|
|||
const SessionsSessionIdViewingPostItemType(this.value);
|
||||
}
|
||||
|
||||
enum EpisodeIdIntroTimestampsGetMode {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('Introduction')
|
||||
introduction('Introduction'),
|
||||
@JsonValue('Credits')
|
||||
credits('Credits');
|
||||
|
||||
final String? value;
|
||||
|
||||
const EpisodeIdIntroTimestampsGetMode(this.value);
|
||||
}
|
||||
|
||||
enum EpisodeIdIntroTimestampsV1GetMode {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('Introduction')
|
||||
introduction('Introduction'),
|
||||
@JsonValue('Credits')
|
||||
credits('Credits');
|
||||
|
||||
final String? value;
|
||||
|
||||
const EpisodeIdIntroTimestampsV1GetMode(this.value);
|
||||
}
|
||||
|
||||
enum IntrosAllGetMode {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('Introduction')
|
||||
introduction('Introduction'),
|
||||
@JsonValue('Credits')
|
||||
credits('Credits');
|
||||
|
||||
final String? value;
|
||||
|
||||
const IntrosAllGetMode(this.value);
|
||||
}
|
||||
|
||||
enum IntrosEraseTimestampsPostMode {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
||||
@JsonValue('Introduction')
|
||||
introduction('Introduction'),
|
||||
@JsonValue('Credits')
|
||||
credits('Credits');
|
||||
|
||||
final String? value;
|
||||
|
||||
const IntrosEraseTimestampsPostMode(this.value);
|
||||
}
|
||||
|
||||
enum ShowsSeriesIdEpisodesGetSortBy {
|
||||
@JsonValue(null)
|
||||
swaggerGeneratedUnknown(null),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,47 +0,0 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first, invalid_annotation_target
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'intro_skip_model.freezed.dart';
|
||||
part 'intro_skip_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class IntroOutSkipModel with _$IntroOutSkipModel {
|
||||
const IntroOutSkipModel._();
|
||||
factory IntroOutSkipModel({
|
||||
IntroSkipModel? intro,
|
||||
IntroSkipModel? credits,
|
||||
}) = _IntroOutSkipModel;
|
||||
|
||||
factory IntroOutSkipModel.fromJson(Map<String, dynamic> json) => _$IntroOutSkipModelFromJson(json);
|
||||
|
||||
bool introInRange(Duration position) {
|
||||
if (intro == null) return false;
|
||||
return (position.compareTo(intro!.showTime) >= 0 && position.compareTo(intro!.hideTime) <= 0);
|
||||
}
|
||||
|
||||
bool creditsInRange(Duration position) {
|
||||
if (credits == null) return false;
|
||||
return (position.compareTo(credits!.showTime) >= 0 && position.compareTo(credits!.hideTime) <= 0);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class IntroSkipModel with _$IntroSkipModel {
|
||||
factory IntroSkipModel({
|
||||
@JsonKey(name: "EpisodeId") required String id,
|
||||
@JsonKey(name: "Valid") required bool valid,
|
||||
@JsonKey(name: "IntroStart", fromJson: _durationFromMilliseconds, toJson: _durationToMilliseconds)
|
||||
required Duration start,
|
||||
@JsonKey(name: "IntroEnd", fromJson: _durationFromMilliseconds, toJson: _durationToMilliseconds)
|
||||
required Duration end,
|
||||
@JsonKey(name: "ShowSkipPromptAt", fromJson: _durationFromMilliseconds, toJson: _durationToMilliseconds)
|
||||
required Duration showTime,
|
||||
@JsonKey(name: "HideSkipPromptAt", fromJson: _durationFromMilliseconds, toJson: _durationToMilliseconds)
|
||||
required Duration hideTime,
|
||||
}) = _IntroSkipModel;
|
||||
|
||||
factory IntroSkipModel.fromJson(Map<String, dynamic> json) => _$IntroSkipModelFromJson(json);
|
||||
}
|
||||
|
||||
Duration _durationFromMilliseconds(num milliseconds) => Duration(milliseconds: (milliseconds * 1000).toInt());
|
||||
num _durationToMilliseconds(Duration duration) => duration.inMilliseconds.toDouble() / 1000.0;
|
||||
|
|
@ -1,595 +0,0 @@
|
|||
// 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 'intro_skip_model.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');
|
||||
|
||||
IntroOutSkipModel _$IntroOutSkipModelFromJson(Map<String, dynamic> json) {
|
||||
return _IntroOutSkipModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$IntroOutSkipModel {
|
||||
IntroSkipModel? get intro => throw _privateConstructorUsedError;
|
||||
IntroSkipModel? get credits => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this IntroOutSkipModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of IntroOutSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$IntroOutSkipModelCopyWith<IntroOutSkipModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $IntroOutSkipModelCopyWith<$Res> {
|
||||
factory $IntroOutSkipModelCopyWith(
|
||||
IntroOutSkipModel value, $Res Function(IntroOutSkipModel) then) =
|
||||
_$IntroOutSkipModelCopyWithImpl<$Res, IntroOutSkipModel>;
|
||||
@useResult
|
||||
$Res call({IntroSkipModel? intro, IntroSkipModel? credits});
|
||||
|
||||
$IntroSkipModelCopyWith<$Res>? get intro;
|
||||
$IntroSkipModelCopyWith<$Res>? get credits;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$IntroOutSkipModelCopyWithImpl<$Res, $Val extends IntroOutSkipModel>
|
||||
implements $IntroOutSkipModelCopyWith<$Res> {
|
||||
_$IntroOutSkipModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of IntroOutSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? intro = freezed,
|
||||
Object? credits = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
intro: freezed == intro
|
||||
? _value.intro
|
||||
: intro // ignore: cast_nullable_to_non_nullable
|
||||
as IntroSkipModel?,
|
||||
credits: freezed == credits
|
||||
? _value.credits
|
||||
: credits // ignore: cast_nullable_to_non_nullable
|
||||
as IntroSkipModel?,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
/// Create a copy of IntroOutSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$IntroSkipModelCopyWith<$Res>? get intro {
|
||||
if (_value.intro == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $IntroSkipModelCopyWith<$Res>(_value.intro!, (value) {
|
||||
return _then(_value.copyWith(intro: value) as $Val);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a copy of IntroOutSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$IntroSkipModelCopyWith<$Res>? get credits {
|
||||
if (_value.credits == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $IntroSkipModelCopyWith<$Res>(_value.credits!, (value) {
|
||||
return _then(_value.copyWith(credits: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$IntroOutSkipModelImplCopyWith<$Res>
|
||||
implements $IntroOutSkipModelCopyWith<$Res> {
|
||||
factory _$$IntroOutSkipModelImplCopyWith(_$IntroOutSkipModelImpl value,
|
||||
$Res Function(_$IntroOutSkipModelImpl) then) =
|
||||
__$$IntroOutSkipModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({IntroSkipModel? intro, IntroSkipModel? credits});
|
||||
|
||||
@override
|
||||
$IntroSkipModelCopyWith<$Res>? get intro;
|
||||
@override
|
||||
$IntroSkipModelCopyWith<$Res>? get credits;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$IntroOutSkipModelImplCopyWithImpl<$Res>
|
||||
extends _$IntroOutSkipModelCopyWithImpl<$Res, _$IntroOutSkipModelImpl>
|
||||
implements _$$IntroOutSkipModelImplCopyWith<$Res> {
|
||||
__$$IntroOutSkipModelImplCopyWithImpl(_$IntroOutSkipModelImpl _value,
|
||||
$Res Function(_$IntroOutSkipModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of IntroOutSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? intro = freezed,
|
||||
Object? credits = freezed,
|
||||
}) {
|
||||
return _then(_$IntroOutSkipModelImpl(
|
||||
intro: freezed == intro
|
||||
? _value.intro
|
||||
: intro // ignore: cast_nullable_to_non_nullable
|
||||
as IntroSkipModel?,
|
||||
credits: freezed == credits
|
||||
? _value.credits
|
||||
: credits // ignore: cast_nullable_to_non_nullable
|
||||
as IntroSkipModel?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$IntroOutSkipModelImpl extends _IntroOutSkipModel {
|
||||
_$IntroOutSkipModelImpl({this.intro, this.credits}) : super._();
|
||||
|
||||
factory _$IntroOutSkipModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$IntroOutSkipModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
final IntroSkipModel? intro;
|
||||
@override
|
||||
final IntroSkipModel? credits;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'IntroOutSkipModel(intro: $intro, credits: $credits)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$IntroOutSkipModelImpl &&
|
||||
(identical(other.intro, intro) || other.intro == intro) &&
|
||||
(identical(other.credits, credits) || other.credits == credits));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, intro, credits);
|
||||
|
||||
/// Create a copy of IntroOutSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$IntroOutSkipModelImplCopyWith<_$IntroOutSkipModelImpl> get copyWith =>
|
||||
__$$IntroOutSkipModelImplCopyWithImpl<_$IntroOutSkipModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$IntroOutSkipModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _IntroOutSkipModel extends IntroOutSkipModel {
|
||||
factory _IntroOutSkipModel(
|
||||
{final IntroSkipModel? intro,
|
||||
final IntroSkipModel? credits}) = _$IntroOutSkipModelImpl;
|
||||
_IntroOutSkipModel._() : super._();
|
||||
|
||||
factory _IntroOutSkipModel.fromJson(Map<String, dynamic> json) =
|
||||
_$IntroOutSkipModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
IntroSkipModel? get intro;
|
||||
@override
|
||||
IntroSkipModel? get credits;
|
||||
|
||||
/// Create a copy of IntroOutSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$IntroOutSkipModelImplCopyWith<_$IntroOutSkipModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
IntroSkipModel _$IntroSkipModelFromJson(Map<String, dynamic> json) {
|
||||
return _IntroSkipModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$IntroSkipModel {
|
||||
@JsonKey(name: "EpisodeId")
|
||||
String get id => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "Valid")
|
||||
bool get valid => throw _privateConstructorUsedError;
|
||||
@JsonKey(
|
||||
name: "IntroStart",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get start => throw _privateConstructorUsedError;
|
||||
@JsonKey(
|
||||
name: "IntroEnd",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get end => throw _privateConstructorUsedError;
|
||||
@JsonKey(
|
||||
name: "ShowSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get showTime => throw _privateConstructorUsedError;
|
||||
@JsonKey(
|
||||
name: "HideSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get hideTime => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this IntroSkipModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of IntroSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$IntroSkipModelCopyWith<IntroSkipModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $IntroSkipModelCopyWith<$Res> {
|
||||
factory $IntroSkipModelCopyWith(
|
||||
IntroSkipModel value, $Res Function(IntroSkipModel) then) =
|
||||
_$IntroSkipModelCopyWithImpl<$Res, IntroSkipModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: "EpisodeId") String id,
|
||||
@JsonKey(name: "Valid") bool valid,
|
||||
@JsonKey(
|
||||
name: "IntroStart",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration start,
|
||||
@JsonKey(
|
||||
name: "IntroEnd",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration end,
|
||||
@JsonKey(
|
||||
name: "ShowSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration showTime,
|
||||
@JsonKey(
|
||||
name: "HideSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration hideTime});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$IntroSkipModelCopyWithImpl<$Res, $Val extends IntroSkipModel>
|
||||
implements $IntroSkipModelCopyWith<$Res> {
|
||||
_$IntroSkipModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of IntroSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? valid = null,
|
||||
Object? start = null,
|
||||
Object? end = null,
|
||||
Object? showTime = null,
|
||||
Object? hideTime = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
valid: null == valid
|
||||
? _value.valid
|
||||
: valid // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
start: null == start
|
||||
? _value.start
|
||||
: start // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
end: null == end
|
||||
? _value.end
|
||||
: end // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
showTime: null == showTime
|
||||
? _value.showTime
|
||||
: showTime // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
hideTime: null == hideTime
|
||||
? _value.hideTime
|
||||
: hideTime // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$IntroSkipModelImplCopyWith<$Res>
|
||||
implements $IntroSkipModelCopyWith<$Res> {
|
||||
factory _$$IntroSkipModelImplCopyWith(_$IntroSkipModelImpl value,
|
||||
$Res Function(_$IntroSkipModelImpl) then) =
|
||||
__$$IntroSkipModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: "EpisodeId") String id,
|
||||
@JsonKey(name: "Valid") bool valid,
|
||||
@JsonKey(
|
||||
name: "IntroStart",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration start,
|
||||
@JsonKey(
|
||||
name: "IntroEnd",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration end,
|
||||
@JsonKey(
|
||||
name: "ShowSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration showTime,
|
||||
@JsonKey(
|
||||
name: "HideSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration hideTime});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$IntroSkipModelImplCopyWithImpl<$Res>
|
||||
extends _$IntroSkipModelCopyWithImpl<$Res, _$IntroSkipModelImpl>
|
||||
implements _$$IntroSkipModelImplCopyWith<$Res> {
|
||||
__$$IntroSkipModelImplCopyWithImpl(
|
||||
_$IntroSkipModelImpl _value, $Res Function(_$IntroSkipModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of IntroSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? valid = null,
|
||||
Object? start = null,
|
||||
Object? end = null,
|
||||
Object? showTime = null,
|
||||
Object? hideTime = null,
|
||||
}) {
|
||||
return _then(_$IntroSkipModelImpl(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
valid: null == valid
|
||||
? _value.valid
|
||||
: valid // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
start: null == start
|
||||
? _value.start
|
||||
: start // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
end: null == end
|
||||
? _value.end
|
||||
: end // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
showTime: null == showTime
|
||||
? _value.showTime
|
||||
: showTime // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
hideTime: null == hideTime
|
||||
? _value.hideTime
|
||||
: hideTime // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$IntroSkipModelImpl implements _IntroSkipModel {
|
||||
_$IntroSkipModelImpl(
|
||||
{@JsonKey(name: "EpisodeId") required this.id,
|
||||
@JsonKey(name: "Valid") required this.valid,
|
||||
@JsonKey(
|
||||
name: "IntroStart",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required this.start,
|
||||
@JsonKey(
|
||||
name: "IntroEnd",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required this.end,
|
||||
@JsonKey(
|
||||
name: "ShowSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required this.showTime,
|
||||
@JsonKey(
|
||||
name: "HideSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required this.hideTime});
|
||||
|
||||
factory _$IntroSkipModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$IntroSkipModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
@JsonKey(name: "EpisodeId")
|
||||
final String id;
|
||||
@override
|
||||
@JsonKey(name: "Valid")
|
||||
final bool valid;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "IntroStart",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
final Duration start;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "IntroEnd",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
final Duration end;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "ShowSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
final Duration showTime;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "HideSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
final Duration hideTime;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'IntroSkipModel(id: $id, valid: $valid, start: $start, end: $end, showTime: $showTime, hideTime: $hideTime)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$IntroSkipModelImpl &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.valid, valid) || other.valid == valid) &&
|
||||
(identical(other.start, start) || other.start == start) &&
|
||||
(identical(other.end, end) || other.end == end) &&
|
||||
(identical(other.showTime, showTime) ||
|
||||
other.showTime == showTime) &&
|
||||
(identical(other.hideTime, hideTime) ||
|
||||
other.hideTime == hideTime));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, id, valid, start, end, showTime, hideTime);
|
||||
|
||||
/// Create a copy of IntroSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$IntroSkipModelImplCopyWith<_$IntroSkipModelImpl> get copyWith =>
|
||||
__$$IntroSkipModelImplCopyWithImpl<_$IntroSkipModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$IntroSkipModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _IntroSkipModel implements IntroSkipModel {
|
||||
factory _IntroSkipModel(
|
||||
{@JsonKey(name: "EpisodeId") required final String id,
|
||||
@JsonKey(name: "Valid") required final bool valid,
|
||||
@JsonKey(
|
||||
name: "IntroStart",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required final Duration start,
|
||||
@JsonKey(
|
||||
name: "IntroEnd",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required final Duration end,
|
||||
@JsonKey(
|
||||
name: "ShowSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required final Duration showTime,
|
||||
@JsonKey(
|
||||
name: "HideSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
required final Duration hideTime}) = _$IntroSkipModelImpl;
|
||||
|
||||
factory _IntroSkipModel.fromJson(Map<String, dynamic> json) =
|
||||
_$IntroSkipModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: "EpisodeId")
|
||||
String get id;
|
||||
@override
|
||||
@JsonKey(name: "Valid")
|
||||
bool get valid;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "IntroStart",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get start;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "IntroEnd",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get end;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "ShowSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get showTime;
|
||||
@override
|
||||
@JsonKey(
|
||||
name: "HideSkipPromptAt",
|
||||
fromJson: _durationFromMilliseconds,
|
||||
toJson: _durationToMilliseconds)
|
||||
Duration get hideTime;
|
||||
|
||||
/// Create a copy of IntroSkipModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$IntroSkipModelImplCopyWith<_$IntroSkipModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'intro_skip_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$IntroOutSkipModelImpl _$$IntroOutSkipModelImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$IntroOutSkipModelImpl(
|
||||
intro: json['intro'] == null
|
||||
? null
|
||||
: IntroSkipModel.fromJson(json['intro'] as Map<String, dynamic>),
|
||||
credits: json['credits'] == null
|
||||
? null
|
||||
: IntroSkipModel.fromJson(json['credits'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$IntroOutSkipModelImplToJson(
|
||||
_$IntroOutSkipModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'intro': instance.intro,
|
||||
'credits': instance.credits,
|
||||
};
|
||||
|
||||
_$IntroSkipModelImpl _$$IntroSkipModelImplFromJson(Map<String, dynamic> json) =>
|
||||
_$IntroSkipModelImpl(
|
||||
id: json['EpisodeId'] as String,
|
||||
valid: json['Valid'] as bool,
|
||||
start: _durationFromMilliseconds(json['IntroStart'] as num),
|
||||
end: _durationFromMilliseconds(json['IntroEnd'] as num),
|
||||
showTime: _durationFromMilliseconds(json['ShowSkipPromptAt'] as num),
|
||||
hideTime: _durationFromMilliseconds(json['HideSkipPromptAt'] as num),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$IntroSkipModelImplToJson(
|
||||
_$IntroSkipModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'EpisodeId': instance.id,
|
||||
'Valid': instance.valid,
|
||||
'IntroStart': _durationToMilliseconds(instance.start),
|
||||
'IntroEnd': _durationToMilliseconds(instance.end),
|
||||
'ShowSkipPromptAt': _durationToMilliseconds(instance.showTime),
|
||||
'HideSkipPromptAt': _durationToMilliseconds(instance.hideTime),
|
||||
};
|
||||
79
lib/models/items/media_segments_model.dart
Normal file
79
lib/models/items/media_segments_model.dart
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
|
||||
part 'media_segments_model.freezed.dart';
|
||||
part 'media_segments_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class MediaSegmentsModel with _$MediaSegmentsModel {
|
||||
const MediaSegmentsModel._();
|
||||
|
||||
factory MediaSegmentsModel({
|
||||
@Default([]) List<MediaSegment> segments,
|
||||
}) = _MediaSegmentsModel;
|
||||
|
||||
factory MediaSegmentsModel.fromJson(Map<String, dynamic> json) => _$MediaSegmentsModelFromJson(json);
|
||||
|
||||
MediaSegment? get intro => segments.firstWhereOrNull((element) => element.type == MediaSegmentType.intro);
|
||||
MediaSegment? get outro => segments.firstWhereOrNull((element) => element.type == MediaSegmentType.outro);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class MediaSegment with _$MediaSegment {
|
||||
const MediaSegment._();
|
||||
|
||||
factory MediaSegment({
|
||||
required MediaSegmentType type,
|
||||
required Duration start,
|
||||
required Duration end,
|
||||
}) = _MediaSegment;
|
||||
|
||||
factory MediaSegment.fromJson(Map<String, dynamic> json) => _$MediaSegmentFromJson(json);
|
||||
|
||||
bool inRange(Duration position) => (position.compareTo(start) >= 0 && position.compareTo(end) <= 0);
|
||||
}
|
||||
|
||||
enum MediaSegmentType {
|
||||
unknown,
|
||||
commercial,
|
||||
preview,
|
||||
recap,
|
||||
outro,
|
||||
intro;
|
||||
|
||||
Color get color => switch (this) {
|
||||
MediaSegmentType.unknown => Colors.black,
|
||||
MediaSegmentType.commercial => Colors.purpleAccent,
|
||||
MediaSegmentType.preview => Colors.deepOrangeAccent,
|
||||
MediaSegmentType.recap => Colors.lightBlueAccent,
|
||||
MediaSegmentType.outro => Colors.yellowAccent,
|
||||
MediaSegmentType.intro => Colors.greenAccent,
|
||||
};
|
||||
|
||||
static MediaSegmentType fromDto(dto.MediaSegmentType? value) {
|
||||
return switch (value) {
|
||||
dto.MediaSegmentType.swaggerGeneratedUnknown => MediaSegmentType.unknown,
|
||||
dto.MediaSegmentType.unknown => MediaSegmentType.unknown,
|
||||
dto.MediaSegmentType.commercial => MediaSegmentType.commercial,
|
||||
dto.MediaSegmentType.preview => MediaSegmentType.preview,
|
||||
dto.MediaSegmentType.recap => MediaSegmentType.recap,
|
||||
dto.MediaSegmentType.outro => MediaSegmentType.outro,
|
||||
dto.MediaSegmentType.intro => MediaSegmentType.intro,
|
||||
null => MediaSegmentType.unknown,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
extension MediaSegmentExtension on dto.MediaSegmentDto {
|
||||
MediaSegment get toSegment => MediaSegment(
|
||||
type: MediaSegmentType.fromDto(type),
|
||||
start: _durationToMilliseconds(startTicks ?? 0),
|
||||
end: _durationToMilliseconds(endTicks ?? 0),
|
||||
);
|
||||
}
|
||||
|
||||
Duration _durationToMilliseconds(num milliseconds) => Duration(milliseconds: (milliseconds ~/ 10000));
|
||||
363
lib/models/items/media_segments_model.freezed.dart
Normal file
363
lib/models/items/media_segments_model.freezed.dart
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
// 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 'media_segments_model.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');
|
||||
|
||||
MediaSegmentsModel _$MediaSegmentsModelFromJson(Map<String, dynamic> json) {
|
||||
return _MediaSegmentsModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MediaSegmentsModel {
|
||||
List<MediaSegment> get segments => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this MediaSegmentsModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of MediaSegmentsModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$MediaSegmentsModelCopyWith<MediaSegmentsModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $MediaSegmentsModelCopyWith<$Res> {
|
||||
factory $MediaSegmentsModelCopyWith(
|
||||
MediaSegmentsModel value, $Res Function(MediaSegmentsModel) then) =
|
||||
_$MediaSegmentsModelCopyWithImpl<$Res, MediaSegmentsModel>;
|
||||
@useResult
|
||||
$Res call({List<MediaSegment> segments});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$MediaSegmentsModelCopyWithImpl<$Res, $Val extends MediaSegmentsModel>
|
||||
implements $MediaSegmentsModelCopyWith<$Res> {
|
||||
_$MediaSegmentsModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of MediaSegmentsModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? segments = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
segments: null == segments
|
||||
? _value.segments
|
||||
: segments // ignore: cast_nullable_to_non_nullable
|
||||
as List<MediaSegment>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MediaSegmentsModelImplCopyWith<$Res>
|
||||
implements $MediaSegmentsModelCopyWith<$Res> {
|
||||
factory _$$MediaSegmentsModelImplCopyWith(_$MediaSegmentsModelImpl value,
|
||||
$Res Function(_$MediaSegmentsModelImpl) then) =
|
||||
__$$MediaSegmentsModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({List<MediaSegment> segments});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MediaSegmentsModelImplCopyWithImpl<$Res>
|
||||
extends _$MediaSegmentsModelCopyWithImpl<$Res, _$MediaSegmentsModelImpl>
|
||||
implements _$$MediaSegmentsModelImplCopyWith<$Res> {
|
||||
__$$MediaSegmentsModelImplCopyWithImpl(_$MediaSegmentsModelImpl _value,
|
||||
$Res Function(_$MediaSegmentsModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of MediaSegmentsModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? segments = null,
|
||||
}) {
|
||||
return _then(_$MediaSegmentsModelImpl(
|
||||
segments: null == segments
|
||||
? _value._segments
|
||||
: segments // ignore: cast_nullable_to_non_nullable
|
||||
as List<MediaSegment>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$MediaSegmentsModelImpl extends _MediaSegmentsModel {
|
||||
_$MediaSegmentsModelImpl({final List<MediaSegment> segments = const []})
|
||||
: _segments = segments,
|
||||
super._();
|
||||
|
||||
factory _$MediaSegmentsModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$MediaSegmentsModelImplFromJson(json);
|
||||
|
||||
final List<MediaSegment> _segments;
|
||||
@override
|
||||
@JsonKey()
|
||||
List<MediaSegment> get segments {
|
||||
if (_segments is EqualUnmodifiableListView) return _segments;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_segments);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MediaSegmentsModel(segments: $segments)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$MediaSegmentsModelImpl &&
|
||||
const DeepCollectionEquality().equals(other._segments, _segments));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, const DeepCollectionEquality().hash(_segments));
|
||||
|
||||
/// Create a copy of MediaSegmentsModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$MediaSegmentsModelImplCopyWith<_$MediaSegmentsModelImpl> get copyWith =>
|
||||
__$$MediaSegmentsModelImplCopyWithImpl<_$MediaSegmentsModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$MediaSegmentsModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MediaSegmentsModel extends MediaSegmentsModel {
|
||||
factory _MediaSegmentsModel({final List<MediaSegment> segments}) =
|
||||
_$MediaSegmentsModelImpl;
|
||||
_MediaSegmentsModel._() : super._();
|
||||
|
||||
factory _MediaSegmentsModel.fromJson(Map<String, dynamic> json) =
|
||||
_$MediaSegmentsModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
List<MediaSegment> get segments;
|
||||
|
||||
/// Create a copy of MediaSegmentsModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$MediaSegmentsModelImplCopyWith<_$MediaSegmentsModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
MediaSegment _$MediaSegmentFromJson(Map<String, dynamic> json) {
|
||||
return _MediaSegment.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MediaSegment {
|
||||
MediaSegmentType get type => throw _privateConstructorUsedError;
|
||||
Duration get start => throw _privateConstructorUsedError;
|
||||
Duration get end => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this MediaSegment to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of MediaSegment
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$MediaSegmentCopyWith<MediaSegment> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $MediaSegmentCopyWith<$Res> {
|
||||
factory $MediaSegmentCopyWith(
|
||||
MediaSegment value, $Res Function(MediaSegment) then) =
|
||||
_$MediaSegmentCopyWithImpl<$Res, MediaSegment>;
|
||||
@useResult
|
||||
$Res call({MediaSegmentType type, Duration start, Duration end});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$MediaSegmentCopyWithImpl<$Res, $Val extends MediaSegment>
|
||||
implements $MediaSegmentCopyWith<$Res> {
|
||||
_$MediaSegmentCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of MediaSegment
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? type = null,
|
||||
Object? start = null,
|
||||
Object? end = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
type: null == type
|
||||
? _value.type
|
||||
: type // ignore: cast_nullable_to_non_nullable
|
||||
as MediaSegmentType,
|
||||
start: null == start
|
||||
? _value.start
|
||||
: start // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
end: null == end
|
||||
? _value.end
|
||||
: end // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MediaSegmentImplCopyWith<$Res>
|
||||
implements $MediaSegmentCopyWith<$Res> {
|
||||
factory _$$MediaSegmentImplCopyWith(
|
||||
_$MediaSegmentImpl value, $Res Function(_$MediaSegmentImpl) then) =
|
||||
__$$MediaSegmentImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({MediaSegmentType type, Duration start, Duration end});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MediaSegmentImplCopyWithImpl<$Res>
|
||||
extends _$MediaSegmentCopyWithImpl<$Res, _$MediaSegmentImpl>
|
||||
implements _$$MediaSegmentImplCopyWith<$Res> {
|
||||
__$$MediaSegmentImplCopyWithImpl(
|
||||
_$MediaSegmentImpl _value, $Res Function(_$MediaSegmentImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of MediaSegment
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? type = null,
|
||||
Object? start = null,
|
||||
Object? end = null,
|
||||
}) {
|
||||
return _then(_$MediaSegmentImpl(
|
||||
type: null == type
|
||||
? _value.type
|
||||
: type // ignore: cast_nullable_to_non_nullable
|
||||
as MediaSegmentType,
|
||||
start: null == start
|
||||
? _value.start
|
||||
: start // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
end: null == end
|
||||
? _value.end
|
||||
: end // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$MediaSegmentImpl extends _MediaSegment {
|
||||
_$MediaSegmentImpl(
|
||||
{required this.type, required this.start, required this.end})
|
||||
: super._();
|
||||
|
||||
factory _$MediaSegmentImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$MediaSegmentImplFromJson(json);
|
||||
|
||||
@override
|
||||
final MediaSegmentType type;
|
||||
@override
|
||||
final Duration start;
|
||||
@override
|
||||
final Duration end;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MediaSegment(type: $type, start: $start, end: $end)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$MediaSegmentImpl &&
|
||||
(identical(other.type, type) || other.type == type) &&
|
||||
(identical(other.start, start) || other.start == start) &&
|
||||
(identical(other.end, end) || other.end == end));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, type, start, end);
|
||||
|
||||
/// Create a copy of MediaSegment
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$MediaSegmentImplCopyWith<_$MediaSegmentImpl> get copyWith =>
|
||||
__$$MediaSegmentImplCopyWithImpl<_$MediaSegmentImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$MediaSegmentImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MediaSegment extends MediaSegment {
|
||||
factory _MediaSegment(
|
||||
{required final MediaSegmentType type,
|
||||
required final Duration start,
|
||||
required final Duration end}) = _$MediaSegmentImpl;
|
||||
_MediaSegment._() : super._();
|
||||
|
||||
factory _MediaSegment.fromJson(Map<String, dynamic> json) =
|
||||
_$MediaSegmentImpl.fromJson;
|
||||
|
||||
@override
|
||||
MediaSegmentType get type;
|
||||
@override
|
||||
Duration get start;
|
||||
@override
|
||||
Duration get end;
|
||||
|
||||
/// Create a copy of MediaSegment
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$MediaSegmentImplCopyWith<_$MediaSegmentImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
45
lib/models/items/media_segments_model.g.dart
Normal file
45
lib/models/items/media_segments_model.g.dart
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'media_segments_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$MediaSegmentsModelImpl _$$MediaSegmentsModelImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$MediaSegmentsModelImpl(
|
||||
segments: (json['segments'] as List<dynamic>?)
|
||||
?.map((e) => MediaSegment.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const [],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$MediaSegmentsModelImplToJson(
|
||||
_$MediaSegmentsModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'segments': instance.segments,
|
||||
};
|
||||
|
||||
_$MediaSegmentImpl _$$MediaSegmentImplFromJson(Map<String, dynamic> json) =>
|
||||
_$MediaSegmentImpl(
|
||||
type: $enumDecode(_$MediaSegmentTypeEnumMap, json['type']),
|
||||
start: Duration(microseconds: (json['start'] as num).toInt()),
|
||||
end: Duration(microseconds: (json['end'] as num).toInt()),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$MediaSegmentImplToJson(_$MediaSegmentImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'type': _$MediaSegmentTypeEnumMap[instance.type]!,
|
||||
'start': instance.start.inMicroseconds,
|
||||
'end': instance.end.inMicroseconds,
|
||||
};
|
||||
|
||||
const _$MediaSegmentTypeEnumMap = {
|
||||
MediaSegmentType.unknown: 'unknown',
|
||||
MediaSegmentType.commercial: 'commercial',
|
||||
MediaSegmentType.preview: 'preview',
|
||||
MediaSegmentType.recap: 'recap',
|
||||
MediaSegmentType.outro: 'outro',
|
||||
MediaSegmentType.intro: 'intro',
|
||||
};
|
||||
|
|
@ -5,7 +5,7 @@ import 'package:media_kit/media_kit.dart';
|
|||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/trick_play_model.dart';
|
||||
import 'package:fladder/models/playback/playback_model.dart';
|
||||
|
|
@ -23,7 +23,7 @@ class DirectPlaybackModel implements PlaybackModel {
|
|||
required this.media,
|
||||
required this.playbackInfo,
|
||||
this.mediaStreams,
|
||||
this.introSkipModel,
|
||||
this.mediaSegments,
|
||||
this.chapters,
|
||||
this.trickPlay,
|
||||
this.queue = const [],
|
||||
|
|
@ -42,7 +42,7 @@ class DirectPlaybackModel implements PlaybackModel {
|
|||
final MediaStreamsModel? mediaStreams;
|
||||
|
||||
@override
|
||||
final IntroOutSkipModel? introSkipModel;
|
||||
final MediaSegmentsModel? mediaSegments;
|
||||
|
||||
@override
|
||||
final List<Chapter>? chapters;
|
||||
|
|
@ -180,7 +180,7 @@ class DirectPlaybackModel implements PlaybackModel {
|
|||
ValueGetter<Duration>? lastPosition,
|
||||
PlaybackInfoResponse? playbackInfo,
|
||||
ValueGetter<MediaStreamsModel?>? mediaStreams,
|
||||
ValueGetter<IntroOutSkipModel?>? introSkipModel,
|
||||
ValueGetter<MediaSegmentsModel?>? mediaSegments,
|
||||
ValueGetter<List<Chapter>?>? chapters,
|
||||
ValueGetter<TrickPlayModel?>? trickPlay,
|
||||
List<ItemBaseModel>? queue,
|
||||
|
|
@ -190,7 +190,7 @@ class DirectPlaybackModel implements PlaybackModel {
|
|||
media: media != null ? media() : this.media,
|
||||
playbackInfo: playbackInfo ?? this.playbackInfo,
|
||||
mediaStreams: mediaStreams != null ? mediaStreams() : this.mediaStreams,
|
||||
introSkipModel: introSkipModel != null ? introSkipModel() : this.introSkipModel,
|
||||
mediaSegments: mediaSegments != null ? mediaSegments() : this.mediaSegments,
|
||||
chapters: chapters != null ? chapters() : this.chapters,
|
||||
trickPlay: trickPlay != null ? trickPlay() : this.trickPlay,
|
||||
queue: queue ?? this.queue,
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/trick_play_model.dart';
|
||||
import 'package:fladder/models/playback/playback_model.dart';
|
||||
import 'package:fladder/models/syncing/sync_item.dart';
|
||||
import 'package:fladder/providers/sync_provider.dart';
|
||||
import 'package:fladder/util/duration_extensions.dart';
|
||||
import 'package:fladder/util/list_extensions.dart';
|
||||
import 'package:fladder/wrappers/media_control_wrapper.dart'
|
||||
if (dart.library.html) 'package:fladder/wrappers/media_control_wrapper_web.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/playback/playback_model.dart';
|
||||
import 'package:fladder/providers/sync_provider.dart';
|
||||
import 'package:fladder/util/duration_extensions.dart';
|
||||
|
||||
class OfflinePlaybackModel implements PlaybackModel {
|
||||
OfflinePlaybackModel({
|
||||
|
|
@ -24,7 +24,7 @@ class OfflinePlaybackModel implements PlaybackModel {
|
|||
required this.syncedItem,
|
||||
this.mediaStreams,
|
||||
this.playbackInfo,
|
||||
this.introSkipModel,
|
||||
this.mediaSegments,
|
||||
this.trickPlay,
|
||||
this.queue = const [],
|
||||
this.syncedQueue = const [],
|
||||
|
|
@ -45,7 +45,7 @@ class OfflinePlaybackModel implements PlaybackModel {
|
|||
final MediaStreamsModel? mediaStreams;
|
||||
|
||||
@override
|
||||
final IntroOutSkipModel? introSkipModel;
|
||||
final MediaSegmentsModel? mediaSegments;
|
||||
|
||||
@override
|
||||
List<Chapter>? get chapters => syncedItem.chapters;
|
||||
|
|
@ -156,7 +156,7 @@ class OfflinePlaybackModel implements PlaybackModel {
|
|||
ValueGetter<Media?>? media,
|
||||
SyncedItem? syncedItem,
|
||||
ValueGetter<MediaStreamsModel?>? mediaStreams,
|
||||
ValueGetter<IntroOutSkipModel?>? introSkipModel,
|
||||
ValueGetter<MediaSegmentsModel?>? mediaSegments,
|
||||
ValueGetter<TrickPlayModel?>? trickPlay,
|
||||
List<ItemBaseModel>? queue,
|
||||
List<SyncedItem>? syncedQueue,
|
||||
|
|
@ -166,7 +166,7 @@ class OfflinePlaybackModel implements PlaybackModel {
|
|||
media: media != null ? media() : this.media,
|
||||
syncedItem: syncedItem ?? this.syncedItem,
|
||||
mediaStreams: mediaStreams != null ? mediaStreams() : this.mediaStreams,
|
||||
introSkipModel: introSkipModel != null ? introSkipModel() : this.introSkipModel,
|
||||
mediaSegments: mediaSegments != null ? mediaSegments() : this.mediaSegments,
|
||||
trickPlay: trickPlay != null ? trickPlay() : this.trickPlay,
|
||||
queue: queue ?? this.queue,
|
||||
syncedQueue: syncedQueue ?? this.syncedQueue,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
|||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/episode_model.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/season_model.dart';
|
||||
import 'package:fladder/models/items/series_model.dart';
|
||||
|
|
@ -43,7 +43,7 @@ abstract class PlaybackModel {
|
|||
final ItemBaseModel item = throw UnimplementedError();
|
||||
final Media? media = throw UnimplementedError();
|
||||
final List<ItemBaseModel> queue = const [];
|
||||
final IntroOutSkipModel? introSkipModel = null;
|
||||
final MediaSegmentsModel? mediaSegments = null;
|
||||
final PlaybackInfoResponse? playbackInfo = throw UnimplementedError();
|
||||
|
||||
List<Chapter>? get chapters;
|
||||
|
|
@ -118,7 +118,7 @@ class PlaybackModelHelper {
|
|||
item: syncedItemModel,
|
||||
syncedItem: syncedItem,
|
||||
trickPlay: syncedItem.trickPlayModel,
|
||||
introSkipModel: syncedItem.introOutSkipModel,
|
||||
mediaSegments: syncedItem.mediaSegments,
|
||||
media: Media(syncedItem.videoFile.path),
|
||||
queue: itemQueue.whereNotNull().toList(),
|
||||
syncedQueue: children,
|
||||
|
|
@ -188,7 +188,7 @@ class PlaybackModelHelper {
|
|||
defaultSubStreamIndex: streamModel?.defaultSubStreamIndex,
|
||||
);
|
||||
|
||||
final intro = await api.introSkipGet(id: item.id);
|
||||
final mediaSegments = await api.mediaSegmentsGet(id: item.id);
|
||||
final trickPlay = (await api.getTrickPlay(item: fullItem.body, ref: ref))?.body;
|
||||
final chapters = fullItem.body?.overview.chapters ?? [];
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ class PlaybackModelHelper {
|
|||
return DirectPlaybackModel(
|
||||
item: fullItem.body ?? item,
|
||||
queue: queue,
|
||||
introSkipModel: intro?.body,
|
||||
mediaSegments: mediaSegments?.body,
|
||||
chapters: chapters,
|
||||
playbackInfo: playbackInfo,
|
||||
trickPlay: trickPlay,
|
||||
|
|
@ -225,7 +225,7 @@ class PlaybackModelHelper {
|
|||
return TranscodePlaybackModel(
|
||||
item: fullItem.body ?? item,
|
||||
queue: queue,
|
||||
introSkipModel: intro?.body,
|
||||
mediaSegments: mediaSegments?.body,
|
||||
chapters: chapters,
|
||||
trickPlay: trickPlay,
|
||||
playbackInfo: playbackInfo,
|
||||
|
|
@ -343,7 +343,7 @@ class PlaybackModelHelper {
|
|||
newModel = DirectPlaybackModel(
|
||||
item: playbackModel.item,
|
||||
queue: playbackModel.queue,
|
||||
introSkipModel: playbackModel.introSkipModel,
|
||||
mediaSegments: playbackModel.mediaSegments,
|
||||
chapters: playbackModel.chapters,
|
||||
playbackInfo: playbackInfo,
|
||||
trickPlay: playbackModel.trickPlay,
|
||||
|
|
@ -354,7 +354,7 @@ class PlaybackModelHelper {
|
|||
newModel = TranscodePlaybackModel(
|
||||
item: playbackModel.item,
|
||||
queue: playbackModel.queue,
|
||||
introSkipModel: playbackModel.introSkipModel,
|
||||
mediaSegments: playbackModel.mediaSegments,
|
||||
chapters: playbackModel.chapters,
|
||||
playbackInfo: playbackInfo,
|
||||
trickPlay: playbackModel.trickPlay,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'package:media_kit/media_kit.dart';
|
|||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/trick_play_model.dart';
|
||||
import 'package:fladder/models/playback/playback_model.dart';
|
||||
|
|
@ -23,7 +23,7 @@ class TranscodePlaybackModel implements PlaybackModel {
|
|||
required this.media,
|
||||
required this.playbackInfo,
|
||||
this.mediaStreams,
|
||||
this.introSkipModel,
|
||||
this.mediaSegments,
|
||||
this.chapters,
|
||||
this.trickPlay,
|
||||
this.queue = const [],
|
||||
|
|
@ -42,7 +42,7 @@ class TranscodePlaybackModel implements PlaybackModel {
|
|||
final MediaStreamsModel? mediaStreams;
|
||||
|
||||
@override
|
||||
final IntroOutSkipModel? introSkipModel;
|
||||
final MediaSegmentsModel? mediaSegments;
|
||||
|
||||
@override
|
||||
final List<Chapter>? chapters;
|
||||
|
|
@ -181,7 +181,7 @@ class TranscodePlaybackModel implements PlaybackModel {
|
|||
ValueGetter<Duration>? lastPosition,
|
||||
PlaybackInfoResponse? playbackInfo,
|
||||
ValueGetter<MediaStreamsModel?>? mediaStreams,
|
||||
ValueGetter<IntroOutSkipModel?>? introSkipModel,
|
||||
ValueGetter<MediaSegmentsModel?>? mediaSegments,
|
||||
ValueGetter<List<Chapter>?>? chapters,
|
||||
ValueGetter<TrickPlayModel?>? trickPlay,
|
||||
List<ItemBaseModel>? queue,
|
||||
|
|
@ -191,7 +191,7 @@ class TranscodePlaybackModel implements PlaybackModel {
|
|||
media: media != null ? media() : this.media,
|
||||
playbackInfo: playbackInfo ?? this.playbackInfo,
|
||||
mediaStreams: mediaStreams != null ? mediaStreams() : this.mediaStreams,
|
||||
introSkipModel: introSkipModel != null ? introSkipModel() : this.introSkipModel,
|
||||
mediaSegments: mediaSegments != null ? mediaSegments() : this.mediaSegments,
|
||||
chapters: chapters != null ? chapters() : this.chapters,
|
||||
trickPlay: trickPlay != null ? trickPlay() : this.trickPlay,
|
||||
queue: queue ?? this.queue,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class ISyncedItem {
|
|||
int? fileSize;
|
||||
String? videoFileName;
|
||||
String? trickPlayModel;
|
||||
String? introOutroSkipModel;
|
||||
String? mediaSegments;
|
||||
String? images;
|
||||
List<String>? chapters;
|
||||
List<String>? subtitles;
|
||||
|
|
@ -50,7 +50,7 @@ class ISyncedItem {
|
|||
this.fileSize,
|
||||
this.videoFileName,
|
||||
this.trickPlayModel,
|
||||
this.introOutroSkipModel,
|
||||
this.mediaSegments,
|
||||
this.images,
|
||||
this.chapters,
|
||||
this.subtitles,
|
||||
|
|
@ -68,8 +68,7 @@ class ISyncedItem {
|
|||
sortName: syncedItem.sortName,
|
||||
videoFileName: syncedItem.videoFileName,
|
||||
trickPlayModel: syncedItem.fTrickPlayModel != null ? jsonEncode(syncedItem.fTrickPlayModel?.toJson()) : null,
|
||||
introOutroSkipModel:
|
||||
syncedItem.introOutSkipModel != null ? jsonEncode(syncedItem.introOutSkipModel?.toJson()) : null,
|
||||
mediaSegments: syncedItem.mediaSegments != null ? jsonEncode(syncedItem.mediaSegments?.toJson()) : null,
|
||||
images: syncedItem.fImages != null ? jsonEncode(syncedItem.fImages?.toJson()) : null,
|
||||
chapters: syncedItem.fChapters.map((e) => jsonEncode(e.toJson())).toList(),
|
||||
subtitles: syncedItem.subtitles.map((e) => jsonEncode(e.toJson())).toList(),
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ const ISyncedItemSchema = IsarGeneratedSchema(
|
|||
type: IsarType.string,
|
||||
),
|
||||
IsarPropertySchema(
|
||||
name: 'introOutroSkipModel',
|
||||
name: 'mediaSegments',
|
||||
type: IsarType.string,
|
||||
),
|
||||
IsarPropertySchema(
|
||||
|
|
@ -141,7 +141,7 @@ int serializeISyncedItem(IsarWriter writer, ISyncedItem object) {
|
|||
}
|
||||
}
|
||||
{
|
||||
final value = object.introOutroSkipModel;
|
||||
final value = object.mediaSegments;
|
||||
if (value == null) {
|
||||
IsarCore.writeNull(writer, 10);
|
||||
} else {
|
||||
|
|
@ -218,8 +218,8 @@ ISyncedItem deserializeISyncedItem(IsarReader reader) {
|
|||
_videoFileName = IsarCore.readString(reader, 8);
|
||||
final String? _trickPlayModel;
|
||||
_trickPlayModel = IsarCore.readString(reader, 9);
|
||||
final String? _introOutroSkipModel;
|
||||
_introOutroSkipModel = IsarCore.readString(reader, 10);
|
||||
final String? _mediaSegments;
|
||||
_mediaSegments = IsarCore.readString(reader, 10);
|
||||
final String? _images;
|
||||
_images = IsarCore.readString(reader, 11);
|
||||
final List<String>? _chapters;
|
||||
|
|
@ -268,7 +268,7 @@ ISyncedItem deserializeISyncedItem(IsarReader reader) {
|
|||
fileSize: _fileSize,
|
||||
videoFileName: _videoFileName,
|
||||
trickPlayModel: _trickPlayModel,
|
||||
introOutroSkipModel: _introOutroSkipModel,
|
||||
mediaSegments: _mediaSegments,
|
||||
images: _images,
|
||||
chapters: _chapters,
|
||||
subtitles: _subtitles,
|
||||
|
|
@ -361,7 +361,7 @@ sealed class _ISyncedItemUpdate {
|
|||
int? fileSize,
|
||||
String? videoFileName,
|
||||
String? trickPlayModel,
|
||||
String? introOutroSkipModel,
|
||||
String? mediaSegments,
|
||||
String? images,
|
||||
String? userData,
|
||||
});
|
||||
|
|
@ -383,7 +383,7 @@ class _ISyncedItemUpdateImpl implements _ISyncedItemUpdate {
|
|||
Object? fileSize = ignore,
|
||||
Object? videoFileName = ignore,
|
||||
Object? trickPlayModel = ignore,
|
||||
Object? introOutroSkipModel = ignore,
|
||||
Object? mediaSegments = ignore,
|
||||
Object? images = ignore,
|
||||
Object? userData = ignore,
|
||||
}) {
|
||||
|
|
@ -398,7 +398,7 @@ class _ISyncedItemUpdateImpl implements _ISyncedItemUpdate {
|
|||
if (fileSize != ignore) 7: fileSize as int?,
|
||||
if (videoFileName != ignore) 8: videoFileName as String?,
|
||||
if (trickPlayModel != ignore) 9: trickPlayModel as String?,
|
||||
if (introOutroSkipModel != ignore) 10: introOutroSkipModel as String?,
|
||||
if (mediaSegments != ignore) 10: mediaSegments as String?,
|
||||
if (images != ignore) 11: images as String?,
|
||||
if (userData != ignore) 14: userData as String?,
|
||||
}) >
|
||||
|
|
@ -417,7 +417,7 @@ sealed class _ISyncedItemUpdateAll {
|
|||
int? fileSize,
|
||||
String? videoFileName,
|
||||
String? trickPlayModel,
|
||||
String? introOutroSkipModel,
|
||||
String? mediaSegments,
|
||||
String? images,
|
||||
String? userData,
|
||||
});
|
||||
|
|
@ -439,7 +439,7 @@ class _ISyncedItemUpdateAllImpl implements _ISyncedItemUpdateAll {
|
|||
Object? fileSize = ignore,
|
||||
Object? videoFileName = ignore,
|
||||
Object? trickPlayModel = ignore,
|
||||
Object? introOutroSkipModel = ignore,
|
||||
Object? mediaSegments = ignore,
|
||||
Object? images = ignore,
|
||||
Object? userData = ignore,
|
||||
}) {
|
||||
|
|
@ -452,7 +452,7 @@ class _ISyncedItemUpdateAllImpl implements _ISyncedItemUpdateAll {
|
|||
if (fileSize != ignore) 7: fileSize as int?,
|
||||
if (videoFileName != ignore) 8: videoFileName as String?,
|
||||
if (trickPlayModel != ignore) 9: trickPlayModel as String?,
|
||||
if (introOutroSkipModel != ignore) 10: introOutroSkipModel as String?,
|
||||
if (mediaSegments != ignore) 10: mediaSegments as String?,
|
||||
if (images != ignore) 11: images as String?,
|
||||
if (userData != ignore) 14: userData as String?,
|
||||
});
|
||||
|
|
@ -475,7 +475,7 @@ sealed class _ISyncedItemQueryUpdate {
|
|||
int? fileSize,
|
||||
String? videoFileName,
|
||||
String? trickPlayModel,
|
||||
String? introOutroSkipModel,
|
||||
String? mediaSegments,
|
||||
String? images,
|
||||
String? userData,
|
||||
});
|
||||
|
|
@ -497,7 +497,7 @@ class _ISyncedItemQueryUpdateImpl implements _ISyncedItemQueryUpdate {
|
|||
Object? fileSize = ignore,
|
||||
Object? videoFileName = ignore,
|
||||
Object? trickPlayModel = ignore,
|
||||
Object? introOutroSkipModel = ignore,
|
||||
Object? mediaSegments = ignore,
|
||||
Object? images = ignore,
|
||||
Object? userData = ignore,
|
||||
}) {
|
||||
|
|
@ -510,7 +510,7 @@ class _ISyncedItemQueryUpdateImpl implements _ISyncedItemQueryUpdate {
|
|||
if (fileSize != ignore) 7: fileSize as int?,
|
||||
if (videoFileName != ignore) 8: videoFileName as String?,
|
||||
if (trickPlayModel != ignore) 9: trickPlayModel as String?,
|
||||
if (introOutroSkipModel != ignore) 10: introOutroSkipModel as String?,
|
||||
if (mediaSegments != ignore) 10: mediaSegments as String?,
|
||||
if (images != ignore) 11: images as String?,
|
||||
if (userData != ignore) 14: userData as String?,
|
||||
});
|
||||
|
|
@ -540,7 +540,7 @@ class _ISyncedItemQueryBuilderUpdateImpl implements _ISyncedItemQueryUpdate {
|
|||
Object? fileSize = ignore,
|
||||
Object? videoFileName = ignore,
|
||||
Object? trickPlayModel = ignore,
|
||||
Object? introOutroSkipModel = ignore,
|
||||
Object? mediaSegments = ignore,
|
||||
Object? images = ignore,
|
||||
Object? userData = ignore,
|
||||
}) {
|
||||
|
|
@ -555,7 +555,7 @@ class _ISyncedItemQueryBuilderUpdateImpl implements _ISyncedItemQueryUpdate {
|
|||
if (fileSize != ignore) 7: fileSize as int?,
|
||||
if (videoFileName != ignore) 8: videoFileName as String?,
|
||||
if (trickPlayModel != ignore) 9: trickPlayModel as String?,
|
||||
if (introOutroSkipModel != ignore) 10: introOutroSkipModel as String?,
|
||||
if (mediaSegments != ignore) 10: mediaSegments as String?,
|
||||
if (images != ignore) 11: images as String?,
|
||||
if (userData != ignore) 14: userData as String?,
|
||||
});
|
||||
|
|
@ -2015,21 +2015,21 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelIsNull() {
|
||||
mediaSegmentsIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const IsNullCondition(property: 10));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelIsNotNull() {
|
||||
mediaSegmentsIsNotNull() {
|
||||
return QueryBuilder.apply(not(), (query) {
|
||||
return query.addFilterCondition(const IsNullCondition(property: 10));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelEqualTo(
|
||||
mediaSegmentsEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -2045,7 +2045,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelGreaterThan(
|
||||
mediaSegmentsGreaterThan(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -2061,7 +2061,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelGreaterThanOrEqualTo(
|
||||
mediaSegmentsGreaterThanOrEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -2077,7 +2077,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelLessThan(
|
||||
mediaSegmentsLessThan(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -2093,7 +2093,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelLessThanOrEqualTo(
|
||||
mediaSegmentsLessThanOrEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -2109,7 +2109,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelBetween(
|
||||
mediaSegmentsBetween(
|
||||
String? lower,
|
||||
String? upper, {
|
||||
bool caseSensitive = true,
|
||||
|
|
@ -2127,7 +2127,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelStartsWith(
|
||||
mediaSegmentsStartsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -2143,7 +2143,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelEndsWith(
|
||||
mediaSegmentsEndsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -2159,7 +2159,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelContains(String value, {bool caseSensitive = true}) {
|
||||
mediaSegmentsContains(String value, {bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(
|
||||
ContainsCondition(
|
||||
|
|
@ -2172,7 +2172,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelMatches(String pattern, {bool caseSensitive = true}) {
|
||||
mediaSegmentsMatches(String pattern, {bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(
|
||||
MatchesCondition(
|
||||
|
|
@ -2185,7 +2185,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelIsEmpty() {
|
||||
mediaSegmentsIsEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(
|
||||
const EqualCondition(
|
||||
|
|
@ -2197,7 +2197,7 @@ extension ISyncedItemQueryFilter
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterFilterCondition>
|
||||
introOutroSkipModelIsNotEmpty() {
|
||||
mediaSegmentsIsNotEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(
|
||||
const GreaterCondition(
|
||||
|
|
@ -3189,8 +3189,8 @@ extension ISyncedItemQuerySortBy
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy>
|
||||
sortByIntroOutroSkipModel({bool caseSensitive = true}) {
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy> sortByMediaSegments(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(
|
||||
10,
|
||||
|
|
@ -3199,8 +3199,8 @@ extension ISyncedItemQuerySortBy
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy>
|
||||
sortByIntroOutroSkipModelDesc({bool caseSensitive = true}) {
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy> sortByMediaSegmentsDesc(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(
|
||||
10,
|
||||
|
|
@ -3377,15 +3377,15 @@ extension ISyncedItemQuerySortThenBy
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy>
|
||||
thenByIntroOutroSkipModel({bool caseSensitive = true}) {
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy> thenByMediaSegments(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(10, caseSensitive: caseSensitive);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy>
|
||||
thenByIntroOutroSkipModelDesc({bool caseSensitive = true}) {
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterSortBy> thenByMediaSegmentsDesc(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(10, sort: Sort.desc, caseSensitive: caseSensitive);
|
||||
});
|
||||
|
|
@ -3477,7 +3477,7 @@ extension ISyncedItemQueryWhereDistinct
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, ISyncedItem, QAfterDistinct>
|
||||
distinctByIntroOutroSkipModel({bool caseSensitive = true}) {
|
||||
distinctByMediaSegments({bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(10, caseSensitive: caseSensitive);
|
||||
});
|
||||
|
|
@ -3566,8 +3566,7 @@ extension ISyncedItemQueryProperty1
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, String?, QAfterProperty>
|
||||
introOutroSkipModelProperty() {
|
||||
QueryBuilder<ISyncedItem, String?, QAfterProperty> mediaSegmentsProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addProperty(10);
|
||||
});
|
||||
|
|
@ -3657,7 +3656,7 @@ extension ISyncedItemQueryProperty2<R>
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, (R, String?), QAfterProperty>
|
||||
introOutroSkipModelProperty() {
|
||||
mediaSegmentsProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addProperty(10);
|
||||
});
|
||||
|
|
@ -3749,7 +3748,7 @@ extension ISyncedItemQueryProperty3<R1, R2>
|
|||
}
|
||||
|
||||
QueryBuilder<ISyncedItem, (R1, R2, String?), QOperations>
|
||||
introOutroSkipModelProperty() {
|
||||
mediaSegmentsProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addProperty(10);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
|||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/trick_play_model.dart';
|
||||
|
|
@ -38,7 +38,7 @@ class SyncedItem with _$SyncedItem {
|
|||
String? sortName,
|
||||
int? fileSize,
|
||||
String? videoFileName,
|
||||
IntroOutSkipModel? introOutSkipModel,
|
||||
MediaSegmentsModel? mediaSegments,
|
||||
TrickPlayModel? fTrickPlayModel,
|
||||
ImagesData? fImages,
|
||||
@Default([]) List<Chapter> fChapters,
|
||||
|
|
@ -132,8 +132,8 @@ class SyncedItem with _$SyncedItem {
|
|||
path: joinAll([savePath, isarSyncedItem.path ?? ""]),
|
||||
fileSize: isarSyncedItem.fileSize,
|
||||
videoFileName: isarSyncedItem.videoFileName,
|
||||
introOutSkipModel: isarSyncedItem.introOutroSkipModel != null
|
||||
? IntroOutSkipModel.fromJson(jsonDecode(isarSyncedItem.introOutroSkipModel!))
|
||||
mediaSegments: isarSyncedItem.mediaSegments != null
|
||||
? MediaSegmentsModel.fromJson(jsonDecode(isarSyncedItem.mediaSegments!))
|
||||
: null,
|
||||
fTrickPlayModel: isarSyncedItem.trickPlayModel != null
|
||||
? TrickPlayModel.fromJson(jsonDecode(isarSyncedItem.trickPlayModel!))
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@ mixin _$SyncedItem {
|
|||
String? get sortName => throw _privateConstructorUsedError;
|
||||
int? get fileSize => throw _privateConstructorUsedError;
|
||||
String? get videoFileName => throw _privateConstructorUsedError;
|
||||
IntroOutSkipModel? get introOutSkipModel =>
|
||||
throw _privateConstructorUsedError;
|
||||
MediaSegmentsModel? get mediaSegments => throw _privateConstructorUsedError;
|
||||
TrickPlayModel? get fTrickPlayModel => throw _privateConstructorUsedError;
|
||||
ImagesData? get fImages => throw _privateConstructorUsedError;
|
||||
List<Chapter> get fChapters => throw _privateConstructorUsedError;
|
||||
|
|
@ -57,14 +56,14 @@ abstract class $SyncedItemCopyWith<$Res> {
|
|||
String? sortName,
|
||||
int? fileSize,
|
||||
String? videoFileName,
|
||||
IntroOutSkipModel? introOutSkipModel,
|
||||
MediaSegmentsModel? mediaSegments,
|
||||
TrickPlayModel? fTrickPlayModel,
|
||||
ImagesData? fImages,
|
||||
List<Chapter> fChapters,
|
||||
List<SubStreamModel> subtitles,
|
||||
@UserDataJsonSerializer() UserData? userData});
|
||||
|
||||
$IntroOutSkipModelCopyWith<$Res>? get introOutSkipModel;
|
||||
$MediaSegmentsModelCopyWith<$Res>? get mediaSegments;
|
||||
$TrickPlayModelCopyWith<$Res>? get fTrickPlayModel;
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +91,7 @@ class _$SyncedItemCopyWithImpl<$Res, $Val extends SyncedItem>
|
|||
Object? sortName = freezed,
|
||||
Object? fileSize = freezed,
|
||||
Object? videoFileName = freezed,
|
||||
Object? introOutSkipModel = freezed,
|
||||
Object? mediaSegments = freezed,
|
||||
Object? fTrickPlayModel = freezed,
|
||||
Object? fImages = freezed,
|
||||
Object? fChapters = null,
|
||||
|
|
@ -136,10 +135,10 @@ class _$SyncedItemCopyWithImpl<$Res, $Val extends SyncedItem>
|
|||
? _value.videoFileName
|
||||
: videoFileName // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
introOutSkipModel: freezed == introOutSkipModel
|
||||
? _value.introOutSkipModel
|
||||
: introOutSkipModel // ignore: cast_nullable_to_non_nullable
|
||||
as IntroOutSkipModel?,
|
||||
mediaSegments: freezed == mediaSegments
|
||||
? _value.mediaSegments
|
||||
: mediaSegments // ignore: cast_nullable_to_non_nullable
|
||||
as MediaSegmentsModel?,
|
||||
fTrickPlayModel: freezed == fTrickPlayModel
|
||||
? _value.fTrickPlayModel
|
||||
: fTrickPlayModel // ignore: cast_nullable_to_non_nullable
|
||||
|
|
@ -167,13 +166,13 @@ class _$SyncedItemCopyWithImpl<$Res, $Val extends SyncedItem>
|
|||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$IntroOutSkipModelCopyWith<$Res>? get introOutSkipModel {
|
||||
if (_value.introOutSkipModel == null) {
|
||||
$MediaSegmentsModelCopyWith<$Res>? get mediaSegments {
|
||||
if (_value.mediaSegments == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $IntroOutSkipModelCopyWith<$Res>(_value.introOutSkipModel!, (value) {
|
||||
return _then(_value.copyWith(introOutSkipModel: value) as $Val);
|
||||
return $MediaSegmentsModelCopyWith<$Res>(_value.mediaSegments!, (value) {
|
||||
return _then(_value.copyWith(mediaSegments: value) as $Val);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +209,7 @@ abstract class _$$SyncItemImplCopyWith<$Res>
|
|||
String? sortName,
|
||||
int? fileSize,
|
||||
String? videoFileName,
|
||||
IntroOutSkipModel? introOutSkipModel,
|
||||
MediaSegmentsModel? mediaSegments,
|
||||
TrickPlayModel? fTrickPlayModel,
|
||||
ImagesData? fImages,
|
||||
List<Chapter> fChapters,
|
||||
|
|
@ -218,7 +217,7 @@ abstract class _$$SyncItemImplCopyWith<$Res>
|
|||
@UserDataJsonSerializer() UserData? userData});
|
||||
|
||||
@override
|
||||
$IntroOutSkipModelCopyWith<$Res>? get introOutSkipModel;
|
||||
$MediaSegmentsModelCopyWith<$Res>? get mediaSegments;
|
||||
@override
|
||||
$TrickPlayModelCopyWith<$Res>? get fTrickPlayModel;
|
||||
}
|
||||
|
|
@ -245,7 +244,7 @@ class __$$SyncItemImplCopyWithImpl<$Res>
|
|||
Object? sortName = freezed,
|
||||
Object? fileSize = freezed,
|
||||
Object? videoFileName = freezed,
|
||||
Object? introOutSkipModel = freezed,
|
||||
Object? mediaSegments = freezed,
|
||||
Object? fTrickPlayModel = freezed,
|
||||
Object? fImages = freezed,
|
||||
Object? fChapters = null,
|
||||
|
|
@ -289,10 +288,10 @@ class __$$SyncItemImplCopyWithImpl<$Res>
|
|||
? _value.videoFileName
|
||||
: videoFileName // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
introOutSkipModel: freezed == introOutSkipModel
|
||||
? _value.introOutSkipModel
|
||||
: introOutSkipModel // ignore: cast_nullable_to_non_nullable
|
||||
as IntroOutSkipModel?,
|
||||
mediaSegments: freezed == mediaSegments
|
||||
? _value.mediaSegments
|
||||
: mediaSegments // ignore: cast_nullable_to_non_nullable
|
||||
as MediaSegmentsModel?,
|
||||
fTrickPlayModel: freezed == fTrickPlayModel
|
||||
? _value.fTrickPlayModel
|
||||
: fTrickPlayModel // ignore: cast_nullable_to_non_nullable
|
||||
|
|
@ -330,7 +329,7 @@ class _$SyncItemImpl extends _SyncItem {
|
|||
this.sortName,
|
||||
this.fileSize,
|
||||
this.videoFileName,
|
||||
this.introOutSkipModel,
|
||||
this.mediaSegments,
|
||||
this.fTrickPlayModel,
|
||||
this.fImages,
|
||||
final List<Chapter> fChapters = const [],
|
||||
|
|
@ -361,7 +360,7 @@ class _$SyncItemImpl extends _SyncItem {
|
|||
@override
|
||||
final String? videoFileName;
|
||||
@override
|
||||
final IntroOutSkipModel? introOutSkipModel;
|
||||
final MediaSegmentsModel? mediaSegments;
|
||||
@override
|
||||
final TrickPlayModel? fTrickPlayModel;
|
||||
@override
|
||||
|
|
@ -390,7 +389,7 @@ class _$SyncItemImpl extends _SyncItem {
|
|||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SyncedItem(id: $id, syncing: $syncing, parentId: $parentId, userId: $userId, path: $path, markedForDelete: $markedForDelete, sortName: $sortName, fileSize: $fileSize, videoFileName: $videoFileName, introOutSkipModel: $introOutSkipModel, fTrickPlayModel: $fTrickPlayModel, fImages: $fImages, fChapters: $fChapters, subtitles: $subtitles, userData: $userData)';
|
||||
return 'SyncedItem(id: $id, syncing: $syncing, parentId: $parentId, userId: $userId, path: $path, markedForDelete: $markedForDelete, sortName: $sortName, fileSize: $fileSize, videoFileName: $videoFileName, mediaSegments: $mediaSegments, fTrickPlayModel: $fTrickPlayModel, fImages: $fImages, fChapters: $fChapters, subtitles: $subtitles, userData: $userData)';
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -412,8 +411,8 @@ class _$SyncItemImpl extends _SyncItem {
|
|||
other.fileSize == fileSize) &&
|
||||
(identical(other.videoFileName, videoFileName) ||
|
||||
other.videoFileName == videoFileName) &&
|
||||
(identical(other.introOutSkipModel, introOutSkipModel) ||
|
||||
other.introOutSkipModel == introOutSkipModel) &&
|
||||
(identical(other.mediaSegments, mediaSegments) ||
|
||||
other.mediaSegments == mediaSegments) &&
|
||||
(identical(other.fTrickPlayModel, fTrickPlayModel) ||
|
||||
other.fTrickPlayModel == fTrickPlayModel) &&
|
||||
(identical(other.fImages, fImages) || other.fImages == fImages) &&
|
||||
|
|
@ -437,7 +436,7 @@ class _$SyncItemImpl extends _SyncItem {
|
|||
sortName,
|
||||
fileSize,
|
||||
videoFileName,
|
||||
introOutSkipModel,
|
||||
mediaSegments,
|
||||
fTrickPlayModel,
|
||||
fImages,
|
||||
const DeepCollectionEquality().hash(_fChapters),
|
||||
|
|
@ -464,7 +463,7 @@ abstract class _SyncItem extends SyncedItem {
|
|||
final String? sortName,
|
||||
final int? fileSize,
|
||||
final String? videoFileName,
|
||||
final IntroOutSkipModel? introOutSkipModel,
|
||||
final MediaSegmentsModel? mediaSegments,
|
||||
final TrickPlayModel? fTrickPlayModel,
|
||||
final ImagesData? fImages,
|
||||
final List<Chapter> fChapters,
|
||||
|
|
@ -491,7 +490,7 @@ abstract class _SyncItem extends SyncedItem {
|
|||
@override
|
||||
String? get videoFileName;
|
||||
@override
|
||||
IntroOutSkipModel? get introOutSkipModel;
|
||||
MediaSegmentsModel? get mediaSegments;
|
||||
@override
|
||||
TrickPlayModel? get fTrickPlayModel;
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:ficonsax/ficonsax.dart';
|
||||
import 'package:fladder/models/items/item_stream_model.dart';
|
||||
import 'package:fladder/models/syncing/sync_item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/item_stream_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/syncing/sync_item.dart';
|
||||
import 'package:fladder/providers/user_provider.dart';
|
||||
|
||||
enum PlaybackType {
|
||||
|
|
@ -100,7 +101,7 @@ class VideoStream {
|
|||
final String playSessionId;
|
||||
final List<Chapter>? chapters;
|
||||
final List<Chapter>? trickPlay;
|
||||
final IntroSkipModel? introSkipModel;
|
||||
final MediaSegmentsModel? mediaSegments;
|
||||
final int? audioStreamIndex;
|
||||
final int? subtitleStreamIndex;
|
||||
final MediaStreamsModel? mediaStreamsModel;
|
||||
|
|
@ -129,7 +130,7 @@ class VideoStream {
|
|||
required this.playSessionId,
|
||||
this.chapters,
|
||||
this.trickPlay,
|
||||
this.introSkipModel,
|
||||
this.mediaSegments,
|
||||
this.audioStreamIndex,
|
||||
this.subtitleStreamIndex,
|
||||
this.mediaStreamsModel,
|
||||
|
|
@ -143,7 +144,7 @@ class VideoStream {
|
|||
String? playSessionId,
|
||||
List<Chapter>? chapters,
|
||||
List<Chapter>? trickPlay,
|
||||
IntroSkipModel? introSkipModel,
|
||||
MediaSegmentsModel? mediaSegments,
|
||||
int? audioStreamIndex,
|
||||
int? subtitleStreamIndex,
|
||||
MediaStreamsModel? mediaStreamsModel,
|
||||
|
|
@ -156,7 +157,7 @@ class VideoStream {
|
|||
playSessionId: playSessionId ?? this.playSessionId,
|
||||
chapters: chapters ?? this.chapters,
|
||||
trickPlay: trickPlay ?? this.trickPlay,
|
||||
introSkipModel: introSkipModel ?? this.introSkipModel,
|
||||
mediaSegments: mediaSegments ?? this.mediaSegments,
|
||||
audioStreamIndex: audioStreamIndex ?? this.audioStreamIndex,
|
||||
subtitleStreamIndex: subtitleStreamIndex ?? this.subtitleStreamIndex,
|
||||
mediaStreamsModel: mediaStreamsModel ?? this.mediaStreamsModel,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'dart:typed_data';
|
||||
|
||||
|
|
@ -12,7 +11,7 @@ import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
|||
import 'package:fladder/models/account_model.dart';
|
||||
import 'package:fladder/models/credentials_model.dart';
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/items/trick_play_model.dart';
|
||||
import 'package:fladder/providers/api_provider.dart';
|
||||
import 'package:fladder/providers/image_provider.dart';
|
||||
|
|
@ -871,20 +870,14 @@ class JellyService {
|
|||
userId: account?.id,
|
||||
);
|
||||
|
||||
Future<Response<IntroOutSkipModel>?> introSkipGet({
|
||||
Future<Response<MediaSegmentsModel>?> mediaSegmentsGet({
|
||||
required String id,
|
||||
}) async {
|
||||
try {
|
||||
final response = await api.episodeIdIntroTimestampsGet(id: id);
|
||||
final outro = await api.episodeIdIntroSkipperSegmentsGet(id: id);
|
||||
final map = jsonDecode(outro.bodyString) as Map<String, dynamic>;
|
||||
final newModel = IntroOutSkipModel(
|
||||
intro:
|
||||
map["Introduction"] != null ? IntroSkipModel.fromJson(map["Introduction"] as Map<String, dynamic>) : null,
|
||||
credits: map["Credits"] != null ? IntroSkipModel.fromJson(map["Credits"] as Map<String, dynamic>) : null,
|
||||
);
|
||||
final response = await api.mediaSegmentsItemIdGet(itemId: id);
|
||||
final newSegments = response.body?.items?.map((e) => e.toSegment).toList() ?? [];
|
||||
return response.copyWith(
|
||||
body: newModel,
|
||||
body: MediaSegmentsModel(segments: newSegments),
|
||||
);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
|
|
@ -927,7 +920,7 @@ class JellyService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<Response<List<SessionInfo>>> sessionsInfo(String deviceId) async => api.sessionsGet(deviceId: deviceId);
|
||||
Future<Response<List<SessionInfoDto>>> sessionsInfo(String deviceId) async => api.sessionsGet(deviceId: deviceId);
|
||||
|
||||
Future<Response<bool>> quickConnect(String code) async => api.quickConnectAuthorizePost(code: code);
|
||||
|
||||
|
|
|
|||
|
|
@ -436,12 +436,12 @@ class SyncNotifier extends StateNotifier<SyncSettingsModel> {
|
|||
final subtitles = await saveExternalSubtitles(newState?.mediaStreamsModel?.subStreams, syncItem);
|
||||
|
||||
final trickPlayFile = await saveTrickPlayData(item, directory);
|
||||
final introOutroSkip = (await api.introSkipGet(id: syncItem.id))?.body;
|
||||
final mediaSegments = (await api.mediaSegmentsGet(id: syncItem.id))?.body;
|
||||
|
||||
syncItem = syncItem.copyWith(
|
||||
subtitles: subtitles,
|
||||
fTrickPlayModel: trickPlayFile,
|
||||
introOutSkipModel: introOutroSkip,
|
||||
mediaSegments: mediaSegments,
|
||||
);
|
||||
|
||||
await updateItem(syncItem);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:fladder/providers/video_player_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
|
||||
import 'package:fladder/providers/video_player_provider.dart';
|
||||
import 'package:fladder/screens/video_player/components/video_player_chapters.dart';
|
||||
import 'package:fladder/screens/video_player/components/video_player_queue.dart';
|
||||
|
||||
|
|
@ -84,10 +84,10 @@ class IntroSkipButton extends ConsumerWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class CreditsSkipButton extends ConsumerWidget {
|
||||
class OutroSkipButton extends ConsumerWidget {
|
||||
final bool isOverlayVisible;
|
||||
final Function()? skipCredits;
|
||||
const CreditsSkipButton({this.skipCredits, required this.isOverlayVisible, super.key});
|
||||
final Function()? skipOutro;
|
||||
const OutroSkipButton({this.skipOutro, required this.isOverlayVisible, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
|
@ -96,7 +96,7 @@ class CreditsSkipButton extends ConsumerWidget {
|
|||
opacity: 1,
|
||||
duration: const Duration(milliseconds: 250),
|
||||
child: ElevatedButton(
|
||||
onPressed: () => skipCredits?.call(),
|
||||
onPressed: () => skipOutro?.call(),
|
||||
style: ElevatedButton.styleFrom(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8),
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class _VideoPlayerNextWrapperState extends ConsumerState<VideoPlayerNextWrapper>
|
|||
return;
|
||||
}
|
||||
|
||||
final credits = ref.read(playBackModel)?.introSkipModel?.credits;
|
||||
final credits = ref.read(playBackModel)?.mediaSegments?.outro;
|
||||
|
||||
if (nextType == AutoNextType.static || credits == null) {
|
||||
if ((model.duration - model.position).abs() < const Duration(seconds: 32)) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:collection/collection.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/providers/video_player_provider.dart';
|
||||
import 'package:fladder/util/duration_extensions.dart';
|
||||
import 'package:fladder/util/list_padding.dart';
|
||||
|
|
@ -54,7 +54,7 @@ class _ChapterProgressSliderState extends ConsumerState<VideoProgressBar> {
|
|||
final isVisible = (onDragStart ? true : onHoverStart);
|
||||
final player = ref.watch(videoPlayerProvider);
|
||||
final position = onDragStart ? currentDuration : widget.position;
|
||||
final IntroOutSkipModel? introCreditsModel = ref.read(playBackModel.select((value) => value?.introSkipModel));
|
||||
final MediaSegmentsModel? mediaSegments = ref.read(playBackModel.select((value) => value?.mediaSegments));
|
||||
final relativeFraction = position.inMilliseconds / widget.duration.inMilliseconds;
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
|
|
@ -138,35 +138,21 @@ class _ChapterProgressSliderState extends ConsumerState<VideoProgressBar> {
|
|||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
if (introCreditsModel?.intro?.start != null && introCreditsModel?.intro?.end != null)
|
||||
Positioned(
|
||||
left: calculateStartOffset(constraints, introCreditsModel!.intro!.start),
|
||||
right: calculateRightOffset(constraints, introCreditsModel.intro!.end),
|
||||
...?mediaSegments?.segments.map(
|
||||
(segment) => Positioned(
|
||||
left: calculateStartOffset(constraints, segment.start),
|
||||
right: calculateRightOffset(constraints, segment.end),
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
height: 6,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.8),
|
||||
color: segment.type.color,
|
||||
borderRadius: BorderRadius.circular(
|
||||
100,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (introCreditsModel?.credits?.start != null && introCreditsModel?.credits?.end != null)
|
||||
Positioned(
|
||||
left: calculateStartOffset(constraints, introCreditsModel!.credits!.start),
|
||||
right: calculateRightOffset(constraints, introCreditsModel.credits!.end),
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
height: 6,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.orangeAccent.withOpacity(0.8),
|
||||
borderRadius: BorderRadius.circular(
|
||||
100,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!widget.buffering) ...{
|
||||
//VideoBufferBar
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import 'package:screen_brightness/screen_brightness.dart';
|
|||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||
import 'package:fladder/models/items/media_segments_model.dart';
|
||||
import 'package:fladder/models/media_playback_model.dart';
|
||||
import 'package:fladder/models/playback/playback_model.dart';
|
||||
import 'package:fladder/providers/settings/client_settings_provider.dart';
|
||||
|
|
@ -57,10 +57,10 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
late final double bottomPadding = MediaQuery.of(context).viewPadding.bottom;
|
||||
|
||||
bool _onKey(KeyEvent value) {
|
||||
final introSkipModel = ref.read(playBackModel.select((value) => value?.introSkipModel));
|
||||
final mediaSegments = ref.read(playBackModel.select((value) => value?.mediaSegments));
|
||||
final position = ref.read(mediaPlaybackProvider).position;
|
||||
bool showIntroSkipButton = introSkipModel?.introInRange(position) ?? false;
|
||||
bool showCreditSkipButton = introSkipModel?.creditsInRange(position) ?? false;
|
||||
bool showIntroSkipButton = mediaSegments?.intro?.inRange(position) ?? false;
|
||||
bool showOutroSkipButton = mediaSegments?.outro?.inRange(position) ?? false;
|
||||
if (value is KeyRepeatEvent) {
|
||||
if (value.logicalKey == LogicalKeyboardKey.arrowUp) {
|
||||
resetTimer();
|
||||
|
|
@ -76,9 +76,9 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
if (value is KeyDownEvent) {
|
||||
if (value.logicalKey == LogicalKeyboardKey.keyS) {
|
||||
if (showIntroSkipButton) {
|
||||
skipIntro(introSkipModel);
|
||||
} else if (showCreditSkipButton) {
|
||||
skipCredits(introSkipModel);
|
||||
skipIntro(mediaSegments);
|
||||
} else if (showOutroSkipButton) {
|
||||
skipOutro(mediaSegments);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -116,7 +116,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final introSkipModel = ref.watch(playBackModel.select((value) => value?.introSkipModel));
|
||||
final mediaSegments = ref.watch(playBackModel.select((value) => value?.mediaSegments));
|
||||
final player = ref.watch(videoPlayerProvider.select((value) => value.controller));
|
||||
return InputHandler(
|
||||
autoFocus: false,
|
||||
|
|
@ -167,8 +167,8 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final position = ref.watch(mediaPlaybackProvider.select((value) => value.position));
|
||||
bool showIntroSkipButton = introSkipModel?.introInRange(position) ?? false;
|
||||
bool showCreditSkipButton = introSkipModel?.creditsInRange(position) ?? false;
|
||||
bool showIntroSkipButton = mediaSegments?.intro?.inRange(position) ?? false;
|
||||
bool showOutroSkipButton = mediaSegments?.outro?.inRange(position) ?? false;
|
||||
return Stack(
|
||||
children: [
|
||||
if (showIntroSkipButton)
|
||||
|
|
@ -178,18 +178,18 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
padding: const EdgeInsets.all(32),
|
||||
child: IntroSkipButton(
|
||||
isOverlayVisible: showOverlay,
|
||||
skipIntro: () => skipIntro(introSkipModel),
|
||||
skipIntro: () => skipIntro(mediaSegments),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (showCreditSkipButton)
|
||||
if (showOutroSkipButton)
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: CreditsSkipButton(
|
||||
child: OutroSkipButton(
|
||||
isOverlayVisible: showOverlay,
|
||||
skipCredits: () => skipCredits(introSkipModel),
|
||||
skipOutro: () => skipOutro(mediaSegments),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -582,17 +582,17 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
);
|
||||
}
|
||||
|
||||
void skipIntro(IntroOutSkipModel? introSkipModel) {
|
||||
void skipIntro(MediaSegmentsModel? mediaSegments) {
|
||||
resetTimer();
|
||||
final end = introSkipModel?.intro?.end;
|
||||
final end = mediaSegments?.intro?.end;
|
||||
if (end != null) {
|
||||
ref.read(videoPlayerProvider).seek(end);
|
||||
}
|
||||
}
|
||||
|
||||
void skipCredits(IntroOutSkipModel? introSkipModel) {
|
||||
void skipOutro(MediaSegmentsModel? mediaSegments) {
|
||||
resetTimer();
|
||||
final end = introSkipModel?.credits?.end;
|
||||
final end = mediaSegments?.outro?.end;
|
||||
if (end != null) {
|
||||
ref.read(videoPlayerProvider).seek(end);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import 'package:transparent_image/transparent_image.dart';
|
|||
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/providers/settings/client_settings_provider.dart';
|
||||
import 'package:fladder/util/adaptive_layout.dart';
|
||||
|
||||
class FladderImage extends ConsumerWidget {
|
||||
final ImageData? image;
|
||||
|
|
@ -29,7 +28,6 @@ class FladderImage extends ConsumerWidget {
|
|||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final useBluredPlaceHolder = ref.watch(clientSettingsProvider.select((value) => value.blurPlaceHolders));
|
||||
final newImage = image;
|
||||
final blurSize = AdaptiveLayout.of(context).isDesktop ? 32 : 16;
|
||||
if (newImage == null) {
|
||||
return placeHolder ?? Container();
|
||||
} else {
|
||||
|
|
@ -44,8 +42,6 @@ class FladderImage extends ConsumerWidget {
|
|||
filterQuality: FilterQuality.low,
|
||||
image: BlurHashImage(
|
||||
newImage.hash,
|
||||
decodingWidth: blurSize,
|
||||
decodingHeight: blurSize,
|
||||
),
|
||||
),
|
||||
if (!blurOnly)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue