search: undated, untitled filters

This commit is contained in:
Thibault Deckers 2022-09-06 12:04:32 +02:00
parent 7469a04795
commit d926d943fd
27 changed files with 202 additions and 70 deletions

View file

@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Collection / Info: edit title via IPTC / XMP - Collection / Info: edit title via IPTC / XMP
- Albums / Countries / Tags: size displayed in list view details, sort by size - Albums / Countries / Tags: size displayed in list view details, sort by size
- Search: `undated` and `untitled` filters
- Greek translation (thanks Emmanouil Papavergis) - Greek translation (thanks Emmanouil Papavergis)
### Changed ### Changed

View file

@ -94,11 +94,11 @@
"filterBinLabel": "Papierkorb", "filterBinLabel": "Papierkorb",
"filterFavouriteLabel": "Favorit", "filterFavouriteLabel": "Favorit",
"filterLocationEmptyLabel": "Ungeortet", "filterNoLocationLabel": "Ungeortet",
"filterTagEmptyLabel": "Unmarkiert", "filterNoRatingLabel": "Nicht bewertet",
"filterNoTagLabel": "Unmarkiert",
"filterOnThisDayLabel": "Am heutigen Tag", "filterOnThisDayLabel": "Am heutigen Tag",
"filterRecentlyAddedLabel": "Kürzlich hinzugefügt", "filterRecentlyAddedLabel": "Kürzlich hinzugefügt",
"filterRatingUnratedLabel": "Nicht bewertet",
"filterRatingRejectedLabel": "Verworfen", "filterRatingRejectedLabel": "Verworfen",
"filterTypeAnimatedLabel": "Animationen", "filterTypeAnimatedLabel": "Animationen",
"filterTypeMotionPhotoLabel": "Bewegtes Foto", "filterTypeMotionPhotoLabel": "Bewegtes Foto",

View file

@ -94,11 +94,11 @@
"filterBinLabel": "Κάδος ανακύκλωσης", "filterBinLabel": "Κάδος ανακύκλωσης",
"filterFavouriteLabel": "Αγαπημένα", "filterFavouriteLabel": "Αγαπημένα",
"filterLocationEmptyLabel": "Χωρίς τοποθεσία", "filterNoLocationLabel": "Χωρίς τοποθεσία",
"filterTagEmptyLabel": "Χωρίς ετικέτα", "filterNoRatingLabel": "Χωρίς βαθμολογία",
"filterNoTagLabel": "Χωρίς ετικέτα",
"filterOnThisDayLabel": "Αυτή τη μέρα", "filterOnThisDayLabel": "Αυτή τη μέρα",
"filterRecentlyAddedLabel": "Προστέθηκαν πρόσφατα", "filterRecentlyAddedLabel": "Προστέθηκαν πρόσφατα",
"filterRatingUnratedLabel": "Χωρίς βαθμολογία",
"filterRatingRejectedLabel": "Απορριφθέντα", "filterRatingRejectedLabel": "Απορριφθέντα",
"filterTypeAnimatedLabel": "Κινούμενα", "filterTypeAnimatedLabel": "Κινούμενα",
"filterTypeMotionPhotoLabel": "Φωτογραφίες με κίνηση", "filterTypeMotionPhotoLabel": "Φωτογραφίες με κίνηση",

View file

@ -123,11 +123,13 @@
"filterBinLabel": "Recycle bin", "filterBinLabel": "Recycle bin",
"filterFavouriteLabel": "Favorite", "filterFavouriteLabel": "Favorite",
"filterLocationEmptyLabel": "Unlocated", "filterNoDateLabel": "Undated",
"filterTagEmptyLabel": "Untagged", "filterNoLocationLabel": "Unlocated",
"filterNoRatingLabel": "Unrated",
"filterNoTagLabel": "Untagged",
"filterNoTitleLabel": "Untitled",
"filterOnThisDayLabel": "On this day", "filterOnThisDayLabel": "On this day",
"filterRecentlyAddedLabel": "Recently added", "filterRecentlyAddedLabel": "Recently added",
"filterRatingUnratedLabel": "Unrated",
"filterRatingRejectedLabel": "Rejected", "filterRatingRejectedLabel": "Rejected",
"filterTypeAnimatedLabel": "Animated", "filterTypeAnimatedLabel": "Animated",
"filterTypeMotionPhotoLabel": "Motion Photo", "filterTypeMotionPhotoLabel": "Motion Photo",
@ -605,6 +607,7 @@
"searchPlacesSectionTitle": "Places", "searchPlacesSectionTitle": "Places",
"searchTagsSectionTitle": "Tags", "searchTagsSectionTitle": "Tags",
"searchRatingSectionTitle": "Ratings", "searchRatingSectionTitle": "Ratings",
"searchMetadataSectionTitle": "Metadata",
"settingsPageTitle": "Settings", "settingsPageTitle": "Settings",
"settingsSystemDefault": "System", "settingsSystemDefault": "System",

View file

@ -94,10 +94,10 @@
"filterBinLabel": "Cesto de basura", "filterBinLabel": "Cesto de basura",
"filterFavouriteLabel": "Favorito", "filterFavouriteLabel": "Favorito",
"filterLocationEmptyLabel": "No localizado", "filterNoLocationLabel": "No localizado",
"filterTagEmptyLabel": "Sin etiquetar", "filterNoRatingLabel": "Sin clasificar",
"filterNoTagLabel": "Sin etiquetar",
"filterOnThisDayLabel": "De este día", "filterOnThisDayLabel": "De este día",
"filterRatingUnratedLabel": "Sin clasificar",
"filterRatingRejectedLabel": "Rechazado", "filterRatingRejectedLabel": "Rechazado",
"filterTypeAnimatedLabel": "Animado", "filterTypeAnimatedLabel": "Animado",
"filterTypeMotionPhotoLabel": "Foto en movimiento", "filterTypeMotionPhotoLabel": "Foto en movimiento",

View file

@ -95,11 +95,13 @@
"filterBinLabel": "Corbeille", "filterBinLabel": "Corbeille",
"filterFavouriteLabel": "Favori", "filterFavouriteLabel": "Favori",
"filterLocationEmptyLabel": "Sans lieu", "filterNoDateLabel": "Sans date",
"filterTagEmptyLabel": "Sans libellé", "filterNoLocationLabel": "Sans lieu",
"filterNoRatingLabel": "Sans notation",
"filterNoTagLabel": "Sans libellé",
"filterNoTitleLabel": "Sans titre",
"filterOnThisDayLabel": "Ce jour-là", "filterOnThisDayLabel": "Ce jour-là",
"filterRecentlyAddedLabel": "Ajouté récemment", "filterRecentlyAddedLabel": "Ajouté récemment",
"filterRatingUnratedLabel": "Sans notation",
"filterRatingRejectedLabel": "Rejeté", "filterRatingRejectedLabel": "Rejeté",
"filterTypeAnimatedLabel": "Animation", "filterTypeAnimatedLabel": "Animation",
"filterTypeMotionPhotoLabel": "Photo animée", "filterTypeMotionPhotoLabel": "Photo animée",
@ -425,6 +427,7 @@
"searchPlacesSectionTitle": "Lieux", "searchPlacesSectionTitle": "Lieux",
"searchTagsSectionTitle": "Libellés", "searchTagsSectionTitle": "Libellés",
"searchRatingSectionTitle": "Notations", "searchRatingSectionTitle": "Notations",
"searchMetadataSectionTitle": "Métadonnées",
"settingsPageTitle": "Réglages", "settingsPageTitle": "Réglages",
"settingsSystemDefault": "Système", "settingsSystemDefault": "Système",

View file

