diff --git a/CHANGELOG.md b/CHANGELOG.md index e6ef22be9..5a91a5711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- dynamic album decompose action + ## [v1.12.0] - 2024-12-19 ### Added diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a04876369..7ab3fc430 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -92,6 +92,7 @@ "chipActionGoToPlacePage": "Show in Places", "chipActionGoToTagPage": "Show in Tags", "chipActionGoToExplorerPage": "Show in Explorer", + "chipActionDecompose": "Split", "chipActionFilterOut": "Filter out", "chipActionFilterIn": "Filter in", "chipActionHide": "Hide", diff --git a/lib/model/filters/set_and.dart b/lib/model/filters/set_and.dart index ca4aea296..225bb2689 100644 --- a/lib/model/filters/set_and.dart +++ b/lib/model/filters/set_and.dart @@ -18,6 +18,8 @@ class SetAndFilter extends CollectionFilter { CollectionFilter get _first => _filters.first; + Set get innerFilters => _filters.toSet(); + SetAndFilter(Set filters, {super.reversed = false}) { _filters = filters.toList().sorted(); _test = (entry) => _filters.every((v) => v.test(entry)); diff --git a/lib/model/source/collection_lens.dart b/lib/model/source/collection_lens.dart index 81d3bed0d..c77ddfef4 100644 --- a/lib/model/source/collection_lens.dart +++ b/lib/model/source/collection_lens.dart @@ -167,10 +167,12 @@ class CollectionLens with ChangeNotifier { } } - void addFilter(CollectionFilter filter) { - if (filters.contains(filter)) return; - filters.removeWhere((other) => !filter.isCompatible(other)); - filters.add(filter); + void addFilters(Set newFilters) { + if (filters.containsAll(newFilters)) return; + for (final filter in newFilters) { + filters.removeWhere((other) => !filter.isCompatible(other)); + } + filters.addAll(newFilters); _onFilterChanged(); } diff --git a/lib/theme/icons.dart b/lib/theme/icons.dart index 031788e88..25aa0b918 100644 --- a/lib/theme/icons.dart +++ b/lib/theme/icons.dart @@ -145,6 +145,7 @@ class AIcons { static final showFullscreenArrows = MdiIcons.arrowExpand; static const showFullscreenCorners = Icons.fullscreen_outlined; static const slideshow = Icons.slideshow_outlined; + static const split = Icons.call_split_outlined; static const stats = Icons.donut_small_outlined; static const vaultLock = Icons.lock_outlined; static const vaultAdd = Icons.enhanced_encryption_outlined; diff --git a/lib/view/src/actions/chip.dart b/lib/view/src/actions/chip.dart index 75b0f5ed6..03afd4455 100644 --- a/lib/view/src/actions/chip.dart +++ b/lib/view/src/actions/chip.dart @@ -16,6 +16,7 @@ extension ExtraChipActionView on ChipAction { ChipAction.ratingOrLower => // different data depending on state toString(), + ChipAction.decompose => l10n.chipActionDecompose, ChipAction.reverse => // different data depending on state l10n.chipActionFilterOut, @@ -33,6 +34,7 @@ extension ExtraChipActionView on ChipAction { ChipAction.goToTagPage => AIcons.tag, ChipAction.goToExplorerPage => AIcons.explorer, ChipAction.ratingOrGreater || ChipAction.ratingOrLower => AIcons.rating, + ChipAction.decompose => AIcons.split, ChipAction.reverse => AIcons.reverse, ChipAction.hide => AIcons.hide, ChipAction.lockVault => AIcons.vaultLock, diff --git a/lib/widgets/collection/app_bar.dart b/lib/widgets/collection/app_bar.dart index 89f921856..8946e9504 100644 --- a/lib/widgets/collection/app_bar.dart +++ b/lib/widgets/collection/app_bar.dart @@ -3,8 +3,10 @@ import 'dart:math'; import 'package:aves/app_mode.dart'; import 'package:aves/model/entry/entry.dart'; +import 'package:aves/model/filters/covered/dynamic_album.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/query.dart'; +import 'package:aves/model/filters/set_and.dart'; import 'package:aves/model/filters/trash.dart'; import 'package:aves/model/query.dart'; import 'package:aves/model/selection.dart'; @@ -33,8 +35,8 @@ import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/search/route.dart'; import 'package:aves/widgets/common/tile_extent_controller.dart'; import 'package:aves/widgets/dialogs/tile_view_dialog.dart'; -import 'package:aves/widgets/filter_grids/common/action_delegates/chip.dart'; import 'package:aves/widgets/search/search_delegate.dart'; +import 'package:aves/widgets/viewer/controls/notifications.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; @@ -199,10 +201,22 @@ class _CollectionAppBarState extends State with SingleTickerPr ), ), if (showFilterBar) - NotificationListener( + NotificationListener( onNotification: (notification) { - collection.addFilter(notification.filter); - return true; + if (notification is SelectFilterNotification) { + collection.addFilters({notification.filter}); + return true; + } else if (notification is DecomposeFilterNotification) { + final filter = notification.filter; + if (filter is DynamicAlbumFilter) { + final innerFilter = filter.filter; + final newFilters = innerFilter is SetAndFilter ? innerFilter.innerFilters : {innerFilter}; + collection.addFilters(newFilters); + collection.removeFilter(filter); + return true; + } + } + return false; }, child: FilterBar( filters: visibleFilters, diff --git a/lib/widgets/common/identity/aves_filter_chip.dart b/lib/widgets/common/identity/aves_filter_chip.dart index 4e33ce13c..e9c9ddd35 100644 --- a/lib/widgets/common/identity/aves_filter_chip.dart +++ b/lib/widgets/common/identity/aves_filter_chip.dart @@ -3,12 +3,8 @@ import 'dart:math'; import 'package:aves/app_mode.dart'; import 'package:aves/model/covers.dart'; -import 'package:aves/model/filters/covered/stored_album.dart'; import 'package:aves/model/filters/filters.dart'; -import 'package:aves/model/filters/covered/location.dart'; -import 'package:aves/model/filters/path.dart'; import 'package:aves/model/filters/rating.dart'; -import 'package:aves/model/filters/covered/tag.dart'; import 'package:aves/model/settings/enums/accessibility_animations.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/colors.dart'; @@ -101,21 +97,6 @@ class AvesFilterChip extends StatefulWidget { static Future showDefaultLongPressMenu(BuildContext context, CollectionFilter filter, Offset tapPosition) async { if (context.read>().value.canNavigate) { - final actions = [ - if (filter is AlbumBaseFilter) ChipAction.goToAlbumPage, - if (filter is StoredAlbumFilter || filter is PathFilter) ChipAction.goToExplorerPage, - if ((filter is LocationFilter && filter.level == LocationLevel.country)) ChipAction.goToCountryPage, - if ((filter is LocationFilter && filter.level == LocationLevel.place)) ChipAction.goToPlacePage, - if (filter is TagFilter) ChipAction.goToTagPage, - if (filter is RatingFilter && 1 < filter.rating && filter.rating < 5) ...[ - if (filter.op != RatingFilter.opOrGreater) ChipAction.ratingOrGreater, - if (filter.op != RatingFilter.opOrLower) ChipAction.ratingOrLower, - ], - ChipAction.reverse, - ChipAction.hide, - ChipAction.lockVault, - ]; - // remove focus, if any, to prevent the keyboard from showing up // after the user is done with the popup menu FocusManager.instance.primaryFocus?.unfocus(); @@ -132,7 +113,7 @@ class AvesFilterChip extends StatefulWidget { child: Text(filter.getLabel(context)), ), const PopupMenuDivider(), - ...actions.where((action) => actionDelegate.isVisible(action, filter: filter)).map((action) { + ...ChipAction.values.where((action) => actionDelegate.isVisible(action, filter: filter)).map((action) { late String text; switch (action) { case ChipAction.reverse: diff --git a/lib/widgets/common/map/buttons/coordinate_filter.dart b/lib/widgets/common/map/buttons/coordinate_filter.dart index df2f3661b..80405f34c 100644 --- a/lib/widgets/common/map/buttons/coordinate_filter.dart +++ b/lib/widgets/common/map/buttons/coordinate_filter.dart @@ -92,7 +92,7 @@ class _OverlayCoordinateFilterChipState extends State FilterSelectedNotification(CoordinateFilter(bounds.sw, bounds.ne)).dispatch(context), + onTap: (filter) => SelectFilterNotification(CoordinateFilter(bounds.sw, bounds.ne)).dispatch(context), ), ), ); diff --git a/lib/widgets/explorer/explorer_action_delegate.dart b/lib/widgets/explorer/explorer_action_delegate.dart index f97a8438f..3d8641c69 100644 --- a/lib/widgets/explorer/explorer_action_delegate.dart +++ b/lib/widgets/explorer/explorer_action_delegate.dart @@ -97,7 +97,12 @@ class ExplorerActionDelegate with FeedbackMixin { } void _hide(BuildContext context) { - ChipActionDelegate().onActionSelected(context, _getPathFilter(), ChipAction.hide); + final chipActionDelegate = ChipActionDelegate(); + const action = ChipAction.hide; + final pathFilter = _getPathFilter(); + if (chipActionDelegate.isVisible(action, filter: pathFilter)) { + chipActionDelegate.onActionSelected(context, pathFilter, action); + } } void _goToStats(BuildContext context) { diff --git a/lib/widgets/filter_grids/common/action_delegates/chip.dart b/lib/widgets/filter_grids/common/action_delegates/chip.dart index 7f05b7fb5..c250ee3ee 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip.dart @@ -1,4 +1,7 @@ +import 'package:aves/model/filters/covered/dynamic_album.dart'; +import 'package:aves/model/filters/covered/location.dart'; import 'package:aves/model/filters/covered/stored_album.dart'; +import 'package:aves/model/filters/covered/tag.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/path.dart'; import 'package:aves/model/filters/rating.dart'; @@ -15,6 +18,7 @@ import 'package:aves/widgets/filter_grids/albums_page.dart'; import 'package:aves/widgets/filter_grids/countries_page.dart'; import 'package:aves/widgets/filter_grids/places_page.dart'; import 'package:aves/widgets/filter_grids/tags_page.dart'; +import 'package:aves/widgets/viewer/controls/notifications.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -26,12 +30,21 @@ class ChipActionDelegate with FeedbackMixin, VaultAwareMixin { }) { switch (action) { case ChipAction.goToAlbumPage: + return filter is AlbumBaseFilter; case ChipAction.goToCountryPage: + return filter is LocationFilter && filter.level == LocationLevel.country; case ChipAction.goToPlacePage: + return filter is LocationFilter && filter.level == LocationLevel.place; case ChipAction.goToTagPage: + return filter is TagFilter; case ChipAction.goToExplorerPage: + return filter is StoredAlbumFilter || filter is PathFilter; case ChipAction.ratingOrGreater: + return filter is RatingFilter && 1 < filter.rating && filter.rating < 5 && filter.op != RatingFilter.opOrGreater; case ChipAction.ratingOrLower: + return filter is RatingFilter && 1 < filter.rating && filter.rating < 5 && filter.op != RatingFilter.opOrLower; + case ChipAction.decompose: + return filter is DynamicAlbumFilter; case ChipAction.reverse: return true; case ChipAction.hide: @@ -69,11 +82,13 @@ class ChipActionDelegate with FeedbackMixin, VaultAwareMixin { ); } case ChipAction.ratingOrGreater: - FilterNotification((filter as RatingFilter).copyWith(RatingFilter.opOrGreater)).dispatch(context); + SelectFilterNotification((filter as RatingFilter).copyWith(RatingFilter.opOrGreater)).dispatch(context); case ChipAction.ratingOrLower: - FilterNotification((filter as RatingFilter).copyWith(RatingFilter.opOrLower)).dispatch(context); + SelectFilterNotification((filter as RatingFilter).copyWith(RatingFilter.opOrLower)).dispatch(context); + case ChipAction.decompose: + DecomposeFilterNotification(filter).dispatch(context); case ChipAction.reverse: - FilterNotification(filter.reverse()).dispatch(context); + SelectFilterNotification(filter.reverse()).dispatch(context); case ChipAction.hide: _hide(context, filter); case ChipAction.lockVault: @@ -119,10 +134,3 @@ class ChipActionDelegate with FeedbackMixin, VaultAwareMixin { settings.changeFilterVisibility({filter}, false); } } - -@immutable -class FilterNotification extends Notification { - final CollectionFilter filter; - - const FilterNotification(this.filter); -} diff --git a/lib/widgets/map/map_page.dart b/lib/widgets/map/map_page.dart index 4d4743f49..0dad07d20 100644 --- a/lib/widgets/map/map_page.dart +++ b/lib/widgets/map/map_page.dart @@ -4,8 +4,8 @@ import 'package:aves/app_mode.dart'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/extensions/location.dart'; import 'package:aves/model/filters/coordinate.dart'; -import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/covered/location.dart'; +import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/highlight.dart'; import 'package:aves/model/media/geotiff.dart'; import 'package:aves/model/settings/enums/accessibility_animations.dart'; @@ -31,7 +31,6 @@ import 'package:aves/widgets/common/map/map_action_delegate.dart'; import 'package:aves/widgets/common/providers/highlight_info_provider.dart'; import 'package:aves/widgets/common/providers/map_theme_provider.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart'; -import 'package:aves/widgets/filter_grids/common/action_delegates/chip.dart'; import 'package:aves/widgets/map/scroller.dart'; import 'package:aves/widgets/viewer/controls/notifications.dart'; import 'package:aves/widgets/viewer/entry_viewer_page.dart'; @@ -203,9 +202,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin Widget build(BuildContext context) { return NotificationListener( onNotification: (notification) { - if (notification is FilterSelectedNotification) { - _goToCollection(notification.filter); - } else if (notification is FilterNotification) { + if (notification is SelectFilterNotification) { _goToCollection(notification.filter); } else if (notification is OpenMapAppNotification) { _openMapApp(); diff --git a/lib/widgets/search/search_delegate.dart b/lib/widgets/search/search_delegate.dart index d648f4b57..e73acf4bc 100644 --- a/lib/widgets/search/search_delegate.dart +++ b/lib/widgets/search/search_delegate.dart @@ -1,16 +1,18 @@ import 'package:aves/model/dynamic_albums.dart'; -import 'package:aves/model/filters/covered/stored_album.dart'; import 'package:aves/model/filters/aspect_ratio.dart'; +import 'package:aves/model/filters/covered/dynamic_album.dart'; +import 'package:aves/model/filters/covered/location.dart'; +import 'package:aves/model/filters/covered/stored_album.dart'; +import 'package:aves/model/filters/covered/tag.dart'; import 'package:aves/model/filters/date.dart'; import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/filters.dart'; -import 'package:aves/model/filters/covered/location.dart'; import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/missing.dart'; import 'package:aves/model/filters/query.dart'; import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/recent.dart'; -import 'package:aves/model/filters/covered/tag.dart'; +import 'package:aves/model/filters/set_and.dart'; import 'package:aves/model/filters/type.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/album.dart'; @@ -29,7 +31,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/search/delegate.dart'; import 'package:aves/widgets/common/search/page.dart'; -import 'package:aves/widgets/filter_grids/common/action_delegates/chip.dart'; +import 'package:aves/widgets/viewer/controls/notifications.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -91,10 +93,21 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va final upQuery = query.trim().toUpperCase(); bool containQuery(String s) => s.toUpperCase().contains(upQuery); return SafeArea( - child: NotificationListener( + child: NotificationListener( onNotification: (notification) { - _select(context, notification.filter); - return true; + if (notification is SelectFilterNotification) { + _select(context, {notification.filter}); + return true; + } else if (notification is DecomposeFilterNotification) { + final filter = notification.filter; + if (filter is DynamicAlbumFilter) { + final innerFilter = filter.filter; + final newFilters = innerFilter is SetAndFilter ? innerFilter.innerFilters : {innerFilter}; + _select(context, newFilters); + return true; + } + } + return false; }, child: ValueListenableBuilder( valueListenable: _expandedSectionNotifier, @@ -159,7 +172,7 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va required List filters, HeroType Function(CollectionFilter filter)? heroTypeBuilder, }) { - void onTap(filter) => _select(context, filter is QueryFilter ? QueryFilter(filter.query) : filter); + void onTap(filter) => _select(context, {filter is QueryFilter ? QueryFilter(filter.query) : filter}); const onLongPress = AvesFilterChip.showDefaultLongPressMenu; return title != null ? TitledExpandableFilterRow( @@ -303,7 +316,7 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va // `buildResults` is called in the build phase, // so we post the call that will filter the collection // and possibly trigger a rebuild here - _select(context, _buildQueryFilter(true)); + _select(context, {_buildQueryFilter(true)}); }); } return const SizedBox(); @@ -314,29 +327,33 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va return cleanQuery.isNotEmpty ? QueryFilter(cleanQuery, colorful: colorful) : null; } - Future _select(BuildContext context, CollectionFilter? filter) async { - if (filter == null) { + Future _select(BuildContext context, Set filters) async { + final newFilters = filters.nonNulls.toSet(); + if (newFilters.isEmpty) { goBack(context); return; } - if (!await unlockFilter(context, filter)) return; + for (final filter in newFilters) { + if (!await unlockFilter(context, filter)) return; - if (settings.saveSearchHistory) { - final history = settings.searchHistory - ..remove(filter) - ..insert(0, filter); - settings.searchHistory = history.take(searchHistoryCount).toList(); + if (settings.saveSearchHistory) { + final history = settings.searchHistory + ..remove(filter) + ..insert(0, filter); + settings.searchHistory = history.take(searchHistoryCount).toList(); + } } + if (parentCollection != null) { - _applyToParentCollectionPage(context, filter); + _applyToParentCollectionPage(context, newFilters); } else { - _jumpToCollectionPage(context, {filter}); + _jumpToCollectionPage(context, newFilters); } } - void _applyToParentCollectionPage(BuildContext context, CollectionFilter filter) { - parentCollection!.addFilter(filter); + void _applyToParentCollectionPage(BuildContext context, Set filters) { + parentCollection!.addFilters(filters); if (Navigator.canPop(context)) { // We delay closing the current page after applying the filter selection // so that hero animation target is ready in the `FilterBar`, diff --git a/lib/widgets/stats/stats_page.dart b/lib/widgets/stats/stats_page.dart index 8100e3ce1..64dc0dd92 100644 --- a/lib/widgets/stats/stats_page.dart +++ b/lib/widgets/stats/stats_page.dart @@ -1,11 +1,11 @@ import 'dart:async'; import 'package:aves/model/entry/entry.dart'; -import 'package:aves/model/filters/covered/stored_album.dart'; -import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/covered/location.dart'; -import 'package:aves/model/filters/rating.dart'; +import 'package:aves/model/filters/covered/stored_album.dart'; import 'package:aves/model/filters/covered/tag.dart'; +import 'package:aves/model/filters/filters.dart'; +import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; @@ -24,11 +24,11 @@ import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/media_query.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/empty.dart'; -import 'package:aves/widgets/filter_grids/common/action_delegates/chip.dart'; import 'package:aves/widgets/stats/date/histogram.dart'; import 'package:aves/widgets/stats/filter_table.dart'; import 'package:aves/widgets/stats/mime_donut.dart'; import 'package:aves/widgets/stats/percent_text.dart'; +import 'package:aves/widgets/viewer/controls/notifications.dart'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; @@ -172,7 +172,7 @@ class _StatsPageState extends State with FeedbackMixin, VaultAwareMix ], ), ); - child = NotificationListener( + child = NotificationListener( onNotification: (notification) { _onFilterSelection(context, notification.filter); return true; @@ -336,7 +336,7 @@ class _StatsPageState extends State with FeedbackMixin, VaultAwareMix } void _applyToParentCollectionPage(BuildContext context, CollectionFilter filter) { - widget.parentCollection!.addFilter(filter); + widget.parentCollection!.addFilters({filter}); // We delay closing the current page after applying the filter selection // so that hero animation target is ready in the `FilterBar`, // even when the target is a child of an `AnimatedList`. @@ -384,7 +384,7 @@ class StatsTopPage extends StatelessWidget { child: SafeArea( bottom: false, child: Builder(builder: (context) { - return NotificationListener( + return NotificationListener( onNotification: (notification) { onFilterSelection(notification.filter); return true; diff --git a/lib/widgets/viewer/controls/notifications.dart b/lib/widgets/viewer/controls/notifications.dart index ab9c78fa3..29ac67f68 100644 --- a/lib/widgets/viewer/controls/notifications.dart +++ b/lib/widgets/viewer/controls/notifications.dart @@ -89,13 +89,23 @@ class CastNotification extends Notification with EquatableMixin { } @immutable -class FilterSelectedNotification extends Notification with EquatableMixin { +class SelectFilterNotification extends Notification with EquatableMixin { final CollectionFilter filter; @override List get props => [filter]; - const FilterSelectedNotification(this.filter); + const SelectFilterNotification(this.filter); +} + +@immutable +class DecomposeFilterNotification extends Notification with EquatableMixin { + final CollectionFilter filter; + + @override + List get props => [filter]; + + const DecomposeFilterNotification(this.filter); } @immutable diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index 752fbff57..456db9b6b 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -564,7 +564,7 @@ class _EntryViewerStackState extends State with EntryViewContr } bool _handleNotification(dynamic notification) { - if (notification is FilterSelectedNotification) { + if (notification is SelectFilterNotification) { _goToCollection(notification.filter); } else if (notification is CastNotification) { _cast(notification.enabled); diff --git a/lib/widgets/viewer/info/info_page.dart b/lib/widgets/viewer/info/info_page.dart index 8e123b58b..551c4a2ee 100644 --- a/lib/widgets/viewer/info/info_page.dart +++ b/lib/widgets/viewer/info/info_page.dart @@ -10,7 +10,6 @@ import 'package:aves/theme/durations.dart'; import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/basic/tv_edge_focus.dart'; -import 'package:aves/widgets/filter_grids/common/action_delegates/chip.dart'; import 'package:aves/widgets/viewer/action/entry_info_action_delegate.dart'; import 'package:aves/widgets/viewer/controls/notifications.dart'; import 'package:aves/widgets/viewer/info/basic_section.dart'; @@ -235,7 +234,7 @@ class _InfoPageContentState extends State<_InfoPageContent> { ), ); - return NotificationListener( + return NotificationListener( onNotification: (notification) { _onFilter(notification.filter); return true; @@ -288,6 +287,6 @@ class _InfoPageContentState extends State<_InfoPageContent> { void _onFilter(CollectionFilter filter) { if (!mounted) return; - FilterSelectedNotification(filter).dispatch(context); + SelectFilterNotification(filter).dispatch(context); } } diff --git a/plugins/aves_model/lib/src/actions/chip.dart b/plugins/aves_model/lib/src/actions/chip.dart index a035ef5cf..b2b119c8f 100644 --- a/plugins/aves_model/lib/src/actions/chip.dart +++ b/plugins/aves_model/lib/src/actions/chip.dart @@ -6,6 +6,7 @@ enum ChipAction { goToExplorerPage, ratingOrGreater, ratingOrLower, + decompose, reverse, hide, lockVault,