minor
This commit is contained in:
parent
6cb6489fa9
commit
a3c354af0c
11 changed files with 140 additions and 40 deletions
|
@ -20,11 +20,12 @@ class AlbumFilter extends CoveredCollectionFilter {
|
||||||
|
|
||||||
const AlbumFilter(this.album, this.displayName);
|
const AlbumFilter(this.album, this.displayName);
|
||||||
|
|
||||||
AlbumFilter.fromMap(Map<String, dynamic> json)
|
factory AlbumFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return AlbumFilter(
|
||||||
json['album'],
|
json['album'],
|
||||||
json['uniqueName'],
|
json['uniqueName'],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
|
@ -23,11 +23,12 @@ class CoordinateFilter extends CollectionFilter {
|
||||||
|
|
||||||
const CoordinateFilter(this.sw, this.ne, {this.minuteSecondPadding = false});
|
const CoordinateFilter(this.sw, this.ne, {this.minuteSecondPadding = false});
|
||||||
|
|
||||||
CoordinateFilter.fromMap(Map<String, dynamic> json)
|
factory CoordinateFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return CoordinateFilter(
|
||||||
LatLng.fromJson(json['sw']),
|
LatLng.fromJson(json['sw']),
|
||||||
LatLng.fromJson(json['ne']),
|
LatLng.fromJson(json['ne']),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
91
lib/model/filters/date.dart
Normal file
91
lib/model/filters/date.dart
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import 'package:aves/model/device.dart';
|
||||||
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
import 'package:aves/theme/icons.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class LocationFilter extends CoveredCollectionFilter {
|
||||||
|
static const type = 'location';
|
||||||
|
static const locationSeparator = ';';
|
||||||
|
|
||||||
|
final LocationLevel level;
|
||||||
|
late final String _location;
|
||||||
|
late final String? _countryCode;
|
||||||
|
late final EntryFilter _test;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [level, _location, _countryCode];
|
||||||
|
|
||||||
|
LocationFilter(this.level, String location) {
|
||||||
|
final split = location.split(locationSeparator);
|
||||||
|
_location = split.isNotEmpty ? split[0] : location;
|
||||||
|
_countryCode = split.length > 1 ? split[1] : null;
|
||||||
|
|
||||||
|
if (_location.isEmpty) {
|
||||||
|
_test = (entry) => !entry.hasGps;
|
||||||
|
} else if (level == LocationLevel.country) {
|
||||||
|
_test = (entry) => entry.addressDetails?.countryCode == _countryCode;
|
||||||
|
} else if (level == LocationLevel.place) {
|
||||||
|
_test = (entry) => entry.addressDetails?.place == _location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationFilter.fromMap(Map<String, dynamic> json)
|
||||||
|
: this(
|
||||||
|
LocationLevel.values.firstWhereOrNull((v) => v.toString() == json['level']) ?? LocationLevel.place,
|
||||||
|
json['location'],
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toMap() => {
|
||||||
|
'type': type,
|
||||||
|
'level': level.toString(),
|
||||||
|
'location': _countryCode != null ? countryNameAndCode : _location,
|
||||||
|
};
|
||||||
|
|
||||||
|
String get countryNameAndCode => '$_location$locationSeparator$_countryCode';
|
||||||
|
|
||||||
|
String? get countryCode => _countryCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
EntryFilter get test => _test;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get universalLabel => _location;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String getLabel(BuildContext context) => _location.isEmpty ? context.l10n.filterLocationEmptyLabel : _location;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
||||||
|
if (_countryCode != null && device.canRenderFlagEmojis) {
|
||||||
|
final flag = countryCodeToFlag(_countryCode);
|
||||||
|
if (flag != null) {
|
||||||
|
return Text(
|
||||||
|
flag,
|
||||||
|
style: TextStyle(fontSize: size),
|
||||||
|
textScaleFactor: 1.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Icon(_location.isEmpty ? AIcons.locationUnlocated : AIcons.location, size: size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get category => type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get key => '$type-$level-$_location';
|
||||||
|
|
||||||
|
// U+0041 Latin Capital letter A
|
||||||
|
// U+1F1E6 🇦 REGIONAL INDICATOR SYMBOL LETTER A
|
||||||
|
static const _countryCodeToFlagDiff = 0x1F1E6 - 0x0041;
|
||||||
|
|
||||||
|
static String? countryCodeToFlag(String? code) {
|
||||||
|
if (code == null || code.length != 2) return null;
|
||||||
|
return String.fromCharCodes(code.toUpperCase().codeUnits.map((letter) => letter += _countryCodeToFlagDiff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LocationLevel { place, country }
|
|
@ -31,11 +31,12 @@ class LocationFilter extends CoveredCollectionFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocationFilter.fromMap(Map<String, dynamic> json)
|
factory LocationFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return LocationFilter(
|
||||||
LocationLevel.values.firstWhereOrNull((v) => v.toString() == json['level']) ?? LocationLevel.place,
|
LocationLevel.values.firstWhereOrNull((v) => v.toString() == json['level']) ?? LocationLevel.place,
|
||||||
json['location'],
|
json['location'],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
|
@ -43,10 +43,11 @@ class MimeFilter extends CollectionFilter {
|
||||||
_icon = icon ?? AIcons.vector;
|
_icon = icon ?? AIcons.vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeFilter.fromMap(Map<String, dynamic> json)
|
factory MimeFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return MimeFilter(
|
||||||
json['mime'],
|
json['mime'],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
|
@ -15,10 +15,11 @@ class PathFilter extends CollectionFilter {
|
||||||
|
|
||||||
PathFilter(this.path) : _rootAlbum = path.substring(0, path.length - 1);
|
PathFilter(this.path) : _rootAlbum = path.substring(0, path.length - 1);
|
||||||
|
|
||||||
PathFilter.fromMap(Map<String, dynamic> json)
|
factory PathFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return PathFilter(
|
||||||
json['path'],
|
json['path'],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
|
@ -59,10 +59,11 @@ class QueryFilter extends CollectionFilter {
|
||||||
_test = not ? (entry) => !testTitle(entry) : testTitle;
|
_test = not ? (entry) => !testTitle(entry) : testTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryFilter.fromMap(Map<String, dynamic> json)
|
factory QueryFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return QueryFilter(
|
||||||
json['query'],
|
json['query'],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
|
@ -13,10 +13,11 @@ class RatingFilter extends CollectionFilter {
|
||||||
|
|
||||||
const RatingFilter(this.rating);
|
const RatingFilter(this.rating);
|
||||||
|
|
||||||
RatingFilter.fromMap(Map<String, dynamic> json)
|
factory RatingFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return RatingFilter(
|
||||||
json['rating'] ?? 0,
|
json['rating'] ?? 0,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
|
@ -20,11 +20,12 @@ class TagFilter extends CoveredCollectionFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TagFilter.fromMap(Map<String, dynamic> json)
|
factory TagFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this(
|
return TagFilter(
|
||||||
json['tag'],
|
json['tag'],
|
||||||
not: json['not'] ?? false,
|
not: json['not'] ?? false,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
|
@ -59,10 +59,11 @@ class TypeFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeFilter.fromMap(Map<String, dynamic> json)
|
factory TypeFilter.fromMap(Map<String, dynamic> json) {
|
||||||
: this._private(
|
return TypeFilter._private(
|
||||||
json['itemType'],
|
json['itemType'],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
|
|
0
lib/widgets/stats/histogram.dart
Normal file
0
lib/widgets/stats/histogram.dart
Normal file
Loading…
Reference in a new issue