@ -94,10 +94,10 @@
"filterBinLabel": "Tong sampah", "filterBinLabel": "Tong sampah",
"filterFavouriteLabel": "Favorit", "filterFavouriteLabel": "Favorit",
"filterLocationEmptyLabel": "Lokasi yang tidak ditemukan", "filterNoLocationLabel": "Lokasi yang tidak ditemukan",
"filterTagEmptyLabel": "Tidak dilabel", "filterNoRatingLabel": "Belum diberi nilai",
"filterNoTagLabel": "Tidak dilabel",
"filterOnThisDayLabel": "Di hari ini", "filterOnThisDayLabel": "Di hari ini",
"filterRatingUnratedLabel": "Belum diberi nilai",
"filterRatingRejectedLabel": "Ditolak", "filterRatingRejectedLabel": "Ditolak",
"filterTypeAnimatedLabel": "Teranimasi", "filterTypeAnimatedLabel": "Teranimasi",
"filterTypeMotionPhotoLabel": "Foto bergerak", "filterTypeMotionPhotoLabel": "Foto bergerak",

View file

@ -94,11 +94,11 @@
"filterBinLabel": "Cestino", "filterBinLabel": "Cestino",
"filterFavouriteLabel": "Preferiti", "filterFavouriteLabel": "Preferiti",
"filterLocationEmptyLabel": "Senza posizione", "filterNoLocationLabel": "Senza posizione",
"filterTagEmptyLabel": "Senza etichetta", "filterNoRatingLabel": "Non valutato",
"filterNoTagLabel": "Senza etichetta",
"filterOnThisDayLabel": "In questo giorno", "filterOnThisDayLabel": "In questo giorno",
"filterRecentlyAddedLabel": "Aggiunto di recente", "filterRecentlyAddedLabel": "Aggiunto di recente",
"filterRatingUnratedLabel": "Non valutato",
"filterRatingRejectedLabel": "Rifiutato", "filterRatingRejectedLabel": "Rifiutato",
"filterTypeAnimatedLabel": "Animato", "filterTypeAnimatedLabel": "Animato",
"filterTypeMotionPhotoLabel": "Foto in movimento", "filterTypeMotionPhotoLabel": "Foto in movimento",

View file

@ -94,10 +94,10 @@
"filterBinLabel": "ごみ箱", "filterBinLabel": "ごみ箱",
"filterFavouriteLabel": "お気に入り", "filterFavouriteLabel": "お気に入り",
"filterLocationEmptyLabel": "位置情報なし", "filterNoLocationLabel": "位置情報なし",
"filterTagEmptyLabel": "タグ情報なし", "filterNoRatingLabel": "評価情報なし",
"filterNoTagLabel": "タグ情報なし",
"filterOnThisDayLabel": "過去のこの日", "filterOnThisDayLabel": "過去のこの日",
"filterRatingUnratedLabel": "評価情報なし",
"filterRatingRejectedLabel": "拒否", "filterRatingRejectedLabel": "拒否",
"filterTypeAnimatedLabel": "アニメーション", "filterTypeAnimatedLabel": "アニメーション",
"filterTypeMotionPhotoLabel": "モーションフォト", "filterTypeMotionPhotoLabel": "モーションフォト",

View file

@ -95,11 +95,13 @@
"filterBinLabel": "휴지통", "filterBinLabel": "휴지통",
"filterFavouriteLabel": "즐겨찾기", "filterFavouriteLabel": "즐겨찾기",
"filterLocationEmptyLabel": "장소 없음", "filterNoDateLabel": "날짜 없음",
"filterTagEmptyLabel": "태그 없음", "filterNoLocationLabel": "장소 없음",
"filterNoRatingLabel": "별점 없음",
"filterNoTagLabel": "태그 없음",
"filterNoTitleLabel": "제목 없음",
"filterOnThisDayLabel": "이 날", "filterOnThisDayLabel": "이 날",
"filterRecentlyAddedLabel": "최근 추가된", "filterRecentlyAddedLabel": "최근 추가된",
"filterRatingUnratedLabel": "별점 없음",
"filterRatingRejectedLabel": "거부됨", "filterRatingRejectedLabel": "거부됨",
"filterTypeAnimatedLabel": "애니메이션", "filterTypeAnimatedLabel": "애니메이션",
"filterTypeMotionPhotoLabel": "모션 사진", "filterTypeMotionPhotoLabel": "모션 사진",
@ -425,6 +427,7 @@
"searchPlacesSectionTitle": "장소", "searchPlacesSectionTitle": "장소",
"searchTagsSectionTitle": "태그", "searchTagsSectionTitle": "태그",
"searchRatingSectionTitle": "별점", "searchRatingSectionTitle": "별점",
"searchMetadataSectionTitle": "메타데이터",
"settingsPageTitle": "설정", "settingsPageTitle": "설정",
"settingsSystemDefault": "시스템", "settingsSystemDefault": "시스템",

View file

@ -94,11 +94,11 @@
"filterBinLabel": "Prullenbak", "filterBinLabel": "Prullenbak",
"filterFavouriteLabel": "Favorieten", "filterFavouriteLabel": "Favorieten",
"filterLocationEmptyLabel": "Geen locatie", "filterNoLocationLabel": "Geen locatie",
"filterTagEmptyLabel": "Geen label", "filterNoRatingLabel": "Geen rating",
"filterNoTagLabel": "Geen label",
"filterOnThisDayLabel": "Op deze dag", "filterOnThisDayLabel": "Op deze dag",
"filterRecentlyAddedLabel": "Recent toegevoegd", "filterRecentlyAddedLabel": "Recent toegevoegd",
"filterRatingUnratedLabel": "Geen rating",
"filterRatingRejectedLabel": "Afgekeurd", "filterRatingRejectedLabel": "Afgekeurd",
"filterTypeAnimatedLabel": "Geanimeerd", "filterTypeAnimatedLabel": "Geanimeerd",
"filterTypeMotionPhotoLabel": "Bewegende Foto", "filterTypeMotionPhotoLabel": "Bewegende Foto",

View file

@ -94,11 +94,11 @@
"filterBinLabel": "Lixeira", "filterBinLabel": "Lixeira",
"filterFavouriteLabel": "Favorito", "filterFavouriteLabel": "Favorito",
"filterLocationEmptyLabel": "Não localizado", "filterNoLocationLabel": "Não localizado",
"filterTagEmptyLabel": "Sem etiqueta", "filterNoRatingLabel": "Sem classificação",
"filterNoTagLabel": "Sem etiqueta",
"filterOnThisDayLabel": "Neste dia", "filterOnThisDayLabel": "Neste dia",
"filterRecentlyAddedLabel": "Adicionado recentemente", "filterRecentlyAddedLabel": "Adicionado recentemente",
"filterRatingUnratedLabel": "Sem classificação",
"filterRatingRejectedLabel": "Rejeitado", "filterRatingRejectedLabel": "Rejeitado",
"filterTypeAnimatedLabel": "Animado", "filterTypeAnimatedLabel": "Animado",
"filterTypeMotionPhotoLabel": "Foto em movimento", "filterTypeMotionPhotoLabel": "Foto em movimento",

View file

@ -94,9 +94,9 @@
"filterBinLabel": "Корзина", "filterBinLabel": "Корзина",
"filterFavouriteLabel": "Избранное", "filterFavouriteLabel": "Избранное",
"filterLocationEmptyLabel": "Без местоположения", "filterNoLocationLabel": "Без местоположения",
"filterTagEmptyLabel": "Без тегов", "filterNoRatingLabel": "Без рейтинга",
"filterRatingUnratedLabel": "Без рейтинга", "filterNoTagLabel": "Без тегов",
"filterRatingRejectedLabel": "Отклонённое", "filterRatingRejectedLabel": "Отклонённое",
"filterTypeAnimatedLabel": "GIF", "filterTypeAnimatedLabel": "GIF",
"filterTypeMotionPhotoLabel": "Живое фото", "filterTypeMotionPhotoLabel": "Живое фото",

View file

@ -91,9 +91,9 @@
"filterBinLabel": "Geri dönüşüm kutusu", "filterBinLabel": "Geri dönüşüm kutusu",
"filterFavouriteLabel": "Favori", "filterFavouriteLabel": "Favori",
"filterLocationEmptyLabel": "Konumsuz", "filterNoLocationLabel": "Konumsuz",
"filterTagEmptyLabel": "Etiketsiz", "filterNoRatingLabel": "Derecelendirilmemiş",
"filterRatingUnratedLabel": "Derecelendirilmemiş", "filterNoTagLabel": "Etiketsiz",
"filterRatingRejectedLabel": "Reddedilmiş", "filterRatingRejectedLabel": "Reddedilmiş",
"filterTypeAnimatedLabel": "Hareketli", "filterTypeAnimatedLabel": "Hareketli",
"filterTypeMotionPhotoLabel": "Hareketli Fotoğraf", "filterTypeMotionPhotoLabel": "Hareketli Fotoğraf",

