#1012 show chip selection in collection via or filter

This commit is contained in:
Thibault Deckers 2024-05-30 23:32:13 +02:00
parent ece28db3f8
commit fe0c2e345b
26 changed files with 139 additions and 56 deletions

View file

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
## <a id="unreleased"></a>[Unreleased] ## <a id="unreleased"></a>[Unreleased]
### Added
- Albums / Countries / Tags: show selection in Collection
### Changed ### Changed
- Screen saver: black background, consistent with slideshow - Screen saver: black background, consistent with slideshow

View file

@ -32,7 +32,10 @@ extension ExtraAppMode on AppMode {
AppMode.pickMultipleMediaExternal, AppMode.pickMultipleMediaExternal,
}.contains(this); }.contains(this);
bool get canSelectFilter => this == AppMode.main; bool get canSelectFilter => {
AppMode.main,
AppMode.pickCollectionFiltersExternal,
}.contains(this);
bool get canCreateFilter => { bool get canCreateFilter => {
AppMode.main, AppMode.main,

View file

@ -85,6 +85,7 @@
"sourceStateLocatingPlaces": "Locating places", "sourceStateLocatingPlaces": "Locating places",
"chipActionDelete": "Delete", "chipActionDelete": "Delete",
"chipActionShowCollection": "Show in Collection",
"chipActionGoToAlbumPage": "Show in Albums", "chipActionGoToAlbumPage": "Show in Albums",
"chipActionGoToCountryPage": "Show in Countries", "chipActionGoToCountryPage": "Show in Countries",
"chipActionGoToPlacePage": "Show in Places", "chipActionGoToPlacePage": "Show in Places",

View file

@ -68,9 +68,7 @@ class AspectRatioFilter extends CollectionFilter {
} }
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.aspectRatio, size: size);
return Icon(AIcons.aspectRatio, size: size);
}
@override @override
String get category => type; String get category => type;

View file

@ -69,7 +69,7 @@ class CoordinateFilter extends CollectionFilter {
} }
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.geoBounds, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.geoBounds, size: size);
@override @override
String get category => type; String get category => type;

View file

@ -122,9 +122,7 @@ class DateFilter extends CollectionFilter {
} }
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.date, size: size);
return Icon(AIcons.date, size: size);
}
@override @override
String get category => type; String get category => type;

View file

@ -45,7 +45,7 @@ class FavouriteFilter extends CollectionFilter {
String getLabel(BuildContext context) => context.l10n.filterFavouriteLabel; String getLabel(BuildContext context) => context.l10n.filterFavouriteLabel;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.favourite, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.favourite, size: size);
@override @override
Future<Color> color(BuildContext context) { Future<Color> color(BuildContext context) {

View file

@ -10,6 +10,7 @@ import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/location.dart';
import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/filters/missing.dart'; import 'package:aves/model/filters/missing.dart';
import 'package:aves/model/filters/or.dart';
import 'package:aves/model/filters/path.dart'; import 'package:aves/model/filters/path.dart';
import 'package:aves/model/filters/placeholder.dart'; import 'package:aves/model/filters/placeholder.dart';
import 'package:aves/model/filters/query.dart'; import 'package:aves/model/filters/query.dart';
@ -43,6 +44,7 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
AspectRatioFilter.type, AspectRatioFilter.type,
MissingFilter.type, MissingFilter.type,
PathFilter.type, PathFilter.type,
OrFilter.type,
]; ];
final bool reversed; final bool reversed;
@ -68,6 +70,8 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
return MimeFilter.fromMap(jsonMap); return MimeFilter.fromMap(jsonMap);
case MissingFilter.type: case MissingFilter.type:
return MissingFilter.fromMap(jsonMap); return MissingFilter.fromMap(jsonMap);
case OrFilter.type:
return OrFilter.fromMap(jsonMap);
case PathFilter.type: case PathFilter.type:
return PathFilter.fromMap(jsonMap); return PathFilter.fromMap(jsonMap);
case PlaceholderFilter.type: case PlaceholderFilter.type:

