diff --git a/CHANGELOG.md b/CHANGELOG.md index 76754fc1e..a5edbeb38 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 + +- Collection: `select all` available as quick action + ## [v1.11.0] - 2024-05-01 ### Added diff --git a/lib/model/selection.dart b/lib/model/selection.dart index f26d0c4d9..b49ffdc0d 100644 --- a/lib/model/selection.dart +++ b/lib/model/selection.dart @@ -28,12 +28,15 @@ class Selection extends ChangeNotifier { void addToSelection(Iterable items) { if (items.isEmpty) return; + + select(); _selectedItems.addAll(items); notifyListeners(); } void removeFromSelection(Iterable items) { if (items.isEmpty) return; + _selectedItems.removeAll(items); notifyListeners(); } diff --git a/lib/widgets/collection/app_bar.dart b/lib/widgets/collection/app_bar.dart index 20aa7c3d8..30b19b9d4 100644 --- a/lib/widgets/collection/app_bar.dart +++ b/lib/widgets/collection/app_bar.dart @@ -379,7 +379,8 @@ class _CollectionAppBarState extends State with SingleTickerPr final browsingQuickActions = settings.collectionBrowsingQuickActions; final selectionQuickActions = isTrash ? [EntrySetAction.delete, EntrySetAction.restore] : settings.collectionSelectionQuickActions; - final quickActionButtons = (isSelecting ? selectionQuickActions : browsingQuickActions).where(isVisible).map( + final quickActions = isSelecting ? selectionQuickActions : browsingQuickActions; + final quickActionButtons = quickActions.where(isVisible).map( (action) => _buildButtonIcon(context, action, enabled: canApply(action), selection: selection), ); @@ -390,13 +391,13 @@ class _CollectionAppBarState extends State with SingleTickerPr // key is expected by test driver key: const Key('appbar-menu-button'), itemBuilder: (context) { - final generalMenuItems = EntrySetActions.general.where(isVisible).map( + bool _isValidForMenu(EntrySetAction? v) => v == null || (!quickActions.contains(v) && isVisible(v)); + final generalMenuItems = EntrySetActions.general.where(_isValidForMenu).map( (action) => _toMenuItem(action, enabled: canApply(action), selection: selection), ); - final browsingMenuActions = EntrySetActions.pageBrowsing.where((v) => !browsingQuickActions.contains(v)); - final selectionMenuActions = EntrySetActions.pageSelection.where((v) => !selectionQuickActions.contains(v)); - final contextualMenuActions = (isSelecting ? selectionMenuActions : browsingMenuActions).where((v) => v == null || isVisible(v)).fold([], (prev, v) { + final allContextualActions = isSelecting ? EntrySetActions.pageSelection: EntrySetActions.pageBrowsing; + final contextualMenuActions = allContextualActions.where(_isValidForMenu).fold([], (prev, v) { if (v == null && (prev.isEmpty || prev.last == null)) return prev; return [...prev, v]; }); diff --git a/lib/widgets/collection/entry_set_action_delegate.dart b/lib/widgets/collection/entry_set_action_delegate.dart index 3abf41f8c..23f444808 100644 --- a/lib/widgets/collection/entry_set_action_delegate.dart +++ b/lib/widgets/collection/entry_set_action_delegate.dart @@ -66,7 +66,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware case EntrySetAction.select: return appMode.canSelectMedia && !isSelecting; case EntrySetAction.selectAll: - return isSelecting && selectedItemCount < itemCount; + return (isSelecting && selectedItemCount < itemCount) || (!isSelecting && settings.collectionBrowsingQuickActions.contains(action)); case EntrySetAction.selectNone: return isSelecting && selectedItemCount == itemCount; // browsing @@ -127,7 +127,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware case EntrySetAction.select: return hasItems; case EntrySetAction.selectAll: - return selectedItemCount < itemCount; + return selectedItemCount < itemCount || (!isSelecting && settings.collectionBrowsingQuickActions.contains(action)); case EntrySetAction.selectNone: return hasSelection; case EntrySetAction.searchCollection: diff --git a/lib/widgets/settings/privacy/hidden_items_page.dart b/lib/widgets/settings/privacy/hidden_items_page.dart index 5006f979c..2d88c27d3 100644 --- a/lib/widgets/settings/privacy/hidden_items_page.dart +++ b/lib/widgets/settings/privacy/hidden_items_page.dart @@ -102,7 +102,6 @@ class _HiddenFilters extends StatelessWidget { children: [ Expanded( child: LayoutBuilder(builder: (context, constraints) { - debugPrint('TLAD constraints=$constraints'); return Row( children: [ AvesFilterChip( diff --git a/lib/widgets/settings/thumbnails/collection_actions_editor_page.dart b/lib/widgets/settings/thumbnails/collection_actions_editor_page.dart index c16762cd7..0741b39c5 100644 --- a/lib/widgets/settings/thumbnails/collection_actions_editor_page.dart +++ b/lib/widgets/settings/thumbnails/collection_actions_editor_page.dart @@ -19,7 +19,9 @@ class CollectionActionEditorPage extends StatelessWidget { Tab(text: l10n.settingsCollectionQuickActionTabBrowsing), QuickActionEditorBody( bannerText: context.l10n.settingsCollectionBrowsingQuickActionEditorBanner, - allAvailableActions: const [EntrySetActions.collectionEditorBrowsing], + allAvailableActions: const [ + EntrySetActions.collectionEditorBrowsing, + ], actionIcon: (action) => action.getIcon(), actionText: (context, action) => action.getText(context), load: () => settings.collectionBrowsingQuickActions, diff --git a/plugins/aves_model/lib/src/actions/entry_set.dart b/plugins/aves_model/lib/src/actions/entry_set.dart index 0cf289223..171497d6a 100644 --- a/plugins/aves_model/lib/src/actions/entry_set.dart +++ b/plugins/aves_model/lib/src/actions/entry_set.dart @@ -65,6 +65,8 @@ class EntrySetActions { EntrySetAction.map, EntrySetAction.slideshow, EntrySetAction.stats, + // only available as a quick action + EntrySetAction.selectAll, ]; // `null` items are converted to dividers @@ -98,6 +100,7 @@ class EntrySetActions { EntrySetAction.map, EntrySetAction.slideshow, EntrySetAction.stats, + EntrySetAction.selectAll, // editing actions are in their subsection ];