View file

@ -94,11 +94,11 @@
"filterBinLabel": "回收站", "filterBinLabel": "回收站",
"filterFavouriteLabel": "收藏夹", "filterFavouriteLabel": "收藏夹",
"filterLocationEmptyLabel": "未定位", "filterNoLocationLabel": "未定位",
"filterTagEmptyLabel": "无标签", "filterNoRatingLabel": "未评分",
"filterNoTagLabel": "无标签",
"filterOnThisDayLabel": "选择日期", "filterOnThisDayLabel": "选择日期",
"filterRecentlyAddedLabel": "最近添加", "filterRecentlyAddedLabel": "最近添加",
"filterRatingUnratedLabel": "未评分",
"filterRatingRejectedLabel": "拒绝", "filterRatingRejectedLabel": "拒绝",
"filterTypeAnimatedLabel": "动画", "filterTypeAnimatedLabel": "动画",
"filterTypeMotionPhotoLabel": "动态照片", "filterTypeMotionPhotoLabel": "动态照片",

View file

@ -8,6 +8,7 @@ import 'package:aves/model/filters/date.dart';
import 'package:aves/model/filters/favourite.dart'; 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/path.dart'; import 'package:aves/model/filters/path.dart';
import 'package:aves/model/filters/query.dart'; import 'package:aves/model/filters/query.dart';
import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/rating.dart';
@ -30,12 +31,14 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
MimeFilter.type, MimeFilter.type,
AlbumFilter.type, AlbumFilter.type,
TypeFilter.type, TypeFilter.type,
RecentlyAddedFilter.type,
DateFilter.type, DateFilter.type,
LocationFilter.type, LocationFilter.type,
CoordinateFilter.type, CoordinateFilter.type,
FavouriteFilter.type, FavouriteFilter.type,
RatingFilter.type, RatingFilter.type,
TagFilter.type, TagFilter.type,
MissingFilter.type,
PathFilter.type, PathFilter.type,
]; ];
@ -63,6 +66,8 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
return LocationFilter.fromMap(jsonMap); return LocationFilter.fromMap(jsonMap);
case MimeFilter.type: case MimeFilter.type:
return MimeFilter.fromMap(jsonMap); return MimeFilter.fromMap(jsonMap);
case MissingFilter.type:
return MissingFilter.fromMap(jsonMap);
case PathFilter.type: case PathFilter.type:
return PathFilter.fromMap(jsonMap); return PathFilter.fromMap(jsonMap);
case QueryFilter.type: case QueryFilter.type:

View file

@ -56,7 +56,7 @@ class LocationFilter extends CoveredCollectionFilter {
String get universalLabel => _location; String get universalLabel => _location;
@override @override
String getLabel(BuildContext context) => _location.isEmpty ? context.l10n.filterLocationEmptyLabel : _location; String getLabel(BuildContext context) => _location.isEmpty ? context.l10n.filterNoLocationLabel : _location;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {

View file

@ -0,0 +1,73 @@
import 'package:aves/model/filters/filters.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:flutter/widgets.dart';
class MissingFilter extends CollectionFilter {
static const type = 'missing';
static const _date = 'date';
static const _title = 'title';
final String metadataType;
late final EntryFilter _test;
late final IconData _icon;
static final date = MissingFilter._private(_date);
static final title = MissingFilter._private(_title);
@override
List<Object?> get props => [metadataType];
MissingFilter._private(this.metadataType) {
switch (metadataType) {
case _date:
_test = (entry) => (entry.catalogMetadata?.dateMillis ?? 0) == 0;
_icon = AIcons.dateUndated;
break;
case _title:
_test = (entry) => (entry.catalogMetadata?.xmpTitle ?? '').isEmpty;
_icon = AIcons.descriptionUntitled;
break;
}
}
factory MissingFilter.fromMap(Map<String, dynamic> json) {
return MissingFilter._private(
json['metadataType'],
);
}
@override
Map<String, dynamic> toMap() => {
'type': type,
'metadataType': metadataType,
};
@override
EntryFilter get test => _test;
@override
String get universalLabel => metadataType;
@override
String getLabel(BuildContext context) {
switch (metadataType) {
case _date:
return context.l10n.filterNoDateLabel;
case _title:
return context.l10n.filterNoTitleLabel;
default:
return metadataType;
}
}
@override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
@override
String get category => type;
@override
String get key => '$type-$metadataType';
}

View file

@ -57,7 +57,7 @@ class RatingFilter extends CollectionFilter {
case -1: case -1:
return context.l10n.filterRatingRejectedLabel; return context.l10n.filterRatingRejectedLabel;
case 0: case 0:
return context.l10n.filterRatingUnratedLabel; return context.l10n.filterNoRatingLabel;
default: default:
return '\u2B50' * rating; return '\u2B50' * rating;
} }

View file

@ -38,7 +38,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.recent, 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

@ -44,7 +44,7 @@ class TagFilter extends CoveredCollectionFilter {
String get universalLabel => tag; String get universalLabel => tag;
@override @override
String getLabel(BuildContext context) => tag.isEmpty ? context.l10n.filterTagEmptyLabel : 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}) => showGenericIcon ? Icon(tag.isEmpty ? AIcons.tagUntagged : AIcons.tag, size: size) : null;

View file

@ -16,7 +16,10 @@ class AIcons {
static const IconData checked = Icons.done_outlined; static const IconData checked = Icons.done_outlined;
static const IconData counter = Icons.plus_one_outlined; static const IconData counter = Icons.plus_one_outlined;
static const IconData date = Icons.calendar_today_outlined; static const IconData date = Icons.calendar_today_outlined;
static const IconData dateRecent = Icons.today_outlined;
static const IconData dateUndated = Icons.event_busy_outlined;
static const IconData description = Icons.description_outlined; static const IconData description = Icons.description_outlined;
static const IconData descriptionUntitled = Icons.comments_disabled_outlined;
static const IconData disc = Icons.fiber_manual_record; static const IconData disc = Icons.fiber_manual_record;
static const IconData display = Icons.light_mode_outlined; static const IconData display = Icons.light_mode_outlined;
static const IconData error = Icons.error_outline; static const IconData error = Icons.error_outline;
@ -35,7 +38,6 @@ class AIcons {
static const IconData ratingRejected = MdiIcons.starMinusOutline; static const IconData ratingRejected = MdiIcons.starMinusOutline;
static const IconData ratingUnrated = MdiIcons.starOffOutline; static const IconData ratingUnrated = MdiIcons.starOffOutline;
static const IconData raw = Icons.raw_on_outlined; static const IconData raw = Icons.raw_on_outlined;
static const IconData recent = Icons.today_outlined;
static const IconData shooting = Icons.camera_outlined; static const IconData shooting = Icons.camera_outlined;
static const IconData removableStorage = Icons.sd_storage_outlined; static const IconData removableStorage = Icons.sd_storage_outlined;
static const IconData sensorControlEnabled = Icons.explore_outlined; static const IconData sensorControlEnabled = Icons.explore_outlined;

View file

@ -95,7 +95,7 @@ class _EditEntryRatingDialogState extends State<EditEntryRatingDialog> {
_action = v!; _action = v!;
_rating = 0; _rating = 0;
}), }),
title: Text(l10n.filterRatingUnratedLabel), title: Text(l10n.filterNoRatingLabel),
), ),
], ],
actions: [ actions: [

View file

@ -125,7 +125,7 @@ class _TagEditorPageState extends State<TagEditorPage> {
const Icon(AIcons.tagUntagged, color: untaggedColor), const Icon(AIcons.tagUntagged, color: untaggedColor),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
l10n.filterTagEmptyLabel, l10n.filterNoTagLabel,
style: const TextStyle(color: untaggedColor), style: const TextStyle(color: untaggedColor),
), ),
], ],

View file

