mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-11 08:20:49 -07:00
Init repo
This commit is contained in:
commit
764b6034e3
566 changed files with 212335 additions and 0 deletions
90
lib/models/items/chapters_model.dart
Normal file
90
lib/models/items/chapters_model.dart
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fladder/main.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/providers/image_provider.dart';
|
||||
|
||||
class Chapter {
|
||||
final String name;
|
||||
final String imageUrl;
|
||||
final Uint8List? imageData;
|
||||
final Duration startPosition;
|
||||
Chapter({
|
||||
required this.name,
|
||||
required this.imageUrl,
|
||||
this.imageData,
|
||||
required this.startPosition,
|
||||
});
|
||||
|
||||
ImageProvider get imageProvider {
|
||||
if (imageData != null) {
|
||||
return Image.memory(imageData!).image;
|
||||
}
|
||||
if (imageUrl.startsWith("http")) {
|
||||
return CachedNetworkImageProvider(
|
||||
cacheKey: name + imageUrl,
|
||||
cacheManager: CustomCacheManager.instance,
|
||||
imageUrl,
|
||||
);
|
||||
} else {
|
||||
return Image.file(
|
||||
key: Key(name + imageUrl),
|
||||
File(imageUrl),
|
||||
).image;
|
||||
}
|
||||
}
|
||||
|
||||
static List<Chapter> chaptersFromInfo(String itemId, List<dto.ChapterInfo> chapters, Ref ref) {
|
||||
return chapters
|
||||
.mapIndexed((index, element) => Chapter(
|
||||
name: element.name ?? "",
|
||||
imageUrl: ref.read(imageUtilityProvider).getChapterUrl(itemId, index),
|
||||
startPosition: Duration(milliseconds: (element.startPositionTicks ?? 0) ~/ 10000)))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Chapter copyWith({
|
||||
String? name,
|
||||
String? imageUrl,
|
||||
Duration? startPosition,
|
||||
}) {
|
||||
return Chapter(
|
||||
name: name ?? this.name,
|
||||
imageUrl: imageUrl ?? this.imageUrl,
|
||||
startPosition: startPosition ?? this.startPosition,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'name': name,
|
||||
'imageUrl': imageUrl,
|
||||
'startPosition': startPosition.inMilliseconds,
|
||||
};
|
||||
}
|
||||
|
||||
factory Chapter.fromMap(Map<String, dynamic> map) {
|
||||
return Chapter(
|
||||
name: map['name'] ?? '',
|
||||
imageUrl: map['imageUrl'] ?? '',
|
||||
startPosition: Duration(milliseconds: map['startPosition'] as int),
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory Chapter.fromJson(String source) => Chapter.fromMap(json.decode(source));
|
||||
}
|
||||
|
||||
extension ChapterExtension on List<Chapter> {
|
||||
Chapter? getChapterFromDuration(Duration duration) {
|
||||
return lastWhereOrNull((element) => element.startPosition < duration);
|
||||
}
|
||||
}
|
||||
201
lib/models/items/episode_model.dart
Normal file
201
lib/models/items/episode_model.dart
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:fladder/jellyfin/enum_models.dart';
|
||||
import 'package:fladder/models/items/series_model.dart';
|
||||
import 'package:fladder/util/localization_helper.dart';
|
||||
import 'package:fladder/util/string_extensions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/item_stream_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'episode_model.mapper.dart';
|
||||
|
||||
enum EpisodeStatus { available, unaired, missing }
|
||||
|
||||
@MappableClass()
|
||||
class EpisodeModel extends ItemStreamModel with EpisodeModelMappable {
|
||||
final String? seriesName;
|
||||
final int season;
|
||||
final int episode;
|
||||
final List<Chapter> chapters;
|
||||
final ItemLocation? location;
|
||||
final DateTime? dateAired;
|
||||
const EpisodeModel({
|
||||
required this.seriesName,
|
||||
required this.season,
|
||||
required this.episode,
|
||||
this.chapters = const [],
|
||||
this.location,
|
||||
this.dateAired,
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
required super.parentImages,
|
||||
required super.mediaStreams,
|
||||
super.canDelete,
|
||||
super.canDownload,
|
||||
super.jellyType,
|
||||
});
|
||||
EpisodeStatus get status {
|
||||
return switch (location) {
|
||||
ItemLocation.filesystem => EpisodeStatus.available,
|
||||
ItemLocation.virtual =>
|
||||
(dateAired?.isBefore(DateTime.now()) == true) ? EpisodeStatus.missing : EpisodeStatus.unaired,
|
||||
_ => EpisodeStatus.missing
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String? detailedName(BuildContext context) => "${subTextShort(context)} - $name";
|
||||
|
||||
@override
|
||||
SeriesModel get parentBaseModel => SeriesModel(
|
||||
originalTitle: '',
|
||||
sortName: '',
|
||||
status: "",
|
||||
name: seriesName ?? "",
|
||||
id: parentId ?? "",
|
||||
playlistId: playlistId,
|
||||
overview: overview,
|
||||
parentId: parentId,
|
||||
images: images,
|
||||
childCount: childCount,
|
||||
primaryRatio: primaryRatio,
|
||||
userData: UserData(),
|
||||
);
|
||||
|
||||
@override
|
||||
String get streamId => parentId ?? "";
|
||||
|
||||
@override
|
||||
String get title => seriesName ?? name;
|
||||
|
||||
@override
|
||||
MediaStreamsModel? get streamModel => mediaStreams;
|
||||
|
||||
@override
|
||||
ImagesData? get getPosters => parentImages;
|
||||
|
||||
@override
|
||||
String? get subText => name.isEmpty ? "TBA" : name;
|
||||
|
||||
@override
|
||||
String? subTextShort(BuildContext context) => seasonEpisodeLabel(context);
|
||||
|
||||
@override
|
||||
String? label(BuildContext context) => "${subTextShort(context)} - $name";
|
||||
|
||||
@override
|
||||
bool get playAble => switch (status) {
|
||||
EpisodeStatus.available => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
@override
|
||||
String playButtonLabel(BuildContext context) {
|
||||
final string = seasonEpisodeLabel(context).maxLength();
|
||||
return progress != 0 ? context.localized.resume(string) : context.localized.play(string);
|
||||
}
|
||||
|
||||
String seasonAnnotation(BuildContext context) => context.localized.season(1)[0];
|
||||
String episodeAnnotation(BuildContext context) => context.localized.episode(1)[0];
|
||||
|
||||
String seasonEpisodeLabel(BuildContext context) {
|
||||
return "${seasonAnnotation(context)}$season - ${episodeAnnotation(context)}$episode";
|
||||
}
|
||||
|
||||
String seasonEpisodeLabelFull(BuildContext context) {
|
||||
return "${context.localized.season(1)} $season - ${context.localized.episode(1)} $episode";
|
||||
}
|
||||
|
||||
String episodeLabel(BuildContext context) {
|
||||
return "${seasonEpisodeLabel(context)} - $subText";
|
||||
}
|
||||
|
||||
String get fullName {
|
||||
return "$episode. $subText";
|
||||
}
|
||||
|
||||
@override
|
||||
bool get syncAble => playAble;
|
||||
|
||||
@override
|
||||
factory EpisodeModel.fromBaseDto(dto.BaseItemDto item, Ref ref) => EpisodeModel(
|
||||
seriesName: item.seriesName,
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.seriesId,
|
||||
playlistId: item.playlistItemId,
|
||||
dateAired: item.premiereDate,
|
||||
chapters: Chapter.chaptersFromInfo(item.id ?? "", item.chapters ?? [], ref),
|
||||
images: ImagesData.fromBaseItem(item, ref, getOriginalSize: true),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
season: item.parentIndexNumber ?? 0,
|
||||
episode: item.indexNumber ?? 0,
|
||||
location: ItemLocation.fromDto(item.locationType),
|
||||
parentImages: ImagesData.fromBaseItemParent(item, ref),
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
mediaStreams:
|
||||
MediaStreamsModel.fromMediaStreamsList(item.mediaSources?.firstOrNull, item.mediaStreams ?? [], ref),
|
||||
jellyType: item.type,
|
||||
);
|
||||
|
||||
static List<EpisodeModel> episodesFromDto(List<dto.BaseItemDto>? dto, Ref ref) {
|
||||
return dto?.map((e) => EpisodeModel.fromBaseDto(e, ref)).toList() ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
extension EpisodeListExtensions on List<EpisodeModel> {
|
||||
Map<int, List<EpisodeModel>> get episodesBySeason {
|
||||
Map<int, List<EpisodeModel>> groupedItems = {};
|
||||
for (int i = 0; i < length; i++) {
|
||||
int seasonIndex = this[i].season;
|
||||
if (!groupedItems.containsKey(seasonIndex)) {
|
||||
groupedItems[seasonIndex] = [this[i]];
|
||||
} else {
|
||||
groupedItems[seasonIndex]?.add(this[i]);
|
||||
}
|
||||
}
|
||||
return groupedItems;
|
||||
}
|
||||
|
||||
EpisodeModel? get nextUp {
|
||||
final lastProgress =
|
||||
lastIndexWhere((element) => element.userData.progress != 0 && element.status == EpisodeStatus.available);
|
||||
final lastPlayed =
|
||||
lastIndexWhere((element) => element.userData.played && element.status == EpisodeStatus.available);
|
||||
|
||||
if (lastProgress == -1 && lastPlayed == -1) {
|
||||
return firstWhereOrNull((element) => element.status == EpisodeStatus.available);
|
||||
} else {
|
||||
return getRange(lastProgress > lastPlayed ? lastProgress : lastPlayed + 1, length)
|
||||
.firstWhereOrNull((element) => element.status == EpisodeStatus.available);
|
||||
}
|
||||
}
|
||||
|
||||
bool get allPlayed {
|
||||
for (var element in this) {
|
||||
if (!element.userData.played) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
301
lib/models/items/episode_model.mapper.dart
Normal file
301
lib/models/items/episode_model.mapper.dart
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'episode_model.dart';
|
||||
|
||||
class EpisodeModelMapper extends SubClassMapperBase<EpisodeModel> {
|
||||
EpisodeModelMapper._();
|
||||
|
||||
static EpisodeModelMapper? _instance;
|
||||
static EpisodeModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = EpisodeModelMapper._());
|
||||
ItemStreamModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'EpisodeModel';
|
||||
|
||||
static String? _$seriesName(EpisodeModel v) => v.seriesName;
|
||||
static const Field<EpisodeModel, String> _f$seriesName =
|
||||
Field('seriesName', _$seriesName);
|
||||
static int _$season(EpisodeModel v) => v.season;
|
||||
static const Field<EpisodeModel, int> _f$season = Field('season', _$season);
|
||||
static int _$episode(EpisodeModel v) => v.episode;
|
||||
static const Field<EpisodeModel, int> _f$episode =
|
||||
Field('episode', _$episode);
|
||||
static List<Chapter> _$chapters(EpisodeModel v) => v.chapters;
|
||||
static const Field<EpisodeModel, List<Chapter>> _f$chapters =
|
||||
Field('chapters', _$chapters, opt: true, def: const []);
|
||||
static ItemLocation? _$location(EpisodeModel v) => v.location;
|
||||
static const Field<EpisodeModel, ItemLocation> _f$location =
|
||||
Field('location', _$location, opt: true);
|
||||
static DateTime? _$dateAired(EpisodeModel v) => v.dateAired;
|
||||
static const Field<EpisodeModel, DateTime> _f$dateAired =
|
||||
Field('dateAired', _$dateAired, opt: true);
|
||||
static String _$name(EpisodeModel v) => v.name;
|
||||
static const Field<EpisodeModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(EpisodeModel v) => v.id;
|
||||
static const Field<EpisodeModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(EpisodeModel v) => v.overview;
|
||||
static const Field<EpisodeModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(EpisodeModel v) => v.parentId;
|
||||
static const Field<EpisodeModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(EpisodeModel v) => v.playlistId;
|
||||
static const Field<EpisodeModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(EpisodeModel v) => v.images;
|
||||
static const Field<EpisodeModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(EpisodeModel v) => v.childCount;
|
||||
static const Field<EpisodeModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(EpisodeModel v) => v.primaryRatio;
|
||||
static const Field<EpisodeModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(EpisodeModel v) => v.userData;
|
||||
static const Field<EpisodeModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static ImagesData? _$parentImages(EpisodeModel v) => v.parentImages;
|
||||
static const Field<EpisodeModel, ImagesData> _f$parentImages =
|
||||
Field('parentImages', _$parentImages);
|
||||
static MediaStreamsModel _$mediaStreams(EpisodeModel v) => v.mediaStreams;
|
||||
static const Field<EpisodeModel, MediaStreamsModel> _f$mediaStreams =
|
||||
Field('mediaStreams', _$mediaStreams);
|
||||
static bool? _$canDelete(EpisodeModel v) => v.canDelete;
|
||||
static const Field<EpisodeModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete, opt: true);
|
||||
static bool? _$canDownload(EpisodeModel v) => v.canDownload;
|
||||
static const Field<EpisodeModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload, opt: true);
|
||||
static dto.BaseItemKind? _$jellyType(EpisodeModel v) => v.jellyType;
|
||||
static const Field<EpisodeModel, dto.BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<EpisodeModel> fields = const {
|
||||
#seriesName: _f$seriesName,
|
||||
#season: _f$season,
|
||||
#episode: _f$episode,
|
||||
#chapters: _f$chapters,
|
||||
#location: _f$location,
|
||||
#dateAired: _f$dateAired,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#parentImages: _f$parentImages,
|
||||
#mediaStreams: _f$mediaStreams,
|
||||
#canDelete: _f$canDelete,
|
||||
#canDownload: _f$canDownload,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'EpisodeModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemStreamModelMapper.ensureInitialized();
|
||||
|
||||
static EpisodeModel _instantiate(DecodingData data) {
|
||||
return EpisodeModel(
|
||||
seriesName: data.dec(_f$seriesName),
|
||||
season: data.dec(_f$season),
|
||||
episode: data.dec(_f$episode),
|
||||
chapters: data.dec(_f$chapters),
|
||||
location: data.dec(_f$location),
|
||||
dateAired: data.dec(_f$dateAired),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
parentImages: data.dec(_f$parentImages),
|
||||
mediaStreams: data.dec(_f$mediaStreams),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static EpisodeModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<EpisodeModel>(map);
|
||||
}
|
||||
|
||||
static EpisodeModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<EpisodeModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin EpisodeModelMappable {
|
||||
String toJson() {
|
||||
return EpisodeModelMapper.ensureInitialized()
|
||||
.encodeJson<EpisodeModel>(this as EpisodeModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return EpisodeModelMapper.ensureInitialized()
|
||||
.encodeMap<EpisodeModel>(this as EpisodeModel);
|
||||
}
|
||||
|
||||
EpisodeModelCopyWith<EpisodeModel, EpisodeModel, EpisodeModel> get copyWith =>
|
||||
_EpisodeModelCopyWithImpl(this as EpisodeModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return EpisodeModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as EpisodeModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension EpisodeModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, EpisodeModel, $Out> {
|
||||
EpisodeModelCopyWith<$R, EpisodeModel, $Out> get $asEpisodeModel =>
|
||||
$base.as((v, t, t2) => _EpisodeModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class EpisodeModelCopyWith<$R, $In extends EpisodeModel, $Out>
|
||||
implements ItemStreamModelCopyWith<$R, $In, $Out> {
|
||||
ListCopyWith<$R, Chapter, ObjectCopyWith<$R, Chapter, Chapter>> get chapters;
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{String? seriesName,
|
||||
int? season,
|
||||
int? episode,
|
||||
List<Chapter>? chapters,
|
||||
ItemLocation? location,
|
||||
DateTime? dateAired,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
ImagesData? parentImages,
|
||||
MediaStreamsModel? mediaStreams,
|
||||
bool? canDelete,
|
||||
bool? canDownload,
|
||||
dto.BaseItemKind? jellyType});
|
||||
EpisodeModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _EpisodeModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, EpisodeModel, $Out>
|
||||
implements EpisodeModelCopyWith<$R, EpisodeModel, $Out> {
|
||||
_EpisodeModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<EpisodeModel> $mapper =
|
||||
EpisodeModelMapper.ensureInitialized();
|
||||
@override
|
||||
ListCopyWith<$R, Chapter, ObjectCopyWith<$R, Chapter, Chapter>>
|
||||
get chapters => ListCopyWith($value.chapters,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t), (v) => call(chapters: v));
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{Object? seriesName = $none,
|
||||
int? season,
|
||||
int? episode,
|
||||
List<Chapter>? chapters,
|
||||
Object? location = $none,
|
||||
Object? dateAired = $none,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? parentImages = $none,
|
||||
MediaStreamsModel? mediaStreams,
|
||||
Object? canDelete = $none,
|
||||
Object? canDownload = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (seriesName != $none) #seriesName: seriesName,
|
||||
if (season != null) #season: season,
|
||||
if (episode != null) #episode: episode,
|
||||
if (chapters != null) #chapters: chapters,
|
||||
if (location != $none) #location: location,
|
||||
if (dateAired != $none) #dateAired: dateAired,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (parentImages != $none) #parentImages: parentImages,
|
||||
if (mediaStreams != null) #mediaStreams: mediaStreams,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
EpisodeModel $make(CopyWithData data) => EpisodeModel(
|
||||
seriesName: data.get(#seriesName, or: $value.seriesName),
|
||||
season: data.get(#season, or: $value.season),
|
||||
episode: data.get(#episode, or: $value.episode),
|
||||
chapters: data.get(#chapters, or: $value.chapters),
|
||||
location: data.get(#location, or: $value.location),
|
||||
dateAired: data.get(#dateAired, or: $value.dateAired),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
parentImages: data.get(#parentImages, or: $value.parentImages),
|
||||
mediaStreams: data.get(#mediaStreams, or: $value.mediaStreams),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
EpisodeModelCopyWith<$R2, EpisodeModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_EpisodeModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
50
lib/models/items/folder_model.dart
Normal file
50
lib/models/items/folder_model.dart
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'folder_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class FolderModel extends ItemBaseModel with FolderModelMappable {
|
||||
final List<ItemBaseModel> items;
|
||||
|
||||
const FolderModel({
|
||||
required this.items,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
required super.name,
|
||||
required super.id,
|
||||
super.canDownload,
|
||||
super.canDelete,
|
||||
super.jellyType,
|
||||
});
|
||||
|
||||
factory FolderModel.fromBaseDto(BaseItemDto item, Ref ref) {
|
||||
return FolderModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
images: ImagesData.fromBaseItem(item, ref),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
items: [],
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
);
|
||||
}
|
||||
}
|
||||
242
lib/models/items/folder_model.mapper.dart
Normal file
242
lib/models/items/folder_model.mapper.dart
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'folder_model.dart';
|
||||
|
||||
class FolderModelMapper extends SubClassMapperBase<FolderModel> {
|
||||
FolderModelMapper._();
|
||||
|
||||
static FolderModelMapper? _instance;
|
||||
static FolderModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = FolderModelMapper._());
|
||||
ItemBaseModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'FolderModel';
|
||||
|
||||
static List<ItemBaseModel> _$items(FolderModel v) => v.items;
|
||||
static const Field<FolderModel, List<ItemBaseModel>> _f$items =
|
||||
Field('items', _$items);
|
||||
static OverviewModel _$overview(FolderModel v) => v.overview;
|
||||
static const Field<FolderModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(FolderModel v) => v.parentId;
|
||||
static const Field<FolderModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(FolderModel v) => v.playlistId;
|
||||
static const Field<FolderModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(FolderModel v) => v.images;
|
||||
static const Field<FolderModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(FolderModel v) => v.childCount;
|
||||
static const Field<FolderModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(FolderModel v) => v.primaryRatio;
|
||||
static const Field<FolderModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(FolderModel v) => v.userData;
|
||||
static const Field<FolderModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static String _$name(FolderModel v) => v.name;
|
||||
static const Field<FolderModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(FolderModel v) => v.id;
|
||||
static const Field<FolderModel, String> _f$id = Field('id', _$id);
|
||||
static bool? _$canDownload(FolderModel v) => v.canDownload;
|
||||
static const Field<FolderModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload, opt: true);
|
||||
static bool? _$canDelete(FolderModel v) => v.canDelete;
|
||||
static const Field<FolderModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete, opt: true);
|
||||
static BaseItemKind? _$jellyType(FolderModel v) => v.jellyType;
|
||||
static const Field<FolderModel, BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<FolderModel> fields = const {
|
||||
#items: _f$items,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#canDownload: _f$canDownload,
|
||||
#canDelete: _f$canDelete,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'FolderModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
|
||||
static FolderModel _instantiate(DecodingData data) {
|
||||
return FolderModel(
|
||||
items: data.dec(_f$items),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static FolderModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<FolderModel>(map);
|
||||
}
|
||||
|
||||
static FolderModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<FolderModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin FolderModelMappable {
|
||||
String toJson() {
|
||||
return FolderModelMapper.ensureInitialized()
|
||||
.encodeJson<FolderModel>(this as FolderModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return FolderModelMapper.ensureInitialized()
|
||||
.encodeMap<FolderModel>(this as FolderModel);
|
||||
}
|
||||
|
||||
FolderModelCopyWith<FolderModel, FolderModel, FolderModel> get copyWith =>
|
||||
_FolderModelCopyWithImpl(this as FolderModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return FolderModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as FolderModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension FolderModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, FolderModel, $Out> {
|
||||
FolderModelCopyWith<$R, FolderModel, $Out> get $asFolderModel =>
|
||||
$base.as((v, t, t2) => _FolderModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class FolderModelCopyWith<$R, $In extends FolderModel, $Out>
|
||||
implements ItemBaseModelCopyWith<$R, $In, $Out> {
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>> get items;
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{List<ItemBaseModel>? items,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
String? name,
|
||||
String? id,
|
||||
bool? canDownload,
|
||||
bool? canDelete,
|
||||
BaseItemKind? jellyType});
|
||||
FolderModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _FolderModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, FolderModel, $Out>
|
||||
implements FolderModelCopyWith<$R, FolderModel, $Out> {
|
||||
_FolderModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<FolderModel> $mapper =
|
||||
FolderModelMapper.ensureInitialized();
|
||||
@override
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>>
|
||||
get items => ListCopyWith(
|
||||
$value.items, (v, t) => v.copyWith.$chain(t), (v) => call(items: v));
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{List<ItemBaseModel>? items,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
String? name,
|
||||
String? id,
|
||||
Object? canDownload = $none,
|
||||
Object? canDelete = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (items != null) #items: items,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
FolderModel $make(CopyWithData data) => FolderModel(
|
||||
items: data.get(#items, or: $value.items),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
FolderModelCopyWith<$R2, FolderModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_FolderModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
286
lib/models/items/images_models.dart
Normal file
286
lib/models/items/images_models.dart
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fladder/main.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart' as enums;
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/providers/image_provider.dart';
|
||||
import 'package:fladder/util/jelly_id.dart';
|
||||
|
||||
class ImagesData {
|
||||
final ImageData? primary;
|
||||
final List<ImageData>? backDrop;
|
||||
final ImageData? logo;
|
||||
ImagesData({
|
||||
this.primary,
|
||||
this.backDrop,
|
||||
this.logo,
|
||||
});
|
||||
|
||||
bool get isEmpty {
|
||||
if (primary == null && backDrop == null) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageData? get firstOrNull {
|
||||
return primary ?? backDrop?[0];
|
||||
}
|
||||
|
||||
ImageData? get randomBackDrop => (backDrop?..shuffle())?.firstOrNull ?? primary;
|
||||
|
||||
factory ImagesData.fromBaseItem(
|
||||
dto.BaseItemDto item,
|
||||
Ref ref, {
|
||||
Size backDrop = const Size(2000, 2000),
|
||||
Size logo = const Size(1000, 1000),
|
||||
Size primary = const Size(600, 600),
|
||||
bool getOriginalSize = false,
|
||||
int quality = 90,
|
||||
}) {
|
||||
final newImgesData = ImagesData(
|
||||
primary: item.imageTags?['Primary'] != null
|
||||
? ImageData(
|
||||
path: getOriginalSize
|
||||
? ref.read(imageUtilityProvider).getItemsOrigImageUrl(
|
||||
item.id!,
|
||||
type: enums.ImageType.primary,
|
||||
)
|
||||
: ref.read(imageUtilityProvider).getItemsImageUrl(
|
||||
(item.id!),
|
||||
type: enums.ImageType.primary,
|
||||
maxHeight: primary.height.toInt(),
|
||||
maxWidth: primary.width.toInt(),
|
||||
quality: quality,
|
||||
),
|
||||
key: item.imageTags?['Primary'],
|
||||
hash: item.imageBlurHashes?.primary?[item.imageTags?['Primary']] as String? ?? "",
|
||||
)
|
||||
: null,
|
||||
logo: item.imageTags?['Logo'] != null
|
||||
? ImageData(
|
||||
path: getOriginalSize
|
||||
? ref.read(imageUtilityProvider).getItemsOrigImageUrl(
|
||||
item.id!,
|
||||
type: enums.ImageType.logo,
|
||||
)
|
||||
: ref.read(imageUtilityProvider).getItemsImageUrl(
|
||||
(item.id!),
|
||||
type: enums.ImageType.logo,
|
||||
maxHeight: logo.height.toInt(),
|
||||
maxWidth: logo.width.toInt(),
|
||||
quality: quality,
|
||||
),
|
||||
key: item.imageTags?['Logo'],
|
||||
hash: item.imageBlurHashes?.logo?[item.imageTags?['Logo']] as String? ?? "")
|
||||
: null,
|
||||
backDrop: (item.backdropImageTags ?? []).mapIndexed(
|
||||
(index, backdrop) {
|
||||
final image = ImageData(
|
||||
path: getOriginalSize
|
||||
? ref.read(imageUtilityProvider).getBackdropOrigImage(
|
||||
item.id!,
|
||||
index,
|
||||
backdrop,
|
||||
)
|
||||
: ref.read(imageUtilityProvider).getBackdropImage(
|
||||
(item.id!),
|
||||
index,
|
||||
backdrop,
|
||||
maxHeight: backDrop.height.toInt(),
|
||||
maxWidth: backDrop.width.toInt(),
|
||||
quality: quality,
|
||||
),
|
||||
key: backdrop,
|
||||
hash: item.imageBlurHashes?.backdrop?[backdrop] ?? jellyId,
|
||||
);
|
||||
return image;
|
||||
},
|
||||
).toList(),
|
||||
);
|
||||
return newImgesData;
|
||||
}
|
||||
|
||||
static ImagesData? fromBaseItemParent(
|
||||
dto.BaseItemDto item,
|
||||
Ref ref, {
|
||||
Size backDrop = const Size(2000, 2000),
|
||||
Size logo = const Size(1000, 1000),
|
||||
Size primary = const Size(600, 600),
|
||||
int quality = 90,
|
||||
}) {
|
||||
if (item.seriesId == null && item.parentId == null) return null;
|
||||
final newImgesData = ImagesData(
|
||||
primary: (item.seriesPrimaryImageTag != null)
|
||||
? ImageData(
|
||||
path: ref.read(imageUtilityProvider).getItemsImageUrl(
|
||||
(item.seriesId!),
|
||||
type: enums.ImageType.primary,
|
||||
maxHeight: primary.height.toInt(),
|
||||
maxWidth: primary.width.toInt(),
|
||||
quality: quality,
|
||||
),
|
||||
key: item.seriesPrimaryImageTag ?? "",
|
||||
hash: item.imageBlurHashes?.primary?[item.seriesPrimaryImageTag] as String? ?? "")
|
||||
: null,
|
||||
logo: (item.parentLogoImageTag != null)
|
||||
? ImageData(
|
||||
path: ref.read(imageUtilityProvider).getItemsImageUrl(
|
||||
(item.seriesId!),
|
||||
type: enums.ImageType.logo,
|
||||
maxHeight: logo.height.toInt(),
|
||||
maxWidth: logo.width.toInt(),
|
||||
quality: quality,
|
||||
),
|
||||
key: item.parentLogoImageTag ?? "",
|
||||
hash: item.imageBlurHashes?.logo?[item.parentLogoImageTag] as String? ?? "")
|
||||
: null,
|
||||
backDrop: (item.backdropImageTags ?? []).mapIndexed(
|
||||
(index, backdrop) {
|
||||
final image = ImageData(
|
||||
path: ref.read(imageUtilityProvider).getBackdropImage(
|
||||
((item.seriesId ?? item.parentId)!),
|
||||
index,
|
||||
backdrop,
|
||||
maxHeight: backDrop.height.toInt(),
|
||||
maxWidth: backDrop.width.toInt(),
|
||||
quality: quality,
|
||||
),
|
||||
key: backdrop,
|
||||
hash: item.imageBlurHashes?.backdrop?[backdrop],
|
||||
);
|
||||
return image;
|
||||
},
|
||||
).toList(),
|
||||
);
|
||||
return newImgesData;
|
||||
}
|
||||
|
||||
static ImagesData? fromPersonDto(
|
||||
dto.BaseItemPerson item,
|
||||
Ref ref, {
|
||||
Size backDrop = const Size(2000, 2000),
|
||||
Size logo = const Size(1000, 1000),
|
||||
Size primary = const Size(2000, 2000),
|
||||
int quality = 90,
|
||||
}) {
|
||||
return ImagesData(
|
||||
primary: (item.primaryImageTag != null && item.imageBlurHashes != null)
|
||||
? ImageData(
|
||||
path: ref.read(imageUtilityProvider).getItemsImageUrl(
|
||||
item.id ?? "",
|
||||
type: enums.ImageType.primary,
|
||||
maxHeight: primary.height.toInt(),
|
||||
maxWidth: primary.width.toInt(),
|
||||
quality: quality,
|
||||
),
|
||||
key: item.primaryImageTag ?? "",
|
||||
hash: item.imageBlurHashes?.primary?[item.primaryImageTag] as String? ?? jellyId)
|
||||
: null,
|
||||
logo: null,
|
||||
backDrop: null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'ImagesData(primary: $primary, backDrop: $backDrop, logo: $logo)';
|
||||
|
||||
ImagesData copyWith({
|
||||
ValueGetter<ImageData?>? primary,
|
||||
ValueGetter<List<ImageData>?>? backDrop,
|
||||
ValueGetter<ImageData?>? logo,
|
||||
}) {
|
||||
return ImagesData(
|
||||
primary: primary != null ? primary() : this.primary,
|
||||
backDrop: backDrop != null ? backDrop() : this.backDrop,
|
||||
logo: logo != null ? logo() : this.logo,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'primary': primary?.toMap(),
|
||||
'backDrop': backDrop?.map((x) => x.toMap()).toList(),
|
||||
'logo': logo?.toMap(),
|
||||
};
|
||||
}
|
||||
|
||||
factory ImagesData.fromMap(Map<String, dynamic> map) {
|
||||
return ImagesData(
|
||||
primary: map['primary'] != null ? ImageData.fromMap(map['primary']) : null,
|
||||
backDrop:
|
||||
map['backDrop'] != null ? List<ImageData>.from(map['backDrop']?.map((x) => ImageData.fromMap(x))) : null,
|
||||
logo: map['logo'] != null ? ImageData.fromMap(map['logo']) : null,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory ImagesData.fromJson(String source) => ImagesData.fromMap(json.decode(source));
|
||||
}
|
||||
|
||||
class ImageData {
|
||||
final String path;
|
||||
final String hash;
|
||||
final String key;
|
||||
ImageData({
|
||||
this.path = '',
|
||||
this.hash = '',
|
||||
this.key = '',
|
||||
});
|
||||
|
||||
ImageProvider get imageProvider {
|
||||
if (path.startsWith("http")) {
|
||||
return CachedNetworkImageProvider(
|
||||
cacheKey: key,
|
||||
cacheManager: CustomCacheManager.instance,
|
||||
path,
|
||||
);
|
||||
} else {
|
||||
return Image.file(
|
||||
key: Key(key),
|
||||
File(path),
|
||||
).image;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'ImageData(path: $path, hash: $hash, key: $key)';
|
||||
|
||||
ImageData copyWith({
|
||||
String? path,
|
||||
String? hash,
|
||||
String? key,
|
||||
}) {
|
||||
return ImageData(
|
||||
path: path ?? this.path,
|
||||
hash: hash ?? this.hash,
|
||||
key: key ?? this.key,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'path': path,
|
||||
'hash': hash,
|
||||
'key': key,
|
||||
};
|
||||
}
|
||||
|
||||
factory ImageData.fromMap(Map<String, dynamic> map) {
|
||||
return ImageData(
|
||||
path: map['path'] ?? '',
|
||||
hash: map['hash'] ?? '',
|
||||
key: map['key'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory ImageData.fromJson(String source) => ImageData.fromMap(json.decode(source));
|
||||
}
|
||||
47
lib/models/items/intro_skip_model.dart
Normal file
47
lib/models/items/intro_skip_model.dart
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// 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;
|
||||
565
lib/models/items/intro_skip_model.freezed.dart
Normal file
565
lib/models/items/intro_skip_model.freezed.dart
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
// 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;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$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;
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@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);
|
||||
});
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
@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(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, intro, credits);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@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;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$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;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$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;
|
||||
|
||||
@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);
|
||||
|
||||
@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(ignore: true)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, id, valid, start, end, showTime, hideTime);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@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;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$IntroSkipModelImplCopyWith<_$IntroSkipModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
46
lib/models/items/intro_skip_model.g.dart
Normal file
46
lib/models/items/intro_skip_model.g.dart
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// 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),
|
||||
};
|
||||
21
lib/models/items/item_properties_model.dart
Normal file
21
lib/models/items/item_properties_model.dart
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'item_properties_model.freezed.dart';
|
||||
|
||||
@Freezed(fromJson: false, toJson: false)
|
||||
class ItemPropertiesModel with _$ItemPropertiesModel {
|
||||
const ItemPropertiesModel._();
|
||||
|
||||
factory ItemPropertiesModel._internal({
|
||||
required bool canDelete,
|
||||
required bool canDownload,
|
||||
}) = _ItemPropertiesModel;
|
||||
|
||||
factory ItemPropertiesModel.fromBaseDto(dto.BaseItemDto dtoItem) {
|
||||
return ItemPropertiesModel._internal(
|
||||
canDelete: dtoItem.canDelete ?? false,
|
||||
canDownload: dtoItem.canDownload ?? false,
|
||||
);
|
||||
}
|
||||
}
|
||||
156
lib/models/items/item_properties_model.freezed.dart
Normal file
156
lib/models/items/item_properties_model.freezed.dart
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
// 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 'item_properties_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');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ItemPropertiesModel {
|
||||
bool get canDelete => throw _privateConstructorUsedError;
|
||||
bool get canDownload => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$ItemPropertiesModelCopyWith<ItemPropertiesModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ItemPropertiesModelCopyWith<$Res> {
|
||||
factory $ItemPropertiesModelCopyWith(
|
||||
ItemPropertiesModel value, $Res Function(ItemPropertiesModel) then) =
|
||||
_$ItemPropertiesModelCopyWithImpl<$Res, ItemPropertiesModel>;
|
||||
@useResult
|
||||
$Res call({bool canDelete, bool canDownload});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ItemPropertiesModelCopyWithImpl<$Res, $Val extends ItemPropertiesModel>
|
||||
implements $ItemPropertiesModelCopyWith<$Res> {
|
||||
_$ItemPropertiesModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? canDelete = null,
|
||||
Object? canDownload = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
canDelete: null == canDelete
|
||||
? _value.canDelete
|
||||
: canDelete // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
canDownload: null == canDownload
|
||||
? _value.canDownload
|
||||
: canDownload // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ItemPropertiesModelImplCopyWith<$Res>
|
||||
implements $ItemPropertiesModelCopyWith<$Res> {
|
||||
factory _$$ItemPropertiesModelImplCopyWith(_$ItemPropertiesModelImpl value,
|
||||
$Res Function(_$ItemPropertiesModelImpl) then) =
|
||||
__$$ItemPropertiesModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({bool canDelete, bool canDownload});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ItemPropertiesModelImplCopyWithImpl<$Res>
|
||||
extends _$ItemPropertiesModelCopyWithImpl<$Res, _$ItemPropertiesModelImpl>
|
||||
implements _$$ItemPropertiesModelImplCopyWith<$Res> {
|
||||
__$$ItemPropertiesModelImplCopyWithImpl(_$ItemPropertiesModelImpl _value,
|
||||
$Res Function(_$ItemPropertiesModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? canDelete = null,
|
||||
Object? canDownload = null,
|
||||
}) {
|
||||
return _then(_$ItemPropertiesModelImpl(
|
||||
canDelete: null == canDelete
|
||||
? _value.canDelete
|
||||
: canDelete // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
canDownload: null == canDownload
|
||||
? _value.canDownload
|
||||
: canDownload // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$ItemPropertiesModelImpl extends _ItemPropertiesModel {
|
||||
_$ItemPropertiesModelImpl(
|
||||
{required this.canDelete, required this.canDownload})
|
||||
: super._();
|
||||
|
||||
@override
|
||||
final bool canDelete;
|
||||
@override
|
||||
final bool canDownload;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ItemPropertiesModel._internal(canDelete: $canDelete, canDownload: $canDownload)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ItemPropertiesModelImpl &&
|
||||
(identical(other.canDelete, canDelete) ||
|
||||
other.canDelete == canDelete) &&
|
||||
(identical(other.canDownload, canDownload) ||
|
||||
other.canDownload == canDownload));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, canDelete, canDownload);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ItemPropertiesModelImplCopyWith<_$ItemPropertiesModelImpl> get copyWith =>
|
||||
__$$ItemPropertiesModelImplCopyWithImpl<_$ItemPropertiesModelImpl>(
|
||||
this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _ItemPropertiesModel extends ItemPropertiesModel {
|
||||
factory _ItemPropertiesModel(
|
||||
{required final bool canDelete,
|
||||
required final bool canDownload}) = _$ItemPropertiesModelImpl;
|
||||
_ItemPropertiesModel._() : super._();
|
||||
|
||||
@override
|
||||
bool get canDelete;
|
||||
@override
|
||||
bool get canDownload;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$ItemPropertiesModelImplCopyWith<_$ItemPropertiesModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
380
lib/models/items/item_shared_models.dart
Normal file
380
lib/models/items/item_shared_models.dart
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'item_shared_models.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class UserData with UserDataMappable {
|
||||
final bool isFavourite;
|
||||
final int playCount;
|
||||
final int? unPlayedItemCount;
|
||||
final int playbackPositionTicks;
|
||||
final double progress;
|
||||
final bool played;
|
||||
final DateTime? lastPlayed;
|
||||
const UserData({
|
||||
this.isFavourite = false,
|
||||
this.playCount = 0,
|
||||
this.unPlayedItemCount,
|
||||
this.playbackPositionTicks = 0,
|
||||
this.progress = 0,
|
||||
this.lastPlayed,
|
||||
this.played = false,
|
||||
});
|
||||
|
||||
factory UserData.fromDto(dto.UserItemDataDto? dto) {
|
||||
if (dto == null) {
|
||||
return UserData();
|
||||
}
|
||||
return UserData(
|
||||
isFavourite: dto.isFavorite ?? false,
|
||||
playCount: dto.playCount ?? 0,
|
||||
playbackPositionTicks: dto.playbackPositionTicks ?? 0,
|
||||
played: dto.played ?? false,
|
||||
unPlayedItemCount: dto.unplayedItemCount ?? 0,
|
||||
lastPlayed: dto.lastPlayedDate,
|
||||
progress: dto.playedPercentage ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
Duration get playBackPosition => Duration(milliseconds: playbackPositionTicks ~/ 10000);
|
||||
|
||||
factory UserData.fromMap(Map<String, dynamic> map) => UserDataMapper.fromMap(map);
|
||||
factory UserData.fromJson(String json) => UserDataMapper.fromJson(json);
|
||||
}
|
||||
|
||||
class UserDataJsonSerializer extends JsonConverter<UserData, String> {
|
||||
const UserDataJsonSerializer();
|
||||
|
||||
@override
|
||||
UserData fromJson(String json) {
|
||||
return UserData.fromJson(json);
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson(UserData object) {
|
||||
return object.toJson();
|
||||
}
|
||||
}
|
||||
|
||||
enum EditorLockedFields {
|
||||
name("Name"),
|
||||
overView("Overview"),
|
||||
genres("Genres"),
|
||||
officialRating("OfficialRating"),
|
||||
cast("Cast"),
|
||||
productionLocations("ProductionLocations"),
|
||||
runTime("Runtime"),
|
||||
studios("Studios"),
|
||||
tags("Tags"),
|
||||
;
|
||||
|
||||
const EditorLockedFields(this.value);
|
||||
|
||||
static Map<EditorLockedFields, bool> enabled(List<String> fromStrings) => Map.fromEntries(
|
||||
EditorLockedFields.values.map(
|
||||
(e) => MapEntry(e, fromStrings.contains(e.value)),
|
||||
),
|
||||
);
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
enum DisplayOrder {
|
||||
empty(""),
|
||||
aired("aired"),
|
||||
originalAirDate("originalAirDate"),
|
||||
absolute("absolute"),
|
||||
dvd("dvd"),
|
||||
digital("digital"),
|
||||
storyArc("storyArc"),
|
||||
production("production"),
|
||||
tv("tv"),
|
||||
;
|
||||
|
||||
const DisplayOrder(this.value);
|
||||
|
||||
static DisplayOrder? fromMap(String? value) {
|
||||
return DisplayOrder.values.firstWhereOrNull((element) => element.value == value) ?? DisplayOrder.empty;
|
||||
}
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
enum ShowStatus {
|
||||
empty(""),
|
||||
ended("Ended"),
|
||||
continuing("Continuing");
|
||||
|
||||
const ShowStatus(this.value);
|
||||
|
||||
static ShowStatus? fromMap(String? value) {
|
||||
return ShowStatus.values.firstWhereOrNull((element) => element.value == value) ?? ShowStatus.empty;
|
||||
}
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
class ExternalUrls {
|
||||
final String name;
|
||||
final String url;
|
||||
ExternalUrls({
|
||||
required this.name,
|
||||
required this.url,
|
||||
});
|
||||
|
||||
static List<ExternalUrls> fromDto(List<dto.ExternalUrl> dto) {
|
||||
return dto.map((e) => ExternalUrls(name: e.name ?? "", url: e.url ?? "")).toList();
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'Name': name,
|
||||
'Url': url,
|
||||
};
|
||||
}
|
||||
|
||||
factory ExternalUrls.fromMap(Map<String, dynamic> map) {
|
||||
return ExternalUrls(
|
||||
name: map['Name'] ?? '',
|
||||
url: map['Url'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory ExternalUrls.fromJson(String source) => ExternalUrls.fromMap(json.decode(source));
|
||||
}
|
||||
|
||||
class GenreItems {
|
||||
final String id;
|
||||
final String name;
|
||||
GenreItems({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => 'GenreItems(id: $id, name: $name)';
|
||||
}
|
||||
|
||||
class Person {
|
||||
final String id;
|
||||
final String name;
|
||||
final ImageData? image;
|
||||
final String role;
|
||||
final PersonKind? type;
|
||||
Person({
|
||||
required this.id,
|
||||
this.name = "",
|
||||
this.image,
|
||||
this.role = "",
|
||||
this.type,
|
||||
});
|
||||
|
||||
static Person fromBaseDto(dto.BaseItemDto item, Ref ref) {
|
||||
return Person(
|
||||
id: item.id ?? "",
|
||||
name: item.name ?? "",
|
||||
image: ImagesData.fromBaseItem(item, ref).primary,
|
||||
);
|
||||
}
|
||||
|
||||
static Person fromBasePerson(dto.BaseItemPerson person, Ref ref) {
|
||||
return Person(
|
||||
id: person.id ?? "",
|
||||
name: person.name ?? "",
|
||||
image: ImagesData.fromPersonDto(person, ref)?.primary,
|
||||
role: person.role ?? "",
|
||||
type: person.type);
|
||||
}
|
||||
|
||||
dto.BaseItemPerson toPerson() {
|
||||
return dto.BaseItemPerson(
|
||||
id: id,
|
||||
name: name,
|
||||
type: type,
|
||||
role: role,
|
||||
);
|
||||
}
|
||||
|
||||
static List<Person> peopleFromDto(List<dto.BaseItemPerson>? people, Ref ref) {
|
||||
return people
|
||||
?.mapIndexed(
|
||||
(index, person) => fromBasePerson(person, ref),
|
||||
)
|
||||
.toList() ??
|
||||
[];
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'People(id: $id, name: $name, imageUrl: $image, role: $role, type: $type)';
|
||||
}
|
||||
}
|
||||
|
||||
class Studio {
|
||||
final String id;
|
||||
final String name;
|
||||
Studio({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
Studio copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
ValueGetter<String?>? image,
|
||||
}) {
|
||||
return Studio(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'Studio(name: $name, id: $id)';
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
};
|
||||
}
|
||||
|
||||
factory Studio.fromMap(Map<String, dynamic> map) {
|
||||
return Studio(
|
||||
id: map['id'] ?? map['Id'] ?? '',
|
||||
name: map['name'] ?? map['Name'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory Studio.fromJson(String source) => Studio.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is Studio && other.id == id && other.name == name;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode ^ name.hashCode;
|
||||
}
|
||||
|
||||
// class UserData {
|
||||
// final bool isFavourite;
|
||||
// final int playCount;
|
||||
// final int? unPlayedItemCount;
|
||||
// final int playbackPositionTicks;
|
||||
// final double progress;
|
||||
// final bool played;
|
||||
// UserData({
|
||||
// this.isFavourite = false,
|
||||
// this.playCount = 0,
|
||||
// this.unPlayedItemCount,
|
||||
// this.playbackPositionTicks = 0,
|
||||
// this.progress = 0,
|
||||
// this.played = false,
|
||||
// });
|
||||
|
||||
// factory UserData.fromDto(dto.UserItemDataDto? dto) {
|
||||
// if (dto == null) {
|
||||
// return UserData();
|
||||
// }
|
||||
// return UserData(
|
||||
// isFavourite: dto.isFavorite ?? false,
|
||||
// playCount: dto.playCount ?? 0,
|
||||
// playbackPositionTicks: dto.playbackPositionTicks ?? 0,
|
||||
// played: dto.played ?? false,
|
||||
// unPlayedItemCount: dto.unplayedItemCount ?? 0,
|
||||
// progress: dto.playedPercentage ?? 0,
|
||||
// );
|
||||
// }
|
||||
|
||||
// Duration get playBackPosition => Duration(milliseconds: playbackPositionTicks ~/ 10000);
|
||||
|
||||
// @override
|
||||
// String toString() {
|
||||
// return 'UserData(isFavourite: $isFavourite, playCount: $playCount, unPlayedItemCount: $unPlayedItemCount, playbackPositionTicks: $playbackPositionTicks, progress: $progress, played: $played)';
|
||||
// }
|
||||
|
||||
// UserData copyWith({
|
||||
// bool? isFavourite,
|
||||
// int? playCount,
|
||||
// int? unPlayedItemCount,
|
||||
// int? playbackPositionTicks,
|
||||
// double? progress,
|
||||
// bool? played,
|
||||
// }) {
|
||||
// return UserData(
|
||||
// isFavourite: isFavourite ?? this.isFavourite,
|
||||
// playCount: playCount ?? this.playCount,
|
||||
// unPlayedItemCount: unPlayedItemCount ?? this.unPlayedItemCount,
|
||||
// playbackPositionTicks: playbackPositionTicks ?? this.playbackPositionTicks,
|
||||
// progress: progress ?? this.progress,
|
||||
// played: played ?? this.played,
|
||||
// );
|
||||
// }
|
||||
|
||||
// Map<String, dynamic> toMap() {
|
||||
// return <String, dynamic>{
|
||||
// 'isFavourite': isFavourite,
|
||||
// 'playCount': playCount,
|
||||
// 'unPlayedItemCount': unPlayedItemCount,
|
||||
// 'playbackPositionTicks': playbackPositionTicks,
|
||||
// 'progress': progress,
|
||||
// 'played': played,
|
||||
// };
|
||||
// }
|
||||
|
||||
// factory UserData.fromMap(Map<String, dynamic> map) {
|
||||
// return UserData(
|
||||
// isFavourite: (map['isFavourite'] ?? false) as bool,
|
||||
// playCount: (map['playCount'] ?? 0) as int,
|
||||
// unPlayedItemCount: (map['unPlayedItemCount'] ?? 0) as int,
|
||||
// playbackPositionTicks: (map['playbackPositionTicks'] ?? 0) as int,
|
||||
// progress: (map['progress'] ?? 0.0) as double,
|
||||
// played: (map['played'] ?? false) as bool,
|
||||
// );
|
||||
// }
|
||||
|
||||
// String toJson() => json.encode(toMap());
|
||||
|
||||
// factory UserData.fromJson(String source) => UserData.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
// @override
|
||||
// bool operator ==(covariant UserData other) {
|
||||
// if (identical(this, other)) return true;
|
||||
|
||||
// return other.isFavourite == isFavourite &&
|
||||
// other.playCount == playCount &&
|
||||
// other.unPlayedItemCount == unPlayedItemCount &&
|
||||
// other.playbackPositionTicks == playbackPositionTicks &&
|
||||
// other.progress == progress &&
|
||||
// other.played == played;
|
||||
// }
|
||||
|
||||
// @override
|
||||
// int get hashCode {
|
||||
// return isFavourite.hashCode ^
|
||||
// playCount.hashCode ^
|
||||
// unPlayedItemCount.hashCode ^
|
||||
// playbackPositionTicks.hashCode ^
|
||||
// progress.hashCode ^
|
||||
// played.hashCode;
|
||||
// }
|
||||
// }
|
||||
162
lib/models/items/item_shared_models.mapper.dart
Normal file
162
lib/models/items/item_shared_models.mapper.dart
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'item_shared_models.dart';
|
||||
|
||||
class UserDataMapper extends ClassMapperBase<UserData> {
|
||||
UserDataMapper._();
|
||||
|
||||
static UserDataMapper? _instance;
|
||||
static UserDataMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = UserDataMapper._());
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'UserData';
|
||||
|
||||
static bool _$isFavourite(UserData v) => v.isFavourite;
|
||||
static const Field<UserData, bool> _f$isFavourite =
|
||||
Field('isFavourite', _$isFavourite, opt: true, def: false);
|
||||
static int _$playCount(UserData v) => v.playCount;
|
||||
static const Field<UserData, int> _f$playCount =
|
||||
Field('playCount', _$playCount, opt: true, def: 0);
|
||||
static int? _$unPlayedItemCount(UserData v) => v.unPlayedItemCount;
|
||||
static const Field<UserData, int> _f$unPlayedItemCount =
|
||||
Field('unPlayedItemCount', _$unPlayedItemCount, opt: true);
|
||||
static int _$playbackPositionTicks(UserData v) => v.playbackPositionTicks;
|
||||
static const Field<UserData, int> _f$playbackPositionTicks = Field(
|
||||
'playbackPositionTicks', _$playbackPositionTicks,
|
||||
opt: true, def: 0);
|
||||
static double _$progress(UserData v) => v.progress;
|
||||
static const Field<UserData, double> _f$progress =
|
||||
Field('progress', _$progress, opt: true, def: 0);
|
||||
static DateTime? _$lastPlayed(UserData v) => v.lastPlayed;
|
||||
static const Field<UserData, DateTime> _f$lastPlayed =
|
||||
Field('lastPlayed', _$lastPlayed, opt: true);
|
||||
static bool _$played(UserData v) => v.played;
|
||||
static const Field<UserData, bool> _f$played =
|
||||
Field('played', _$played, opt: true, def: false);
|
||||
|
||||
@override
|
||||
final MappableFields<UserData> fields = const {
|
||||
#isFavourite: _f$isFavourite,
|
||||
#playCount: _f$playCount,
|
||||
#unPlayedItemCount: _f$unPlayedItemCount,
|
||||
#playbackPositionTicks: _f$playbackPositionTicks,
|
||||
#progress: _f$progress,
|
||||
#lastPlayed: _f$lastPlayed,
|
||||
#played: _f$played,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
static UserData _instantiate(DecodingData data) {
|
||||
return UserData(
|
||||
isFavourite: data.dec(_f$isFavourite),
|
||||
playCount: data.dec(_f$playCount),
|
||||
unPlayedItemCount: data.dec(_f$unPlayedItemCount),
|
||||
playbackPositionTicks: data.dec(_f$playbackPositionTicks),
|
||||
progress: data.dec(_f$progress),
|
||||
lastPlayed: data.dec(_f$lastPlayed),
|
||||
played: data.dec(_f$played));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static UserData fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<UserData>(map);
|
||||
}
|
||||
|
||||
static UserData fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<UserData>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin UserDataMappable {
|
||||
String toJson() {
|
||||
return UserDataMapper.ensureInitialized()
|
||||
.encodeJson<UserData>(this as UserData);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return UserDataMapper.ensureInitialized()
|
||||
.encodeMap<UserData>(this as UserData);
|
||||
}
|
||||
|
||||
UserDataCopyWith<UserData, UserData, UserData> get copyWith =>
|
||||
_UserDataCopyWithImpl(this as UserData, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return UserDataMapper.ensureInitialized().stringifyValue(this as UserData);
|
||||
}
|
||||
}
|
||||
|
||||
extension UserDataValueCopy<$R, $Out> on ObjectCopyWith<$R, UserData, $Out> {
|
||||
UserDataCopyWith<$R, UserData, $Out> get $asUserData =>
|
||||
$base.as((v, t, t2) => _UserDataCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class UserDataCopyWith<$R, $In extends UserData, $Out>
|
||||
implements ClassCopyWith<$R, $In, $Out> {
|
||||
$R call(
|
||||
{bool? isFavourite,
|
||||
int? playCount,
|
||||
int? unPlayedItemCount,
|
||||
int? playbackPositionTicks,
|
||||
double? progress,
|
||||
DateTime? lastPlayed,
|
||||
bool? played});
|
||||
UserDataCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _UserDataCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, UserData, $Out>
|
||||
implements UserDataCopyWith<$R, UserData, $Out> {
|
||||
_UserDataCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<UserData> $mapper =
|
||||
UserDataMapper.ensureInitialized();
|
||||
@override
|
||||
$R call(
|
||||
{bool? isFavourite,
|
||||
int? playCount,
|
||||
Object? unPlayedItemCount = $none,
|
||||
int? playbackPositionTicks,
|
||||
double? progress,
|
||||
Object? lastPlayed = $none,
|
||||
bool? played}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (isFavourite != null) #isFavourite: isFavourite,
|
||||
if (playCount != null) #playCount: playCount,
|
||||
if (unPlayedItemCount != $none) #unPlayedItemCount: unPlayedItemCount,
|
||||
if (playbackPositionTicks != null)
|
||||
#playbackPositionTicks: playbackPositionTicks,
|
||||
if (progress != null) #progress: progress,
|
||||
if (lastPlayed != $none) #lastPlayed: lastPlayed,
|
||||
if (played != null) #played: played
|
||||
}));
|
||||
@override
|
||||
UserData $make(CopyWithData data) => UserData(
|
||||
isFavourite: data.get(#isFavourite, or: $value.isFavourite),
|
||||
playCount: data.get(#playCount, or: $value.playCount),
|
||||
unPlayedItemCount:
|
||||
data.get(#unPlayedItemCount, or: $value.unPlayedItemCount),
|
||||
playbackPositionTicks:
|
||||
data.get(#playbackPositionTicks, or: $value.playbackPositionTicks),
|
||||
progress: data.get(#progress, or: $value.progress),
|
||||
lastPlayed: data.get(#lastPlayed, or: $value.lastPlayed),
|
||||
played: data.get(#played, or: $value.played));
|
||||
|
||||
@override
|
||||
UserDataCopyWith<$R2, UserData, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_UserDataCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
67
lib/models/items/item_stream_model.dart
Normal file
67
lib/models/items/item_stream_model.dart
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/episode_model.dart';
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/movie_model.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'item_stream_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class ItemStreamModel extends ItemBaseModel with ItemStreamModelMappable {
|
||||
final ImagesData? parentImages;
|
||||
final MediaStreamsModel mediaStreams;
|
||||
const ItemStreamModel({
|
||||
required this.parentImages,
|
||||
required this.mediaStreams,
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
required super.canDelete,
|
||||
required super.canDownload,
|
||||
super.jellyType,
|
||||
});
|
||||
factory ItemStreamModel.fromBaseDto(dto.BaseItemDto item, Ref ref) {
|
||||
return switch (item.type) {
|
||||
BaseItemKind.episode => EpisodeModel.fromBaseDto(item, ref),
|
||||
BaseItemKind.movie => MovieModel.fromBaseDto(item, ref),
|
||||
_ => ItemStreamModel._fromBaseDto(item, ref)
|
||||
};
|
||||
}
|
||||
|
||||
factory ItemStreamModel._fromBaseDto(dto.BaseItemDto item, Ref ref) {
|
||||
return ItemStreamModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
images: ImagesData.fromBaseItem(item, ref),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
parentImages: ImagesData.fromBaseItemParent(item, ref),
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
mediaStreams:
|
||||
MediaStreamsModel.fromMediaStreamsList(item.mediaSources?.firstOrNull, item.mediaStreams ?? [], ref),
|
||||
);
|
||||
}
|
||||
|
||||
String? get videoPropertiesLabel {
|
||||
if (mediaStreams.displayProfile == null && mediaStreams.resolution == null) return null;
|
||||
return "${mediaStreams.displayProfile?.value}";
|
||||
}
|
||||
}
|
||||
245
lib/models/items/item_stream_model.mapper.dart
Normal file
245
lib/models/items/item_stream_model.mapper.dart
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'item_stream_model.dart';
|
||||
|
||||
class ItemStreamModelMapper extends SubClassMapperBase<ItemStreamModel> {
|
||||
ItemStreamModelMapper._();
|
||||
|
||||
static ItemStreamModelMapper? _instance;
|
||||
static ItemStreamModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = ItemStreamModelMapper._());
|
||||
ItemBaseModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'ItemStreamModel';
|
||||
|
||||
static ImagesData? _$parentImages(ItemStreamModel v) => v.parentImages;
|
||||
static const Field<ItemStreamModel, ImagesData> _f$parentImages =
|
||||
Field('parentImages', _$parentImages);
|
||||
static MediaStreamsModel _$mediaStreams(ItemStreamModel v) => v.mediaStreams;
|
||||
static const Field<ItemStreamModel, MediaStreamsModel> _f$mediaStreams =
|
||||
Field('mediaStreams', _$mediaStreams);
|
||||
static String _$name(ItemStreamModel v) => v.name;
|
||||
static const Field<ItemStreamModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(ItemStreamModel v) => v.id;
|
||||
static const Field<ItemStreamModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(ItemStreamModel v) => v.overview;
|
||||
static const Field<ItemStreamModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(ItemStreamModel v) => v.parentId;
|
||||
static const Field<ItemStreamModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(ItemStreamModel v) => v.playlistId;
|
||||
static const Field<ItemStreamModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(ItemStreamModel v) => v.images;
|
||||
static const Field<ItemStreamModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(ItemStreamModel v) => v.childCount;
|
||||
static const Field<ItemStreamModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(ItemStreamModel v) => v.primaryRatio;
|
||||
static const Field<ItemStreamModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(ItemStreamModel v) => v.userData;
|
||||
static const Field<ItemStreamModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static bool? _$canDelete(ItemStreamModel v) => v.canDelete;
|
||||
static const Field<ItemStreamModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete);
|
||||
static bool? _$canDownload(ItemStreamModel v) => v.canDownload;
|
||||
static const Field<ItemStreamModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload);
|
||||
static dto.BaseItemKind? _$jellyType(ItemStreamModel v) => v.jellyType;
|
||||
static const Field<ItemStreamModel, dto.BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<ItemStreamModel> fields = const {
|
||||
#parentImages: _f$parentImages,
|
||||
#mediaStreams: _f$mediaStreams,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#canDelete: _f$canDelete,
|
||||
#canDownload: _f$canDownload,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'ItemStreamModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
|
||||
static ItemStreamModel _instantiate(DecodingData data) {
|
||||
return ItemStreamModel(
|
||||
parentImages: data.dec(_f$parentImages),
|
||||
mediaStreams: data.dec(_f$mediaStreams),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static ItemStreamModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<ItemStreamModel>(map);
|
||||
}
|
||||
|
||||
static ItemStreamModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<ItemStreamModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin ItemStreamModelMappable {
|
||||
String toJson() {
|
||||
return ItemStreamModelMapper.ensureInitialized()
|
||||
.encodeJson<ItemStreamModel>(this as ItemStreamModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return ItemStreamModelMapper.ensureInitialized()
|
||||
.encodeMap<ItemStreamModel>(this as ItemStreamModel);
|
||||
}
|
||||
|
||||
ItemStreamModelCopyWith<ItemStreamModel, ItemStreamModel, ItemStreamModel>
|
||||
get copyWith => _ItemStreamModelCopyWithImpl(
|
||||
this as ItemStreamModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return ItemStreamModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as ItemStreamModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension ItemStreamModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, ItemStreamModel, $Out> {
|
||||
ItemStreamModelCopyWith<$R, ItemStreamModel, $Out> get $asItemStreamModel =>
|
||||
$base.as((v, t, t2) => _ItemStreamModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class ItemStreamModelCopyWith<$R, $In extends ItemStreamModel, $Out>
|
||||
implements ItemBaseModelCopyWith<$R, $In, $Out> {
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{ImagesData? parentImages,
|
||||
MediaStreamsModel? mediaStreams,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
bool? canDelete,
|
||||
bool? canDownload,
|
||||
dto.BaseItemKind? jellyType});
|
||||
ItemStreamModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _ItemStreamModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, ItemStreamModel, $Out>
|
||||
implements ItemStreamModelCopyWith<$R, ItemStreamModel, $Out> {
|
||||
_ItemStreamModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<ItemStreamModel> $mapper =
|
||||
ItemStreamModelMapper.ensureInitialized();
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{Object? parentImages = $none,
|
||||
MediaStreamsModel? mediaStreams,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? canDelete = $none,
|
||||
Object? canDownload = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (parentImages != $none) #parentImages: parentImages,
|
||||
if (mediaStreams != null) #mediaStreams: mediaStreams,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
ItemStreamModel $make(CopyWithData data) => ItemStreamModel(
|
||||
parentImages: data.get(#parentImages, or: $value.parentImages),
|
||||
mediaStreams: data.get(#mediaStreams, or: $value.mediaStreams),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
ItemStreamModelCopyWith<$R2, ItemStreamModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_ItemStreamModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
372
lib/models/items/media_streams_model.dart
Normal file
372
lib/models/items/media_streams_model.dart
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/providers/user_provider.dart';
|
||||
import 'package:fladder/util/video_properties.dart';
|
||||
|
||||
class MediaStreamsModel {
|
||||
final int? defaultAudioStreamIndex;
|
||||
final int? defaultSubStreamIndex;
|
||||
final List<VideoStreamModel> videoStreams;
|
||||
final List<AudioStreamModel> audioStreams;
|
||||
final List<SubStreamModel> subStreams;
|
||||
MediaStreamsModel({
|
||||
this.defaultAudioStreamIndex,
|
||||
this.defaultSubStreamIndex,
|
||||
required this.videoStreams,
|
||||
required this.audioStreams,
|
||||
required this.subStreams,
|
||||
});
|
||||
|
||||
bool get isNull {
|
||||
return defaultAudioStreamIndex == null ||
|
||||
defaultSubStreamIndex == null ||
|
||||
audioStreams.isEmpty ||
|
||||
subStreams.isEmpty;
|
||||
}
|
||||
|
||||
bool get isNotEmpty {
|
||||
return audioStreams.isNotEmpty && subStreams.isNotEmpty;
|
||||
}
|
||||
|
||||
AudioStreamModel? get currentAudioStream {
|
||||
if (defaultAudioStreamIndex == -1) {
|
||||
return AudioStreamModel.no();
|
||||
}
|
||||
return audioStreams.firstWhereOrNull((element) => element.index == defaultAudioStreamIndex) ??
|
||||
audioStreams.firstOrNull;
|
||||
}
|
||||
|
||||
SubStreamModel? get currentSubStream {
|
||||
if (defaultSubStreamIndex == -1) {
|
||||
return SubStreamModel.no();
|
||||
}
|
||||
return subStreams.firstWhereOrNull((element) => element.index == defaultSubStreamIndex) ?? subStreams.firstOrNull;
|
||||
}
|
||||
|
||||
DisplayProfile? get displayProfile {
|
||||
return DisplayProfile.fromVideoStreams(videoStreams);
|
||||
}
|
||||
|
||||
Resolution? get resolution {
|
||||
return Resolution.fromVideoStream(videoStreams.firstOrNull);
|
||||
}
|
||||
|
||||
String? get resolutionText {
|
||||
final stream = videoStreams.firstOrNull;
|
||||
if (stream == null) return null;
|
||||
return "${stream.width}x${stream.height}";
|
||||
}
|
||||
|
||||
Widget? audioIcon(
|
||||
BuildContext context,
|
||||
Function()? onTap,
|
||||
) {
|
||||
final audioStream = audioStreams.firstWhereOrNull((element) => element.isDefault) ?? audioStreams.firstOrNull;
|
||||
if (audioStream == null) return null;
|
||||
return DefaultVideoInformationBox(
|
||||
onTap: onTap,
|
||||
child: Text(
|
||||
audioStream.title,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget subtitleIcon(
|
||||
BuildContext context,
|
||||
Function()? onTap,
|
||||
) {
|
||||
return DefaultVideoInformationBox(
|
||||
onTap: onTap,
|
||||
child: Icon(
|
||||
subStreams.isNotEmpty ? Icons.subtitles_rounded : Icons.subtitles_off_outlined,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static MediaStreamsModel fromMediaStreamsList(
|
||||
dto.MediaSourceInfo? mediaSource, List<dto.MediaStream> streams, Ref ref) {
|
||||
return MediaStreamsModel(
|
||||
defaultAudioStreamIndex: mediaSource?.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: mediaSource?.defaultSubtitleStreamIndex,
|
||||
videoStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.video)
|
||||
.map(
|
||||
(e) => VideoStreamModel.fromMediaStream(e),
|
||||
)
|
||||
.sortByExternal(),
|
||||
audioStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.audio)
|
||||
.map(
|
||||
(e) => AudioStreamModel.fromMediaStream(e),
|
||||
)
|
||||
.sortByExternal(),
|
||||
subStreams: streams
|
||||
.where((element) => element.type == dto.MediaStreamType.subtitle)
|
||||
.map(
|
||||
(sub) => SubStreamModel.fromMediaStream(sub, ref),
|
||||
)
|
||||
.sortByExternal(),
|
||||
);
|
||||
}
|
||||
|
||||
MediaStreamsModel copyWith({
|
||||
int? defaultAudioStreamIndex,
|
||||
int? defaultSubStreamIndex,
|
||||
List<VideoStreamModel>? videoStreams,
|
||||
List<AudioStreamModel>? audioStreams,
|
||||
List<SubStreamModel>? subStreams,
|
||||
}) {
|
||||
return MediaStreamsModel(
|
||||
defaultAudioStreamIndex: defaultAudioStreamIndex ?? this.defaultAudioStreamIndex,
|
||||
defaultSubStreamIndex: defaultSubStreamIndex ?? this.defaultSubStreamIndex,
|
||||
videoStreams: videoStreams ?? this.videoStreams,
|
||||
audioStreams: audioStreams ?? this.audioStreams,
|
||||
subStreams: subStreams ?? this.subStreams,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MediaStreamsModel(defaultAudioStreamIndex: $defaultAudioStreamIndex, defaultSubStreamIndex: $defaultSubStreamIndex, videoStreams: $videoStreams, audioStreams: $audioStreams, subStreams: $subStreams)';
|
||||
}
|
||||
}
|
||||
|
||||
class StreamModel {
|
||||
final String name;
|
||||
final String codec;
|
||||
final bool isDefault;
|
||||
final bool isExternal;
|
||||
final int index;
|
||||
StreamModel({
|
||||
required this.name,
|
||||
required this.codec,
|
||||
required this.isDefault,
|
||||
required this.isExternal,
|
||||
required this.index,
|
||||
});
|
||||
}
|
||||
|
||||
class VideoStreamModel extends StreamModel {
|
||||
final int width;
|
||||
final int height;
|
||||
final double frameRate;
|
||||
final String? videoDoViTitle;
|
||||
final VideoRangeType? videoRangeType;
|
||||
VideoStreamModel({
|
||||
required super.name,
|
||||
required super.codec,
|
||||
required super.isDefault,
|
||||
required super.isExternal,
|
||||
required super.index,
|
||||
required this.videoDoViTitle,
|
||||
required this.videoRangeType,
|
||||
required this.width,
|
||||
required this.height,
|
||||
required this.frameRate,
|
||||
});
|
||||
|
||||
factory VideoStreamModel.fromMediaStream(dto.MediaStream stream) {
|
||||
return VideoStreamModel(
|
||||
name: stream.title ?? "",
|
||||
isDefault: stream.isDefault ?? false,
|
||||
codec: stream.codec ?? "",
|
||||
videoDoViTitle: stream.videoDoViTitle,
|
||||
videoRangeType: stream.videoRangeType,
|
||||
width: stream.width ?? 0,
|
||||
height: stream.height ?? 0,
|
||||
frameRate: stream.realFrameRate ?? 24,
|
||||
isExternal: stream.isExternal ?? false,
|
||||
index: stream.index ?? -1,
|
||||
);
|
||||
}
|
||||
String get prettyName {
|
||||
return "${Resolution.fromVideoStream(this)?.value} - ${DisplayProfile.fromVideoStream(this).value} - (${codec.toUpperCase()})";
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'VideoStreamModel(width: $width, height: $height, frameRate: $frameRate, videoDoViTitle: $videoDoViTitle, videoRangeType: $videoRangeType)';
|
||||
}
|
||||
}
|
||||
|
||||
//Instead of using sortBy(a.isExternal etc..) this one seems to be more consistent for some reason
|
||||
extension SortByExternalExtension<T extends StreamModel> on Iterable<T> {
|
||||
List<T> sortByExternal() {
|
||||
return [...where((element) => !element.isExternal), ...where((element) => element.isExternal)];
|
||||
}
|
||||
}
|
||||
|
||||
class AudioStreamModel extends StreamModel {
|
||||
final String displayTitle;
|
||||
final String language;
|
||||
final String channelLayout;
|
||||
|
||||
AudioStreamModel({
|
||||
required this.displayTitle,
|
||||
required super.name,
|
||||
required super.codec,
|
||||
required super.isDefault,
|
||||
required super.isExternal,
|
||||
required super.index,
|
||||
required this.language,
|
||||
required this.channelLayout,
|
||||
});
|
||||
|
||||
factory AudioStreamModel.fromMediaStream(dto.MediaStream stream) {
|
||||
return AudioStreamModel(
|
||||
displayTitle: stream.displayTitle ?? "",
|
||||
name: stream.title ?? "",
|
||||
isDefault: stream.isDefault ?? false,
|
||||
codec: stream.codec ?? "",
|
||||
language: stream.language ?? "Unknown",
|
||||
channelLayout: stream.channelLayout ?? "",
|
||||
isExternal: stream.isExternal ?? false,
|
||||
index: stream.index ?? -1,
|
||||
);
|
||||
}
|
||||
|
||||
String get title =>
|
||||
[name, language, codec, channelLayout].whereNotNull().where((element) => element.isNotEmpty).join(' - ');
|
||||
|
||||
AudioStreamModel.no({
|
||||
super.name = 'Off',
|
||||
this.displayTitle = 'Off',
|
||||
this.language = '',
|
||||
super.codec = '',
|
||||
this.channelLayout = '',
|
||||
super.isDefault = false,
|
||||
super.isExternal = false,
|
||||
super.index = -1,
|
||||
});
|
||||
}
|
||||
|
||||
class SubStreamModel extends StreamModel {
|
||||
String id;
|
||||
String title;
|
||||
String displayTitle;
|
||||
String language;
|
||||
String? url;
|
||||
bool supportsExternalStream;
|
||||
SubStreamModel({
|
||||
required super.name,
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.displayTitle,
|
||||
required this.language,
|
||||
this.url,
|
||||
required super.codec,
|
||||
required super.isDefault,
|
||||
required super.isExternal,
|
||||
required super.index,
|
||||
this.supportsExternalStream = false,
|
||||
});
|
||||
|
||||
SubStreamModel.no({
|
||||
super.name = 'Off',
|
||||
this.id = 'Off',
|
||||
this.title = 'Off',
|
||||
this.displayTitle = 'Off',
|
||||
this.language = '',
|
||||
this.url = '',
|
||||
super.codec = '',
|
||||
super.isDefault = false,
|
||||
super.isExternal = false,
|
||||
super.index = -1,
|
||||
this.supportsExternalStream = false,
|
||||
});
|
||||
|
||||
factory SubStreamModel.fromMediaStream(dto.MediaStream stream, Ref ref) {
|
||||
return SubStreamModel(
|
||||
name: stream.title ?? "",
|
||||
title: stream.title ?? "",
|
||||
displayTitle: stream.displayTitle ?? "",
|
||||
language: stream.language ?? "Unknown",
|
||||
isDefault: stream.isDefault ?? false,
|
||||
codec: stream.codec ?? "",
|
||||
id: stream.hashCode.toString(),
|
||||
supportsExternalStream: stream.supportsExternalStream ?? false,
|
||||
url: stream.deliveryUrl != null
|
||||
? "${ref.read(userProvider)?.server ?? ""}${stream.deliveryUrl}}".replaceAll(".vtt", ".srt")
|
||||
: null,
|
||||
isExternal: stream.isExternal ?? false,
|
||||
index: stream.index ?? -1,
|
||||
);
|
||||
}
|
||||
|
||||
SubStreamModel copyWith({
|
||||
String? name,
|
||||
String? id,
|
||||
String? title,
|
||||
String? displayTitle,
|
||||
String? language,
|
||||
ValueGetter<String?>? url,
|
||||
String? codec,
|
||||
bool? isDefault,
|
||||
bool? isExternal,
|
||||
int? index,
|
||||
bool? supportsExternalStream,
|
||||
}) {
|
||||
return SubStreamModel(
|
||||
name: name ?? this.name,
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
displayTitle: displayTitle ?? this.displayTitle,
|
||||
language: language ?? this.language,
|
||||
url: url != null ? url() : this.url,
|
||||
supportsExternalStream: supportsExternalStream ?? this.supportsExternalStream,
|
||||
codec: codec ?? this.codec,
|
||||
isDefault: isDefault ?? this.isDefault,
|
||||
isExternal: isExternal ?? this.isExternal,
|
||||
index: index ?? this.index,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'name': name,
|
||||
'id': id,
|
||||
'title': title,
|
||||
'displayTitle': displayTitle,
|
||||
'language': language,
|
||||
'url': url,
|
||||
'supportsExternalStream': supportsExternalStream,
|
||||
'codec': codec,
|
||||
'isExternal': isExternal,
|
||||
'isDefault': isDefault,
|
||||
'index': index,
|
||||
};
|
||||
}
|
||||
|
||||
factory SubStreamModel.fromMap(Map<String, dynamic> map) {
|
||||
return SubStreamModel(
|
||||
name: map['name'] ?? '',
|
||||
id: map['id'] ?? '',
|
||||
title: map['title'] ?? '',
|
||||
displayTitle: map['displayTitle'] ?? '',
|
||||
language: map['language'] ?? '',
|
||||
url: map['url'],
|
||||
supportsExternalStream: map['supportsExternalStream'] ?? false,
|
||||
codec: map['codec'] ?? '',
|
||||
isDefault: map['isDefault'] ?? false,
|
||||
isExternal: map['isExternal'] ?? false,
|
||||
index: map['index'] ?? -1,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory SubStreamModel.fromJson(String source) => SubStreamModel.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SubFile(title: $title, displayTitle: $displayTitle, language: $language, url: $url, isExternal: $isExternal)';
|
||||
}
|
||||
}
|
||||
107
lib/models/items/movie_model.dart
Normal file
107
lib/models/items/movie_model.dart
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
|
||||
import 'package:fladder/util/humanize_duration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
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/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/item_stream_model.dart';
|
||||
import 'package:fladder/models/items/media_streams_model.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
import 'package:fladder/screens/details_screens/movie_detail_screen.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'movie_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class MovieModel extends ItemStreamModel with MovieModelMappable {
|
||||
final String originalTitle;
|
||||
final String? path;
|
||||
final DateTime premiereDate;
|
||||
final String sortName;
|
||||
final String status;
|
||||
final List<ItemBaseModel> related;
|
||||
final List<Chapter> chapters;
|
||||
const MovieModel({
|
||||
required this.originalTitle,
|
||||
this.path,
|
||||
this.chapters = const [],
|
||||
required this.premiereDate,
|
||||
required this.sortName,
|
||||
required this.status,
|
||||
this.related = const [],
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
required super.parentImages,
|
||||
required super.mediaStreams,
|
||||
required super.canDownload,
|
||||
required super.canDelete,
|
||||
super.jellyType,
|
||||
});
|
||||
@override
|
||||
String? detailedName(BuildContext context) => "$name${overview.yearAired != null ? " (${overview.yearAired})" : ""}";
|
||||
|
||||
@override
|
||||
Widget get detailScreenWidget => MovieDetailScreen(item: this);
|
||||
|
||||
@override
|
||||
ItemBaseModel get parentBaseModel => this;
|
||||
|
||||
@override
|
||||
String? get subText => overview.yearAired?.toString() ?? overview.runTime.humanize;
|
||||
|
||||
@override
|
||||
bool get playAble => true;
|
||||
|
||||
@override
|
||||
bool get identifiable => true;
|
||||
|
||||
@override
|
||||
String? label(BuildContext context) =>
|
||||
overview.yearAired == null ? overview.runTime.humanize : "$name (${overview.yearAired})";
|
||||
|
||||
@override
|
||||
ImageData? get bannerImage => images?.backDrop?.firstOrNull ?? images?.primary ?? getPosters?.primary;
|
||||
|
||||
@override
|
||||
MediaStreamsModel? get streamModel => mediaStreams;
|
||||
|
||||
@override
|
||||
bool get syncAble => true;
|
||||
|
||||
factory MovieModel.fromBaseDto(dto.BaseItemDto item, Ref ref) {
|
||||
return MovieModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
sortName: item.sortName ?? "",
|
||||
status: item.status ?? "",
|
||||
originalTitle: item.originalTitle ?? "",
|
||||
images: ImagesData.fromBaseItem(item, ref),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
chapters: Chapter.chaptersFromInfo(item.id ?? "", item.chapters ?? [], ref),
|
||||
premiereDate: item.premiereDate ?? DateTime.now(),
|
||||
parentImages: ImagesData.fromBaseItemParent(item, ref),
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
mediaStreams:
|
||||
MediaStreamsModel.fromMediaStreamsList(item.mediaSources?.firstOrNull, item.mediaStreams ?? [], ref),
|
||||
);
|
||||
}
|
||||
}
|
||||
318
lib/models/items/movie_model.mapper.dart
Normal file
318
lib/models/items/movie_model.mapper.dart
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'movie_model.dart';
|
||||
|
||||
class MovieModelMapper extends SubClassMapperBase<MovieModel> {
|
||||
MovieModelMapper._();
|
||||
|
||||
static MovieModelMapper? _instance;
|
||||
static MovieModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = MovieModelMapper._());
|
||||
ItemStreamModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'MovieModel';
|
||||
|
||||
static String _$originalTitle(MovieModel v) => v.originalTitle;
|
||||
static const Field<MovieModel, String> _f$originalTitle =
|
||||
Field('originalTitle', _$originalTitle);
|
||||
static String? _$path(MovieModel v) => v.path;
|
||||
static const Field<MovieModel, String> _f$path =
|
||||
Field('path', _$path, opt: true);
|
||||
static List<Chapter> _$chapters(MovieModel v) => v.chapters;
|
||||
static const Field<MovieModel, List<Chapter>> _f$chapters =
|
||||
Field('chapters', _$chapters, opt: true, def: const []);
|
||||
static DateTime _$premiereDate(MovieModel v) => v.premiereDate;
|
||||
static const Field<MovieModel, DateTime> _f$premiereDate =
|
||||
Field('premiereDate', _$premiereDate);
|
||||
static String _$sortName(MovieModel v) => v.sortName;
|
||||
static const Field<MovieModel, String> _f$sortName =
|
||||
Field('sortName', _$sortName);
|
||||
static String _$status(MovieModel v) => v.status;
|
||||
static const Field<MovieModel, String> _f$status = Field('status', _$status);
|
||||
static List<ItemBaseModel> _$related(MovieModel v) => v.related;
|
||||
static const Field<MovieModel, List<ItemBaseModel>> _f$related =
|
||||
Field('related', _$related, opt: true, def: const []);
|
||||
static String _$name(MovieModel v) => v.name;
|
||||
static const Field<MovieModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(MovieModel v) => v.id;
|
||||
static const Field<MovieModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(MovieModel v) => v.overview;
|
||||
static const Field<MovieModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(MovieModel v) => v.parentId;
|
||||
static const Field<MovieModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(MovieModel v) => v.playlistId;
|
||||
static const Field<MovieModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(MovieModel v) => v.images;
|
||||
static const Field<MovieModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(MovieModel v) => v.childCount;
|
||||
static const Field<MovieModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(MovieModel v) => v.primaryRatio;
|
||||
static const Field<MovieModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(MovieModel v) => v.userData;
|
||||
static const Field<MovieModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static ImagesData? _$parentImages(MovieModel v) => v.parentImages;
|
||||
static const Field<MovieModel, ImagesData> _f$parentImages =
|
||||
Field('parentImages', _$parentImages);
|
||||
static MediaStreamsModel _$mediaStreams(MovieModel v) => v.mediaStreams;
|
||||
static const Field<MovieModel, MediaStreamsModel> _f$mediaStreams =
|
||||
Field('mediaStreams', _$mediaStreams);
|
||||
static bool? _$canDownload(MovieModel v) => v.canDownload;
|
||||
static const Field<MovieModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload);
|
||||
static bool? _$canDelete(MovieModel v) => v.canDelete;
|
||||
static const Field<MovieModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete);
|
||||
static dto.BaseItemKind? _$jellyType(MovieModel v) => v.jellyType;
|
||||
static const Field<MovieModel, dto.BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<MovieModel> fields = const {
|
||||
#originalTitle: _f$originalTitle,
|
||||
#path: _f$path,
|
||||
#chapters: _f$chapters,
|
||||
#premiereDate: _f$premiereDate,
|
||||
#sortName: _f$sortName,
|
||||
#status: _f$status,
|
||||
#related: _f$related,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#parentImages: _f$parentImages,
|
||||
#mediaStreams: _f$mediaStreams,
|
||||
#canDownload: _f$canDownload,
|
||||
#canDelete: _f$canDelete,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'MovieModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemStreamModelMapper.ensureInitialized();
|
||||
|
||||
static MovieModel _instantiate(DecodingData data) {
|
||||
return MovieModel(
|
||||
originalTitle: data.dec(_f$originalTitle),
|
||||
path: data.dec(_f$path),
|
||||
chapters: data.dec(_f$chapters),
|
||||
premiereDate: data.dec(_f$premiereDate),
|
||||
sortName: data.dec(_f$sortName),
|
||||
status: data.dec(_f$status),
|
||||
related: data.dec(_f$related),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
parentImages: data.dec(_f$parentImages),
|
||||
mediaStreams: data.dec(_f$mediaStreams),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static MovieModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<MovieModel>(map);
|
||||
}
|
||||
|
||||
static MovieModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<MovieModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin MovieModelMappable {
|
||||
String toJson() {
|
||||
return MovieModelMapper.ensureInitialized()
|
||||
.encodeJson<MovieModel>(this as MovieModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return MovieModelMapper.ensureInitialized()
|
||||
.encodeMap<MovieModel>(this as MovieModel);
|
||||
}
|
||||
|
||||
MovieModelCopyWith<MovieModel, MovieModel, MovieModel> get copyWith =>
|
||||
_MovieModelCopyWithImpl(this as MovieModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return MovieModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as MovieModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension MovieModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, MovieModel, $Out> {
|
||||
MovieModelCopyWith<$R, MovieModel, $Out> get $asMovieModel =>
|
||||
$base.as((v, t, t2) => _MovieModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class MovieModelCopyWith<$R, $In extends MovieModel, $Out>
|
||||
implements ItemStreamModelCopyWith<$R, $In, $Out> {
|
||||
ListCopyWith<$R, Chapter, ObjectCopyWith<$R, Chapter, Chapter>> get chapters;
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>> get related;
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{String? originalTitle,
|
||||
String? path,
|
||||
List<Chapter>? chapters,
|
||||
DateTime? premiereDate,
|
||||
String? sortName,
|
||||
String? status,
|
||||
List<ItemBaseModel>? related,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
ImagesData? parentImages,
|
||||
MediaStreamsModel? mediaStreams,
|
||||
bool? canDownload,
|
||||
bool? canDelete,
|
||||
dto.BaseItemKind? jellyType});
|
||||
MovieModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _MovieModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, MovieModel, $Out>
|
||||
implements MovieModelCopyWith<$R, MovieModel, $Out> {
|
||||
_MovieModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<MovieModel> $mapper =
|
||||
MovieModelMapper.ensureInitialized();
|
||||
@override
|
||||
ListCopyWith<$R, Chapter, ObjectCopyWith<$R, Chapter, Chapter>>
|
||||
get chapters => ListCopyWith($value.chapters,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t), (v) => call(chapters: v));
|
||||
@override
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>>
|
||||
get related => ListCopyWith($value.related,
|
||||
(v, t) => v.copyWith.$chain(t), (v) => call(related: v));
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{String? originalTitle,
|
||||
Object? path = $none,
|
||||
List<Chapter>? chapters,
|
||||
DateTime? premiereDate,
|
||||
String? sortName,
|
||||
String? status,
|
||||
List<ItemBaseModel>? related,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? parentImages = $none,
|
||||
MediaStreamsModel? mediaStreams,
|
||||
Object? canDownload = $none,
|
||||
Object? canDelete = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (originalTitle != null) #originalTitle: originalTitle,
|
||||
if (path != $none) #path: path,
|
||||
if (chapters != null) #chapters: chapters,
|
||||
if (premiereDate != null) #premiereDate: premiereDate,
|
||||
if (sortName != null) #sortName: sortName,
|
||||
if (status != null) #status: status,
|
||||
if (related != null) #related: related,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (parentImages != $none) #parentImages: parentImages,
|
||||
if (mediaStreams != null) #mediaStreams: mediaStreams,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
MovieModel $make(CopyWithData data) => MovieModel(
|
||||
originalTitle: data.get(#originalTitle, or: $value.originalTitle),
|
||||
path: data.get(#path, or: $value.path),
|
||||
chapters: data.get(#chapters, or: $value.chapters),
|
||||
premiereDate: data.get(#premiereDate, or: $value.premiereDate),
|
||||
sortName: data.get(#sortName, or: $value.sortName),
|
||||
status: data.get(#status, or: $value.status),
|
||||
related: data.get(#related, or: $value.related),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
parentImages: data.get(#parentImages, or: $value.parentImages),
|
||||
mediaStreams: data.get(#mediaStreams, or: $value.mediaStreams),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
MovieModelCopyWith<$R2, MovieModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_MovieModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
82
lib/models/items/overview_model.dart
Normal file
82
lib/models/items/overview_model.dart
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/models/items/chapters_model.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/trick_play_model.dart';
|
||||
import 'package:fladder/util/duration_extensions.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'overview_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class OverviewModel with OverviewModelMappable {
|
||||
final Duration? runTime;
|
||||
final String summary;
|
||||
final int? yearAired;
|
||||
final DateTime? dateAdded;
|
||||
final String? parentalRating;
|
||||
final int? productionYear;
|
||||
final double? criticRating;
|
||||
final double? communityRating;
|
||||
final Map<String, TrickPlayModel>? trickPlayInfo;
|
||||
final List<Chapter>? chapters;
|
||||
final List<ExternalUrls>? externalUrls;
|
||||
final List<Studio> studios;
|
||||
final List<String> genres;
|
||||
final List<GenreItems> genreItems;
|
||||
final List<String> tags;
|
||||
final List<Person> people;
|
||||
const OverviewModel({
|
||||
this.runTime,
|
||||
this.summary = "",
|
||||
this.yearAired,
|
||||
this.dateAdded,
|
||||
this.parentalRating,
|
||||
this.productionYear,
|
||||
this.criticRating,
|
||||
this.communityRating,
|
||||
this.trickPlayInfo,
|
||||
this.chapters,
|
||||
this.externalUrls,
|
||||
this.studios = const [],
|
||||
this.genres = const [],
|
||||
this.genreItems = const [],
|
||||
this.tags = const [],
|
||||
this.people = const [],
|
||||
});
|
||||
|
||||
List<Person> get directors {
|
||||
return people.where((element) => element.type == PersonKind.director).toList();
|
||||
}
|
||||
|
||||
List<Person> get writers {
|
||||
return people.where((element) => element.type == PersonKind.writer).toList();
|
||||
}
|
||||
|
||||
factory OverviewModel.fromBaseItemDto(BaseItemDto item, Ref ref) {
|
||||
final trickPlayItem = item.trickplay;
|
||||
return OverviewModel(
|
||||
runTime: item.runTimeDuration,
|
||||
yearAired: item.productionYear,
|
||||
parentalRating: item.officialRating,
|
||||
summary: item.overview ?? "",
|
||||
genres: item.genres ?? [],
|
||||
criticRating: item.criticRating,
|
||||
communityRating: item.communityRating,
|
||||
tags: item.tags ?? [],
|
||||
dateAdded: item.dateCreated,
|
||||
trickPlayInfo:
|
||||
trickPlayItem != null && trickPlayItem.isNotEmpty ? TrickPlayModel.toTrickPlayMap(trickPlayItem) : null,
|
||||
chapters: item.id != null ? Chapter.chaptersFromInfo(item.id ?? "", item.chapters ?? [], ref) : null,
|
||||
studios: item.studios?.map((e) => Studio(id: e.id ?? "", name: e.name ?? "")).toList() ?? [],
|
||||
genreItems: item.genreItems?.map((e) => GenreItems(id: e.id ?? "", name: e.name ?? "")).toList() ?? [],
|
||||
externalUrls: ExternalUrls.fromDto(item.externalUrls ?? []),
|
||||
people: Person.peopleFromDto(item.people ?? [], ref),
|
||||
);
|
||||
}
|
||||
|
||||
factory OverviewModel.fromMap(Map<String, dynamic> map) => OverviewModelMapper.fromMap(map);
|
||||
factory OverviewModel.fromJson(String json) => OverviewModelMapper.fromJson(json);
|
||||
}
|
||||
302
lib/models/items/overview_model.mapper.dart
Normal file
302
lib/models/items/overview_model.mapper.dart
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'overview_model.dart';
|
||||
|
||||
class OverviewModelMapper extends ClassMapperBase<OverviewModel> {
|
||||
OverviewModelMapper._();
|
||||
|
||||
static OverviewModelMapper? _instance;
|
||||
static OverviewModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = OverviewModelMapper._());
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'OverviewModel';
|
||||
|
||||
static Duration? _$runTime(OverviewModel v) => v.runTime;
|
||||
static const Field<OverviewModel, Duration> _f$runTime =
|
||||
Field('runTime', _$runTime, opt: true);
|
||||
static String _$summary(OverviewModel v) => v.summary;
|
||||
static const Field<OverviewModel, String> _f$summary =
|
||||
Field('summary', _$summary, opt: true, def: "");
|
||||
static int? _$yearAired(OverviewModel v) => v.yearAired;
|
||||
static const Field<OverviewModel, int> _f$yearAired =
|
||||
Field('yearAired', _$yearAired, opt: true);
|
||||
static DateTime? _$dateAdded(OverviewModel v) => v.dateAdded;
|
||||
static const Field<OverviewModel, DateTime> _f$dateAdded =
|
||||
Field('dateAdded', _$dateAdded, opt: true);
|
||||
static String? _$parentalRating(OverviewModel v) => v.parentalRating;
|
||||
static const Field<OverviewModel, String> _f$parentalRating =
|
||||
Field('parentalRating', _$parentalRating, opt: true);
|
||||
static int? _$productionYear(OverviewModel v) => v.productionYear;
|
||||
static const Field<OverviewModel, int> _f$productionYear =
|
||||
Field('productionYear', _$productionYear, opt: true);
|
||||
static double? _$criticRating(OverviewModel v) => v.criticRating;
|
||||
static const Field<OverviewModel, double> _f$criticRating =
|
||||
Field('criticRating', _$criticRating, opt: true);
|
||||
static double? _$communityRating(OverviewModel v) => v.communityRating;
|
||||
static const Field<OverviewModel, double> _f$communityRating =
|
||||
Field('communityRating', _$communityRating, opt: true);
|
||||
static Map<String, TrickPlayModel>? _$trickPlayInfo(OverviewModel v) =>
|
||||
v.trickPlayInfo;
|
||||
static const Field<OverviewModel, Map<String, TrickPlayModel>>
|
||||
_f$trickPlayInfo = Field('trickPlayInfo', _$trickPlayInfo, opt: true);
|
||||
static List<Chapter>? _$chapters(OverviewModel v) => v.chapters;
|
||||
static const Field<OverviewModel, List<Chapter>> _f$chapters =
|
||||
Field('chapters', _$chapters, opt: true);
|
||||
static List<ExternalUrls>? _$externalUrls(OverviewModel v) => v.externalUrls;
|
||||
static const Field<OverviewModel, List<ExternalUrls>> _f$externalUrls =
|
||||
Field('externalUrls', _$externalUrls, opt: true);
|
||||
static List<Studio> _$studios(OverviewModel v) => v.studios;
|
||||
static const Field<OverviewModel, List<Studio>> _f$studios =
|
||||
Field('studios', _$studios, opt: true, def: const []);
|
||||
static List<String> _$genres(OverviewModel v) => v.genres;
|
||||
static const Field<OverviewModel, List<String>> _f$genres =
|
||||
Field('genres', _$genres, opt: true, def: const []);
|
||||
static List<GenreItems> _$genreItems(OverviewModel v) => v.genreItems;
|
||||
static const Field<OverviewModel, List<GenreItems>> _f$genreItems =
|
||||
Field('genreItems', _$genreItems, opt: true, def: const []);
|
||||
static List<String> _$tags(OverviewModel v) => v.tags;
|
||||
static const Field<OverviewModel, List<String>> _f$tags =
|
||||
Field('tags', _$tags, opt: true, def: const []);
|
||||
static List<Person> _$people(OverviewModel v) => v.people;
|
||||
static const Field<OverviewModel, List<Person>> _f$people =
|
||||
Field('people', _$people, opt: true, def: const []);
|
||||
|
||||
@override
|
||||
final MappableFields<OverviewModel> fields = const {
|
||||
#runTime: _f$runTime,
|
||||
#summary: _f$summary,
|
||||
#yearAired: _f$yearAired,
|
||||
#dateAdded: _f$dateAdded,
|
||||
#parentalRating: _f$parentalRating,
|
||||
#productionYear: _f$productionYear,
|
||||
#criticRating: _f$criticRating,
|
||||
#communityRating: _f$communityRating,
|
||||
#trickPlayInfo: _f$trickPlayInfo,
|
||||
#chapters: _f$chapters,
|
||||
#externalUrls: _f$externalUrls,
|
||||
#studios: _f$studios,
|
||||
#genres: _f$genres,
|
||||
#genreItems: _f$genreItems,
|
||||
#tags: _f$tags,
|
||||
#people: _f$people,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
static OverviewModel _instantiate(DecodingData data) {
|
||||
return OverviewModel(
|
||||
runTime: data.dec(_f$runTime),
|
||||
summary: data.dec(_f$summary),
|
||||
yearAired: data.dec(_f$yearAired),
|
||||
dateAdded: data.dec(_f$dateAdded),
|
||||
parentalRating: data.dec(_f$parentalRating),
|
||||
productionYear: data.dec(_f$productionYear),
|
||||
criticRating: data.dec(_f$criticRating),
|
||||
communityRating: data.dec(_f$communityRating),
|
||||
trickPlayInfo: data.dec(_f$trickPlayInfo),
|
||||
chapters: data.dec(_f$chapters),
|
||||
externalUrls: data.dec(_f$externalUrls),
|
||||
studios: data.dec(_f$studios),
|
||||
genres: data.dec(_f$genres),
|
||||
genreItems: data.dec(_f$genreItems),
|
||||
tags: data.dec(_f$tags),
|
||||
people: data.dec(_f$people));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static OverviewModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<OverviewModel>(map);
|
||||
}
|
||||
|
||||
static OverviewModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<OverviewModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin OverviewModelMappable {
|
||||
String toJson() {
|
||||
return OverviewModelMapper.ensureInitialized()
|
||||
.encodeJson<OverviewModel>(this as OverviewModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return OverviewModelMapper.ensureInitialized()
|
||||
.encodeMap<OverviewModel>(this as OverviewModel);
|
||||
}
|
||||
|
||||
OverviewModelCopyWith<OverviewModel, OverviewModel, OverviewModel>
|
||||
get copyWith => _OverviewModelCopyWithImpl(
|
||||
this as OverviewModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return OverviewModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as OverviewModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension OverviewModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, OverviewModel, $Out> {
|
||||
OverviewModelCopyWith<$R, OverviewModel, $Out> get $asOverviewModel =>
|
||||
$base.as((v, t, t2) => _OverviewModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class OverviewModelCopyWith<$R, $In extends OverviewModel, $Out>
|
||||
implements ClassCopyWith<$R, $In, $Out> {
|
||||
MapCopyWith<$R, String, TrickPlayModel,
|
||||
ObjectCopyWith<$R, TrickPlayModel, TrickPlayModel>>? get trickPlayInfo;
|
||||
ListCopyWith<$R, Chapter, ObjectCopyWith<$R, Chapter, Chapter>>? get chapters;
|
||||
ListCopyWith<$R, ExternalUrls,
|
||||
ObjectCopyWith<$R, ExternalUrls, ExternalUrls>>? get externalUrls;
|
||||
ListCopyWith<$R, Studio, ObjectCopyWith<$R, Studio, Studio>> get studios;
|
||||
ListCopyWith<$R, String, ObjectCopyWith<$R, String, String>> get genres;
|
||||
ListCopyWith<$R, GenreItems, ObjectCopyWith<$R, GenreItems, GenreItems>>
|
||||
get genreItems;
|
||||
ListCopyWith<$R, String, ObjectCopyWith<$R, String, String>> get tags;
|
||||
ListCopyWith<$R, Person, ObjectCopyWith<$R, Person, Person>> get people;
|
||||
$R call(
|
||||
{Duration? runTime,
|
||||
String? summary,
|
||||
int? yearAired,
|
||||
DateTime? dateAdded,
|
||||
String? parentalRating,
|
||||
int? productionYear,
|
||||
double? criticRating,
|
||||
double? communityRating,
|
||||
Map<String, TrickPlayModel>? trickPlayInfo,
|
||||
List<Chapter>? chapters,
|
||||
List<ExternalUrls>? externalUrls,
|
||||
List<Studio>? studios,
|
||||
List<String>? genres,
|
||||
List<GenreItems>? genreItems,
|
||||
List<String>? tags,
|
||||
List<Person>? people});
|
||||
OverviewModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _OverviewModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, OverviewModel, $Out>
|
||||
implements OverviewModelCopyWith<$R, OverviewModel, $Out> {
|
||||
_OverviewModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<OverviewModel> $mapper =
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
@override
|
||||
MapCopyWith<$R, String, TrickPlayModel,
|
||||
ObjectCopyWith<$R, TrickPlayModel, TrickPlayModel>>?
|
||||
get trickPlayInfo => $value.trickPlayInfo != null
|
||||
? MapCopyWith(
|
||||
$value.trickPlayInfo!,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(trickPlayInfo: v))
|
||||
: null;
|
||||
@override
|
||||
ListCopyWith<$R, Chapter, ObjectCopyWith<$R, Chapter, Chapter>>?
|
||||
get chapters => $value.chapters != null
|
||||
? ListCopyWith(
|
||||
$value.chapters!,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(chapters: v))
|
||||
: null;
|
||||
@override
|
||||
ListCopyWith<$R, ExternalUrls,
|
||||
ObjectCopyWith<$R, ExternalUrls, ExternalUrls>>?
|
||||
get externalUrls => $value.externalUrls != null
|
||||
? ListCopyWith(
|
||||
$value.externalUrls!,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(externalUrls: v))
|
||||
: null;
|
||||
@override
|
||||
ListCopyWith<$R, Studio, ObjectCopyWith<$R, Studio, Studio>> get studios =>
|
||||
ListCopyWith($value.studios, (v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(studios: v));
|
||||
@override
|
||||
ListCopyWith<$R, String, ObjectCopyWith<$R, String, String>> get genres =>
|
||||
ListCopyWith($value.genres, (v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(genres: v));
|
||||
@override
|
||||
ListCopyWith<$R, GenreItems, ObjectCopyWith<$R, GenreItems, GenreItems>>
|
||||
get genreItems => ListCopyWith(
|
||||
$value.genreItems,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(genreItems: v));
|
||||
@override
|
||||
ListCopyWith<$R, String, ObjectCopyWith<$R, String, String>> get tags =>
|
||||
ListCopyWith($value.tags, (v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(tags: v));
|
||||
@override
|
||||
ListCopyWith<$R, Person, ObjectCopyWith<$R, Person, Person>> get people =>
|
||||
ListCopyWith($value.people, (v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(people: v));
|
||||
@override
|
||||
$R call(
|
||||
{Object? runTime = $none,
|
||||
String? summary,
|
||||
Object? yearAired = $none,
|
||||
Object? dateAdded = $none,
|
||||
Object? parentalRating = $none,
|
||||
Object? productionYear = $none,
|
||||
Object? criticRating = $none,
|
||||
Object? communityRating = $none,
|
||||
Object? trickPlayInfo = $none,
|
||||
Object? chapters = $none,
|
||||
Object? externalUrls = $none,
|
||||
List<Studio>? studios,
|
||||
List<String>? genres,
|
||||
List<GenreItems>? genreItems,
|
||||
List<String>? tags,
|
||||
List<Person>? people}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (runTime != $none) #runTime: runTime,
|
||||
if (summary != null) #summary: summary,
|
||||
if (yearAired != $none) #yearAired: yearAired,
|
||||
if (dateAdded != $none) #dateAdded: dateAdded,
|
||||
if (parentalRating != $none) #parentalRating: parentalRating,
|
||||
if (productionYear != $none) #productionYear: productionYear,
|
||||
if (criticRating != $none) #criticRating: criticRating,
|
||||
if (communityRating != $none) #communityRating: communityRating,
|
||||
if (trickPlayInfo != $none) #trickPlayInfo: trickPlayInfo,
|
||||
if (chapters != $none) #chapters: chapters,
|
||||
if (externalUrls != $none) #externalUrls: externalUrls,
|
||||
if (studios != null) #studios: studios,
|
||||
if (genres != null) #genres: genres,
|
||||
if (genreItems != null) #genreItems: genreItems,
|
||||
if (tags != null) #tags: tags,
|
||||
if (people != null) #people: people
|
||||
}));
|
||||
@override
|
||||
OverviewModel $make(CopyWithData data) => OverviewModel(
|
||||
runTime: data.get(#runTime, or: $value.runTime),
|
||||
summary: data.get(#summary, or: $value.summary),
|
||||
yearAired: data.get(#yearAired, or: $value.yearAired),
|
||||
dateAdded: data.get(#dateAdded, or: $value.dateAdded),
|
||||
parentalRating: data.get(#parentalRating, or: $value.parentalRating),
|
||||
productionYear: data.get(#productionYear, or: $value.productionYear),
|
||||
criticRating: data.get(#criticRating, or: $value.criticRating),
|
||||
communityRating: data.get(#communityRating, or: $value.communityRating),
|
||||
trickPlayInfo: data.get(#trickPlayInfo, or: $value.trickPlayInfo),
|
||||
chapters: data.get(#chapters, or: $value.chapters),
|
||||
externalUrls: data.get(#externalUrls, or: $value.externalUrls),
|
||||
studios: data.get(#studios, or: $value.studios),
|
||||
genres: data.get(#genres, or: $value.genres),
|
||||
genreItems: data.get(#genreItems, or: $value.genreItems),
|
||||
tags: data.get(#tags, or: $value.tags),
|
||||
people: data.get(#people, or: $value.people));
|
||||
|
||||
@override
|
||||
OverviewModelCopyWith<$R2, OverviewModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_OverviewModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
68
lib/models/items/person_model.dart
Normal file
68
lib/models/items/person_model.dart
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/movie_model.dart';
|
||||
import 'package:fladder/models/items/series_model.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
part 'person_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class PersonModel extends ItemBaseModel with PersonModelMappable {
|
||||
final DateTime? dateOfBirth;
|
||||
final List<String> birthPlace;
|
||||
final List<MovieModel> movies;
|
||||
final List<SeriesModel> series;
|
||||
const PersonModel({
|
||||
this.dateOfBirth,
|
||||
required this.birthPlace,
|
||||
required this.movies,
|
||||
required this.series,
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
super.canDownload,
|
||||
super.canDelete,
|
||||
super.jellyType,
|
||||
});
|
||||
|
||||
static PersonModel fromBaseDto(BaseItemDto item, Ref ref) {
|
||||
return PersonModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
images: ImagesData.fromBaseItem(item, ref, getOriginalSize: true),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
dateOfBirth: item.premiereDate,
|
||||
birthPlace: item.productionLocations ?? [],
|
||||
movies: [],
|
||||
series: [],
|
||||
);
|
||||
}
|
||||
|
||||
int? get age {
|
||||
if (dateOfBirth == null) return null;
|
||||
final today = DateTime.now();
|
||||
final months = today.month - dateOfBirth!.month;
|
||||
if (months < 0) {
|
||||
return (dateOfBirth!.year - (DateTime.now().year - 1)).abs();
|
||||
} else {
|
||||
return (dateOfBirth!.year - DateTime.now().year).abs();
|
||||
}
|
||||
}
|
||||
}
|
||||
281
lib/models/items/person_model.mapper.dart
Normal file
281
lib/models/items/person_model.mapper.dart
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'person_model.dart';
|
||||
|
||||
class PersonModelMapper extends SubClassMapperBase<PersonModel> {
|
||||
PersonModelMapper._();
|
||||
|
||||
static PersonModelMapper? _instance;
|
||||
static PersonModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = PersonModelMapper._());
|
||||
ItemBaseModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
MovieModelMapper.ensureInitialized();
|
||||
SeriesModelMapper.ensureInitialized();
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'PersonModel';
|
||||
|
||||
static DateTime? _$dateOfBirth(PersonModel v) => v.dateOfBirth;
|
||||
static const Field<PersonModel, DateTime> _f$dateOfBirth =
|
||||
Field('dateOfBirth', _$dateOfBirth, opt: true);
|
||||
static List<String> _$birthPlace(PersonModel v) => v.birthPlace;
|
||||
static const Field<PersonModel, List<String>> _f$birthPlace =
|
||||
Field('birthPlace', _$birthPlace);
|
||||
static List<MovieModel> _$movies(PersonModel v) => v.movies;
|
||||
static const Field<PersonModel, List<MovieModel>> _f$movies =
|
||||
Field('movies', _$movies);
|
||||
static List<SeriesModel> _$series(PersonModel v) => v.series;
|
||||
static const Field<PersonModel, List<SeriesModel>> _f$series =
|
||||
Field('series', _$series);
|
||||
static String _$name(PersonModel v) => v.name;
|
||||
static const Field<PersonModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(PersonModel v) => v.id;
|
||||
static const Field<PersonModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(PersonModel v) => v.overview;
|
||||
static const Field<PersonModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(PersonModel v) => v.parentId;
|
||||
static const Field<PersonModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(PersonModel v) => v.playlistId;
|
||||
static const Field<PersonModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(PersonModel v) => v.images;
|
||||
static const Field<PersonModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(PersonModel v) => v.childCount;
|
||||
static const Field<PersonModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(PersonModel v) => v.primaryRatio;
|
||||
static const Field<PersonModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(PersonModel v) => v.userData;
|
||||
static const Field<PersonModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static bool? _$canDownload(PersonModel v) => v.canDownload;
|
||||
static const Field<PersonModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload, opt: true);
|
||||
static bool? _$canDelete(PersonModel v) => v.canDelete;
|
||||
static const Field<PersonModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete, opt: true);
|
||||
static BaseItemKind? _$jellyType(PersonModel v) => v.jellyType;
|
||||
static const Field<PersonModel, BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<PersonModel> fields = const {
|
||||
#dateOfBirth: _f$dateOfBirth,
|
||||
#birthPlace: _f$birthPlace,
|
||||
#movies: _f$movies,
|
||||
#series: _f$series,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#canDownload: _f$canDownload,
|
||||
#canDelete: _f$canDelete,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'PersonModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
|
||||
static PersonModel _instantiate(DecodingData data) {
|
||||
return PersonModel(
|
||||
dateOfBirth: data.dec(_f$dateOfBirth),
|
||||
birthPlace: data.dec(_f$birthPlace),
|
||||
movies: data.dec(_f$movies),
|
||||
series: data.dec(_f$series),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static PersonModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<PersonModel>(map);
|
||||
}
|
||||
|
||||
static PersonModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<PersonModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin PersonModelMappable {
|
||||
String toJson() {
|
||||
return PersonModelMapper.ensureInitialized()
|
||||
.encodeJson<PersonModel>(this as PersonModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return PersonModelMapper.ensureInitialized()
|
||||
.encodeMap<PersonModel>(this as PersonModel);
|
||||
}
|
||||
|
||||
PersonModelCopyWith<PersonModel, PersonModel, PersonModel> get copyWith =>
|
||||
_PersonModelCopyWithImpl(this as PersonModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return PersonModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as PersonModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension PersonModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, PersonModel, $Out> {
|
||||
PersonModelCopyWith<$R, PersonModel, $Out> get $asPersonModel =>
|
||||
$base.as((v, t, t2) => _PersonModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class PersonModelCopyWith<$R, $In extends PersonModel, $Out>
|
||||
implements ItemBaseModelCopyWith<$R, $In, $Out> {
|
||||
ListCopyWith<$R, String, ObjectCopyWith<$R, String, String>> get birthPlace;
|
||||
ListCopyWith<$R, MovieModel, MovieModelCopyWith<$R, MovieModel, MovieModel>>
|
||||
get movies;
|
||||
ListCopyWith<$R, SeriesModel,
|
||||
SeriesModelCopyWith<$R, SeriesModel, SeriesModel>> get series;
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{DateTime? dateOfBirth,
|
||||
List<String>? birthPlace,
|
||||
List<MovieModel>? movies,
|
||||
List<SeriesModel>? series,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
bool? canDownload,
|
||||
bool? canDelete,
|
||||
BaseItemKind? jellyType});
|
||||
PersonModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _PersonModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, PersonModel, $Out>
|
||||
implements PersonModelCopyWith<$R, PersonModel, $Out> {
|
||||
_PersonModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<PersonModel> $mapper =
|
||||
PersonModelMapper.ensureInitialized();
|
||||
@override
|
||||
ListCopyWith<$R, String, ObjectCopyWith<$R, String, String>> get birthPlace =>
|
||||
ListCopyWith($value.birthPlace, (v, t) => ObjectCopyWith(v, $identity, t),
|
||||
(v) => call(birthPlace: v));
|
||||
@override
|
||||
ListCopyWith<$R, MovieModel, MovieModelCopyWith<$R, MovieModel, MovieModel>>
|
||||
get movies => ListCopyWith($value.movies, (v, t) => v.copyWith.$chain(t),
|
||||
(v) => call(movies: v));
|
||||
@override
|
||||
ListCopyWith<$R, SeriesModel,
|
||||
SeriesModelCopyWith<$R, SeriesModel, SeriesModel>>
|
||||
get series => ListCopyWith($value.series, (v, t) => v.copyWith.$chain(t),
|
||||
(v) => call(series: v));
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{Object? dateOfBirth = $none,
|
||||
List<String>? birthPlace,
|
||||
List<MovieModel>? movies,
|
||||
List<SeriesModel>? series,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? canDownload = $none,
|
||||
Object? canDelete = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (dateOfBirth != $none) #dateOfBirth: dateOfBirth,
|
||||
if (birthPlace != null) #birthPlace: birthPlace,
|
||||
if (movies != null) #movies: movies,
|
||||
if (series != null) #series: series,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
PersonModel $make(CopyWithData data) => PersonModel(
|
||||
dateOfBirth: data.get(#dateOfBirth, or: $value.dateOfBirth),
|
||||
birthPlace: data.get(#birthPlace, or: $value.birthPlace),
|
||||
movies: data.get(#movies, or: $value.movies),
|
||||
series: data.get(#series, or: $value.series),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
PersonModelCopyWith<$R2, PersonModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_PersonModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
154
lib/models/items/photos_model.dart
Normal file
154
lib/models/items/photos_model.dart
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart';
|
||||
import 'package:fladder/util/localization_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
import 'package:fladder/providers/user_provider.dart';
|
||||
import 'package:fladder/screens/shared/fladder_snackbar.dart';
|
||||
import 'package:fladder/util/refresh_state.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'photos_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class PhotoAlbumModel extends ItemBaseModel with PhotoAlbumModelMappable {
|
||||
final List<ItemBaseModel> photos;
|
||||
|
||||
const PhotoAlbumModel({
|
||||
required this.photos,
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
super.canDelete,
|
||||
super.canDownload,
|
||||
super.jellyType,
|
||||
});
|
||||
@override
|
||||
bool get unWatched => userData.unPlayedItemCount != 0;
|
||||
|
||||
@override
|
||||
bool get playAble => true;
|
||||
|
||||
@override
|
||||
ItemBaseModel get parentBaseModel => copyWith(id: parentId);
|
||||
|
||||
factory PhotoAlbumModel.fromBaseDto(dto.BaseItemDto item, Ref ref) {
|
||||
return PhotoAlbumModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
images: ImagesData.fromBaseItem(item, ref),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
photos: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@MappableClass()
|
||||
class PhotoModel extends ItemBaseModel with PhotoModelMappable {
|
||||
final String? albumId;
|
||||
final DateTime? dateTaken;
|
||||
final ImagesData? thumbnail;
|
||||
final FladderItemType internalType;
|
||||
|
||||
const PhotoModel({
|
||||
required this.albumId,
|
||||
required this.dateTaken,
|
||||
required this.thumbnail,
|
||||
required this.internalType,
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
required super.canDownload,
|
||||
required super.canDelete,
|
||||
super.jellyType,
|
||||
});
|
||||
|
||||
@override
|
||||
PhotoAlbumModel get parentBaseModel => PhotoAlbumModel(
|
||||
photos: [],
|
||||
name: "",
|
||||
id: parentId ?? "",
|
||||
overview: overview,
|
||||
parentId: parentId,
|
||||
playlistId: playlistId,
|
||||
images: images,
|
||||
childCount: childCount,
|
||||
primaryRatio: primaryRatio,
|
||||
userData: userData,
|
||||
);
|
||||
|
||||
@override
|
||||
ImagesData? get getPosters => thumbnail;
|
||||
|
||||
@override
|
||||
bool get galleryItem => switch (internalType) {
|
||||
FladderItemType.photo => albumId?.isNotEmpty == true,
|
||||
FladderItemType.video => parentId?.isNotEmpty == true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
@override
|
||||
bool get unWatched => false;
|
||||
|
||||
factory PhotoModel.fromBaseDto(dto.BaseItemDto item, Ref ref) {
|
||||
return PhotoModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
primaryRatio: double.tryParse(item.aspectRatio ?? "") ?? item.primaryImageAspectRatio ?? 1.0,
|
||||
dateTaken: item.dateCreated,
|
||||
albumId: item.albumId,
|
||||
thumbnail: ImagesData.fromBaseItem(item, ref),
|
||||
images: ImagesData.fromBaseItem(item, ref, getOriginalSize: true),
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
internalType: switch (item.type) {
|
||||
BaseItemKind.video => FladderItemType.video,
|
||||
_ => FladderItemType.photo,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
String downloadPath(WidgetRef ref) {
|
||||
return "${ref.read(userProvider)?.server}/Items/$id/Download?api_key=${ref.read(userProvider)?.credentials.token}";
|
||||
}
|
||||
|
||||
Future<void> navigateToAlbum(BuildContext context) async {
|
||||
if ((albumId ?? parentId) == null) {
|
||||
fladderSnackbar(context, title: context.localized.notPartOfAlbum);
|
||||
return;
|
||||
}
|
||||
await parentBaseModel.navigateTo(context);
|
||||
if (context.mounted) context.refreshData();
|
||||
}
|
||||
}
|
||||
498
lib/models/items/photos_model.mapper.dart
Normal file
498
lib/models/items/photos_model.mapper.dart
Normal file
|
|
@ -0,0 +1,498 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'photos_model.dart';
|
||||
|
||||
class PhotoAlbumModelMapper extends SubClassMapperBase<PhotoAlbumModel> {
|
||||
PhotoAlbumModelMapper._();
|
||||
|
||||
static PhotoAlbumModelMapper? _instance;
|
||||
static PhotoAlbumModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = PhotoAlbumModelMapper._());
|
||||
ItemBaseModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'PhotoAlbumModel';
|
||||
|
||||
static List<ItemBaseModel> _$photos(PhotoAlbumModel v) => v.photos;
|
||||
static const Field<PhotoAlbumModel, List<ItemBaseModel>> _f$photos =
|
||||
Field('photos', _$photos);
|
||||
static String _$name(PhotoAlbumModel v) => v.name;
|
||||
static const Field<PhotoAlbumModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(PhotoAlbumModel v) => v.id;
|
||||
static const Field<PhotoAlbumModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(PhotoAlbumModel v) => v.overview;
|
||||
static const Field<PhotoAlbumModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(PhotoAlbumModel v) => v.parentId;
|
||||
static const Field<PhotoAlbumModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(PhotoAlbumModel v) => v.playlistId;
|
||||
static const Field<PhotoAlbumModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(PhotoAlbumModel v) => v.images;
|
||||
static const Field<PhotoAlbumModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(PhotoAlbumModel v) => v.childCount;
|
||||
static const Field<PhotoAlbumModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(PhotoAlbumModel v) => v.primaryRatio;
|
||||
static const Field<PhotoAlbumModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(PhotoAlbumModel v) => v.userData;
|
||||
static const Field<PhotoAlbumModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static bool? _$canDelete(PhotoAlbumModel v) => v.canDelete;
|
||||
static const Field<PhotoAlbumModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete, opt: true);
|
||||
static bool? _$canDownload(PhotoAlbumModel v) => v.canDownload;
|
||||
static const Field<PhotoAlbumModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload, opt: true);
|
||||
static dto.BaseItemKind? _$jellyType(PhotoAlbumModel v) => v.jellyType;
|
||||
static const Field<PhotoAlbumModel, dto.BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<PhotoAlbumModel> fields = const {
|
||||
#photos: _f$photos,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#canDelete: _f$canDelete,
|
||||
#canDownload: _f$canDownload,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'PhotoAlbumModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
|
||||
static PhotoAlbumModel _instantiate(DecodingData data) {
|
||||
return PhotoAlbumModel(
|
||||
photos: data.dec(_f$photos),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static PhotoAlbumModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<PhotoAlbumModel>(map);
|
||||
}
|
||||
|
||||
static PhotoAlbumModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<PhotoAlbumModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin PhotoAlbumModelMappable {
|
||||
String toJson() {
|
||||
return PhotoAlbumModelMapper.ensureInitialized()
|
||||
.encodeJson<PhotoAlbumModel>(this as PhotoAlbumModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return PhotoAlbumModelMapper.ensureInitialized()
|
||||
.encodeMap<PhotoAlbumModel>(this as PhotoAlbumModel);
|
||||
}
|
||||
|
||||
PhotoAlbumModelCopyWith<PhotoAlbumModel, PhotoAlbumModel, PhotoAlbumModel>
|
||||
get copyWith => _PhotoAlbumModelCopyWithImpl(
|
||||
this as PhotoAlbumModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return PhotoAlbumModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as PhotoAlbumModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension PhotoAlbumModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, PhotoAlbumModel, $Out> {
|
||||
PhotoAlbumModelCopyWith<$R, PhotoAlbumModel, $Out> get $asPhotoAlbumModel =>
|
||||
$base.as((v, t, t2) => _PhotoAlbumModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class PhotoAlbumModelCopyWith<$R, $In extends PhotoAlbumModel, $Out>
|
||||
implements ItemBaseModelCopyWith<$R, $In, $Out> {
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>> get photos;
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{List<ItemBaseModel>? photos,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
bool? canDelete,
|
||||
bool? canDownload,
|
||||
dto.BaseItemKind? jellyType});
|
||||
PhotoAlbumModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _PhotoAlbumModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, PhotoAlbumModel, $Out>
|
||||
implements PhotoAlbumModelCopyWith<$R, PhotoAlbumModel, $Out> {
|
||||
_PhotoAlbumModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<PhotoAlbumModel> $mapper =
|
||||
PhotoAlbumModelMapper.ensureInitialized();
|
||||
@override
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>>
|
||||
get photos => ListCopyWith($value.photos, (v, t) => v.copyWith.$chain(t),
|
||||
(v) => call(photos: v));
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{List<ItemBaseModel>? photos,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? canDelete = $none,
|
||||
Object? canDownload = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (photos != null) #photos: photos,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
PhotoAlbumModel $make(CopyWithData data) => PhotoAlbumModel(
|
||||
photos: data.get(#photos, or: $value.photos),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
PhotoAlbumModelCopyWith<$R2, PhotoAlbumModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_PhotoAlbumModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
|
||||
class PhotoModelMapper extends SubClassMapperBase<PhotoModel> {
|
||||
PhotoModelMapper._();
|
||||
|
||||
static PhotoModelMapper? _instance;
|
||||
static PhotoModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = PhotoModelMapper._());
|
||||
ItemBaseModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'PhotoModel';
|
||||
|
||||
static String? _$albumId(PhotoModel v) => v.albumId;
|
||||
static const Field<PhotoModel, String> _f$albumId =
|
||||
Field('albumId', _$albumId);
|
||||
static DateTime? _$dateTaken(PhotoModel v) => v.dateTaken;
|
||||
static const Field<PhotoModel, DateTime> _f$dateTaken =
|
||||
Field('dateTaken', _$dateTaken);
|
||||
static ImagesData? _$thumbnail(PhotoModel v) => v.thumbnail;
|
||||
static const Field<PhotoModel, ImagesData> _f$thumbnail =
|
||||
Field('thumbnail', _$thumbnail);
|
||||
static FladderItemType _$internalType(PhotoModel v) => v.internalType;
|
||||
static const Field<PhotoModel, FladderItemType> _f$internalType =
|
||||
Field('internalType', _$internalType);
|
||||
static String _$name(PhotoModel v) => v.name;
|
||||
static const Field<PhotoModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(PhotoModel v) => v.id;
|
||||
static const Field<PhotoModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(PhotoModel v) => v.overview;
|
||||
static const Field<PhotoModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(PhotoModel v) => v.parentId;
|
||||
static const Field<PhotoModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(PhotoModel v) => v.playlistId;
|
||||
static const Field<PhotoModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(PhotoModel v) => v.images;
|
||||
static const Field<PhotoModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(PhotoModel v) => v.childCount;
|
||||
static const Field<PhotoModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(PhotoModel v) => v.primaryRatio;
|
||||
static const Field<PhotoModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(PhotoModel v) => v.userData;
|
||||
static const Field<PhotoModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static bool? _$canDownload(PhotoModel v) => v.canDownload;
|
||||
static const Field<PhotoModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload);
|
||||
static bool? _$canDelete(PhotoModel v) => v.canDelete;
|
||||
static const Field<PhotoModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete);
|
||||
static dto.BaseItemKind? _$jellyType(PhotoModel v) => v.jellyType;
|
||||
static const Field<PhotoModel, dto.BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<PhotoModel> fields = const {
|
||||
#albumId: _f$albumId,
|
||||
#dateTaken: _f$dateTaken,
|
||||
#thumbnail: _f$thumbnail,
|
||||
#internalType: _f$internalType,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#canDownload: _f$canDownload,
|
||||
#canDelete: _f$canDelete,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'PhotoModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
|
||||
static PhotoModel _instantiate(DecodingData data) {
|
||||
return PhotoModel(
|
||||
albumId: data.dec(_f$albumId),
|
||||
dateTaken: data.dec(_f$dateTaken),
|
||||
thumbnail: data.dec(_f$thumbnail),
|
||||
internalType: data.dec(_f$internalType),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static PhotoModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<PhotoModel>(map);
|
||||
}
|
||||
|
||||
static PhotoModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<PhotoModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin PhotoModelMappable {
|
||||
String toJson() {
|
||||
return PhotoModelMapper.ensureInitialized()
|
||||
.encodeJson<PhotoModel>(this as PhotoModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return PhotoModelMapper.ensureInitialized()
|
||||
.encodeMap<PhotoModel>(this as PhotoModel);
|
||||
}
|
||||
|
||||
PhotoModelCopyWith<PhotoModel, PhotoModel, PhotoModel> get copyWith =>
|
||||
_PhotoModelCopyWithImpl(this as PhotoModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return PhotoModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as PhotoModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension PhotoModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, PhotoModel, $Out> {
|
||||
PhotoModelCopyWith<$R, PhotoModel, $Out> get $asPhotoModel =>
|
||||
$base.as((v, t, t2) => _PhotoModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class PhotoModelCopyWith<$R, $In extends PhotoModel, $Out>
|
||||
implements ItemBaseModelCopyWith<$R, $In, $Out> {
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{String? albumId,
|
||||
DateTime? dateTaken,
|
||||
ImagesData? thumbnail,
|
||||
FladderItemType? internalType,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
bool? canDownload,
|
||||
bool? canDelete,
|
||||
dto.BaseItemKind? jellyType});
|
||||
PhotoModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _PhotoModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, PhotoModel, $Out>
|
||||
implements PhotoModelCopyWith<$R, PhotoModel, $Out> {
|
||||
_PhotoModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<PhotoModel> $mapper =
|
||||
PhotoModelMapper.ensureInitialized();
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{Object? albumId = $none,
|
||||
Object? dateTaken = $none,
|
||||
Object? thumbnail = $none,
|
||||
FladderItemType? internalType,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? canDownload = $none,
|
||||
Object? canDelete = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (albumId != $none) #albumId: albumId,
|
||||
if (dateTaken != $none) #dateTaken: dateTaken,
|
||||
if (thumbnail != $none) #thumbnail: thumbnail,
|
||||
if (internalType != null) #internalType: internalType,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
PhotoModel $make(CopyWithData data) => PhotoModel(
|
||||
albumId: data.get(#albumId, or: $value.albumId),
|
||||
dateTaken: data.get(#dateTaken, or: $value.dateTaken),
|
||||
thumbnail: data.get(#thumbnail, or: $value.thumbnail),
|
||||
internalType: data.get(#internalType, or: $value.internalType),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
PhotoModelCopyWith<$R2, PhotoModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_PhotoModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
98
lib/models/items/season_model.dart
Normal file
98
lib/models/items/season_model.dart
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
import 'package:fladder/models/items/series_model.dart';
|
||||
import 'package:fladder/util/localization_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/episode_model.dart';
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'season_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class SeasonModel extends ItemBaseModel with SeasonModelMappable {
|
||||
final ImagesData? parentImages;
|
||||
final String seasonName;
|
||||
final List<EpisodeModel> episodes;
|
||||
final int episodeCount;
|
||||
final String seriesId;
|
||||
final String seriesName;
|
||||
const SeasonModel({
|
||||
required this.parentImages,
|
||||
required this.seasonName,
|
||||
this.episodes = const [],
|
||||
required this.episodeCount,
|
||||
required this.seriesId,
|
||||
required this.seriesName,
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
required super.canDelete,
|
||||
required super.canDownload,
|
||||
super.jellyType,
|
||||
});
|
||||
factory SeasonModel.fromBaseDto(dto.BaseItemDto item, Ref ref) {
|
||||
return SeasonModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.seasonId ?? item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
images: ImagesData.fromBaseItem(item, ref),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
seasonName: item.seasonName ?? "",
|
||||
episodeCount: item.episodeCount ?? 0,
|
||||
parentImages: ImagesData.fromBaseItemParent(item, ref, primary: const Size(2000, 2000)),
|
||||
seriesId: item.seriesId ?? item.parentId ?? item.id ?? "",
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
seriesName: item.seriesName ?? "",
|
||||
);
|
||||
}
|
||||
|
||||
EpisodeModel? get nextUp {
|
||||
return episodes.lastWhereOrNull((element) => element.userData.progress > 0) ??
|
||||
episodes.firstWhereOrNull((element) => element.userData.played == false);
|
||||
}
|
||||
|
||||
@override
|
||||
ImagesData? get getPosters => images ?? parentImages;
|
||||
|
||||
String localizedName(BuildContext context) => name.replaceFirst("Season", context.localized.season(1));
|
||||
|
||||
@override
|
||||
SeriesModel get parentBaseModel => SeriesModel(
|
||||
originalTitle: '',
|
||||
sortName: '',
|
||||
status: "",
|
||||
name: seriesName,
|
||||
id: parentId ?? "",
|
||||
playlistId: playlistId,
|
||||
overview: overview,
|
||||
parentId: parentId,
|
||||
images: images,
|
||||
childCount: childCount,
|
||||
primaryRatio: primaryRatio,
|
||||
userData: UserData(),
|
||||
);
|
||||
|
||||
static List<SeasonModel> seasonsFromDto(List<dto.BaseItemDto>? dto, Ref ref) {
|
||||
return dto?.map((e) => SeasonModel.fromBaseDto(e, ref)).toList() ?? [];
|
||||
}
|
||||
}
|
||||
287
lib/models/items/season_model.mapper.dart
Normal file
287
lib/models/items/season_model.mapper.dart
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'season_model.dart';
|
||||
|
||||
class SeasonModelMapper extends SubClassMapperBase<SeasonModel> {
|
||||
SeasonModelMapper._();
|
||||
|
||||
static SeasonModelMapper? _instance;
|
||||
static SeasonModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = SeasonModelMapper._());
|
||||
ItemBaseModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
EpisodeModelMapper.ensureInitialized();
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'SeasonModel';
|
||||
|
||||
static ImagesData? _$parentImages(SeasonModel v) => v.parentImages;
|
||||
static const Field<SeasonModel, ImagesData> _f$parentImages =
|
||||
Field('parentImages', _$parentImages);
|
||||
static String _$seasonName(SeasonModel v) => v.seasonName;
|
||||
static const Field<SeasonModel, String> _f$seasonName =
|
||||
Field('seasonName', _$seasonName);
|
||||
static List<EpisodeModel> _$episodes(SeasonModel v) => v.episodes;
|
||||
static const Field<SeasonModel, List<EpisodeModel>> _f$episodes =
|
||||
Field('episodes', _$episodes, opt: true, def: const []);
|
||||
static int _$episodeCount(SeasonModel v) => v.episodeCount;
|
||||
static const Field<SeasonModel, int> _f$episodeCount =
|
||||
Field('episodeCount', _$episodeCount);
|
||||
static String _$seriesId(SeasonModel v) => v.seriesId;
|
||||
static const Field<SeasonModel, String> _f$seriesId =
|
||||
Field('seriesId', _$seriesId);
|
||||
static String _$seriesName(SeasonModel v) => v.seriesName;
|
||||
static const Field<SeasonModel, String> _f$seriesName =
|
||||
Field('seriesName', _$seriesName);
|
||||
static String _$name(SeasonModel v) => v.name;
|
||||
static const Field<SeasonModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(SeasonModel v) => v.id;
|
||||
static const Field<SeasonModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(SeasonModel v) => v.overview;
|
||||
static const Field<SeasonModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(SeasonModel v) => v.parentId;
|
||||
static const Field<SeasonModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(SeasonModel v) => v.playlistId;
|
||||
static const Field<SeasonModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(SeasonModel v) => v.images;
|
||||
static const Field<SeasonModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(SeasonModel v) => v.childCount;
|
||||
static const Field<SeasonModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(SeasonModel v) => v.primaryRatio;
|
||||
static const Field<SeasonModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(SeasonModel v) => v.userData;
|
||||
static const Field<SeasonModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static bool? _$canDelete(SeasonModel v) => v.canDelete;
|
||||
static const Field<SeasonModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete);
|
||||
static bool? _$canDownload(SeasonModel v) => v.canDownload;
|
||||
static const Field<SeasonModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload);
|
||||
static dto.BaseItemKind? _$jellyType(SeasonModel v) => v.jellyType;
|
||||
static const Field<SeasonModel, dto.BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<SeasonModel> fields = const {
|
||||
#parentImages: _f$parentImages,
|
||||
#seasonName: _f$seasonName,
|
||||
#episodes: _f$episodes,
|
||||
#episodeCount: _f$episodeCount,
|
||||
#seriesId: _f$seriesId,
|
||||
#seriesName: _f$seriesName,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#canDelete: _f$canDelete,
|
||||
#canDownload: _f$canDownload,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'SeasonModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
|
||||
static SeasonModel _instantiate(DecodingData data) {
|
||||
return SeasonModel(
|
||||
parentImages: data.dec(_f$parentImages),
|
||||
seasonName: data.dec(_f$seasonName),
|
||||
episodes: data.dec(_f$episodes),
|
||||
episodeCount: data.dec(_f$episodeCount),
|
||||
seriesId: data.dec(_f$seriesId),
|
||||
seriesName: data.dec(_f$seriesName),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static SeasonModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<SeasonModel>(map);
|
||||
}
|
||||
|
||||
static SeasonModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<SeasonModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin SeasonModelMappable {
|
||||
String toJson() {
|
||||
return SeasonModelMapper.ensureInitialized()
|
||||
.encodeJson<SeasonModel>(this as SeasonModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return SeasonModelMapper.ensureInitialized()
|
||||
.encodeMap<SeasonModel>(this as SeasonModel);
|
||||
}
|
||||
|
||||
SeasonModelCopyWith<SeasonModel, SeasonModel, SeasonModel> get copyWith =>
|
||||
_SeasonModelCopyWithImpl(this as SeasonModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return SeasonModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as SeasonModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension SeasonModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, SeasonModel, $Out> {
|
||||
SeasonModelCopyWith<$R, SeasonModel, $Out> get $asSeasonModel =>
|
||||
$base.as((v, t, t2) => _SeasonModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class SeasonModelCopyWith<$R, $In extends SeasonModel, $Out>
|
||||
implements ItemBaseModelCopyWith<$R, $In, $Out> {
|
||||
ListCopyWith<$R, EpisodeModel,
|
||||
EpisodeModelCopyWith<$R, EpisodeModel, EpisodeModel>> get episodes;
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{ImagesData? parentImages,
|
||||
String? seasonName,
|
||||
List<EpisodeModel>? episodes,
|
||||
int? episodeCount,
|
||||
String? seriesId,
|
||||
String? seriesName,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
bool? canDelete,
|
||||
bool? canDownload,
|
||||
dto.BaseItemKind? jellyType});
|
||||
SeasonModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _SeasonModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, SeasonModel, $Out>
|
||||
implements SeasonModelCopyWith<$R, SeasonModel, $Out> {
|
||||
_SeasonModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<SeasonModel> $mapper =
|
||||
SeasonModelMapper.ensureInitialized();
|
||||
@override
|
||||
ListCopyWith<$R, EpisodeModel,
|
||||
EpisodeModelCopyWith<$R, EpisodeModel, EpisodeModel>>
|
||||
get episodes => ListCopyWith($value.episodes,
|
||||
(v, t) => v.copyWith.$chain(t), (v) => call(episodes: v));
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{Object? parentImages = $none,
|
||||
String? seasonName,
|
||||
List<EpisodeModel>? episodes,
|
||||
int? episodeCount,
|
||||
String? seriesId,
|
||||
String? seriesName,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? canDelete = $none,
|
||||
Object? canDownload = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (parentImages != $none) #parentImages: parentImages,
|
||||
if (seasonName != null) #seasonName: seasonName,
|
||||
if (episodes != null) #episodes: episodes,
|
||||
if (episodeCount != null) #episodeCount: episodeCount,
|
||||
if (seriesId != null) #seriesId: seriesId,
|
||||
if (seriesName != null) #seriesName: seriesName,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
SeasonModel $make(CopyWithData data) => SeasonModel(
|
||||
parentImages: data.get(#parentImages, or: $value.parentImages),
|
||||
seasonName: data.get(#seasonName, or: $value.seasonName),
|
||||
episodes: data.get(#episodes, or: $value.episodes),
|
||||
episodeCount: data.get(#episodeCount, or: $value.episodeCount),
|
||||
seriesId: data.get(#seriesId, or: $value.seriesId),
|
||||
seriesName: data.get(#seriesName, or: $value.seriesName),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
SeasonModelCopyWith<$R2, SeasonModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_SeasonModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
96
lib/models/items/series_model.dart
Normal file
96
lib/models/items/series_model.dart
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import 'package:fladder/screens/details_screens/series_detail_screen.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/episode_model.dart';
|
||||
import 'package:fladder/models/items/images_models.dart';
|
||||
import 'package:fladder/models/items/item_shared_models.dart';
|
||||
import 'package:fladder/models/items/overview_model.dart';
|
||||
import 'package:fladder/models/items/season_model.dart';
|
||||
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
|
||||
part 'series_model.mapper.dart';
|
||||
|
||||
@MappableClass()
|
||||
class SeriesModel extends ItemBaseModel with SeriesModelMappable {
|
||||
final List<EpisodeModel>? availableEpisodes;
|
||||
final List<SeasonModel>? seasons;
|
||||
final String originalTitle;
|
||||
final String sortName;
|
||||
final String status;
|
||||
final List<ItemBaseModel> related;
|
||||
const SeriesModel({
|
||||
this.availableEpisodes,
|
||||
this.seasons,
|
||||
required this.originalTitle,
|
||||
required this.sortName,
|
||||
required this.status,
|
||||
this.related = const [],
|
||||
required super.name,
|
||||
required super.id,
|
||||
required super.overview,
|
||||
required super.parentId,
|
||||
required super.playlistId,
|
||||
required super.images,
|
||||
required super.childCount,
|
||||
required super.primaryRatio,
|
||||
required super.userData,
|
||||
super.canDownload,
|
||||
super.canDelete,
|
||||
super.jellyType,
|
||||
});
|
||||
|
||||
EpisodeModel? get nextUp => availableEpisodes?.nextUp ?? availableEpisodes?.firstOrNull;
|
||||
|
||||
@override
|
||||
String detailedName(BuildContext context) => name;
|
||||
|
||||
@override
|
||||
ItemBaseModel get parentBaseModel => this;
|
||||
|
||||
@override
|
||||
Widget get detailScreenWidget => SeriesDetailScreen(item: this);
|
||||
|
||||
@override
|
||||
bool get emptyShow => childCount == 0;
|
||||
|
||||
@override
|
||||
bool get playAble => userData.unPlayedItemCount != 0;
|
||||
|
||||
@override
|
||||
bool get identifiable => true;
|
||||
|
||||
@override
|
||||
bool get unWatched =>
|
||||
!userData.played && userData.progress <= 0 && userData.unPlayedItemCount == 0 && childCount != 0;
|
||||
|
||||
@override
|
||||
String get subText => overview.yearAired?.toString() ?? "";
|
||||
|
||||
List<ItemBaseModel> fetchAllShows() {
|
||||
return availableEpisodes?.map((e) => e).toList() ?? [];
|
||||
}
|
||||
|
||||
@override
|
||||
bool get syncAble => true;
|
||||
|
||||
factory SeriesModel.fromBaseDto(dto.BaseItemDto item, Ref ref) => SeriesModel(
|
||||
name: item.name ?? "",
|
||||
id: item.id ?? "",
|
||||
childCount: item.childCount,
|
||||
overview: OverviewModel.fromBaseItemDto(item, ref),
|
||||
userData: UserData.fromDto(item.userData),
|
||||
parentId: item.parentId,
|
||||
playlistId: item.playlistItemId,
|
||||
images: ImagesData.fromBaseItem(item, ref, getOriginalSize: true),
|
||||
primaryRatio: item.primaryImageAspectRatio,
|
||||
originalTitle: item.originalTitle ?? "",
|
||||
sortName: item.sortName ?? "",
|
||||
canDelete: item.canDelete,
|
||||
canDownload: item.canDownload,
|
||||
status: item.status ?? "Continuing",
|
||||
);
|
||||
}
|
||||
309
lib/models/items/series_model.mapper.dart
Normal file
309
lib/models/items/series_model.mapper.dart
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member
|
||||
// ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter
|
||||
|
||||
part of 'series_model.dart';
|
||||
|
||||
class SeriesModelMapper extends SubClassMapperBase<SeriesModel> {
|
||||
SeriesModelMapper._();
|
||||
|
||||
static SeriesModelMapper? _instance;
|
||||
static SeriesModelMapper ensureInitialized() {
|
||||
if (_instance == null) {
|
||||
MapperContainer.globals.use(_instance = SeriesModelMapper._());
|
||||
ItemBaseModelMapper.ensureInitialized().addSubMapper(_instance!);
|
||||
EpisodeModelMapper.ensureInitialized();
|
||||
SeasonModelMapper.ensureInitialized();
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
OverviewModelMapper.ensureInitialized();
|
||||
UserDataMapper.ensureInitialized();
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@override
|
||||
final String id = 'SeriesModel';
|
||||
|
||||
static List<EpisodeModel>? _$availableEpisodes(SeriesModel v) =>
|
||||
v.availableEpisodes;
|
||||
static const Field<SeriesModel, List<EpisodeModel>> _f$availableEpisodes =
|
||||
Field('availableEpisodes', _$availableEpisodes, opt: true);
|
||||
static List<SeasonModel>? _$seasons(SeriesModel v) => v.seasons;
|
||||
static const Field<SeriesModel, List<SeasonModel>> _f$seasons =
|
||||
Field('seasons', _$seasons, opt: true);
|
||||
static String _$originalTitle(SeriesModel v) => v.originalTitle;
|
||||
static const Field<SeriesModel, String> _f$originalTitle =
|
||||
Field('originalTitle', _$originalTitle);
|
||||
static String _$sortName(SeriesModel v) => v.sortName;
|
||||
static const Field<SeriesModel, String> _f$sortName =
|
||||
Field('sortName', _$sortName);
|
||||
static String _$status(SeriesModel v) => v.status;
|
||||
static const Field<SeriesModel, String> _f$status = Field('status', _$status);
|
||||
static List<ItemBaseModel> _$related(SeriesModel v) => v.related;
|
||||
static const Field<SeriesModel, List<ItemBaseModel>> _f$related =
|
||||
Field('related', _$related, opt: true, def: const []);
|
||||
static String _$name(SeriesModel v) => v.name;
|
||||
static const Field<SeriesModel, String> _f$name = Field('name', _$name);
|
||||
static String _$id(SeriesModel v) => v.id;
|
||||
static const Field<SeriesModel, String> _f$id = Field('id', _$id);
|
||||
static OverviewModel _$overview(SeriesModel v) => v.overview;
|
||||
static const Field<SeriesModel, OverviewModel> _f$overview =
|
||||
Field('overview', _$overview);
|
||||
static String? _$parentId(SeriesModel v) => v.parentId;
|
||||
static const Field<SeriesModel, String> _f$parentId =
|
||||
Field('parentId', _$parentId);
|
||||
static String? _$playlistId(SeriesModel v) => v.playlistId;
|
||||
static const Field<SeriesModel, String> _f$playlistId =
|
||||
Field('playlistId', _$playlistId);
|
||||
static ImagesData? _$images(SeriesModel v) => v.images;
|
||||
static const Field<SeriesModel, ImagesData> _f$images =
|
||||
Field('images', _$images);
|
||||
static int? _$childCount(SeriesModel v) => v.childCount;
|
||||
static const Field<SeriesModel, int> _f$childCount =
|
||||
Field('childCount', _$childCount);
|
||||
static double? _$primaryRatio(SeriesModel v) => v.primaryRatio;
|
||||
static const Field<SeriesModel, double> _f$primaryRatio =
|
||||
Field('primaryRatio', _$primaryRatio);
|
||||
static UserData _$userData(SeriesModel v) => v.userData;
|
||||
static const Field<SeriesModel, UserData> _f$userData =
|
||||
Field('userData', _$userData);
|
||||
static bool? _$canDownload(SeriesModel v) => v.canDownload;
|
||||
static const Field<SeriesModel, bool> _f$canDownload =
|
||||
Field('canDownload', _$canDownload, opt: true);
|
||||
static bool? _$canDelete(SeriesModel v) => v.canDelete;
|
||||
static const Field<SeriesModel, bool> _f$canDelete =
|
||||
Field('canDelete', _$canDelete, opt: true);
|
||||
static dto.BaseItemKind? _$jellyType(SeriesModel v) => v.jellyType;
|
||||
static const Field<SeriesModel, dto.BaseItemKind> _f$jellyType =
|
||||
Field('jellyType', _$jellyType, opt: true);
|
||||
|
||||
@override
|
||||
final MappableFields<SeriesModel> fields = const {
|
||||
#availableEpisodes: _f$availableEpisodes,
|
||||
#seasons: _f$seasons,
|
||||
#originalTitle: _f$originalTitle,
|
||||
#sortName: _f$sortName,
|
||||
#status: _f$status,
|
||||
#related: _f$related,
|
||||
#name: _f$name,
|
||||
#id: _f$id,
|
||||
#overview: _f$overview,
|
||||
#parentId: _f$parentId,
|
||||
#playlistId: _f$playlistId,
|
||||
#images: _f$images,
|
||||
#childCount: _f$childCount,
|
||||
#primaryRatio: _f$primaryRatio,
|
||||
#userData: _f$userData,
|
||||
#canDownload: _f$canDownload,
|
||||
#canDelete: _f$canDelete,
|
||||
#jellyType: _f$jellyType,
|
||||
};
|
||||
@override
|
||||
final bool ignoreNull = true;
|
||||
|
||||
@override
|
||||
final String discriminatorKey = 'type';
|
||||
@override
|
||||
final dynamic discriminatorValue = 'SeriesModel';
|
||||
@override
|
||||
late final ClassMapperBase superMapper =
|
||||
ItemBaseModelMapper.ensureInitialized();
|
||||
|
||||
static SeriesModel _instantiate(DecodingData data) {
|
||||
return SeriesModel(
|
||||
availableEpisodes: data.dec(_f$availableEpisodes),
|
||||
seasons: data.dec(_f$seasons),
|
||||
originalTitle: data.dec(_f$originalTitle),
|
||||
sortName: data.dec(_f$sortName),
|
||||
status: data.dec(_f$status),
|
||||
related: data.dec(_f$related),
|
||||
name: data.dec(_f$name),
|
||||
id: data.dec(_f$id),
|
||||
overview: data.dec(_f$overview),
|
||||
parentId: data.dec(_f$parentId),
|
||||
playlistId: data.dec(_f$playlistId),
|
||||
images: data.dec(_f$images),
|
||||
childCount: data.dec(_f$childCount),
|
||||
primaryRatio: data.dec(_f$primaryRatio),
|
||||
userData: data.dec(_f$userData),
|
||||
canDownload: data.dec(_f$canDownload),
|
||||
canDelete: data.dec(_f$canDelete),
|
||||
jellyType: data.dec(_f$jellyType));
|
||||
}
|
||||
|
||||
@override
|
||||
final Function instantiate = _instantiate;
|
||||
|
||||
static SeriesModel fromMap(Map<String, dynamic> map) {
|
||||
return ensureInitialized().decodeMap<SeriesModel>(map);
|
||||
}
|
||||
|
||||
static SeriesModel fromJson(String json) {
|
||||
return ensureInitialized().decodeJson<SeriesModel>(json);
|
||||
}
|
||||
}
|
||||
|
||||
mixin SeriesModelMappable {
|
||||
String toJson() {
|
||||
return SeriesModelMapper.ensureInitialized()
|
||||
.encodeJson<SeriesModel>(this as SeriesModel);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return SeriesModelMapper.ensureInitialized()
|
||||
.encodeMap<SeriesModel>(this as SeriesModel);
|
||||
}
|
||||
|
||||
SeriesModelCopyWith<SeriesModel, SeriesModel, SeriesModel> get copyWith =>
|
||||
_SeriesModelCopyWithImpl(this as SeriesModel, $identity, $identity);
|
||||
@override
|
||||
String toString() {
|
||||
return SeriesModelMapper.ensureInitialized()
|
||||
.stringifyValue(this as SeriesModel);
|
||||
}
|
||||
}
|
||||
|
||||
extension SeriesModelValueCopy<$R, $Out>
|
||||
on ObjectCopyWith<$R, SeriesModel, $Out> {
|
||||
SeriesModelCopyWith<$R, SeriesModel, $Out> get $asSeriesModel =>
|
||||
$base.as((v, t, t2) => _SeriesModelCopyWithImpl(v, t, t2));
|
||||
}
|
||||
|
||||
abstract class SeriesModelCopyWith<$R, $In extends SeriesModel, $Out>
|
||||
implements ItemBaseModelCopyWith<$R, $In, $Out> {
|
||||
ListCopyWith<$R, EpisodeModel,
|
||||
EpisodeModelCopyWith<$R, EpisodeModel, EpisodeModel>>?
|
||||
get availableEpisodes;
|
||||
ListCopyWith<$R, SeasonModel,
|
||||
SeasonModelCopyWith<$R, SeasonModel, SeasonModel>>? get seasons;
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>> get related;
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview;
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData;
|
||||
@override
|
||||
$R call(
|
||||
{List<EpisodeModel>? availableEpisodes,
|
||||
List<SeasonModel>? seasons,
|
||||
String? originalTitle,
|
||||
String? sortName,
|
||||
String? status,
|
||||
List<ItemBaseModel>? related,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
String? parentId,
|
||||
String? playlistId,
|
||||
ImagesData? images,
|
||||
int? childCount,
|
||||
double? primaryRatio,
|
||||
UserData? userData,
|
||||
bool? canDownload,
|
||||
bool? canDelete,
|
||||
dto.BaseItemKind? jellyType});
|
||||
SeriesModelCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
|
||||
class _SeriesModelCopyWithImpl<$R, $Out>
|
||||
extends ClassCopyWithBase<$R, SeriesModel, $Out>
|
||||
implements SeriesModelCopyWith<$R, SeriesModel, $Out> {
|
||||
_SeriesModelCopyWithImpl(super.value, super.then, super.then2);
|
||||
|
||||
@override
|
||||
late final ClassMapperBase<SeriesModel> $mapper =
|
||||
SeriesModelMapper.ensureInitialized();
|
||||
@override
|
||||
ListCopyWith<$R, EpisodeModel,
|
||||
EpisodeModelCopyWith<$R, EpisodeModel, EpisodeModel>>?
|
||||
get availableEpisodes => $value.availableEpisodes != null
|
||||
? ListCopyWith($value.availableEpisodes!,
|
||||
(v, t) => v.copyWith.$chain(t), (v) => call(availableEpisodes: v))
|
||||
: null;
|
||||
@override
|
||||
ListCopyWith<$R, SeasonModel,
|
||||
SeasonModelCopyWith<$R, SeasonModel, SeasonModel>>?
|
||||
get seasons => $value.seasons != null
|
||||
? ListCopyWith($value.seasons!, (v, t) => v.copyWith.$chain(t),
|
||||
(v) => call(seasons: v))
|
||||
: null;
|
||||
@override
|
||||
ListCopyWith<$R, ItemBaseModel,
|
||||
ItemBaseModelCopyWith<$R, ItemBaseModel, ItemBaseModel>>
|
||||
get related => ListCopyWith($value.related,
|
||||
(v, t) => v.copyWith.$chain(t), (v) => call(related: v));
|
||||
@override
|
||||
OverviewModelCopyWith<$R, OverviewModel, OverviewModel> get overview =>
|
||||
$value.overview.copyWith.$chain((v) => call(overview: v));
|
||||
@override
|
||||
UserDataCopyWith<$R, UserData, UserData> get userData =>
|
||||
$value.userData.copyWith.$chain((v) => call(userData: v));
|
||||
@override
|
||||
$R call(
|
||||
{Object? availableEpisodes = $none,
|
||||
Object? seasons = $none,
|
||||
String? originalTitle,
|
||||
String? sortName,
|
||||
String? status,
|
||||
List<ItemBaseModel>? related,
|
||||
String? name,
|
||||
String? id,
|
||||
OverviewModel? overview,
|
||||
Object? parentId = $none,
|
||||
Object? playlistId = $none,
|
||||
Object? images = $none,
|
||||
Object? childCount = $none,
|
||||
Object? primaryRatio = $none,
|
||||
UserData? userData,
|
||||
Object? canDownload = $none,
|
||||
Object? canDelete = $none,
|
||||
Object? jellyType = $none}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (availableEpisodes != $none) #availableEpisodes: availableEpisodes,
|
||||
if (seasons != $none) #seasons: seasons,
|
||||
if (originalTitle != null) #originalTitle: originalTitle,
|
||||
if (sortName != null) #sortName: sortName,
|
||||
if (status != null) #status: status,
|
||||
if (related != null) #related: related,
|
||||
if (name != null) #name: name,
|
||||
if (id != null) #id: id,
|
||||
if (overview != null) #overview: overview,
|
||||
if (parentId != $none) #parentId: parentId,
|
||||
if (playlistId != $none) #playlistId: playlistId,
|
||||
if (images != $none) #images: images,
|
||||
if (childCount != $none) #childCount: childCount,
|
||||
if (primaryRatio != $none) #primaryRatio: primaryRatio,
|
||||
if (userData != null) #userData: userData,
|
||||
if (canDownload != $none) #canDownload: canDownload,
|
||||
if (canDelete != $none) #canDelete: canDelete,
|
||||
if (jellyType != $none) #jellyType: jellyType
|
||||
}));
|
||||
@override
|
||||
SeriesModel $make(CopyWithData data) => SeriesModel(
|
||||
availableEpisodes:
|
||||
data.get(#availableEpisodes, or: $value.availableEpisodes),
|
||||
seasons: data.get(#seasons, or: $value.seasons),
|
||||
originalTitle: data.get(#originalTitle, or: $value.originalTitle),
|
||||
sortName: data.get(#sortName, or: $value.sortName),
|
||||
status: data.get(#status, or: $value.status),
|
||||
related: data.get(#related, or: $value.related),
|
||||
name: data.get(#name, or: $value.name),
|
||||
id: data.get(#id, or: $value.id),
|
||||
overview: data.get(#overview, or: $value.overview),
|
||||
parentId: data.get(#parentId, or: $value.parentId),
|
||||
playlistId: data.get(#playlistId, or: $value.playlistId),
|
||||
images: data.get(#images, or: $value.images),
|
||||
childCount: data.get(#childCount, or: $value.childCount),
|
||||
primaryRatio: data.get(#primaryRatio, or: $value.primaryRatio),
|
||||
userData: data.get(#userData, or: $value.userData),
|
||||
canDownload: data.get(#canDownload, or: $value.canDownload),
|
||||
canDelete: data.get(#canDelete, or: $value.canDelete),
|
||||
jellyType: data.get(#jellyType, or: $value.jellyType));
|
||||
|
||||
@override
|
||||
SeriesModelCopyWith<$R2, SeriesModel, $Out2> $chain<$R2, $Out2>(
|
||||
Then<$Out2, $R2> t) =>
|
||||
_SeriesModelCopyWithImpl($value, $cast, t);
|
||||
}
|
||||
61
lib/models/items/trick_play_model.dart
Normal file
61
lib/models/items/trick_play_model.dart
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'trick_play_model.freezed.dart';
|
||||
part 'trick_play_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class TrickPlayModel with _$TrickPlayModel {
|
||||
factory TrickPlayModel({
|
||||
required int width,
|
||||
required int height,
|
||||
required int tileWidth,
|
||||
required int tileHeight,
|
||||
required int thumbnailCount,
|
||||
required Duration interval,
|
||||
@Default([]) List<String> images,
|
||||
}) = _TrickPlayModel;
|
||||
|
||||
const TrickPlayModel._();
|
||||
|
||||
int get imagesPerTile => tileWidth * tileHeight;
|
||||
|
||||
String? getTile(Duration position) {
|
||||
final int currentIndex = (position.inMilliseconds ~/ interval.inMilliseconds).clamp(0, thumbnailCount);
|
||||
final int indexOfTile = (currentIndex ~/ imagesPerTile).clamp(0, images.length);
|
||||
return images.elementAtOrNull(indexOfTile);
|
||||
}
|
||||
|
||||
Offset offset(Duration position) {
|
||||
final int currentIndex = (position.inMilliseconds ~/ interval.inMilliseconds).clamp(0, thumbnailCount - 1);
|
||||
final int tileIndex = currentIndex % imagesPerTile;
|
||||
final int column = tileIndex % tileWidth;
|
||||
final int row = tileIndex ~/ tileWidth;
|
||||
return Offset((width * column).toDouble(), (height * row).toDouble());
|
||||
}
|
||||
|
||||
static Map<String, TrickPlayModel> toTrickPlayMap(Map<String, dynamic> map) {
|
||||
Map<String, TrickPlayModel> newMap = {};
|
||||
final firstMap = (((map.entries.first as MapEntry).value as Map<String, dynamic>));
|
||||
newMap.addEntries(firstMap.entries.map(
|
||||
(e) {
|
||||
final map = e.value as Map<String, dynamic>;
|
||||
return MapEntry(
|
||||
e.key,
|
||||
TrickPlayModel(
|
||||
width: map['Width'] as int? ?? 0,
|
||||
height: map['Height'] as int? ?? 0,
|
||||
tileWidth: map['TileWidth'] as int? ?? 0,
|
||||
tileHeight: map['TileHeight'] as int? ?? 0,
|
||||
thumbnailCount: map['ThumbnailCount'] as int? ?? 0,
|
||||
interval: Duration(milliseconds: map['Interval'] as int? ?? 0),
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
return newMap;
|
||||
}
|
||||
|
||||
factory TrickPlayModel.fromJson(Map<String, dynamic> json) => _$TrickPlayModelFromJson(json);
|
||||
}
|
||||
297
lib/models/items/trick_play_model.freezed.dart
Normal file
297
lib/models/items/trick_play_model.freezed.dart
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
// 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 'trick_play_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');
|
||||
|
||||
TrickPlayModel _$TrickPlayModelFromJson(Map<String, dynamic> json) {
|
||||
return _TrickPlayModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$TrickPlayModel {
|
||||
int get width => throw _privateConstructorUsedError;
|
||||
int get height => throw _privateConstructorUsedError;
|
||||
int get tileWidth => throw _privateConstructorUsedError;
|
||||
int get tileHeight => throw _privateConstructorUsedError;
|
||||
int get thumbnailCount => throw _privateConstructorUsedError;
|
||||
Duration get interval => throw _privateConstructorUsedError;
|
||||
List<String> get images => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$TrickPlayModelCopyWith<TrickPlayModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $TrickPlayModelCopyWith<$Res> {
|
||||
factory $TrickPlayModelCopyWith(
|
||||
TrickPlayModel value, $Res Function(TrickPlayModel) then) =
|
||||
_$TrickPlayModelCopyWithImpl<$Res, TrickPlayModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{int width,
|
||||
int height,
|
||||
int tileWidth,
|
||||
int tileHeight,
|
||||
int thumbnailCount,
|
||||
Duration interval,
|
||||
List<String> images});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$TrickPlayModelCopyWithImpl<$Res, $Val extends TrickPlayModel>
|
||||
implements $TrickPlayModelCopyWith<$Res> {
|
||||
_$TrickPlayModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? width = null,
|
||||
Object? height = null,
|
||||
Object? tileWidth = null,
|
||||
Object? tileHeight = null,
|
||||
Object? thumbnailCount = null,
|
||||
Object? interval = null,
|
||||
Object? images = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
width: null == width
|
||||
? _value.width
|
||||
: width // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
height: null == height
|
||||
? _value.height
|
||||
: height // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
tileWidth: null == tileWidth
|
||||
? _value.tileWidth
|
||||
: tileWidth // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
tileHeight: null == tileHeight
|
||||
? _value.tileHeight
|
||||
: tileHeight // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
thumbnailCount: null == thumbnailCount
|
||||
? _value.thumbnailCount
|
||||
: thumbnailCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
interval: null == interval
|
||||
? _value.interval
|
||||
: interval // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
images: null == images
|
||||
? _value.images
|
||||
: images // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$TrickPlayModelImplCopyWith<$Res>
|
||||
implements $TrickPlayModelCopyWith<$Res> {
|
||||
factory _$$TrickPlayModelImplCopyWith(_$TrickPlayModelImpl value,
|
||||
$Res Function(_$TrickPlayModelImpl) then) =
|
||||
__$$TrickPlayModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{int width,
|
||||
int height,
|
||||
int tileWidth,
|
||||
int tileHeight,
|
||||
int thumbnailCount,
|
||||
Duration interval,
|
||||
List<String> images});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$TrickPlayModelImplCopyWithImpl<$Res>
|
||||
extends _$TrickPlayModelCopyWithImpl<$Res, _$TrickPlayModelImpl>
|
||||
implements _$$TrickPlayModelImplCopyWith<$Res> {
|
||||
__$$TrickPlayModelImplCopyWithImpl(
|
||||
_$TrickPlayModelImpl _value, $Res Function(_$TrickPlayModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? width = null,
|
||||
Object? height = null,
|
||||
Object? tileWidth = null,
|
||||
Object? tileHeight = null,
|
||||
Object? thumbnailCount = null,
|
||||
Object? interval = null,
|
||||
Object? images = null,
|
||||
}) {
|
||||
return _then(_$TrickPlayModelImpl(
|
||||
width: null == width
|
||||
? _value.width
|
||||
: width // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
height: null == height
|
||||
? _value.height
|
||||
: height // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
tileWidth: null == tileWidth
|
||||
? _value.tileWidth
|
||||
: tileWidth // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
tileHeight: null == tileHeight
|
||||
? _value.tileHeight
|
||||
: tileHeight // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
thumbnailCount: null == thumbnailCount
|
||||
? _value.thumbnailCount
|
||||
: thumbnailCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
interval: null == interval
|
||||
? _value.interval
|
||||
: interval // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,
|
||||
images: null == images
|
||||
? _value._images
|
||||
: images // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$TrickPlayModelImpl extends _TrickPlayModel {
|
||||
_$TrickPlayModelImpl(
|
||||
{required this.width,
|
||||
required this.height,
|
||||
required this.tileWidth,
|
||||
required this.tileHeight,
|
||||
required this.thumbnailCount,
|
||||
required this.interval,
|
||||
final List<String> images = const []})
|
||||
: _images = images,
|
||||
super._();
|
||||
|
||||
factory _$TrickPlayModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$TrickPlayModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
final int width;
|
||||
@override
|
||||
final int height;
|
||||
@override
|
||||
final int tileWidth;
|
||||
@override
|
||||
final int tileHeight;
|
||||
@override
|
||||
final int thumbnailCount;
|
||||
@override
|
||||
final Duration interval;
|
||||
final List<String> _images;
|
||||
@override
|
||||
@JsonKey()
|
||||
List<String> get images {
|
||||
if (_images is EqualUnmodifiableListView) return _images;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_images);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TrickPlayModel(width: $width, height: $height, tileWidth: $tileWidth, tileHeight: $tileHeight, thumbnailCount: $thumbnailCount, interval: $interval, images: $images)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$TrickPlayModelImpl &&
|
||||
(identical(other.width, width) || other.width == width) &&
|
||||
(identical(other.height, height) || other.height == height) &&
|
||||
(identical(other.tileWidth, tileWidth) ||
|
||||
other.tileWidth == tileWidth) &&
|
||||
(identical(other.tileHeight, tileHeight) ||
|
||||
other.tileHeight == tileHeight) &&
|
||||
(identical(other.thumbnailCount, thumbnailCount) ||
|
||||
other.thumbnailCount == thumbnailCount) &&
|
||||
(identical(other.interval, interval) ||
|
||||
other.interval == interval) &&
|
||||
const DeepCollectionEquality().equals(other._images, _images));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
width,
|
||||
height,
|
||||
tileWidth,
|
||||
tileHeight,
|
||||
thumbnailCount,
|
||||
interval,
|
||||
const DeepCollectionEquality().hash(_images));
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$TrickPlayModelImplCopyWith<_$TrickPlayModelImpl> get copyWith =>
|
||||
__$$TrickPlayModelImplCopyWithImpl<_$TrickPlayModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$TrickPlayModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _TrickPlayModel extends TrickPlayModel {
|
||||
factory _TrickPlayModel(
|
||||
{required final int width,
|
||||
required final int height,
|
||||
required final int tileWidth,
|
||||
required final int tileHeight,
|
||||
required final int thumbnailCount,
|
||||
required final Duration interval,
|
||||
final List<String> images}) = _$TrickPlayModelImpl;
|
||||
_TrickPlayModel._() : super._();
|
||||
|
||||
factory _TrickPlayModel.fromJson(Map<String, dynamic> json) =
|
||||
_$TrickPlayModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
int get width;
|
||||
@override
|
||||
int get height;
|
||||
@override
|
||||
int get tileWidth;
|
||||
@override
|
||||
int get tileHeight;
|
||||
@override
|
||||
int get thumbnailCount;
|
||||
@override
|
||||
Duration get interval;
|
||||
@override
|
||||
List<String> get images;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$TrickPlayModelImplCopyWith<_$TrickPlayModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
33
lib/models/items/trick_play_model.g.dart
Normal file
33
lib/models/items/trick_play_model.g.dart
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'trick_play_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$TrickPlayModelImpl _$$TrickPlayModelImplFromJson(Map<String, dynamic> json) =>
|
||||
_$TrickPlayModelImpl(
|
||||
width: (json['width'] as num).toInt(),
|
||||
height: (json['height'] as num).toInt(),
|
||||
tileWidth: (json['tileWidth'] as num).toInt(),
|
||||
tileHeight: (json['tileHeight'] as num).toInt(),
|
||||
thumbnailCount: (json['thumbnailCount'] as num).toInt(),
|
||||
interval: Duration(microseconds: (json['interval'] as num).toInt()),
|
||||
images: (json['images'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList() ??
|
||||
const [],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$TrickPlayModelImplToJson(
|
||||
_$TrickPlayModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
'tileWidth': instance.tileWidth,
|
||||
'tileHeight': instance.tileHeight,
|
||||
'thumbnailCount': instance.thumbnailCount,
|
||||
'interval': instance.interval.inMicroseconds,
|
||||
'images': instance.images,
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue