mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-16 02:35:59 -07:00
feat: Improve library search screen (#477)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
571b682b80
commit
d22d340181
41 changed files with 2881 additions and 2026 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:iconsax_plus/iconsax_plus.dart';
|
||||
|
||||
|
|
@ -11,7 +12,9 @@ import 'package:fladder/providers/library_search_provider.dart';
|
|||
import 'package:fladder/screens/shared/chips/category_chip.dart';
|
||||
import 'package:fladder/util/localization_helper.dart';
|
||||
import 'package:fladder/util/map_bool_helper.dart';
|
||||
import 'package:fladder/util/position_provider.dart';
|
||||
import 'package:fladder/util/refresh_state.dart';
|
||||
import 'package:fladder/widgets/shared/button_group.dart';
|
||||
|
||||
class LibraryFilterChips extends ConsumerStatefulWidget {
|
||||
const LibraryFilterChips({super.key});
|
||||
|
|
@ -25,133 +28,137 @@ class _LibraryFilterChipsState extends ConsumerState<LibraryFilterChips> {
|
|||
Widget build(BuildContext context) {
|
||||
final uniqueKey = widget.key ?? UniqueKey();
|
||||
final libraryProvider = ref.watch(librarySearchProvider(uniqueKey).notifier);
|
||||
final groupBy = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.groupBy));
|
||||
final favourites = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.favourites));
|
||||
final recursive = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.recursive));
|
||||
final hideEmpty = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.hideEmptyShows));
|
||||
final groupBy = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.filters.groupBy));
|
||||
final favourites = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.filters.favourites));
|
||||
final recursive = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.filters.recursive));
|
||||
final hideEmpty = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.filters.hideEmptyShows));
|
||||
final librarySearchResults = ref.watch(librarySearchProvider(uniqueKey));
|
||||
|
||||
final chips = [
|
||||
if (librarySearchResults.folderOverwrite.isEmpty)
|
||||
CategoryChip(
|
||||
label: Text(context.localized.library(2)),
|
||||
items: librarySearchResults.views.sortByKey((value) => value.name),
|
||||
labelBuilder: (item) => Text(item.name),
|
||||
onSave: (value) => libraryProvider.setViews(value),
|
||||
onCancel: () => libraryProvider.setViews(librarySearchResults.views),
|
||||
onClear: () => libraryProvider.setViews(librarySearchResults.views.setAll(false)),
|
||||
),
|
||||
CategoryChip<FladderItemType>(
|
||||
label: Text(context.localized.type(librarySearchResults.filters.types.length)),
|
||||
items: librarySearchResults.filters.types.sortByKey((value) => value.label(context)),
|
||||
activeIcon: IconsaxPlusBold.filter_tick,
|
||||
labelBuilder: (item) => Row(
|
||||
children: [
|
||||
Icon(item.icon),
|
||||
const SizedBox(width: 12),
|
||||
Text(item.label(context)),
|
||||
],
|
||||
),
|
||||
onSave: (value) => libraryProvider.setTypes(value),
|
||||
onClear: () => libraryProvider.setTypes(librarySearchResults.filters.types.setAll(false)),
|
||||
),
|
||||
ExpressiveButton(
|
||||
isSelected: favourites,
|
||||
icon: favourites ? const Icon(IconsaxPlusBold.heart) : null,
|
||||
label: Text(context.localized.favorites),
|
||||
onPressed: () {
|
||||
libraryProvider.toggleFavourite();
|
||||
context.refreshData();
|
||||
},
|
||||
),
|
||||
ExpressiveButton(
|
||||
isSelected: recursive,
|
||||
icon: recursive ? const Icon(IconsaxPlusBold.tick_circle) : null,
|
||||
label: Text(context.localized.recursive),
|
||||
onPressed: () {
|
||||
libraryProvider.toggleRecursive();
|
||||
context.refreshData();
|
||||
},
|
||||
),
|
||||
if (librarySearchResults.filters.genres.isNotEmpty)
|
||||
CategoryChip<String>(
|
||||
label: Text(context.localized.genre(librarySearchResults.filters.genres.length)),
|
||||
activeIcon: IconsaxPlusBold.hierarchy_2,
|
||||
items: librarySearchResults.filters.genres,
|
||||
labelBuilder: (item) => Text(item),
|
||||
onSave: (value) => libraryProvider.setGenres(value),
|
||||
onCancel: () => libraryProvider.setGenres(librarySearchResults.filters.genres),
|
||||
onClear: () => libraryProvider.setGenres(librarySearchResults.filters.genres.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.filters.studios.isNotEmpty)
|
||||
CategoryChip<Studio>(
|
||||
label: Text(context.localized.studio(librarySearchResults.filters.studios.length)),
|
||||
activeIcon: IconsaxPlusBold.airdrop,
|
||||
items: librarySearchResults.filters.studios,
|
||||
labelBuilder: (item) => Text(item.name),
|
||||
onSave: (value) => libraryProvider.setStudios(value),
|
||||
onCancel: () => libraryProvider.setStudios(librarySearchResults.filters.studios),
|
||||
onClear: () => libraryProvider.setStudios(librarySearchResults.filters.studios.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.filters.tags.isNotEmpty)
|
||||
CategoryChip<String>(
|
||||
label: Text(context.localized.label(librarySearchResults.filters.tags.length)),
|
||||
activeIcon: Icons.label_rounded,
|
||||
items: librarySearchResults.filters.tags,
|
||||
labelBuilder: (item) => Text(item),
|
||||
onSave: (value) => libraryProvider.setTags(value),
|
||||
onCancel: () => libraryProvider.setTags(librarySearchResults.filters.tags),
|
||||
onClear: () => libraryProvider.setTags(librarySearchResults.filters.tags.setAll(false)),
|
||||
),
|
||||
ExpressiveButton(
|
||||
isSelected: groupBy != GroupBy.none,
|
||||
icon: groupBy != GroupBy.none ? const Icon(IconsaxPlusBold.bag_tick) : null,
|
||||
label: Text(context.localized.group),
|
||||
onPressed: () {
|
||||
_openGroupDialogue(context, ref, libraryProvider, uniqueKey);
|
||||
},
|
||||
),
|
||||
CategoryChip<ItemFilter>(
|
||||
label: Text(context.localized.filter(librarySearchResults.filters.itemFilters.length)),
|
||||
items: librarySearchResults.filters.itemFilters,
|
||||
labelBuilder: (item) => Text(item.label(context)),
|
||||
onSave: (value) => libraryProvider.setFilters(value),
|
||||
onClear: () => libraryProvider.setFilters(librarySearchResults.filters.itemFilters.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.filters.types[FladderItemType.series] == true)
|
||||
ExpressiveButton(
|
||||
isSelected: !hideEmpty,
|
||||
icon: !hideEmpty ? const Icon(IconsaxPlusBold.ghost) : null,
|
||||
label: Text(!hideEmpty ? context.localized.hideEmpty : context.localized.showEmpty),
|
||||
onPressed: libraryProvider.toggleEmptyShows,
|
||||
),
|
||||
if (librarySearchResults.filters.officialRatings.isNotEmpty)
|
||||
CategoryChip<String>(
|
||||
label: Text(context.localized.rating(librarySearchResults.filters.officialRatings.length)),
|
||||
activeIcon: Icons.star_rate_rounded,
|
||||
items: librarySearchResults.filters.officialRatings,
|
||||
labelBuilder: (item) => Text(item),
|
||||
onSave: (value) => libraryProvider.setRatings(value),
|
||||
onCancel: () => libraryProvider.setRatings(librarySearchResults.filters.officialRatings),
|
||||
onClear: () => libraryProvider.setRatings(librarySearchResults.filters.officialRatings.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.filters.years.isNotEmpty)
|
||||
CategoryChip<int>(
|
||||
label: Text(context.localized.year(librarySearchResults.filters.years.length)),
|
||||
items: librarySearchResults.filters.years,
|
||||
labelBuilder: (item) => Text(item.toString()),
|
||||
onSave: (value) => libraryProvider.setYears(value),
|
||||
onCancel: () => libraryProvider.setYears(librarySearchResults.filters.years),
|
||||
onClear: () => libraryProvider.setYears(librarySearchResults.filters.years.setAll(false)),
|
||||
),
|
||||
];
|
||||
|
||||
return Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
if (librarySearchResults.folderOverwrite.isEmpty)
|
||||
CategoryChip(
|
||||
label: Text(context.localized.library(2)),
|
||||
items: librarySearchResults.views,
|
||||
labelBuilder: (item) => Text(item.name),
|
||||
onSave: (value) => libraryProvider.setViews(value),
|
||||
onCancel: () => libraryProvider.setViews(librarySearchResults.views),
|
||||
onClear: () => libraryProvider.setViews(librarySearchResults.views.setAll(false)),
|
||||
),
|
||||
CategoryChip<FladderItemType>(
|
||||
label: Text(context.localized.type(librarySearchResults.types.length)),
|
||||
items: librarySearchResults.types,
|
||||
labelBuilder: (item) => Row(
|
||||
children: [
|
||||
Icon(item.icon),
|
||||
const SizedBox(width: 12),
|
||||
Text(item.label(context)),
|
||||
],
|
||||
),
|
||||
onSave: (value) => libraryProvider.setTypes(value),
|
||||
onClear: () => libraryProvider.setTypes(librarySearchResults.types.setAll(false)),
|
||||
),
|
||||
FilterChip(
|
||||
label: Text(context.localized.favorites),
|
||||
avatar: Icon(
|
||||
favourites ? IconsaxPlusBold.heart : IconsaxPlusLinear.heart,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
selected: favourites,
|
||||
showCheckmark: false,
|
||||
onSelected: (_) {
|
||||
libraryProvider.toggleFavourite();
|
||||
context.refreshData();
|
||||
},
|
||||
),
|
||||
FilterChip(
|
||||
label: Text(context.localized.recursive),
|
||||
selected: recursive,
|
||||
onSelected: (_) {
|
||||
libraryProvider.toggleRecursive();
|
||||
context.refreshData();
|
||||
},
|
||||
),
|
||||
if (librarySearchResults.genres.isNotEmpty)
|
||||
CategoryChip<String>(
|
||||
label: Text(context.localized.genre(librarySearchResults.genres.length)),
|
||||
activeIcon: IconsaxPlusBold.hierarchy_2,
|
||||
items: librarySearchResults.genres,
|
||||
labelBuilder: (item) => Text(item),
|
||||
onSave: (value) => libraryProvider.setGenres(value),
|
||||
onCancel: () => libraryProvider.setGenres(librarySearchResults.genres),
|
||||
onClear: () => libraryProvider.setGenres(librarySearchResults.genres.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.studios.isNotEmpty)
|
||||
CategoryChip<Studio>(
|
||||
label: Text(context.localized.studio(librarySearchResults.studios.length)),
|
||||
activeIcon: IconsaxPlusBold.airdrop,
|
||||
items: librarySearchResults.studios,
|
||||
labelBuilder: (item) => Text(item.name),
|
||||
onSave: (value) => libraryProvider.setStudios(value),
|
||||
onCancel: () => libraryProvider.setStudios(librarySearchResults.studios),
|
||||
onClear: () => libraryProvider.setStudios(librarySearchResults.studios.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.tags.isNotEmpty)
|
||||
CategoryChip<String>(
|
||||
label: Text(context.localized.label(librarySearchResults.tags.length)),
|
||||
activeIcon: Icons.label_rounded,
|
||||
items: librarySearchResults.tags,
|
||||
labelBuilder: (item) => Text(item),
|
||||
onSave: (value) => libraryProvider.setTags(value),
|
||||
onCancel: () => libraryProvider.setTags(librarySearchResults.tags),
|
||||
onClear: () => libraryProvider.setTags(librarySearchResults.tags.setAll(false)),
|
||||
),
|
||||
FilterChip(
|
||||
label: Text(context.localized.group),
|
||||
selected: groupBy != GroupBy.none,
|
||||
onSelected: (_) {
|
||||
_openGroupDialogue(context, ref, libraryProvider, uniqueKey);
|
||||
},
|
||||
),
|
||||
CategoryChip<ItemFilter>(
|
||||
label: Text(context.localized.filter(librarySearchResults.filters.length)),
|
||||
items: librarySearchResults.filters,
|
||||
labelBuilder: (item) => Text(item.label(context)),
|
||||
onSave: (value) => libraryProvider.setFilters(value),
|
||||
onClear: () => libraryProvider.setFilters(librarySearchResults.filters.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.types[FladderItemType.series] == true)
|
||||
FilterChip(
|
||||
avatar: Icon(
|
||||
hideEmpty ? Icons.visibility_off_rounded : Icons.visibility_rounded,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
selected: hideEmpty,
|
||||
showCheckmark: false,
|
||||
label: Text(context.localized.hideEmpty),
|
||||
onSelected: libraryProvider.setHideEmpty,
|
||||
),
|
||||
if (librarySearchResults.officialRatings.isNotEmpty)
|
||||
CategoryChip<String>(
|
||||
label: Text(context.localized.rating(librarySearchResults.officialRatings.length)),
|
||||
activeIcon: Icons.star_rate_rounded,
|
||||
items: librarySearchResults.officialRatings,
|
||||
labelBuilder: (item) => Text(item),
|
||||
onSave: (value) => libraryProvider.setRatings(value),
|
||||
onCancel: () => libraryProvider.setRatings(librarySearchResults.officialRatings),
|
||||
onClear: () => libraryProvider.setRatings(librarySearchResults.officialRatings.setAll(false)),
|
||||
),
|
||||
if (librarySearchResults.years.isNotEmpty)
|
||||
CategoryChip<int>(
|
||||
label: Text(context.localized.year(librarySearchResults.years.length)),
|
||||
items: librarySearchResults.years,
|
||||
labelBuilder: (item) => Text(item.toString()),
|
||||
onSave: (value) => libraryProvider.setYears(value),
|
||||
onCancel: () => libraryProvider.setYears(librarySearchResults.years),
|
||||
onClear: () => libraryProvider.setYears(librarySearchResults.years.setAll(false)),
|
||||
),
|
||||
],
|
||||
spacing: 4,
|
||||
children: chips.mapIndexed(
|
||||
(index, element) {
|
||||
final position = index == 0
|
||||
? PositionContext.first
|
||||
: (index == chips.length - 1 ? PositionContext.last : PositionContext.middle);
|
||||
return PositionProvider(position: position, child: element);
|
||||
},
|
||||
).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +171,7 @@ class _LibraryFilterChipsState extends ConsumerState<LibraryFilterChips> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
final groupBy = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.groupBy));
|
||||
final groupBy = ref.watch(librarySearchProvider(uniqueKey).select((v) => v.filters.groupBy));
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.65,
|
||||
|
|
|
|||
|
|
@ -3,41 +3,40 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:iconsax_plus/iconsax_plus.dart';
|
||||
|
||||
import 'package:fladder/models/library_search/library_search_model.dart';
|
||||
import 'package:fladder/providers/library_search_provider.dart';
|
||||
import 'package:fladder/screens/shared/default_alert_dialog.dart';
|
||||
import 'package:fladder/screens/shared/outlined_text_field.dart';
|
||||
import 'package:fladder/util/list_padding.dart';
|
||||
import 'package:fladder/util/localization_helper.dart';
|
||||
|
||||
Future<void> showSavedFilters(
|
||||
BuildContext context,
|
||||
LibrarySearchModel model,
|
||||
LibrarySearchNotifier provider,
|
||||
Key providerKey,
|
||||
) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => LibrarySavedFiltersDialogue(
|
||||
searchModel: model,
|
||||
provider: provider,
|
||||
providerKey: providerKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class LibrarySavedFiltersDialogue extends ConsumerWidget {
|
||||
final LibrarySearchModel searchModel;
|
||||
final LibrarySearchNotifier provider;
|
||||
final Key providerKey;
|
||||
|
||||
const LibrarySavedFiltersDialogue({
|
||||
required this.searchModel,
|
||||
required this.provider,
|
||||
super.key,
|
||||
required this.providerKey,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final controller = TextEditingController();
|
||||
final provider = ref.watch(librarySearchProvider(providerKey).notifier);
|
||||
final currentFilters = ref.watch(librarySearchProvider(providerKey).select((value) => value.filters));
|
||||
final filters = ref.watch(provider.filterProvider);
|
||||
final filterProvider = ref.watch(provider.filterProvider.notifier);
|
||||
final anyFilterSelected = filters.any((element) => element.filter == currentFilters);
|
||||
|
||||
return Dialog(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
|
|
@ -57,68 +56,75 @@ class LibrarySavedFiltersDialogue extends ConsumerWidget {
|
|||
children: [
|
||||
...filters.map(
|
||||
(filter) {
|
||||
final isCurrentFilter = filter.filter == currentFilters;
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Card(
|
||||
child: InkWell(
|
||||
onTap: () => provider.loadModel(filter),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: Text(filter.name)),
|
||||
IconButton.filledTonal(
|
||||
tooltip: context.localized.defaultFilterForLibrary,
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
filter.isFavourite
|
||||
? Colors.yellowAccent.shade700.withValues(alpha: 0.5)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
onPressed: () =>
|
||||
filterProvider.saveFilter(filter.copyWith(isFavourite: !filter.isFavourite)),
|
||||
icon: Icon(
|
||||
color: filter.isFavourite ? Colors.yellowAccent : null,
|
||||
filter.isFavourite ? IconsaxPlusBold.star_1 : IconsaxPlusLinear.star,
|
||||
),
|
||||
),
|
||||
IconButton.filledTonal(
|
||||
tooltip: context.localized.updateFilterForLibrary,
|
||||
onPressed: () => provider.updateFilter(filter),
|
||||
icon: const Icon(IconsaxPlusBold.refresh),
|
||||
),
|
||||
IconButton.filledTonal(
|
||||
tooltip: context.localized.delete,
|
||||
onPressed: () {
|
||||
showDefaultAlertDialog(
|
||||
context,
|
||||
context.localized.removeFilterForLibrary(filter.name),
|
||||
context.localized.deleteFilterConfirmation,
|
||||
(context) {
|
||||
filterProvider.removeFilter(filter);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
context.localized.delete,
|
||||
(context) {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
context.localized.cancel,
|
||||
);
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor:
|
||||
WidgetStatePropertyAll(Theme.of(context).colorScheme.errorContainer),
|
||||
iconColor:
|
||||
WidgetStatePropertyAll(Theme.of(context).colorScheme.onErrorContainer),
|
||||
foregroundColor:
|
||||
WidgetStatePropertyAll(Theme.of(context).colorScheme.onErrorContainer),
|
||||
),
|
||||
icon: const Icon(IconsaxPlusLinear.trash),
|
||||
),
|
||||
].addInBetween(const SizedBox(width: 8)),
|
||||
color: isCurrentFilter
|
||||
? Theme.of(context).colorScheme.primaryContainer.withValues(alpha: 0.75)
|
||||
: null,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: Row(spacing: 8, children: [
|
||||
Expanded(
|
||||
child: OutlinedTextField(
|
||||
fillColor: Colors.transparent,
|
||||
controller: TextEditingController(text: filter.name),
|
||||
onSubmitted: (value) => provider.updateFilter(filter.copyWith(name: value)),
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton.filledTonal(
|
||||
onPressed: isCurrentFilter ? null : () => provider.loadModel(filter.filter),
|
||||
icon: const Icon(IconsaxPlusBold.filter_add),
|
||||
),
|
||||
IconButton.filledTonal(
|
||||
tooltip: context.localized.defaultFilterForLibrary,
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
filter.isFavourite ? Colors.yellowAccent.shade700.withValues(alpha: 0.5) : null,
|
||||
),
|
||||
),
|
||||
onPressed: () =>
|
||||
filterProvider.saveFilter(filter.copyWith(isFavourite: !filter.isFavourite)),
|
||||
icon: Icon(
|
||||
color: filter.isFavourite ? Colors.yellowAccent : null,
|
||||
filter.isFavourite ? IconsaxPlusBold.star_1 : IconsaxPlusLinear.star_1,
|
||||
),
|
||||
),
|
||||
IconButton.filledTonal(
|
||||
tooltip: context.localized.updateFilterForLibrary,
|
||||
onPressed:
|
||||
isCurrentFilter || anyFilterSelected ? null : () => provider.updateFilter(filter),
|
||||
icon: const Icon(IconsaxPlusBold.refresh),
|
||||
),
|
||||
IconButton.filledTonal(
|
||||
tooltip: context.localized.delete,
|
||||
onPressed: () {
|
||||
showDefaultAlertDialog(
|
||||
context,
|
||||
context.localized.removeFilterForLibrary(filter.name),
|
||||
context.localized.deleteFilterConfirmation,
|
||||
(context) {
|
||||
filterProvider.removeFilter(filter);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
context.localized.delete,
|
||||
(context) {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
context.localized.cancel,
|
||||
);
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor:
|
||||
WidgetStatePropertyAll(Theme.of(context).colorScheme.errorContainer),
|
||||
iconColor: WidgetStatePropertyAll(Theme.of(context).colorScheme.onErrorContainer),
|
||||
foregroundColor:
|
||||
WidgetStatePropertyAll(Theme.of(context).colorScheme.onErrorContainer),
|
||||
),
|
||||
icon: const Icon(IconsaxPlusLinear.trash),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -129,31 +135,42 @@ class LibrarySavedFiltersDialogue extends ConsumerWidget {
|
|||
),
|
||||
const Divider(),
|
||||
],
|
||||
if (filters.length < 10)
|
||||
if (filters.length < 10 && !anyFilterSelected)
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: OutlinedTextField(
|
||||
controller: controller,
|
||||
label: context.localized.name,
|
||||
onChanged: (value) => setState(() {}),
|
||||
onSubmitted: (value) => provider.saveFiltersNew(value),
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedTextField(
|
||||
controller: controller,
|
||||
label: context.localized.name,
|
||||
onChanged: (value) => setState(() {}),
|
||||
onSubmitted: (value) => provider.saveFiltersNew(value),
|
||||
),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: controller.text.isEmpty
|
||||
? null
|
||||
: () {
|
||||
provider.saveFiltersNew(controller.text);
|
||||
},
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [Text(context.localized.save), const Icon(IconsaxPlusLinear.save_2)],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
FilledButton.tonal(
|
||||
onPressed: controller.text.isEmpty
|
||||
? null
|
||||
: () {
|
||||
provider.saveFiltersNew(controller.text);
|
||||
},
|
||||
child: const Icon(IconsaxPlusLinear.save_2),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
else
|
||||
else if (filters.length >= 10)
|
||||
Text(context.localized.libraryFiltersLimitReached),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import 'package:sliver_tools/sliver_tools.dart';
|
|||
import 'package:fladder/models/boxset_model.dart';
|
||||
import 'package:fladder/models/item_base_model.dart';
|
||||
import 'package:fladder/models/items/photos_model.dart';
|
||||
import 'package:fladder/models/library_search/library_search_model.dart';
|
||||
import 'package:fladder/models/library_search/library_search_options.dart';
|
||||
import 'package:fladder/models/playlist_model.dart';
|
||||
import 'package:fladder/providers/library_search_provider.dart';
|
||||
|
|
@ -76,7 +77,7 @@ class LibraryViews extends ConsumerWidget {
|
|||
ref.watch(clientSettingsProvider.select((value) => value.posterSize)));
|
||||
final decimal = posterSize - posterSize.toInt();
|
||||
|
||||
final sortingOptions = ref.watch(librarySearchProvider(key!).select((value) => value.sortingOption));
|
||||
final sortingOptions = ref.watch(librarySearchProvider(key!).select((value) => value.filters.sortingOption));
|
||||
|
||||
List<ItemAction> otherActions(ItemBaseModel item) {
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class _SearchBarState extends ConsumerState<SuggestionSearchBar> {
|
|||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: FladderTheme.largeShape.borderRadius,
|
||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||
),
|
||||
shadowColor: Colors.transparent,
|
||||
child: TypeAheadField<ItemBaseModel>(
|
||||
|
|
@ -83,7 +83,7 @@ class _SearchBarState extends ConsumerState<SuggestionSearchBar> {
|
|||
decorationBuilder: (context, child) => DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||
borderRadius: FladderTheme.largeShape.borderRadius,
|
||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue