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');