search: undated, untitled filters
This commit is contained in:
parent
7469a04795
commit
d926d943fd
27 changed files with 202 additions and 70 deletions
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -94,11 +94,11 @@
|
||||||
|
|
||||||
"filterBinLabel": "Κάδος ανακύκλωσης",
|
"filterBinLabel": "Κάδος ανακύκλωσης",
|
||||||
"filterFavouriteLabel": "Αγαπημένα",
|
"filterFavouriteLabel": "Αγαπημένα",
|
||||||
"filterLocationEmptyLabel": "Χωρίς τοποθεσία",
|
"filterNoLocationLabel": "Χωρίς τοποθεσία",
|
||||||
"filterTagEmptyLabel": "Χωρίς ετικέτα",
|
"filterNoRatingLabel": "Χωρίς βαθμολογία",
|
||||||
|
"filterNoTagLabel": "Χωρίς ετικέτα",
|
||||||
"filterOnThisDayLabel": "Αυτή τη μέρα",
|
"filterOnThisDayLabel": "Αυτή τη μέρα",
|
||||||
"filterRecentlyAddedLabel": "Προστέθηκαν πρόσφατα",
|
"filterRecentlyAddedLabel": "Προστέθηκαν πρόσφατα",
|
||||||
"filterRatingUnratedLabel": "Χωρίς βαθμολογία",
|
|
||||||
"filterRatingRejectedLabel": "Απορριφθέντα",
|
"filterRatingRejectedLabel": "Απορριφθέντα",
|
||||||
"filterTypeAnimatedLabel": "Κινούμενα",
|
"filterTypeAnimatedLabel": "Κινούμενα",
|
||||||
"filterTypeMotionPhotoLabel": "Φωτογραφίες με κίνηση",
|
"filterTypeMotionPhotoLabel": "Φωτογραφίες με κίνηση",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -94,10 +94,10 @@
|
||||||
|
|
||||||
"filterBinLabel": "ごみ箱",
|
"filterBinLabel": "ごみ箱",
|
||||||
"filterFavouriteLabel": "お気に入り",
|
"filterFavouriteLabel": "お気に入り",
|
||||||
"filterLocationEmptyLabel": "位置情報なし",
|
"filterNoLocationLabel": "位置情報なし",
|
||||||
"filterTagEmptyLabel": "タグ情報なし",
|
"filterNoRatingLabel": "評価情報なし",
|
||||||
|
"filterNoTagLabel": "タグ情報なし",
|
||||||
"filterOnThisDayLabel": "過去のこの日",
|
"filterOnThisDayLabel": "過去のこの日",
|
||||||
"filterRatingUnratedLabel": "評価情報なし",
|
|
||||||
"filterRatingRejectedLabel": "拒否",
|
"filterRatingRejectedLabel": "拒否",
|
||||||
"filterTypeAnimatedLabel": "アニメーション",
|
"filterTypeAnimatedLabel": "アニメーション",
|
||||||
"filterTypeMotionPhotoLabel": "モーションフォト",
|
"filterTypeMotionPhotoLabel": "モーションフォト",
|
||||||
|
|
|
@ -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": "시스템",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -94,9 +94,9 @@
|
||||||
|
|
||||||
"filterBinLabel": "Корзина",
|
"filterBinLabel": "Корзина",
|
||||||
"filterFavouriteLabel": "Избранное",
|
"filterFavouriteLabel": "Избранное",
|
||||||
"filterLocationEmptyLabel": "Без местоположения",
|
"filterNoLocationLabel": "Без местоположения",
|
||||||
"filterTagEmptyLabel": "Без тегов",
|
"filterNoRatingLabel": "Без рейтинга",
|
||||||
"filterRatingUnratedLabel": "Без рейтинга",
|
"filterNoTagLabel": "Без тегов",
|
||||||
"filterRatingRejectedLabel": "Отклонённое",
|
"filterRatingRejectedLabel": "Отклонённое",
|
||||||
"filterTypeAnimatedLabel": "GIF",
|
"filterTypeAnimatedLabel": "GIF",
|
||||||
"filterTypeMotionPhotoLabel": "Живое фото",
|
"filterTypeMotionPhotoLabel": "Живое фото",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -94,11 +94,11 @@
|
||||||
|
|
||||||
"filterBinLabel": "回收站",
|
"filterBinLabel": "回收站",
|
||||||
"filterFavouriteLabel": "收藏夹",
|
"filterFavouriteLabel": "收藏夹",
|
||||||
"filterLocationEmptyLabel": "未定位",
|
"filterNoLocationLabel": "未定位",
|
||||||
"filterTagEmptyLabel": "无标签",
|
"filterNoRatingLabel": "未评分",
|
||||||
|
"filterNoTagLabel": "无标签",
|
||||||
"filterOnThisDayLabel": "选择日期",
|
"filterOnThisDayLabel": "选择日期",
|
||||||
"filterRecentlyAddedLabel": "最近添加",
|
"filterRecentlyAddedLabel": "最近添加",
|
||||||
"filterRatingUnratedLabel": "未评分",
|
|
||||||
"filterRatingRejectedLabel": "拒绝",
|
"filterRatingRejectedLabel": "拒绝",
|
||||||
"filterTypeAnimatedLabel": "动画",
|
"filterTypeAnimatedLabel": "动画",
|
||||||
"filterTypeMotionPhotoLabel": "动态照片",
|
"filterTypeMotionPhotoLabel": "动态照片",
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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}) {
|
||||||
|
|
73
lib/model/filters/missing.dart
Normal file
73
lib/model/filters/missing.dart
Normal 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';
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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: [
|
||||||
|
|
|
@ -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),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -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(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue