feature: Added option to save and set default filters for libraries (#107)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2024-11-02 15:44:24 +01:00 committed by GitHub
parent d3e34d57e0
commit 691293648b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 1353 additions and 62 deletions

View file

@ -1,16 +1,17 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first, invalid_annotation_target
import 'package:ficonsax/ficonsax.dart';
import 'package:fladder/util/localization_helper.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:ficonsax/ficonsax.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
import 'package:fladder/models/credentials_model.dart';
import 'package:fladder/models/library_filters_model.dart';
import 'package:fladder/util/adaptive_layout.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:fladder/util/localization_helper.dart';
part 'account_model.freezed.dart';
part 'account_model.g.dart';
@ -30,6 +31,7 @@ class AccountModel with _$AccountModel {
@Default([]) List<String> latestItemsExcludes,
@Default([]) List<String> searchQueryHistory,
@Default(false) bool quickConnectState,
@Default([]) List<LibraryFiltersModel> savedFilters,
@JsonKey(includeFromJson: false, includeToJson: false) UserPolicy? policy,
@JsonKey(includeFromJson: false, includeToJson: false) ServerConfiguration? serverConfiguration,
}) = _AccountModel;

View file

@ -30,6 +30,8 @@ mixin _$AccountModel {
List<String> get latestItemsExcludes => throw _privateConstructorUsedError;
List<String> get searchQueryHistory => throw _privateConstructorUsedError;
bool get quickConnectState => throw _privateConstructorUsedError;
List<LibraryFiltersModel> get savedFilters =>
throw _privateConstructorUsedError;
@JsonKey(includeFromJson: false, includeToJson: false)
UserPolicy? get policy => throw _privateConstructorUsedError;
@JsonKey(includeFromJson: false, includeToJson: false)
@ -63,6 +65,7 @@ abstract class $AccountModelCopyWith<$Res> {
List<String> latestItemsExcludes,
List<String> searchQueryHistory,
bool quickConnectState,
List<LibraryFiltersModel> savedFilters,
@JsonKey(includeFromJson: false, includeToJson: false) UserPolicy? policy,
@JsonKey(includeFromJson: false, includeToJson: false)
ServerConfiguration? serverConfiguration});
@ -93,6 +96,7 @@ class _$AccountModelCopyWithImpl<$Res, $Val extends AccountModel>
Object? latestItemsExcludes = null,
Object? searchQueryHistory = null,
Object? quickConnectState = null,
Object? savedFilters = null,
Object? policy = freezed,
Object? serverConfiguration = freezed,
}) {
@ -137,6 +141,10 @@ class _$AccountModelCopyWithImpl<$Res, $Val extends AccountModel>
? _value.quickConnectState
: quickConnectState // ignore: cast_nullable_to_non_nullable
as bool,
savedFilters: null == savedFilters
? _value.savedFilters
: savedFilters // ignore: cast_nullable_to_non_nullable
as List<LibraryFiltersModel>,
policy: freezed == policy
? _value.policy
: policy // ignore: cast_nullable_to_non_nullable
@ -168,6 +176,7 @@ abstract class _$$AccountModelImplCopyWith<$Res>
List<String> latestItemsExcludes,
List<String> searchQueryHistory,
bool quickConnectState,
List<LibraryFiltersModel> savedFilters,
@JsonKey(includeFromJson: false, includeToJson: false) UserPolicy? policy,
@JsonKey(includeFromJson: false, includeToJson: false)
ServerConfiguration? serverConfiguration});
@ -196,6 +205,7 @@ class __$$AccountModelImplCopyWithImpl<$Res>
Object? latestItemsExcludes = null,
Object? searchQueryHistory = null,
Object? quickConnectState = null,
Object? savedFilters = null,
Object? policy = freezed,
Object? serverConfiguration = freezed,
}) {
@ -240,6 +250,10 @@ class __$$AccountModelImplCopyWithImpl<$Res>
? _value.quickConnectState
: quickConnectState // ignore: cast_nullable_to_non_nullable
as bool,
savedFilters: null == savedFilters
? _value._savedFilters
: savedFilters // ignore: cast_nullable_to_non_nullable
as List<LibraryFiltersModel>,
policy: freezed == policy
? _value.policy
: policy // ignore: cast_nullable_to_non_nullable
@ -266,11 +280,13 @@ class _$AccountModelImpl extends _AccountModel with DiagnosticableTreeMixin {
final List<String> latestItemsExcludes = const [],
final List<String> searchQueryHistory = const [],
this.quickConnectState = false,
final List<LibraryFiltersModel> savedFilters = const [],
@JsonKey(includeFromJson: false, includeToJson: false) this.policy,
@JsonKey(includeFromJson: false, includeToJson: false)
this.serverConfiguration})
: _latestItemsExcludes = latestItemsExcludes,
_searchQueryHistory = searchQueryHistory,
_savedFilters = savedFilters,
super._();
factory _$AccountModelImpl.fromJson(Map<String, dynamic> json) =>
@ -315,6 +331,15 @@ class _$AccountModelImpl extends _AccountModel with DiagnosticableTreeMixin {
@override
@JsonKey()
final bool quickConnectState;
final List<LibraryFiltersModel> _savedFilters;
@override
@JsonKey()
List<LibraryFiltersModel> get savedFilters {
if (_savedFilters is EqualUnmodifiableListView) return _savedFilters;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_savedFilters);
}
@override
@JsonKey(includeFromJson: false, includeToJson: false)
final UserPolicy? policy;
@ -324,7 +349,7 @@ class _$AccountModelImpl extends _AccountModel with DiagnosticableTreeMixin {
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return 'AccountModel(name: $name, id: $id, avatar: $avatar, lastUsed: $lastUsed, authMethod: $authMethod, localPin: $localPin, credentials: $credentials, latestItemsExcludes: $latestItemsExcludes, searchQueryHistory: $searchQueryHistory, quickConnectState: $quickConnectState, policy: $policy, serverConfiguration: $serverConfiguration)';
return 'AccountModel(name: $name, id: $id, avatar: $avatar, lastUsed: $lastUsed, authMethod: $authMethod, localPin: $localPin, credentials: $credentials, latestItemsExcludes: $latestItemsExcludes, searchQueryHistory: $searchQueryHistory, quickConnectState: $quickConnectState, savedFilters: $savedFilters, policy: $policy, serverConfiguration: $serverConfiguration)';
}
@override
@ -342,6 +367,7 @@ class _$AccountModelImpl extends _AccountModel with DiagnosticableTreeMixin {
..add(DiagnosticsProperty('latestItemsExcludes', latestItemsExcludes))
..add(DiagnosticsProperty('searchQueryHistory', searchQueryHistory))
..add(DiagnosticsProperty('quickConnectState', quickConnectState))
..add(DiagnosticsProperty('savedFilters', savedFilters))
..add(DiagnosticsProperty('policy', policy))
..add(DiagnosticsProperty('serverConfiguration', serverConfiguration));
}
@ -368,6 +394,8 @@ class _$AccountModelImpl extends _AccountModel with DiagnosticableTreeMixin {
.equals(other._searchQueryHistory, _searchQueryHistory) &&
(identical(other.quickConnectState, quickConnectState) ||
other.quickConnectState == quickConnectState) &&
const DeepCollectionEquality()
.equals(other._savedFilters, _savedFilters) &&
(identical(other.policy, policy) || other.policy == policy) &&
(identical(other.serverConfiguration, serverConfiguration) ||
other.serverConfiguration == serverConfiguration));
@ -387,6 +415,7 @@ class _$AccountModelImpl extends _AccountModel with DiagnosticableTreeMixin {
const DeepCollectionEquality().hash(_latestItemsExcludes),
const DeepCollectionEquality().hash(_searchQueryHistory),
quickConnectState,
const DeepCollectionEquality().hash(_savedFilters),
policy,
serverConfiguration);
@ -418,6 +447,7 @@ abstract class _AccountModel extends AccountModel {
final List<String> latestItemsExcludes,
final List<String> searchQueryHistory,
final bool quickConnectState,
final List<LibraryFiltersModel> savedFilters,
@JsonKey(includeFromJson: false, includeToJson: false)
final UserPolicy? policy,
@JsonKey(includeFromJson: false, includeToJson: false)
@ -448,6 +478,8 @@ abstract class _AccountModel extends AccountModel {
@override
bool get quickConnectState;
@override
List<LibraryFiltersModel> get savedFilters;
@override
@JsonKey(includeFromJson: false, includeToJson: false)
UserPolicy? get policy;
@override

View file

@ -26,6 +26,11 @@ _$AccountModelImpl _$$AccountModelImplFromJson(Map<String, dynamic> json) =>
.toList() ??
const [],
quickConnectState: json['quickConnectState'] as bool? ?? false,
savedFilters: (json['savedFilters'] as List<dynamic>?)
?.map((e) =>
LibraryFiltersModel.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);
Map<String, dynamic> _$$AccountModelImplToJson(_$AccountModelImpl instance) =>
@ -40,6 +45,7 @@ Map<String, dynamic> _$$AccountModelImplToJson(_$AccountModelImpl instance) =>
'latestItemsExcludes': instance.latestItemsExcludes,
'searchQueryHistory': instance.searchQueryHistory,
'quickConnectState': instance.quickConnectState,
'savedFilters': instance.savedFilters,
};
const _$AuthenticationEnumMap = {

View file

@ -20,7 +20,7 @@ extension CollectionTypeExtension on CollectionType {
case CollectionType.tvshows:
return {FladderItemType.series};
case CollectionType.homevideos:
return {FladderItemType.photoalbum, FladderItemType.folder, FladderItemType.photo, FladderItemType.video};
return {FladderItemType.photoAlbum, FladderItemType.folder, FladderItemType.photo, FladderItemType.video};
case CollectionType.boxsets:
case CollectionType.folders:
case CollectionType.books:

View file

@ -210,7 +210,7 @@ class ItemBaseModel with ItemBaseModelMappable {
MovieModel _ => FladderItemType.movie,
SeriesModel _ => FladderItemType.series,
SeasonModel _ => FladderItemType.season,
PhotoAlbumModel _ => FladderItemType.photoalbum,
PhotoAlbumModel _ => FladderItemType.photoAlbum,
PhotoModel model => model.internalType,
EpisodeModel _ => FladderItemType.episode,
BookModel _ => FladderItemType.book,
@ -281,7 +281,7 @@ enum FladderItemType {
icon: IconsaxOutline.user,
selectedicon: IconsaxBold.user,
),
photoalbum(
photoAlbum(
icon: IconsaxOutline.gallery,
selectedicon: IconsaxBold.gallery,
),
@ -331,7 +331,7 @@ enum FladderItemType {
FladderItemType.episode => context.localized.mediaTypeEpisode,
FladderItemType.photo => context.localized.mediaTypePhoto,
FladderItemType.person => context.localized.mediaTypePerson,
FladderItemType.photoalbum => context.localized.mediaTypePhotoAlbum,
FladderItemType.photoAlbum => context.localized.mediaTypePhotoAlbum,
FladderItemType.folder => context.localized.mediaTypeFolder,
FladderItemType.boxset => context.localized.mediaTypeBoxset,
FladderItemType.playlist => context.localized.mediaTypePlaylist,
@ -352,7 +352,7 @@ enum FladderItemType {
FladderItemType.episode => BaseItemKind.episode,
FladderItemType.photo => BaseItemKind.photo,
FladderItemType.person => BaseItemKind.person,
FladderItemType.photoalbum => BaseItemKind.photoalbum,
FladderItemType.photoAlbum => BaseItemKind.photoalbum,
FladderItemType.folder => BaseItemKind.folder,
FladderItemType.boxset => BaseItemKind.boxset,
FladderItemType.playlist => BaseItemKind.playlist,

View file

@ -1,17 +1,17 @@
// 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: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';
import 'package:dart_mappable/dart_mappable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'item_shared_models.mapper.dart';
@MappableClass()

View file

@ -0,0 +1,79 @@
import 'dart:convert';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:xid/xid.dart';
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.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/library_search/library_search_model.dart';
import 'package:fladder/models/library_search/library_search_options.dart';
import 'package:fladder/util/map_bool_helper.dart';
part 'library_filters_model.freezed.dart';
part 'library_filters_model.g.dart';
@freezed
class LibraryFiltersModel with _$LibraryFiltersModel {
const LibraryFiltersModel._();
factory LibraryFiltersModel._internal({
required String id,
required String name,
@Default(false) isFavourite,
required List<String> ids,
required Map<String, bool> genres,
required Map<ItemFilter, bool> filters,
@StudioEncoder() required Map<Studio, bool> studios,
required Map<String, bool> tags,
required Map<int, bool> years,
required Map<String, bool> officialRatings,
required Map<FladderItemType, bool> types,
required SortingOptions sortingOption,
required SortingOrder sortOrder,
required bool favourites,
required bool hideEmptyShows,
required bool recursive,
required GroupBy groupBy,
}) = _LibraryFiltersModel;
factory LibraryFiltersModel.fromJson(Map<String, dynamic> json) => _$LibraryFiltersModelFromJson(json);
factory LibraryFiltersModel.fromLibrarySearch(String name, LibrarySearchModel searchModel) {
return LibraryFiltersModel._internal(
id: Xid().toString(),
name: name,
ids: searchModel.views.included.map((e) => e.id).toList(),
genres: searchModel.genres,
filters: searchModel.filters,
studios: searchModel.studios,
tags: searchModel.tags,
years: searchModel.years,
officialRatings: searchModel.officialRatings,
types: searchModel.types,
sortingOption: searchModel.sortingOption,
sortOrder: searchModel.sortOrder,
favourites: searchModel.favourites,
hideEmptyShows: searchModel.hideEmptyShows,
recursive: searchModel.recursive,
groupBy: searchModel.groupBy,
);
}
bool containsSameIds(List<String> otherIds) => ids.length == otherIds.length && Set.from(ids).containsAll(otherIds);
}
class StudioEncoder implements JsonConverter<Map<Studio, bool>, String> {
const StudioEncoder();
@override
Map<Studio, bool> fromJson(String json) {
final decodedMap = jsonDecode(json) as Map<dynamic, dynamic>;
final studios = decodedMap.map((key, value) => MapEntry(Studio.fromJson(key), value as bool));
return studios;
}
@override
String toJson(Map<Studio, bool> studios) => jsonEncode(studios.map((key, value) => MapEntry(key.toJson(), value)));
}

View file

@ -0,0 +1,573 @@
// 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 'library_filters_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');
LibraryFiltersModel _$LibraryFiltersModelFromJson(Map<String, dynamic> json) {
return _LibraryFiltersModel.fromJson(json);
}
/// @nodoc
mixin _$LibraryFiltersModel {
String get id => throw _privateConstructorUsedError;
String get name => throw _privateConstructorUsedError;
dynamic get isFavourite => throw _privateConstructorUsedError;
List<String> get ids => throw _privateConstructorUsedError;
Map<String, bool> get genres => throw _privateConstructorUsedError;
Map<ItemFilter, bool> get filters => throw _privateConstructorUsedError;
@StudioEncoder()
Map<Studio, bool> get studios => throw _privateConstructorUsedError;
Map<String, bool> get tags => throw _privateConstructorUsedError;
Map<int, bool> get years => throw _privateConstructorUsedError;
Map<String, bool> get officialRatings => throw _privateConstructorUsedError;
Map<FladderItemType, bool> get types => throw _privateConstructorUsedError;
SortingOptions get sortingOption => throw _privateConstructorUsedError;
SortingOrder get sortOrder => throw _privateConstructorUsedError;
bool get favourites => throw _privateConstructorUsedError;
bool get hideEmptyShows => throw _privateConstructorUsedError;
bool get recursive => throw _privateConstructorUsedError;
GroupBy get groupBy => throw _privateConstructorUsedError;
/// Serializes this LibraryFiltersModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of LibraryFiltersModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$LibraryFiltersModelCopyWith<LibraryFiltersModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $LibraryFiltersModelCopyWith<$Res> {
factory $LibraryFiltersModelCopyWith(
LibraryFiltersModel value, $Res Function(LibraryFiltersModel) then) =
_$LibraryFiltersModelCopyWithImpl<$Res, LibraryFiltersModel>;
@useResult
$Res call(
{String id,
String name,
dynamic isFavourite,
List<String> ids,
Map<String, bool> genres,
Map<ItemFilter, bool> filters,
@StudioEncoder() Map<Studio, bool> studios,
Map<String, bool> tags,
Map<int, bool> years,
Map<String, bool> officialRatings,
Map<FladderItemType, bool> types,
SortingOptions sortingOption,
SortingOrder sortOrder,
bool favourites,
bool hideEmptyShows,
bool recursive,
GroupBy groupBy});
}
/// @nodoc
class _$LibraryFiltersModelCopyWithImpl<$Res, $Val extends LibraryFiltersModel>
implements $LibraryFiltersModelCopyWith<$Res> {
_$LibraryFiltersModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of LibraryFiltersModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? name = null,
Object? isFavourite = freezed,
Object? ids = null,
Object? genres = null,
Object? filters = null,
Object? studios = null,
Object? tags = null,
Object? years = null,
Object? officialRatings = null,
Object? types = null,
Object? sortingOption = null,
Object? sortOrder = null,
Object? favourites = null,
Object? hideEmptyShows = null,
Object? recursive = null,
Object? groupBy = null,
}) {
return _then(_value.copyWith(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
isFavourite: freezed == isFavourite
? _value.isFavourite
: isFavourite // ignore: cast_nullable_to_non_nullable
as dynamic,
ids: null == ids
? _value.ids
: ids // ignore: cast_nullable_to_non_nullable
as List<String>,
genres: null == genres
? _value.genres
: genres // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,
filters: null == filters
? _value.filters
: filters // ignore: cast_nullable_to_non_nullable
as Map<ItemFilter, bool>,
studios: null == studios
? _value.studios
: studios // ignore: cast_nullable_to_non_nullable
as Map<Studio, bool>,
tags: null == tags
? _value.tags
: tags // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,
years: null == years
? _value.years
: years // ignore: cast_nullable_to_non_nullable
as Map<int, bool>,
officialRatings: null == officialRatings
? _value.officialRatings
: officialRatings // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,
types: null == types
? _value.types
: types // ignore: cast_nullable_to_non_nullable
as Map<FladderItemType, bool>,
sortingOption: null == sortingOption
? _value.sortingOption
: sortingOption // ignore: cast_nullable_to_non_nullable
as SortingOptions,
sortOrder: null == sortOrder
? _value.sortOrder
: sortOrder // ignore: cast_nullable_to_non_nullable
as SortingOrder,
favourites: null == favourites
? _value.favourites
: favourites // ignore: cast_nullable_to_non_nullable
as bool,
hideEmptyShows: null == hideEmptyShows
? _value.hideEmptyShows
: hideEmptyShows // ignore: cast_nullable_to_non_nullable
as bool,
recursive: null == recursive
? _value.recursive
: recursive // ignore: cast_nullable_to_non_nullable
as bool,
groupBy: null == groupBy
? _value.groupBy
: groupBy // ignore: cast_nullable_to_non_nullable
as GroupBy,
) as $Val);
}
}
/// @nodoc
abstract class _$$LibraryFiltersModelImplCopyWith<$Res>
implements $LibraryFiltersModelCopyWith<$Res> {
factory _$$LibraryFiltersModelImplCopyWith(_$LibraryFiltersModelImpl value,
$Res Function(_$LibraryFiltersModelImpl) then) =
__$$LibraryFiltersModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{String id,
String name,
dynamic isFavourite,
List<String> ids,
Map<String, bool> genres,
Map<ItemFilter, bool> filters,
@StudioEncoder() Map<Studio, bool> studios,
Map<String, bool> tags,
Map<int, bool> years,
Map<String, bool> officialRatings,
Map<FladderItemType, bool> types,
SortingOptions sortingOption,
SortingOrder sortOrder,
bool favourites,
bool hideEmptyShows,
bool recursive,
GroupBy groupBy});
}
/// @nodoc
class __$$LibraryFiltersModelImplCopyWithImpl<$Res>
extends _$LibraryFiltersModelCopyWithImpl<$Res, _$LibraryFiltersModelImpl>
implements _$$LibraryFiltersModelImplCopyWith<$Res> {
__$$LibraryFiltersModelImplCopyWithImpl(_$LibraryFiltersModelImpl _value,
$Res Function(_$LibraryFiltersModelImpl) _then)
: super(_value, _then);
/// Create a copy of LibraryFiltersModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? name = null,
Object? isFavourite = freezed,
Object? ids = null,
Object? genres = null,
Object? filters = null,
Object? studios = null,
Object? tags = null,
Object? years = null,
Object? officialRatings = null,
Object? types = null,
Object? sortingOption = null,
Object? sortOrder = null,
Object? favourites = null,
Object? hideEmptyShows = null,
Object? recursive = null,
Object? groupBy = null,
}) {
return _then(_$LibraryFiltersModelImpl(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
isFavourite: freezed == isFavourite ? _value.isFavourite! : isFavourite,
ids: null == ids
? _value._ids
: ids // ignore: cast_nullable_to_non_nullable
as List<String>,
genres: null == genres
? _value._genres
: genres // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,
filters: null == filters
? _value._filters
: filters // ignore: cast_nullable_to_non_nullable
as Map<ItemFilter, bool>,
studios: null == studios
? _value._studios
: studios // ignore: cast_nullable_to_non_nullable
as Map<Studio, bool>,
tags: null == tags
? _value._tags
: tags // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,
years: null == years
? _value._years
: years // ignore: cast_nullable_to_non_nullable
as Map<int, bool>,
officialRatings: null == officialRatings
? _value._officialRatings
: officialRatings // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,
types: null == types
? _value._types
: types // ignore: cast_nullable_to_non_nullable
as Map<FladderItemType, bool>,
sortingOption: null == sortingOption
? _value.sortingOption
: sortingOption // ignore: cast_nullable_to_non_nullable
as SortingOptions,
sortOrder: null == sortOrder
? _value.sortOrder
: sortOrder // ignore: cast_nullable_to_non_nullable
as SortingOrder,
favourites: null == favourites
? _value.favourites
: favourites // ignore: cast_nullable_to_non_nullable
as bool,
hideEmptyShows: null == hideEmptyShows
? _value.hideEmptyShows
: hideEmptyShows // ignore: cast_nullable_to_non_nullable
as bool,
recursive: null == recursive
? _value.recursive
: recursive // ignore: cast_nullable_to_non_nullable
as bool,
groupBy: null == groupBy
? _value.groupBy
: groupBy // ignore: cast_nullable_to_non_nullable
as GroupBy,
));
}
}
/// @nodoc
@JsonSerializable()
class _$LibraryFiltersModelImpl extends _LibraryFiltersModel {
_$LibraryFiltersModelImpl(
{required this.id,
required this.name,
this.isFavourite = false,
required final List<String> ids,
required final Map<String, bool> genres,
required final Map<ItemFilter, bool> filters,
@StudioEncoder() required final Map<Studio, bool> studios,
required final Map<String, bool> tags,
required final Map<int, bool> years,
required final Map<String, bool> officialRatings,
required final Map<FladderItemType, bool> types,
required this.sortingOption,
required this.sortOrder,
required this.favourites,
required this.hideEmptyShows,
required this.recursive,
required this.groupBy})
: _ids = ids,
_genres = genres,
_filters = filters,
_studios = studios,
_tags = tags,
_years = years,
_officialRatings = officialRatings,
_types = types,
super._();
factory _$LibraryFiltersModelImpl.fromJson(Map<String, dynamic> json) =>
_$$LibraryFiltersModelImplFromJson(json);
@override
final String id;
@override
final String name;
@override
@JsonKey()
final dynamic isFavourite;
final List<String> _ids;
@override
List<String> get ids {
if (_ids is EqualUnmodifiableListView) return _ids;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_ids);
}
final Map<String, bool> _genres;
@override
Map<String, bool> get genres {
if (_genres is EqualUnmodifiableMapView) return _genres;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_genres);
}
final Map<ItemFilter, bool> _filters;
@override
Map<ItemFilter, bool> get filters {
if (_filters is EqualUnmodifiableMapView) return _filters;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_filters);
}
final Map<Studio, bool> _studios;
@override
@StudioEncoder()
Map<Studio, bool> get studios {
if (_studios is EqualUnmodifiableMapView) return _studios;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_studios);
}
final Map<String, bool> _tags;
@override
Map<String, bool> get tags {
if (_tags is EqualUnmodifiableMapView) return _tags;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_tags);
}
final Map<int, bool> _years;
@override
Map<int, bool> get years {
if (_years is EqualUnmodifiableMapView) return _years;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_years);
}
final Map<String, bool> _officialRatings;
@override
Map<String, bool> get officialRatings {
if (_officialRatings is EqualUnmodifiableMapView) return _officialRatings;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_officialRatings);
}
final Map<FladderItemType, bool> _types;
@override
Map<FladderItemType, bool> get types {
if (_types is EqualUnmodifiableMapView) return _types;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_types);
}
@override
final SortingOptions sortingOption;
@override
final SortingOrder sortOrder;
@override
final bool favourites;
@override
final bool hideEmptyShows;
@override
final bool recursive;
@override
final GroupBy groupBy;
@override
String toString() {
return 'LibraryFiltersModel._internal(id: $id, name: $name, isFavourite: $isFavourite, ids: $ids, genres: $genres, filters: $filters, studios: $studios, tags: $tags, years: $years, officialRatings: $officialRatings, types: $types, sortingOption: $sortingOption, sortOrder: $sortOrder, favourites: $favourites, hideEmptyShows: $hideEmptyShows, recursive: $recursive, groupBy: $groupBy)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$LibraryFiltersModelImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.name, name) || other.name == name) &&
const DeepCollectionEquality()
.equals(other.isFavourite, isFavourite) &&
const DeepCollectionEquality().equals(other._ids, _ids) &&
const DeepCollectionEquality().equals(other._genres, _genres) &&
const DeepCollectionEquality().equals(other._filters, _filters) &&
const DeepCollectionEquality().equals(other._studios, _studios) &&
const DeepCollectionEquality().equals(other._tags, _tags) &&
const DeepCollectionEquality().equals(other._years, _years) &&
const DeepCollectionEquality()
.equals(other._officialRatings, _officialRatings) &&
const DeepCollectionEquality().equals(other._types, _types) &&
(identical(other.sortingOption, sortingOption) ||
other.sortingOption == sortingOption) &&
(identical(other.sortOrder, sortOrder) ||
other.sortOrder == sortOrder) &&
(identical(other.favourites, favourites) ||
other.favourites == favourites) &&
(identical(other.hideEmptyShows, hideEmptyShows) ||
other.hideEmptyShows == hideEmptyShows) &&
(identical(other.recursive, recursive) ||
other.recursive == recursive) &&
(identical(other.groupBy, groupBy) || other.groupBy == groupBy));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
id,
name,
const DeepCollectionEquality().hash(isFavourite),
const DeepCollectionEquality().hash(_ids),
const DeepCollectionEquality().hash(_genres),
const DeepCollectionEquality().hash(_filters),
const DeepCollectionEquality().hash(_studios),
const DeepCollectionEquality().hash(_tags),
const DeepCollectionEquality().hash(_years),
const DeepCollectionEquality().hash(_officialRatings),
const DeepCollectionEquality().hash(_types),
sortingOption,
sortOrder,
favourites,
hideEmptyShows,
recursive,
groupBy);
/// Create a copy of LibraryFiltersModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$LibraryFiltersModelImplCopyWith<_$LibraryFiltersModelImpl> get copyWith =>
__$$LibraryFiltersModelImplCopyWithImpl<_$LibraryFiltersModelImpl>(
this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$LibraryFiltersModelImplToJson(
this,
);
}
}
abstract class _LibraryFiltersModel extends LibraryFiltersModel {
factory _LibraryFiltersModel(
{required final String id,
required final String name,
final dynamic isFavourite,
required final List<String> ids,
required final Map<String, bool> genres,
required final Map<ItemFilter, bool> filters,
@StudioEncoder() required final Map<Studio, bool> studios,
required final Map<String, bool> tags,
required final Map<int, bool> years,
required final Map<String, bool> officialRatings,
required final Map<FladderItemType, bool> types,
required final SortingOptions sortingOption,
required final SortingOrder sortOrder,
required final bool favourites,
required final bool hideEmptyShows,
required final bool recursive,
required final GroupBy groupBy}) = _$LibraryFiltersModelImpl;
_LibraryFiltersModel._() : super._();
factory _LibraryFiltersModel.fromJson(Map<String, dynamic> json) =
_$LibraryFiltersModelImpl.fromJson;
@override
String get id;
@override
String get name;
@override
dynamic get isFavourite;
@override
List<String> get ids;
@override
Map<String, bool> get genres;
@override
Map<ItemFilter, bool> get filters;
@override
@StudioEncoder()
Map<Studio, bool> get studios;
@override
Map<String, bool> get tags;
@override
Map<int, bool> get years;
@override
Map<String, bool> get officialRatings;
@override
Map<FladderItemType, bool> get types;
@override
SortingOptions get sortingOption;
@override
SortingOrder get sortOrder;
@override
bool get favourites;
@override
bool get hideEmptyShows;
@override
bool get recursive;
@override
GroupBy get groupBy;
/// Create a copy of LibraryFiltersModel
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$LibraryFiltersModelImplCopyWith<_$LibraryFiltersModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View file

@ -0,0 +1,124 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'library_filters_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$LibraryFiltersModelImpl _$$LibraryFiltersModelImplFromJson(
Map<String, dynamic> json) =>
_$LibraryFiltersModelImpl(
id: json['id'] as String,
name: json['name'] as String,
isFavourite: json['isFavourite'] ?? false,
ids: (json['ids'] as List<dynamic>).map((e) => e as String).toList(),
genres: Map<String, bool>.from(json['genres'] as Map),
filters: (json['filters'] as Map<String, dynamic>).map(
(k, e) => MapEntry($enumDecode(_$ItemFilterEnumMap, k), e as bool),
),
studios: const StudioEncoder().fromJson(json['studios'] as String),
tags: Map<String, bool>.from(json['tags'] as Map),
years: (json['years'] as Map<String, dynamic>).map(
(k, e) => MapEntry(int.parse(k), e as bool),
),
officialRatings: Map<String, bool>.from(json['officialRatings'] as Map),
types: (json['types'] as Map<String, dynamic>).map(
(k, e) => MapEntry($enumDecode(_$FladderItemTypeEnumMap, k), e as bool),
),
sortingOption:
$enumDecode(_$SortingOptionsEnumMap, json['sortingOption']),
sortOrder: $enumDecode(_$SortingOrderEnumMap, json['sortOrder']),
favourites: json['favourites'] as bool,
hideEmptyShows: json['hideEmptyShows'] as bool,
recursive: json['recursive'] as bool,
groupBy: $enumDecode(_$GroupByEnumMap, json['groupBy']),
);
Map<String, dynamic> _$$LibraryFiltersModelImplToJson(
_$LibraryFiltersModelImpl instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'isFavourite': instance.isFavourite,
'ids': instance.ids,
'genres': instance.genres,
'filters':
instance.filters.map((k, e) => MapEntry(_$ItemFilterEnumMap[k], e)),
'studios': const StudioEncoder().toJson(instance.studios),
'tags': instance.tags,
'years': instance.years.map((k, e) => MapEntry(k.toString(), e)),
'officialRatings': instance.officialRatings,
'types': instance.types
.map((k, e) => MapEntry(_$FladderItemTypeEnumMap[k]!, e)),
'sortingOption': _$SortingOptionsEnumMap[instance.sortingOption]!,
'sortOrder': _$SortingOrderEnumMap[instance.sortOrder]!,
'favourites': instance.favourites,
'hideEmptyShows': instance.hideEmptyShows,
'recursive': instance.recursive,
'groupBy': _$GroupByEnumMap[instance.groupBy]!,
};
const _$ItemFilterEnumMap = {
ItemFilter.swaggerGeneratedUnknown: null,
ItemFilter.isfolder: 'IsFolder',
ItemFilter.isnotfolder: 'IsNotFolder',
ItemFilter.isunplayed: 'IsUnplayed',
ItemFilter.isplayed: 'IsPlayed',
ItemFilter.isfavorite: 'IsFavorite',
ItemFilter.isresumable: 'IsResumable',
ItemFilter.likes: 'Likes',
ItemFilter.dislikes: 'Dislikes',
ItemFilter.isfavoriteorlikes: 'IsFavoriteOrLikes',
};
const _$FladderItemTypeEnumMap = {
FladderItemType.baseType: 'baseType',
FladderItemType.audio: 'audio',
FladderItemType.musicAlbum: 'musicAlbum',
FladderItemType.musicVideo: 'musicVideo',
FladderItemType.collectionFolder: 'collectionFolder',
FladderItemType.video: 'video',
FladderItemType.movie: 'movie',
FladderItemType.series: 'series',
FladderItemType.season: 'season',
FladderItemType.episode: 'episode',
FladderItemType.photo: 'photo',
FladderItemType.person: 'person',
FladderItemType.photoAlbum: 'photoAlbum',
FladderItemType.folder: 'folder',
FladderItemType.boxset: 'boxset',
FladderItemType.playlist: 'playlist',
FladderItemType.book: 'book',
};
const _$SortingOptionsEnumMap = {
SortingOptions.name: 'name',
SortingOptions.communityRating: 'communityRating',
SortingOptions.parentalRating: 'parentalRating',
SortingOptions.dateAdded: 'dateAdded',
SortingOptions.dateLastContentAdded: 'dateLastContentAdded',
SortingOptions.favorite: 'favorite',
SortingOptions.datePlayed: 'datePlayed',
SortingOptions.folders: 'folders',
SortingOptions.playCount: 'playCount',
SortingOptions.releaseDate: 'releaseDate',
SortingOptions.runTime: 'runTime',
SortingOptions.random: 'random',
};
const _$SortingOrderEnumMap = {
SortingOrder.ascending: 'ascending',
SortingOrder.descending: 'descending',
};
const _$GroupByEnumMap = {
GroupBy.none: 'none',
GroupBy.name: 'name',
GroupBy.genres: 'genres',
GroupBy.dateAdded: 'dateAdded',
GroupBy.tags: 'tags',
GroupBy.releaseDate: 'releaseDate',
GroupBy.rating: 'rating',
GroupBy.type: 'type',
};

View file

@ -1,15 +1,16 @@
import 'package:collection/collection.dart';
import 'package:dart_mappable/dart_mappable.dart';
import 'package:fladder/util/list_extensions.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:dart_mappable/dart_mappable.dart';
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.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/library_search/library_search_options.dart';
import 'package:fladder/models/view_model.dart';
import 'package:fladder/util/list_extensions.dart';
import 'package:fladder/util/localization_helper.dart';
import 'package:fladder/util/map_bool_helper.dart';
@ -34,7 +35,7 @@ class LibrarySearchModel with LibrarySearchModelMappable {
final SortingOptions sortingOption;
final SortingOrder sortOrder;
final bool favourites;
final bool hideEmtpyShows;
final bool hideEmptyShows;
final bool recursive;
final GroupBy groupBy;
final Map<String, int> lastIndices;
@ -71,14 +72,14 @@ class LibrarySearchModel with LibrarySearchModelMappable {
FladderItemType.musicVideo: false,
FladderItemType.photo: false,
FladderItemType.person: false,
FladderItemType.photoalbum: false,
FladderItemType.photoAlbum: false,
FladderItemType.series: true,
FladderItemType.video: true,
},
this.favourites = false,
this.sortingOption = SortingOptions.name,
this.sortOrder = SortingOrder.ascending,
this.hideEmtpyShows = true,
this.hideEmptyShows = true,
this.recursive = false,
this.groupBy = GroupBy.none,
this.lastIndices = const {},
@ -92,7 +93,7 @@ class LibrarySearchModel with LibrarySearchModelMappable {
tags.hasEnabled ||
years.hasEnabled ||
officialRatings.hasEnabled ||
hideEmtpyShows ||
hideEmptyShows ||
filters.hasEnabled ||
favourites ||
searchQuery.isNotEmpty;
@ -146,7 +147,7 @@ class LibrarySearchModel with LibrarySearchModelMappable {
if (totalItemCount == 0) return false;
return types.included.isEmpty ||
types.included.containsAny(
{...FladderItemType.galleryItem, FladderItemType.photoalbum, FladderItemType.folder},
{...FladderItemType.galleryItem, FladderItemType.photoAlbum, FladderItemType.folder},
);
}
@ -177,7 +178,7 @@ class LibrarySearchModel with LibrarySearchModelMappable {
favourites: false,
recursive: false,
studios: const {},
hideEmtpyShows: true,
hideEmptyShows: true,
);
}

View file

@ -83,7 +83,7 @@ class LibrarySearchModelMapper extends ClassMapperBase<LibrarySearchModel> {
FladderItemType.musicVideo: false,
FladderItemType.photo: false,
FladderItemType.person: false,
FladderItemType.photoalbum: false,
FladderItemType.photoAlbum: false,
FladderItemType.series: true,
FladderItemType.video: true
});
@ -98,9 +98,9 @@ class LibrarySearchModelMapper extends ClassMapperBase<LibrarySearchModel> {
static SortingOrder _$sortOrder(LibrarySearchModel v) => v.sortOrder;
static const Field<LibrarySearchModel, SortingOrder> _f$sortOrder =
Field('sortOrder', _$sortOrder, opt: true, def: SortingOrder.ascending);
static bool _$hideEmtpyShows(LibrarySearchModel v) => v.hideEmtpyShows;
static const Field<LibrarySearchModel, bool> _f$hideEmtpyShows =
Field('hideEmtpyShows', _$hideEmtpyShows, opt: true, def: true);
static bool _$hideEmptyShows(LibrarySearchModel v) => v.hideEmptyShows;
static const Field<LibrarySearchModel, bool> _f$hideEmptyShows =
Field('hideEmptyShows', _$hideEmptyShows, opt: true, def: true);
static bool _$recursive(LibrarySearchModel v) => v.recursive;
static const Field<LibrarySearchModel, bool> _f$recursive =
Field('recursive', _$recursive, opt: true, def: false);
@ -138,7 +138,7 @@ class LibrarySearchModelMapper extends ClassMapperBase<LibrarySearchModel> {
#favourites: _f$favourites,
#sortingOption: _f$sortingOption,
#sortOrder: _f$sortOrder,
#hideEmtpyShows: _f$hideEmtpyShows,
#hideEmptyShows: _f$hideEmptyShows,
#recursive: _f$recursive,
#groupBy: _f$groupBy,
#lastIndices: _f$lastIndices,
@ -167,7 +167,7 @@ class LibrarySearchModelMapper extends ClassMapperBase<LibrarySearchModel> {
favourites: data.dec(_f$favourites),
sortingOption: data.dec(_f$sortingOption),
sortOrder: data.dec(_f$sortOrder),
hideEmtpyShows: data.dec(_f$hideEmtpyShows),
hideEmptyShows: data.dec(_f$hideEmptyShows),
recursive: data.dec(_f$recursive),
groupBy: data.dec(_f$groupBy),
lastIndices: data.dec(_f$lastIndices),
@ -257,7 +257,7 @@ abstract class LibrarySearchModelCopyWith<$R, $In extends LibrarySearchModel,
bool? favourites,
SortingOptions? sortingOption,
SortingOrder? sortOrder,
bool? hideEmtpyShows,
bool? hideEmptyShows,
bool? recursive,
GroupBy? groupBy,
Map<String, int>? lastIndices,
@ -353,7 +353,7 @@ class _LibrarySearchModelCopyWithImpl<$R, $Out>
bool? favourites,
SortingOptions? sortingOption,
SortingOrder? sortOrder,
bool? hideEmtpyShows,
bool? hideEmptyShows,
bool? recursive,
GroupBy? groupBy,
Map<String, int>? lastIndices,
@ -377,7 +377,7 @@ class _LibrarySearchModelCopyWithImpl<$R, $Out>
if (favourites != null) #favourites: favourites,
if (sortingOption != null) #sortingOption: sortingOption,
if (sortOrder != null) #sortOrder: sortOrder,
if (hideEmtpyShows != null) #hideEmtpyShows: hideEmtpyShows,
if (hideEmptyShows != null) #hideEmptyShows: hideEmptyShows,
if (recursive != null) #recursive: recursive,
if (groupBy != null) #groupBy: groupBy,
if (lastIndices != null) #lastIndices: lastIndices,
@ -403,7 +403,7 @@ class _LibrarySearchModelCopyWithImpl<$R, $Out>
favourites: data.get(#favourites, or: $value.favourites),
sortingOption: data.get(#sortingOption, or: $value.sortingOption),
sortOrder: data.get(#sortOrder, or: $value.sortOrder),
hideEmtpyShows: data.get(#hideEmtpyShows, or: $value.hideEmtpyShows),
hideEmptyShows: data.get(#hideEmptyShows, or: $value.hideEmptyShows),
recursive: data.get(#recursive, or: $value.recursive),
groupBy: data.get(#groupBy, or: $value.groupBy),
lastIndices: data.get(#lastIndices, or: $value.lastIndices),