diff --git a/lib/model/filters/album.dart b/lib/model/filters/album.dart index 21c912c89..ec48d627b 100644 --- a/lib/model/filters/album.dart +++ b/lib/model/filters/album.dart @@ -32,7 +32,7 @@ class AlbumFilter extends CollectionFilter { }; @override - EntryFilter get filter => (entry) => entry.directory == album; + EntryFilter get test => (entry) => entry.directory == album; @override String get label => uniqueName ?? album.split(separator).last; diff --git a/lib/model/filters/favourite.dart b/lib/model/filters/favourite.dart index 5d17006c9..348bb4aeb 100644 --- a/lib/model/filters/favourite.dart +++ b/lib/model/filters/favourite.dart @@ -12,7 +12,7 @@ class FavouriteFilter extends CollectionFilter { }; @override - EntryFilter get filter => (entry) => entry.isFavourite; + EntryFilter get test => (entry) => entry.isFavourite; @override String get label => 'Favourite'; diff --git a/lib/model/filters/filters.dart b/lib/model/filters/filters.dart index 1c9ce5aad..be2e18149 100644 --- a/lib/model/filters/filters.dart +++ b/lib/model/filters/filters.dart @@ -49,7 +49,7 @@ abstract class CollectionFilter implements Comparable { String toJson() => jsonEncode(toMap()); - EntryFilter get filter; + EntryFilter get test; bool get isUnique => true; @@ -75,7 +75,6 @@ abstract class CollectionFilter implements Comparable { } } -// TODO TLAD replace this by adding getters to CollectionFilter, with cached entry/count coming from Source class FilterGridItem { final T filter; final AvesEntry entry; diff --git a/lib/model/filters/location.dart b/lib/model/filters/location.dart index 79e515ce1..1d596cba4 100644 --- a/lib/model/filters/location.dart +++ b/lib/model/filters/location.dart @@ -11,7 +11,7 @@ class LocationFilter extends CollectionFilter { final LocationLevel level; String _location; String _countryCode; - EntryFilter _filter; + EntryFilter _test; LocationFilter(this.level, this._location) { final split = _location.split(locationSeparator); @@ -19,11 +19,11 @@ class LocationFilter extends CollectionFilter { if (split.length > 1) _countryCode = split[1]; if (_location.isEmpty) { - _filter = (entry) => !entry.isLocated; + _test = (entry) => !entry.isLocated; } else if (level == LocationLevel.country) { - _filter = (entry) => entry.addressDetails?.countryCode == _countryCode; + _test = (entry) => entry.addressDetails?.countryCode == _countryCode; } else if (level == LocationLevel.place) { - _filter = (entry) => entry.addressDetails?.place == _location; + _test = (entry) => entry.addressDetails?.place == _location; } } @@ -45,7 +45,7 @@ class LocationFilter extends CollectionFilter { String get countryCode => _countryCode; @override - EntryFilter get filter => _filter; + EntryFilter get test => _test; @override String get label => _location.isEmpty ? emptyLabel : _location; diff --git a/lib/model/filters/mime.dart b/lib/model/filters/mime.dart index be6b5f4be..ef21fe65c 100644 --- a/lib/model/filters/mime.dart +++ b/lib/model/filters/mime.dart @@ -14,31 +14,31 @@ class MimeFilter extends CollectionFilter { static const geotiff = 'aves/geotiff'; // subset of `image/tiff` final String mime; - EntryFilter _filter; + EntryFilter _test; String _label; IconData _icon; MimeFilter(this.mime) { var lowMime = mime.toLowerCase(); if (mime == animated) { - _filter = (entry) => entry.isAnimated; + _test = (entry) => entry.isAnimated; _label = 'Animated'; _icon = AIcons.animated; } else if (mime == panorama) { - _filter = (entry) => entry.isImage && entry.is360; + _test = (entry) => entry.isImage && entry.is360; _label = 'Panorama'; _icon = AIcons.threesixty; } else if (mime == sphericalVideo) { - _filter = (entry) => entry.isVideo && entry.is360; + _test = (entry) => entry.isVideo && entry.is360; _label = '360° Video'; _icon = AIcons.threesixty; } else if (mime == geotiff) { - _filter = (entry) => entry.isGeotiff; + _test = (entry) => entry.isGeotiff; _label = 'GeoTIFF'; _icon = AIcons.geo; } else if (lowMime.endsWith('/*')) { lowMime = lowMime.substring(0, lowMime.length - 2); - _filter = (entry) => entry.mimeType.startsWith(lowMime); + _test = (entry) => entry.mimeType.startsWith(lowMime); if (lowMime == 'video') { _label = 'Video'; _icon = AIcons.video; @@ -48,7 +48,7 @@ class MimeFilter extends CollectionFilter { } _label ??= lowMime.split('/')[0].toUpperCase(); } else { - _filter = (entry) => entry.mimeType == lowMime; + _test = (entry) => entry.mimeType == lowMime; _label = MimeUtils.displayType(lowMime); } _icon ??= AIcons.vector; @@ -66,7 +66,7 @@ class MimeFilter extends CollectionFilter { }; @override - EntryFilter get filter => _filter; + EntryFilter get test => _test; @override String get label => _label; diff --git a/lib/model/filters/query.dart b/lib/model/filters/query.dart index 5d84812e0..dcbf6064e 100644 --- a/lib/model/filters/query.dart +++ b/lib/model/filters/query.dart @@ -12,7 +12,7 @@ class QueryFilter extends CollectionFilter { final String query; final bool colorful; - EntryFilter _filter; + EntryFilter _test; QueryFilter(this.query, {this.colorful = true}) { var upQuery = query.toUpperCase(); @@ -29,7 +29,7 @@ class QueryFilter extends CollectionFilter { upQuery = matches.first.group(1); } - _filter = not ? (entry) => !entry.search(upQuery) : (entry) => entry.search(upQuery); + _test = not ? (entry) => !entry.search(upQuery) : (entry) => entry.search(upQuery); } QueryFilter.fromMap(Map json) @@ -44,7 +44,7 @@ class QueryFilter extends CollectionFilter { }; @override - EntryFilter get filter => _filter; + EntryFilter get test => _test; @override bool get isUnique => false; diff --git a/lib/model/filters/tag.dart b/lib/model/filters/tag.dart index 648768f9c..bec9dbe74 100644 --- a/lib/model/filters/tag.dart +++ b/lib/model/filters/tag.dart @@ -8,13 +8,13 @@ class TagFilter extends CollectionFilter { static const emptyLabel = 'untagged'; final String tag; - EntryFilter _filter; + EntryFilter _test; TagFilter(this.tag) { if (tag.isEmpty) { - _filter = (entry) => entry.xmpSubjects.isEmpty; + _test = (entry) => entry.xmpSubjects.isEmpty; } else { - _filter = (entry) => entry.xmpSubjects.contains(tag); + _test = (entry) => entry.xmpSubjects.contains(tag); } } @@ -30,7 +30,7 @@ class TagFilter extends CollectionFilter { }; @override - EntryFilter get filter => _filter; + EntryFilter get test => _test; @override bool get isUnique => false; diff --git a/lib/model/source/album.dart b/lib/model/source/album.dart index 1c358d6f3..2ae41ee85 100644 --- a/lib/model/source/album.dart +++ b/lib/model/source/album.dart @@ -122,11 +122,11 @@ mixin AlbumMixin on SourceBase { } int albumEntryCount(AlbumFilter filter) { - return _filterEntryCountMap.putIfAbsent(filter.album, () => visibleEntries.where((entry) => filter.filter(entry)).length); + return _filterEntryCountMap.putIfAbsent(filter.album, () => visibleEntries.where(filter.test).length); } AvesEntry albumRecentEntry(AlbumFilter filter) { - return _filterRecentEntryMap.putIfAbsent(filter.album, () => sortedEntriesByDate.firstWhere((entry) => filter.filter(entry), orElse: () => null)); + return _filterRecentEntryMap.putIfAbsent(filter.album, () => sortedEntriesByDate.firstWhere(filter.test, orElse: () => null)); } } diff --git a/lib/model/source/collection_lens.dart b/lib/model/source/collection_lens.dart index 109ba3318..fd60b4231 100644 --- a/lib/model/source/collection_lens.dart +++ b/lib/model/source/collection_lens.dart @@ -123,7 +123,7 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin { void _applyFilters() { final entries = source.visibleEntries; - _filteredSortedEntries = List.of(filters.isEmpty ? entries : entries.where((entry) => filters.fold(true, (prev, filter) => prev && filter.filter(entry)))); + _filteredSortedEntries = List.of(filters.isEmpty ? entries : entries.where((entry) => filters.every((filter) => filter.test(entry)))); } void _applySort() { diff --git a/lib/model/source/collection_source.dart b/lib/model/source/collection_source.dart index 53bf70ed8..1e4bd0243 100644 --- a/lib/model/source/collection_source.dart +++ b/lib/model/source/collection_source.dart @@ -70,7 +70,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM Iterable _applyHiddenFilters(Iterable entries) { final hiddenFilters = settings.hiddenFilters; - return hiddenFilters.isEmpty ? entries : entries.where((entry) => !hiddenFilters.any((filter) => filter.filter(entry))); + return hiddenFilters.isEmpty ? entries : entries.where((entry) => !hiddenFilters.any((filter) => filter.test(entry))); } void _invalidate([Set entries]) { @@ -247,6 +247,10 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM updateDirectories(); updateLocations(); updateTags(); + + if (visible) { + refreshMetadata(visibleEntries.where(filter.test).toSet()); + } } } diff --git a/lib/model/source/location.dart b/lib/model/source/location.dart index 616e55463..bf25c2551 100644 --- a/lib/model/source/location.dart +++ b/lib/model/source/location.dart @@ -121,11 +121,11 @@ mixin LocationMixin on SourceBase { } int countryEntryCount(LocationFilter filter) { - return _filterEntryCountMap.putIfAbsent(filter.countryCode, () => visibleEntries.where((entry) => filter.filter(entry)).length); + return _filterEntryCountMap.putIfAbsent(filter.countryCode, () => visibleEntries.where(filter.test).length); } AvesEntry countryRecentEntry(LocationFilter filter) { - return _filterRecentEntryMap.putIfAbsent(filter.countryCode, () => sortedEntriesByDate.firstWhere((entry) => filter.filter(entry), orElse: () => null)); + return _filterRecentEntryMap.putIfAbsent(filter.countryCode, () => sortedEntriesByDate.firstWhere(filter.test, orElse: () => null)); } } diff --git a/lib/model/source/tag.dart b/lib/model/source/tag.dart index 781c5f2ed..1d4a3b32c 100644 --- a/lib/model/source/tag.dart +++ b/lib/model/source/tag.dart @@ -79,11 +79,11 @@ mixin TagMixin on SourceBase { } int tagEntryCount(TagFilter filter) { - return _filterEntryCountMap.putIfAbsent(filter.tag, () => visibleEntries.where((entry) => filter.filter(entry)).length); + return _filterEntryCountMap.putIfAbsent(filter.tag, () => visibleEntries.where(filter.test).length); } AvesEntry tagRecentEntry(TagFilter filter) { - return _filterRecentEntryMap.putIfAbsent(filter.tag, () => sortedEntriesByDate.firstWhere((entry) => filter.filter(entry), orElse: () => null)); + return _filterRecentEntryMap.putIfAbsent(filter.tag, () => sortedEntriesByDate.firstWhere(filter.test, orElse: () => null)); } } diff --git a/lib/widgets/filter_grids/common/chip_action_delegate.dart b/lib/widgets/filter_grids/common/chip_action_delegate.dart index 86d1c318e..c5345788b 100644 --- a/lib/widgets/filter_grids/common/chip_action_delegate.dart +++ b/lib/widgets/filter_grids/common/chip_action_delegate.dart @@ -60,7 +60,7 @@ class AlbumChipActionDelegate extends ChipActionDelegate with FeedbackMixin, Per } Future _showDeleteDialog(BuildContext context, AlbumFilter filter) async { - final selection = source.visibleEntries.where(filter.filter).toSet(); + final selection = source.visibleEntries.where(filter.test).toSet(); final count = selection.length; final confirmed = await showDialog( @@ -115,7 +115,7 @@ class AlbumChipActionDelegate extends ChipActionDelegate with FeedbackMixin, Per if (!await checkStoragePermissionForAlbums(context, {album})) return; - final todoEntries = source.visibleEntries.where(filter.filter).toSet(); + final todoEntries = source.visibleEntries.where(filter.test).toSet(); final destinationAlbum = path.join(path.dirname(album), newName); if (!await checkFreeSpaceForMove(context, todoEntries, destinationAlbum, MoveType.move)) return;