#416 search: portrait, landscape filters
This commit is contained in:
parent
92639a7066
commit
5a6153b970
8 changed files with 140 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -124,6 +124,8 @@
|
|||
"entryInfoActionRemoveMetadata": "Remove metadata",
|
||||
"entryInfoActionExportMetadata": "Export metadata",
|
||||
|
||||
"filterAspectRatioLandscapeLabel": "Landscape",
|
||||
"filterAspectRatioPortraitLabel": "Portrait",
|
||||
"filterBinLabel": "Recycle bin",
|
||||
"filterFavouriteLabel": "Favorite",
|
||||
"filterNoDateLabel": "Undated",
|
||||
|
|
83
lib/model/filters/aspect_ratio.dart
Normal file
83
lib/model/filters/aspect_ratio.dart
Normal 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';
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue