// ignore_for_file: public_member_api_docs, sort_constructors_first import 'dart:convert'; import 'package:flutter/widgets.dart'; import 'package:collection/collection.dart'; import 'package:dart_mappable/dart_mappable.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart'; import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto; import 'package:fladder/models/items/images_models.dart'; part 'item_shared_models.mapper.dart'; @MappableClass(generateMethods: GenerateMethods.encode | GenerateMethods.decode | GenerateMethods.copy) 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 const 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 map) => UserDataMapper.fromMap(map); factory UserData.fromJson(String json) => UserDataMapper.fromJson(json); } class UserDataJsonSerializer extends JsonConverter { 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 enabled(List 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 fromDto(List dto) { return dto.map((e) => ExternalUrls(name: e.name ?? "", url: e.url ?? "")).toList(); } Map toMap() { return { 'Name': name, 'Url': url, }; } factory ExternalUrls.fromMap(Map 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 peopleFromDto(List? 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? image, }) { return Studio( id: id ?? this.id, name: name ?? this.name, ); } @override String toString() => 'Studio(name: $name, id: $id)'; Map toMap() { return { 'id': id, 'name': name, }; } factory Studio.fromMap(Map 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; }