@ -4,6 +4,7 @@ import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.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/query.dart'; import 'package:aves/model/filters/query.dart';
import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/rating.dart';
import 'package:aves/model/filters/recent.dart'; import 'package:aves/model/filters/recent.dart';
@ -105,6 +106,7 @@ class CollectionSearchDelegate extends AvesSearchDelegate {
_buildPlaceFilters(containQuery), _buildPlaceFilters(containQuery),
_buildTagFilters(containQuery), _buildTagFilters(containQuery),
_buildRatingFilters(context, containQuery), _buildRatingFilters(context, containQuery),
_buildMetadataFilters(context, containQuery),
], ],
); );
}); });
@ -166,11 +168,10 @@ class CollectionSearchDelegate extends AvesSearchDelegate {
return StreamBuilder( return StreamBuilder(
stream: source.eventBus.on<CountriesChangedEvent>(), stream: source.eventBus.on<CountriesChangedEvent>(),
builder: (context, snapshot) { builder: (context, snapshot) {
final filters = source.sortedCountries.where(containQuery).map((s) => LocationFilter(LocationLevel.country, s)).toList();
return _buildFilterRow( return _buildFilterRow(
context: context, context: context,
title: context.l10n.searchCountriesSectionTitle, title: context.l10n.searchCountriesSectionTitle,
filters: filters, filters: source.sortedCountries.where(containQuery).map((s) => LocationFilter(LocationLevel.country, s)).toList(),
); );
}, },
); );
@ -180,15 +181,10 @@ class CollectionSearchDelegate extends AvesSearchDelegate {
return StreamBuilder( return StreamBuilder(
stream: source.eventBus.on<PlacesChangedEvent>(), stream: source.eventBus.on<PlacesChangedEvent>(),
builder: (context, snapshot) { builder: (context, snapshot) {
final filters = source.sortedPlaces.where(containQuery).map((s) => LocationFilter(LocationLevel.place, s));
final noFilter = LocationFilter(LocationLevel.place, '');
return _buildFilterRow( return _buildFilterRow(
context: context, context: context,
title: context.l10n.searchPlacesSectionTitle, title: context.l10n.searchPlacesSectionTitle,
filters: [ filters: source.sortedPlaces.where(containQuery).map((s) => LocationFilter(LocationLevel.place, s)).toList(),
if (containQuery(noFilter.getLabel(context))) noFilter,
...filters,
],
); );
}, },
); );
@ -198,15 +194,10 @@ class CollectionSearchDelegate extends AvesSearchDelegate {
return StreamBuilder( return StreamBuilder(
stream: source.eventBus.on<TagsChangedEvent>(), stream: source.eventBus.on<TagsChangedEvent>(),
builder: (context, snapshot) { builder: (context, snapshot) {
final filters = source.sortedTags.where(containQuery).map(TagFilter.new);
final noFilter = TagFilter('');
return _buildFilterRow( return _buildFilterRow(
context: context, context: context,
title: context.l10n.searchTagsSectionTitle, title: context.l10n.searchTagsSectionTitle,
filters: [ filters: source.sortedTags.where(containQuery).map(TagFilter.new).toList(),
if (containQuery(noFilter.getLabel(context))) noFilter,
...filters,
],
); );
}, },
); );
@ -216,7 +207,21 @@ class CollectionSearchDelegate extends AvesSearchDelegate {
return _buildFilterRow( return _buildFilterRow(
context: context, context: context,
title: context.l10n.searchRatingSectionTitle, title: context.l10n.searchRatingSectionTitle,
filters: [0, 5, 4, 3, 2, 1, -1].map(RatingFilter.new).where((f) => containQuery(f.getLabel(context))).toList(), filters: [5, 4, 3, 2, 1, -1].map(RatingFilter.new).where((f) => containQuery(f.getLabel(context))).toList(),
);
}
Widget _buildMetadataFilters(BuildContext context, _ContainQuery containQuery) {
return _buildFilterRow(
context: context,
title: context.l10n.searchMetadataSectionTitle,
filters: [
MissingFilter.date,
LocationFilter(LocationLevel.place, ''),
TagFilter(''),
const RatingFilter(0),
MissingFilter.title,
].where((f) => containQuery(f.getLabel(context))).toList(),
); );
} }

View file

@ -5,6 +5,7 @@ import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.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/path.dart'; import 'package:aves/model/filters/path.dart';
import 'package:aves/model/filters/query.dart'; import 'package:aves/model/filters/query.dart';
import 'package:aves/model/filters/rating.dart'; import 'package:aves/model/filters/rating.dart';
@ -53,6 +54,9 @@ void main() {
final mime = MimeFilter.video; final mime = MimeFilter.video;
expect(mime, jsonRoundTrip(mime)); expect(mime, jsonRoundTrip(mime));
final missing = MissingFilter.title;
expect(missing, jsonRoundTrip(missing));
final path = PathFilter('/some/path/'); final path = PathFilter('/some/path/');
expect(path, jsonRoundTrip(path)); expect(path, jsonRoundTrip(path));

View file

@ -1,51 +1,78 @@
{ {
"de": [ "de": [
"entryInfoActionEditTitleDescription" "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"searchMetadataSectionTitle"
], ],
"el": [ "el": [
"entryInfoActionEditTitleDescription" "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"searchMetadataSectionTitle"
], ],
"es": [ "es": [
"entryInfoActionEditTitleDescription", "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"filterRecentlyAddedLabel", "filterRecentlyAddedLabel",
"searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"viewerInfoLabelDescription" "viewerInfoLabelDescription"
], ],
"id": [ "id": [
"entryInfoActionEditTitleDescription", "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"filterRecentlyAddedLabel", "filterRecentlyAddedLabel",
"searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"settingsViewerGestureSideTapNext", "settingsViewerGestureSideTapNext",
"viewerInfoLabelDescription" "viewerInfoLabelDescription"
], ],
"it": [ "it": [
"entryInfoActionEditTitleDescription" "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"searchMetadataSectionTitle"
], ],
"ja": [ "ja": [
"entryInfoActionEditTitleDescription", "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"filterRecentlyAddedLabel", "filterRecentlyAddedLabel",
"searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"settingsViewerGestureSideTapNext", "settingsViewerGestureSideTapNext",
"viewerInfoLabelDescription" "viewerInfoLabelDescription"
], ],
"nl": [ "nl": [
"entryInfoActionEditTitleDescription" "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"searchMetadataSectionTitle"
], ],
"pt": [ "pt": [
"entryInfoActionEditTitleDescription" "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"searchMetadataSectionTitle"
], ],
"ru": [ "ru": [
"entryInfoActionEditTitleDescription", "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"filterOnThisDayLabel", "filterOnThisDayLabel",
"filterRecentlyAddedLabel", "filterRecentlyAddedLabel",
"searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"settingsViewerGestureSideTapNext", "settingsViewerGestureSideTapNext",
"settingsSlideshowFillScreen", "settingsSlideshowFillScreen",
@ -58,6 +85,8 @@
"slideshowActionResume", "slideshowActionResume",
"slideshowActionShowInCollection", "slideshowActionShowInCollection",
"entryInfoActionEditTitleDescription", "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"filterOnThisDayLabel", "filterOnThisDayLabel",
"filterRecentlyAddedLabel", "filterRecentlyAddedLabel",
"slideshowVideoPlaybackSkip", "slideshowVideoPlaybackSkip",
@ -71,6 +100,7 @@
"wallpaperTargetLock", "wallpaperTargetLock",
"wallpaperTargetHomeLock", "wallpaperTargetHomeLock",
"menuActionSlideshow", "menuActionSlideshow",
"searchMetadataSectionTitle",
"settingsConfirmationAfterMoveToBinItems", "settingsConfirmationAfterMoveToBinItems",
"settingsViewerGestureSideTapNext", "settingsViewerGestureSideTapNext",
"settingsViewerSlideshowTile", "settingsViewerSlideshowTile",
@ -91,6 +121,9 @@
], ],
"zh": [ "zh": [
"entryInfoActionEditTitleDescription" "entryInfoActionEditTitleDescription",
"filterNoDateLabel",
"filterNoTitleLabel",
"searchMetadataSectionTitle"
] ]
} }