diff --git a/CHANGELOG.md b/CHANGELOG.md index d55cc5b7d..78dce5151 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9fc8bfa26..1e7229c4b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -124,6 +124,8 @@ "entryInfoActionRemoveMetadata": "Remove metadata", "entryInfoActionExportMetadata": "Export metadata", + "filterAspectRatioLandscapeLabel": "Landscape", + "filterAspectRatioPortraitLabel": "Portrait", "filterBinLabel": "Recycle bin", "filterFavouriteLabel": "Favorite", "filterNoDateLabel": "Undated", diff --git a/lib/model/filters/aspect_ratio.dart b/lib/model/filters/aspect_ratio.dart new file mode 100644 index 000000000..92ee97279 --- /dev/null +++ b/lib/model/filters/aspect_ratio.dart @@ -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 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 json) { + return AspectRatioFilter( + json['threshold'] as double, + json['op'] as String, + reversed: json['reversed'] ?? false, + ); + } + + @override + Map 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'; +} diff --git a/lib/model/filters/filters.dart b/lib/model/filters/filters.dart index 930dd2da2..8770c7149 100644 --- a/lib/model/filters/filters.dart +++ b/lib/model/filters/filters.dart @@ -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