diff --git a/lib/model/entry.dart b/lib/model/entry.dart index 8e2831d0d..52c6987e0 100644 --- a/lib/model/entry.dart +++ b/lib/model/entry.dart @@ -376,7 +376,12 @@ class AvesEntry { return 'geo:$latitude,$longitude?q=$latitude,$longitude'; } - List get xmpSubjects => _catalogMetadata?.xmpSubjects?.split(';')?.where((tag) => tag.isNotEmpty)?.toList() ?? []; + List _xmpSubjects; + + List get xmpSubjects { + _xmpSubjects ??= _catalogMetadata?.xmpSubjects?.split(';')?.where((tag) => tag.isNotEmpty)?.toList() ?? []; + return _xmpSubjects; + } String _bestTitle; @@ -400,6 +405,7 @@ class AvesEntry { catalogDateMillis = newMetadata?.dateMillis; _catalogMetadata = newMetadata; _bestTitle = null; + _xmpSubjects = null; metadataChangeNotifier.notifyListeners(); _onImageChanged(oldDateModifiedSecs, oldRotationDegrees, oldIsFlipped); diff --git a/lib/model/filters/album.dart b/lib/model/filters/album.dart index 1ab6ce062..21c912c89 100644 --- a/lib/model/filters/album.dart +++ b/lib/model/filters/album.dart @@ -1,5 +1,4 @@ import 'package:aves/image_providers/app_icon_image_provider.dart'; -import 'package:aves/model/entry.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/utils/android_file_utils.dart'; @@ -33,7 +32,7 @@ class AlbumFilter extends CollectionFilter { }; @override - bool filter(AvesEntry entry) => entry.directory == album; + EntryFilter get filter => (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 c64326959..5d17006c9 100644 --- a/lib/model/filters/favourite.dart +++ b/lib/model/filters/favourite.dart @@ -1,4 +1,3 @@ -import 'package:aves/model/entry.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/theme/icons.dart'; import 'package:flutter/material.dart'; @@ -13,7 +12,7 @@ class FavouriteFilter extends CollectionFilter { }; @override - bool filter(AvesEntry entry) => entry.isFavourite; + EntryFilter get filter => (entry) => entry.isFavourite; @override String get label => 'Favourite'; diff --git a/lib/model/filters/filters.dart b/lib/model/filters/filters.dart index a3e985302..1c9ce5aad 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()); - bool filter(AvesEntry entry); + EntryFilter get filter; bool get isUnique => true; @@ -91,3 +91,5 @@ class FilterGridItem { @override int get hashCode => hashValues(filter, entry); } + +typedef EntryFilter = bool Function(AvesEntry); diff --git a/lib/model/filters/location.dart b/lib/model/filters/location.dart index c702cf2c4..c739f62be 100644 --- a/lib/model/filters/location.dart +++ b/lib/model/filters/location.dart @@ -1,4 +1,3 @@ -import 'package:aves/model/entry.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/theme/icons.dart'; import 'package:flutter/foundation.dart'; @@ -12,11 +11,20 @@ class LocationFilter extends CollectionFilter { final LocationLevel level; String _location; String _countryCode; + EntryFilter _filter; LocationFilter(this.level, this._location) { final split = _location.split(locationSeparator); if (split.isNotEmpty) _location = split[0]; if (split.length > 1) _countryCode = split[1]; + + if (_location.isEmpty) { + _filter = (entry) => !entry.isLocated; + } else if (level == LocationLevel.country) { + _filter = (entry) => entry.addressDetails?.countryCode == _countryCode; + } else if (level == LocationLevel.place) { + _filter = (entry) => entry.addressDetails?.place == _location; + } } LocationFilter.fromMap(Map json) @@ -35,7 +43,7 @@ class LocationFilter extends CollectionFilter { String get countryNameAndCode => '$_location$locationSeparator$_countryCode'; @override - bool filter(AvesEntry entry) => _location.isEmpty ? !entry.isLocated : entry.isLocated && ((level == LocationLevel.country && entry.addressDetails.countryCode == _countryCode) || (level == LocationLevel.place && entry.addressDetails.place == _location)); + EntryFilter get filter => _filter; @override String get label => _location.isEmpty ? emptyLabel : _location; diff --git a/lib/model/filters/mime.dart b/lib/model/filters/mime.dart index 5944c27df..be6b5f4be 100644 --- a/lib/model/filters/mime.dart +++ b/lib/model/filters/mime.dart @@ -1,5 +1,4 @@ import 'package:aves/model/filters/filters.dart'; -import 'package:aves/model/entry.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/utils/mime_utils.dart'; import 'package:flutter/foundation.dart'; @@ -15,7 +14,7 @@ class MimeFilter extends CollectionFilter { static const geotiff = 'aves/geotiff'; // subset of `image/tiff` final String mime; - bool Function(AvesEntry) _filter; + EntryFilter _filter; String _label; IconData _icon; @@ -67,7 +66,7 @@ class MimeFilter extends CollectionFilter { }; @override - bool filter(AvesEntry entry) => _filter(entry); + EntryFilter get filter => _filter; @override String get label => _label; diff --git a/lib/model/filters/query.dart b/lib/model/filters/query.dart index 33fe221e4..ad740e41f 100644 --- a/lib/model/filters/query.dart +++ b/lib/model/filters/query.dart @@ -1,4 +1,3 @@ -import 'package:aves/model/entry.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/theme/icons.dart'; import 'package:flutter/foundation.dart'; @@ -12,7 +11,7 @@ class QueryFilter extends CollectionFilter { final String query; final bool colorful; - bool Function(AvesEntry) _filter; + EntryFilter _filter; QueryFilter(this.query, {this.colorful = true}) { var upQuery = query.toUpperCase(); @@ -44,7 +43,7 @@ class QueryFilter extends CollectionFilter { }; @override - bool filter(AvesEntry entry) => _filter(entry); + EntryFilter get filter => _filter; @override bool get isUnique => false; diff --git a/lib/model/filters/tag.dart b/lib/model/filters/tag.dart index 5d21f0b7f..648768f9c 100644 --- a/lib/model/filters/tag.dart +++ b/lib/model/filters/tag.dart @@ -1,4 +1,3 @@ -import 'package:aves/model/entry.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/theme/icons.dart'; import 'package:flutter/foundation.dart'; @@ -9,8 +8,15 @@ class TagFilter extends CollectionFilter { static const emptyLabel = 'untagged'; final String tag; + EntryFilter _filter; - const TagFilter(this.tag); + TagFilter(this.tag) { + if (tag.isEmpty) { + _filter = (entry) => entry.xmpSubjects.isEmpty; + } else { + _filter = (entry) => entry.xmpSubjects.contains(tag); + } + } TagFilter.fromMap(Map json) : this( @@ -24,7 +30,7 @@ class TagFilter extends CollectionFilter { }; @override - bool filter(AvesEntry entry) => tag.isEmpty ? entry.xmpSubjects.isEmpty : entry.xmpSubjects.contains(tag); + EntryFilter get filter => _filter; @override bool get isUnique => false;