View file

@ -89,7 +89,7 @@ class LocationFilter extends CoveredCollectionFilter {
String getLabel(BuildContext context) => _isUnlocated ? context.l10n.filterNoLocationLabel : _location; String getLabel(BuildContext context) => _isUnlocated ? context.l10n.filterNoLocationLabel : _location;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
if (_isUnlocated) { if (_isUnlocated) {
return Icon(AIcons.locationUnlocated, size: size); return Icon(AIcons.locationUnlocated, size: size);
} }

View file

@ -77,7 +77,7 @@ class MimeFilter extends CollectionFilter {
} }
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
@override @override
Future<Color> color(BuildContext context) { Future<Color> color(BuildContext context) {

View file

@ -70,7 +70,7 @@ class MissingFilter extends CollectionFilter {
} }
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
@override @override
String get category => type; String get category => type;

72
lib/model/filters/or.dart Normal file
View file

@ -0,0 +1,72 @@
import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/filters/location.dart';
import 'package:aves/theme/icons.dart';
import 'package:collection/collection.dart';
import 'package:flutter/widgets.dart';
class OrFilter extends CollectionFilter {
static const type = 'or';
late final List<CollectionFilter> _filters;
late final EntryFilter _test;
late final IconData? _genericIcon;
@override
List<Object?> get props => [_filters, reversed];
CollectionFilter get _first => _filters.first;
OrFilter(Set<CollectionFilter> filters, {super.reversed = false}) {
_filters = filters.toList().sorted();
_test = (entry) => _filters.any((v) => v.test(entry));
switch (_first) {
case AlbumFilter():
_genericIcon = AIcons.album;
case LocationFilter(level: LocationLevel.country):
_genericIcon = AIcons.country;
case LocationFilter(level: LocationLevel.state):
_genericIcon = AIcons.state;
default:
_genericIcon = null;
}
}
factory OrFilter.fromMap(Map<String, dynamic> json) {
return OrFilter(
(json['filters'] as List).cast<String>().map(CollectionFilter.fromJson).whereNotNull().toSet(),
reversed: json['reversed'] ?? false,
);
}
@override
Map<String, dynamic> toMap() => {
'type': type,
'filters': _filters.map((v) => v.toJson()).toList(),
'reversed': reversed,
};
@override
EntryFilter get positiveTest => _test;
@override
bool get exclusiveProp => false;
@override
String get universalLabel => _filters.map((v) => v.universalLabel).join(', ');
@override
String getLabel(BuildContext context) => _filters.map((v) => v.getLabel(context)).join(', ');
@override
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
return _genericIcon != null ? Icon(_genericIcon, size: size) : _first.iconBuilder(context, size, showGenericIcon: showGenericIcon);
}
@override
String get category => _first.category;
@override
String get key => '$type-$reversed-${_filters.map((v) => v.key)}';
}

View file

@ -96,7 +96,7 @@ class PlaceholderFilter extends CollectionFilter {
} }
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
@override @override
String get category => type; String get category => type;

View file

@ -82,7 +82,7 @@ class QueryFilter extends CollectionFilter {
String get universalLabel => query; String get universalLabel => query;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.text, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.text, size: size);
@override @override
Future<Color> color(BuildContext context) { Future<Color> color(BuildContext context) {

View file

@ -51,7 +51,7 @@ class RecentlyAddedFilter extends CollectionFilter {
String getLabel(BuildContext context) => context.l10n.filterRecentlyAddedLabel; String getLabel(BuildContext context) => context.l10n.filterRecentlyAddedLabel;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.dateRecent, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.dateRecent, size: size);
@override @override
String get category => type; String get category => type;

View file

@ -47,7 +47,9 @@ class TagFilter extends CoveredCollectionFilter {
String getLabel(BuildContext context) => tag.isEmpty ? context.l10n.filterNoTagLabel : tag; String getLabel(BuildContext context) => tag.isEmpty ? context.l10n.filterNoTagLabel : tag;
@override @override
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => showGenericIcon ? Icon(tag.isEmpty ? AIcons.tagUntagged : AIcons.tag, size: size) : null; Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
return showGenericIcon ? Icon(tag.isEmpty ? AIcons.tagUntagged : AIcons.tag, size: size) : null;
}
@override @override
String get category => type; String get category => type;

View file

@ -41,7 +41,7 @@ class TrashFilter extends CollectionFilter {
String getLabel(BuildContext context) => context.l10n.filterBinLabel; String getLabel(BuildContext context) => context.l10n.filterBinLabel;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.bin, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.bin, size: size);
@override @override
String get category => type; String get category => type;

View file

@ -99,7 +99,7 @@ class TypeFilter extends CollectionFilter {
} }
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size); Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
@override @override
Future<Color> color(BuildContext context) { Future<Color> color(BuildContext context) {

View file

@ -30,6 +30,7 @@ extension ExtraChipSetActionView on ChipSetAction {
ChipSetAction.unpin => l10n.chipActionUnpin, ChipSetAction.unpin => l10n.chipActionUnpin,
ChipSetAction.lockVault => l10n.chipActionLock, ChipSetAction.lockVault => l10n.chipActionLock,
ChipSetAction.showCountryStates => l10n.chipActionShowCountryStates, ChipSetAction.showCountryStates => l10n.chipActionShowCountryStates,
ChipSetAction.showCollection => l10n.chipActionShowCollection,
// selecting (single filter) // selecting (single filter)
ChipSetAction.rename => l10n.chipActionRename, ChipSetAction.rename => l10n.chipActionRename,
ChipSetAction.setCover => l10n.chipActionSetCover, ChipSetAction.setCover => l10n.chipActionSetCover,
@ -64,6 +65,7 @@ extension ExtraChipSetActionView on ChipSetAction {
ChipSetAction.unpin => AIcons.unpin, ChipSetAction.unpin => AIcons.unpin,
ChipSetAction.lockVault => AIcons.vaultLock, ChipSetAction.lockVault => AIcons.vaultLock,
ChipSetAction.showCountryStates => AIcons.state, ChipSetAction.showCountryStates => AIcons.state,
ChipSetAction.showCollection => AIcons.allCollection,
// selecting (single filter) // selecting (single filter)
ChipSetAction.rename => AIcons.name, ChipSetAction.rename => AIcons.name,
ChipSetAction.setCover => AIcons.setCover, ChipSetAction.setCover => AIcons.setCover,

View file

@ -385,7 +385,6 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
case AppMode.pickSingleMediaExternal: case AppMode.pickSingleMediaExternal:
case AppMode.pickMultipleMediaExternal: case AppMode.pickMultipleMediaExternal:
_saveTopEntries(); _saveTopEntries();
break;
default: default:
break; break;
} }
@ -393,7 +392,6 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
availability.onResume(); availability.onResume();
RecentlyAddedFilter.updateNow(); RecentlyAddedFilter.updateNow();
_mediaStoreSource.checkForChanges(); _mediaStoreSource.checkForChanges();
break;
default: default:
break; break;
} }
@ -639,10 +637,8 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
case AppMode.screenSaver: case AppMode.screenSaver:
// we cannot modify brightness without access to the activity // we cannot modify brightness without access to the activity
_screenBrightness = null; _screenBrightness = null;
break;
default: default:
_screenBrightness = ScreenBrightness(); _screenBrightness = ScreenBrightness();
break;
} }
} }
} }

View file

