#416 search: portrait, landscape filters

This commit is contained in:
Thibault Deckers 2022-11-29 18:34:44 +01:00
parent 92639a7066
commit 5a6153b970
8 changed files with 140 additions and 1 deletions

View file

@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- Viewer: optionally show rating & tags on overlay
- Viewer: long press on rating quick action for quicker rating
- Search: missing address filter
- Search: missing address, portrait, landscape filters
- Lithuanian translation (thanks Gediminas Murauskas)
### Changed

View file

@ -124,6 +124,8 @@
"entryInfoActionRemoveMetadata": "Remove metadata",
"entryInfoActionExportMetadata": "Export metadata",
"filterAspectRatioLandscapeLabel": "Landscape",
"filterAspectRatioPortraitLabel": "Portrait",
"filterBinLabel": "Recycle bin",
"filterFavouriteLabel": "Favorite",
"filterNoDateLabel": "Undated",

View file

@ -0,0 +1,83 @@
import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/filters/query.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:flutter/widgets.dart';
class AspectRatioFilter extends CollectionFilter {
static const type = 'aspect_ratio';
final double threshold;
final String op;
late final EntryFilter _test;
static final landscape = AspectRatioFilter(1, QueryFilter.opGreater);
static final portrait = AspectRatioFilter(1, QueryFilter.opLower);
@override
List<Object?> get props => [threshold, op, reversed];
AspectRatioFilter(this.threshold, this.op, {super.reversed = false}) {
switch (op) {
case QueryFilter.opEqual:
_test = (entry) => entry.displayAspectRatio == threshold;
break;
case QueryFilter.opLower:
_test = (entry) => entry.displayAspectRatio < threshold;
break;
case QueryFilter.opGreater:
_test = (entry) => entry.displayAspectRatio > threshold;
break;
}
}
factory AspectRatioFilter.fromMap(Map<String, dynamic> json) {
return AspectRatioFilter(
json['threshold'] as double,
json['op'] as String,
reversed: json['reversed'] ?? false,
);
}
@override
Map<String, dynamic> toMap() => {
'type': type,
'threshold': threshold,
'op': op,
'reversed': reversed,
};
@override
EntryFilter get positiveTest => _test;
@override
bool get exclusiveProp => true;
@override
String get universalLabel => '$op $threshold';
@override
String getLabel(BuildContext context) {
final l10n = context.l10n;
if (threshold == 1) {
switch (op) {
case QueryFilter.opGreater:
return l10n.filterAspectRatioLandscapeLabel;
case QueryFilter.opLower:
return l10n.filterAspectRatioPortraitLabel;
}
}
return universalLabel;
}
@override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
return Icon(AIcons.aspectRatio, size: size);
}
@override
String get category => type;
@override
String get key => '$type-$reversed-$threshold-$op';
}

View file

