diff --git a/CHANGELOG.md b/CHANGELOG.md index 07929406c..3933615aa 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 + +- Search: week day filters + ### Changed - revert to Skia rendering engine diff --git a/lib/model/filters/filters.dart b/lib/model/filters/filters.dart index b7ffa40e4..bc3db189f 100644 --- a/lib/model/filters/filters.dart +++ b/lib/model/filters/filters.dart @@ -21,6 +21,7 @@ import 'package:aves/model/filters/set_and.dart'; import 'package:aves/model/filters/set_or.dart'; import 'package:aves/model/filters/trash.dart'; import 'package:aves/model/filters/type.dart'; +import 'package:aves/model/filters/weekday.dart'; import 'package:aves/theme/colors.dart'; import 'package:collection/collection.dart'; import 'package:equatable/equatable.dart'; @@ -36,11 +37,13 @@ abstract class CollectionFilter extends Equatable implements Comparable get props => [weekday, reversed]; + + WeekDayFilter(this.weekday, {super.reversed = false}) { + _test = (entry) => entry.bestDate?.weekday == weekday; + } + + factory WeekDayFilter.fromMap(Map json) { + return WeekDayFilter( + json['weekday'] as int, + reversed: json['reversed'] ?? false, + ); + } + + @override + Map toMap() => { + 'type': type, + 'weekday': weekday, + 'reversed': reversed, + }; + + @override + EntryFilter get positiveTest => _test; + + @override + bool get exclusiveProp => true; + + @override + String get universalLabel => weekday.toString(); + + @override + String getLabel(BuildContext context) { + final dateSymbols = DateFormat(null, context.locale).dateSymbols; + return dateSymbols.STANDALONEWEEKDAYS[weekday % 7]; + } + + @override + Widget? iconBuilder(BuildContext context, double size, {bool allowGenericIcon = true}) => Icon(AIcons.dateWeekday, size: size); + + @override + String get category => type; + + @override + String get key => '$type-$reversed-$weekday'; +} diff --git a/lib/theme/icons.dart b/lib/theme/icons.dart index 62b1d519e..fef92dac7 100644 --- a/lib/theme/icons.dart +++ b/lib/theme/icons.dart @@ -72,6 +72,7 @@ class AIcons { static const dateByMonth = Symbols.calendar_month; static const dateRecent = Symbols.today; static const dateUndated = Symbols.event_busy; + static const dateWeekday = Symbols.today; static const geoBounds = Symbols.public; static const location = Symbols.place; static const locationUnlocated = Symbols.location_off; diff --git a/lib/widgets/search/search_delegate.dart b/lib/widgets/search/search_delegate.dart index 0aab58689..3b8fc2527 100644 --- a/lib/widgets/search/search_delegate.dart +++ b/lib/widgets/search/search_delegate.dart @@ -15,6 +15,7 @@ import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/recent.dart'; import 'package:aves/model/filters/set_and.dart'; import 'package:aves/model/filters/type.dart'; +import 'package:aves/model/filters/weekday.dart'; import 'package:aves/model/grouping/common.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/album.dart'; @@ -67,6 +68,7 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va ]; static final _monthFilters = List.generate(12, (i) => DateFilter(DateLevel.m, DateTime(1, i + 1))); + static final _weekdayFilters = List.generate(7, (i) => WeekDayFilter(i + 1)); CollectionSearchDelegate({ required super.searchFieldLabel, @@ -200,6 +202,7 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va DateFilter.onThisDay, RecentlyAddedFilter.instance, ..._monthFilters, + ..._weekdayFilters, ].where((f) => containQuery(f.getLabel(context))).toList(); return _buildFilterRow( context: context, diff --git a/lib/widgets/viewer/info/basic_section.dart b/lib/widgets/viewer/info/basic_section.dart index f3d91ccf5..8d1429fbe 100644 --- a/lib/widgets/viewer/info/basic_section.dart +++ b/lib/widgets/viewer/info/basic_section.dart @@ -13,6 +13,7 @@ import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/type.dart'; +import 'package:aves/model/filters/weekday.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/ref/mime_types.dart'; @@ -130,7 +131,7 @@ class _BasicSectionState extends State { if (entry.isImage && entry.is360) TypeFilter.panorama, if (entry.isPureVideo && entry.is360) TypeFilter.sphericalVideo, if (entry.isPureVideo && !entry.is360) MimeFilter.video, - if (dateTime != null) DateFilter(DateLevel.ymd, dateTime.date), + if (dateTime != null) ...[DateFilter(DateLevel.ymd, dateTime.date), WeekDayFilter(dateTime.weekday)], if (album != null) StoredAlbumFilter(album, collection?.source.getStoredAlbumDisplayName(context, album)), if (entry.rating != 0) RatingFilter(entry.rating), ...tags.map(TagFilter.new), diff --git a/test/model/filters_test.dart b/test/model/filters_test.dart index 85b7e9ece..c34dc5d88 100644 --- a/test/model/filters_test.dart +++ b/test/model/filters_test.dart @@ -18,6 +18,7 @@ import 'package:aves/model/filters/recent.dart'; import 'package:aves/model/filters/set_and.dart'; import 'package:aves/model/filters/set_or.dart'; import 'package:aves/model/filters/type.dart'; +import 'package:aves/model/filters/weekday.dart'; import 'package:aves/model/grouping/common.dart'; import 'package:aves/services/common/services.dart'; import 'package:latlong2/latlong.dart'; @@ -80,6 +81,9 @@ void main() { final type = TypeFilter.sphericalVideo; expect(type, jsonRoundTrip(type)); + final weekday = WeekDayFilter(5); + expect(weekday, jsonRoundTrip(weekday)); + // covered final album = StoredAlbumFilter('path/to/album', 'album');