@ -133,16 +133,12 @@ class AvesFilterChip extends StatefulWidget {
switch (action) { switch (action) {
case ChipAction.reverse: case ChipAction.reverse:
text = filter.reversed ? context.l10n.chipActionFilterIn : context.l10n.chipActionFilterOut; text = filter.reversed ? context.l10n.chipActionFilterIn : context.l10n.chipActionFilterOut;
break;
case ChipAction.ratingOrGreater: case ChipAction.ratingOrGreater:
text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrGreater); text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrGreater);
break;
case ChipAction.ratingOrLower: case ChipAction.ratingOrLower:
text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrLower); text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrLower);
break;
default: default:
text = action.getText(context); text = action.getText(context);
break;
} }
return PopupMenuItem( return PopupMenuItem(
value: action, value: action,

View file

@ -414,10 +414,8 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
case TransformActivity.pan: case TransformActivity.pan:
case TransformActivity.resize: case TransformActivity.resize:
_gridDivisionNotifier.value = panResizeGridDivision; _gridDivisionNotifier.value = panResizeGridDivision;
break;
case TransformActivity.straighten: case TransformActivity.straighten:
_gridDivisionNotifier.value = straightenGridDivision; _gridDivisionNotifier.value = straightenGridDivision;
break;
} }
if (activity == TransformActivity.none) { if (activity == TransformActivity.none) {
_gridAnimationController.reverse(); _gridAnimationController.reverse();
@ -452,12 +450,10 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
case ChangeSource.internal: case ChangeSource.internal:
case ChangeSource.animation: case ChangeSource.animation:
_setOutline(currentOutline); _setOutline(currentOutline);
break;
case ChangeSource.gesture: case ChangeSource.gesture:
// TODO TLAD [crop] use other strat // TODO TLAD [crop] use other strat
_setOutline(_applyCropRatioToOutline(currentOutline, _RatioStrategy.contain)); _setOutline(_applyCropRatioToOutline(currentOutline, _RatioStrategy.contain));
_updateCropRegion(); _updateCropRegion();
break;
} }
} }
@ -584,19 +580,15 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
case CropAspectRatio.original: case CropAspectRatio.original:
longCoef = contentSize.longestSide.round(); longCoef = contentSize.longestSide.round();
shortCoef = contentSize.shortestSide.round(); shortCoef = contentSize.shortestSide.round();
break;
case CropAspectRatio.square: case CropAspectRatio.square:
longCoef = 1; longCoef = 1;
shortCoef = 1; shortCoef = 1;
break;
case CropAspectRatio.ar_16_9: case CropAspectRatio.ar_16_9:
longCoef = 16; longCoef = 16;
shortCoef = 9; shortCoef = 9;
break;
case CropAspectRatio.ar_4_3: case CropAspectRatio.ar_4_3:
longCoef = 4; longCoef = 4;
shortCoef = 3; shortCoef = 3;
break;
} }
final contentRect = Offset.zero & contentSize; final contentRect = Offset.zero & contentSize;

View file

@ -49,27 +49,20 @@ class Transformation extends Equatable {
break; break;
case TransformOrientation.rotate90: case TransformOrientation.rotate90:
matrix.rotateZ(math.pi / 2); matrix.rotateZ(math.pi / 2);
break;
case TransformOrientation.rotate180: case TransformOrientation.rotate180:
matrix.rotateZ(math.pi); matrix.rotateZ(math.pi);
break;
case TransformOrientation.rotate270: case TransformOrientation.rotate270:
matrix.rotateZ(3 * math.pi / 2); matrix.rotateZ(3 * math.pi / 2);
break;
case TransformOrientation.transverse: case TransformOrientation.transverse:
matrix.scale(-1.0, 1.0, 1.0); matrix.scale(-1.0, 1.0, 1.0);
matrix.rotateZ(-3 * math.pi / 2); matrix.rotateZ(-3 * math.pi / 2);
break;
case TransformOrientation.flipVertical: case TransformOrientation.flipVertical:
matrix.scale(1.0, -1.0, 1.0); matrix.scale(1.0, -1.0, 1.0);
break;
case TransformOrientation.transpose: case TransformOrientation.transpose:
matrix.scale(-1.0, 1.0, 1.0); matrix.scale(-1.0, 1.0, 1.0);
matrix.rotateZ(-1 * math.pi / 2); matrix.rotateZ(-1 * math.pi / 2);
break;
case TransformOrientation.flipHorizontal: case TransformOrientation.flipHorizontal:
matrix.scale(-1.0, 1.0, 1.0); matrix.scale(-1.0, 1.0, 1.0);
break;
} }
return matrix; return matrix;
} }