@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:aves/model/covers.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/aspect_ratio.dart';
import 'package:aves/model/filters/coordinate.dart';
import 'package:aves/model/filters/date.dart';
import 'package:aves/model/filters/favourite.dart';
@ -38,6 +39,7 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
FavouriteFilter.type,
RatingFilter.type,
TagFilter.type,
AspectRatioFilter.type,
MissingFilter.type,
PathFilter.type,
];
@ -51,6 +53,8 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
switch (type) {
case AlbumFilter.type:
return AlbumFilter.fromMap(jsonMap);
case AspectRatioFilter.type:
return AspectRatioFilter.fromMap(jsonMap);
case CoordinateFilter.type:
return CoordinateFilter.fromMap(jsonMap);
case DateFilter.type:

View file

@ -11,6 +11,7 @@ class AIcons {
static const IconData android = Icons.android;
static const IconData app = Icons.apps_outlined;
static const IconData apply = Icons.done_outlined;
static const IconData aspectRatio = Icons.aspect_ratio_outlined;
static const IconData bin = Icons.delete_outlined;
static const IconData broken = Icons.broken_image_outlined;
static const IconData checked = Icons.done_outlined;

View file

@ -1,4 +1,5 @@
import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/aspect_ratio.dart';
import 'package:aves/model/filters/date.dart';
import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/filters.dart';
@ -40,6 +41,8 @@ class CollectionSearchDelegate extends AvesSearchDelegate {
MimeFilter.video,
TypeFilter.animated,
TypeFilter.motionPhoto,
AspectRatioFilter.portrait,
AspectRatioFilter.landscape,
TypeFilter.panorama,
TypeFilter.sphericalVideo,
TypeFilter.geotiff,

View file

@ -1,4 +1,5 @@
import 'package:aves/model/filters/album.dart';
import 'package:aves/model/filters/aspect_ratio.dart';
import 'package:aves/model/filters/coordinate.dart';
import 'package:aves/model/filters/date.dart';
import 'package:aves/model/filters/favourite.dart';
@ -36,6 +37,9 @@ void main() {
final album = AlbumFilter('path/to/album', 'album');
expect(album, jsonRoundTrip(album));
final aspectRatio = AspectRatioFilter.landscape;
expect(aspectRatio, jsonRoundTrip(aspectRatio));
final bounds = CoordinateFilter(LatLng(29.979167, 28.223615), LatLng(36.451000, 31.134167));
expect(bounds, jsonRoundTrip(bounds));

View file

@ -86,6 +86,8 @@
"entryInfoActionEditTags",
"entryInfoActionRemoveMetadata",
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterBinLabel",
"filterFavouriteLabel",
"filterNoDateLabel",
@ -592,6 +594,8 @@
],
"de": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"subtitlePositionTop",
"subtitlePositionBottom",
@ -604,11 +608,15 @@
],
"el": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
"es": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
@ -700,6 +708,8 @@
"entryInfoActionEditTags",
"entryInfoActionRemoveMetadata",
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterBinLabel",
"filterFavouriteLabel",
"filterNoDateLabel",
@ -1206,12 +1216,16 @@
],
"fr": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
"gl": [
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"accessibilityAnimationsRemove",
"accessibilityAnimationsKeep",
@ -1671,6 +1685,8 @@
"id": [
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"subtitlePositionTop",
"subtitlePositionBottom",
@ -1683,6 +1699,8 @@
],
"it": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
@ -1690,6 +1708,8 @@
"ja": [
"chipActionFilterIn",
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"subtitlePositionTop",
"subtitlePositionBottom",
@ -1702,11 +1722,15 @@
],
"ko": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
"lt": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
@ -1716,6 +1740,8 @@
"videoActionSelectStreams",
"entryInfoActionEditLocation",
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"coordinateFormatDms",
"mapStyleHuaweiNormal",
@ -1836,6 +1862,8 @@
"nl": [
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"subtitlePositionTop",
"subtitlePositionBottom",
@ -1854,6 +1882,8 @@
"timeDays",
"focalLength",
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"filterTypeRawLabel",
"filterTypeSphericalVideoLabel",
@ -2348,6 +2378,8 @@
"pt": [
"entryInfoActionExportMetadata",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"subtitlePositionTop",
"subtitlePositionBottom",
@ -2360,11 +2392,15 @@
],
"ro": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
"ru": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
@ -2378,6 +2414,8 @@
"applyButtonLabel",
"entryActionShowGeoTiffOnMap",
"videoActionCaptureFrame",
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"coordinateDms",
"keepScreenOnViewerOnly",
@ -2742,11 +2780,15 @@
],
"tr": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"settingsViewerShowRatingTags"
],
"zh": [
"filterAspectRatioLandscapeLabel",
"filterAspectRatioPortraitLabel",
"filterNoAddressLabel",
"aboutLicensesFlutterPackagesSectionTitle",
"aboutLicensesDartPackagesSectionTitle",