View file

@ -3,6 +3,7 @@ import 'package:aves/model/covers.dart';
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/filters/or.dart';
import 'package:aves/model/query.dart'; import 'package:aves/model/query.dart';
import 'package:aves/model/selection.dart'; import 'package:aves/model/selection.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
@ -13,6 +14,7 @@ import 'package:aves/theme/colors.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/view/view.dart'; import 'package:aves/view/view.dart';
import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart';
import 'package:aves/widgets/common/action_mixins/permission_aware.dart'; import 'package:aves/widgets/common/action_mixins/permission_aware.dart';
import 'package:aves/widgets/common/action_mixins/size_aware.dart'; import 'package:aves/widgets/common/action_mixins/size_aware.dart';
@ -99,9 +101,11 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
case ChipSetAction.hide: case ChipSetAction.hide:
return isMain; return isMain;
case ChipSetAction.pin: case ChipSetAction.pin:
return !hasSelection || !settings.pinnedFilters.containsAll(selectedFilters); return isMain && (!hasSelection || !settings.pinnedFilters.containsAll(selectedFilters));
case ChipSetAction.unpin: case ChipSetAction.unpin:
return hasSelection && settings.pinnedFilters.containsAll(selectedFilters); return isMain && (hasSelection && settings.pinnedFilters.containsAll(selectedFilters));
case ChipSetAction.showCollection:
return appMode.canNavigate;
case ChipSetAction.delete: case ChipSetAction.delete:
case ChipSetAction.lockVault: case ChipSetAction.lockVault:
case ChipSetAction.showCountryStates: case ChipSetAction.showCountryStates:
@ -149,6 +153,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
case ChipSetAction.unpin: case ChipSetAction.unpin:
case ChipSetAction.lockVault: case ChipSetAction.lockVault:
case ChipSetAction.showCountryStates: case ChipSetAction.showCountryStates:
case ChipSetAction.showCollection:
return hasSelection; return hasSelection;
// selecting (single filter) // selecting (single filter)
case ChipSetAction.rename: case ChipSetAction.rename:
@ -194,6 +199,8 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
case ChipSetAction.unpin: case ChipSetAction.unpin:
settings.pinnedFilters = settings.pinnedFilters..removeAll(getSelectedFilters(context)); settings.pinnedFilters = settings.pinnedFilters..removeAll(getSelectedFilters(context));
browse(context); browse(context);
case ChipSetAction.showCollection:
_goToCollection(context);
case ChipSetAction.delete: case ChipSetAction.delete:
case ChipSetAction.lockVault: case ChipSetAction.lockVault:
case ChipSetAction.showCountryStates: case ChipSetAction.showCountryStates:
@ -251,6 +258,22 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
} }
} }
Future<void> _goToCollection(context) async {
final filters = getSelectedFilters(context);
if (filters.isEmpty) return;
final filter = filters.length > 1 ? OrFilter(filters) : filters.first;
await Navigator.maybeOf(context)?.push(
MaterialPageRoute(
settings: const RouteSettings(name: CollectionPage.routeName),
builder: (context) => CollectionPage(
source: context.read<CollectionSource>(),
filters: {filter},
),
),
);
}
Future<void> _goToMap(BuildContext context) async { Future<void> _goToMap(BuildContext context) async {
final mapCollection = CollectionLens( final mapCollection = CollectionLens(
source: context.read<CollectionSource>(), source: context.read<CollectionSource>(),
@ -264,9 +287,9 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
); );
} }
void _goToSlideshow(BuildContext context) { Future<void> _goToSlideshow(BuildContext context) async {
final entries = _selectedEntries(context).toList(); final entries = _selectedEntries(context).toList();
Navigator.maybeOf(context)?.push( await Navigator.maybeOf(context)?.push(
MaterialPageRoute( MaterialPageRoute(
settings: const RouteSettings(name: SlideshowPage.routeName), settings: const RouteSettings(name: SlideshowPage.routeName),
builder: (context) { builder: (context) {
@ -281,9 +304,9 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
); );
} }
void _goToStats(BuildContext context) { Future<void> _goToStats(BuildContext context) async {
final entries = _selectedEntries(context).toSet(); final entries = _selectedEntries(context).toSet();
Navigator.maybeOf(context)?.push( await Navigator.maybeOf(context)?.push(
MaterialPageRoute( MaterialPageRoute(
settings: const RouteSettings(name: StatsPage.routeName), settings: const RouteSettings(name: StatsPage.routeName),
builder: (context) { builder: (context) {
@ -296,8 +319,8 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
); );
} }
void _goToSearch(BuildContext context) { Future<void> _goToSearch(BuildContext context) async {
Navigator.maybeOf(context)?.push( await Navigator.maybeOf(context)?.push(
SearchPageRoute( SearchPageRoute(
delegate: CollectionSearchDelegate( delegate: CollectionSearchDelegate(
searchFieldLabel: context.l10n.searchCollectionFieldHint, searchFieldLabel: context.l10n.searchCollectionFieldHint,

View file

@ -3,6 +3,7 @@ import 'package:aves/services/intent_service.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/filter_bar.dart'; import 'package:aves/widgets/collection/filter_bar.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/aves_caption.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SettingsCollectionTile extends StatelessWidget { class SettingsCollectionTile extends StatelessWidget {
@ -19,7 +20,6 @@ class SettingsCollectionTile extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = context.l10n; final l10n = context.l10n;
final theme = Theme.of(context); final theme = Theme.of(context);
final textTheme = theme.textTheme;
final hasSubtitle = filters.isEmpty; final hasSubtitle = filters.isEmpty;
// size and padding to match `ListTile` // size and padding to match `ListTile`
@ -39,13 +39,10 @@ class SettingsCollectionTile extends StatelessWidget {
children: [ children: [
Text( Text(
l10n.settingsCollectionTile, l10n.settingsCollectionTile,
style: textTheme.titleMedium!, // fallback to `ListTile` M3 default style
), style: theme.listTileTheme.titleTextStyle ?? theme.textTheme.bodyLarge!.copyWith(color: theme.colorScheme.onSurface),
if (hasSubtitle)
Text(
l10n.drawerCollectionAll,
style: textTheme.bodyMedium!.copyWith(color: theme.colorScheme.onSurfaceVariant),
), ),
if (hasSubtitle) AvesCaption(l10n.drawerCollectionAll),
], ],
), ),
const Spacer(), const Spacer(),

View file

@ -20,6 +20,7 @@ enum ChipSetAction {
unpin, unpin,
lockVault, lockVault,
showCountryStates, showCountryStates,
showCollection,
// selecting (single filter) // selecting (single filter)
rename, rename,
setCover, setCover,
@ -57,6 +58,7 @@ class ChipSetActions {
ChipSetAction.showCountryStates, ChipSetAction.showCountryStates,
ChipSetAction.hide, ChipSetAction.hide,
null, null,
ChipSetAction.showCollection,
ChipSetAction.map, ChipSetAction.map,
ChipSetAction.slideshow, ChipSetAction.slideshow,
ChipSetAction.stats, ChipSetAction.stats,