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);
|
||||
|
||||
AlbumFilter.fromMap(Map<String, dynamic> json)
|
||||
: this(
|
||||
json['album'],
|
||||
json['uniqueName'],
|
||||
);
|
||||
factory AlbumFilter.fromMap(Map<String, dynamic> json) {
|
||||
return AlbumFilter(
|
||||
json['album'],
|
||||
json['uniqueName'],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() => {
|
||||
|
|
|
@ -23,11 +23,12 @@ class CoordinateFilter extends CollectionFilter {
|
|||
|
||||
const CoordinateFilter(this.sw, this.ne, {this.minuteSecondPadding = false});
|
||||
|
||||
CoordinateFilter.fromMap(Map<String, dynamic> json)
|
||||
: this(
|
||||
LatLng.fromJson(json['sw']),
|
||||
LatLng.fromJson(json['ne']),
|
||||
);
|
||||
factory CoordinateFilter.fromMap(Map<String, dynamic> json) {
|
||||
return CoordinateFilter(
|
||||
LatLng.fromJson(json['sw']),
|
||||
LatLng.fromJson(json['ne']),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
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)
|
||||
: this(
|
||||
LocationLevel.values.firstWhereOrNull((v) => v.toString() == json['level']) ?? LocationLevel.place,
|
||||
json['location'],
|
||||
);
|
||||
factory LocationFilter.fromMap(Map<String, dynamic> json) {
|
||||
return LocationFilter(
|
||||
LocationLevel.values.firstWhereOrNull((v) => v.toString() == json['level']) ?? LocationLevel.place,
|
||||
json['location'],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() => {
|
||||
|
|
|
@ -43,10 +43,11 @@ class MimeFilter extends CollectionFilter {
|
|||
_icon = icon ?? AIcons.vector;
|
||||
}
|
||||
|
||||
MimeFilter.fromMap(Map<String, dynamic> json)
|
||||
: this(
|
||||
json['mime'],
|
||||
);
|
||||
factory MimeFilter.fromMap(Map<String, dynamic> json) {
|
||||
return MimeFilter(
|
||||
json['mime'],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() => {
|
||||
|
|
|
@ -15,10 +15,11 @@ class PathFilter extends CollectionFilter {
|
|||
|
||||
PathFilter(this.path) : _rootAlbum = path.substring(0, path.length - 1);
|
||||
|
||||
PathFilter.fromMap(Map<String, dynamic> json)
|
||||
: this(
|
||||
json['path'],
|
||||
);
|
||||
factory PathFilter.fromMap(Map<String, dynamic> json) {
|
||||
return PathFilter(
|
||||
json['path'],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() => {
|
||||
|
|
|
@ -59,10 +59,11 @@ class QueryFilter extends CollectionFilter {
|
|||
_test = not ? (entry) => !testTitle(entry) : testTitle;
|
||||
}
|
||||
|
||||
QueryFilter.fromMap(Map<String, dynamic> json)
|
||||
: this(
|
||||
json['query'],
|
||||
);
|
||||
factory QueryFilter.fromMap(Map<String, dynamic> json) {
|
||||
return QueryFilter(
|
||||
json['query'],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() => {
|
||||
|
|
|
@ -13,10 +13,11 @@ class RatingFilter extends CollectionFilter {
|
|||
|
||||
const RatingFilter(this.rating);
|
||||
|
||||
RatingFilter.fromMap(Map<String, dynamic> json)
|
||||
: this(
|
||||
json['rating'] ?? 0,
|
||||
);
|
||||
factory RatingFilter.fromMap(Map<String, dynamic> json) {
|
||||
return RatingFilter(
|
||||
json['rating'] ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() => {
|
||||
|
|
|
@ -20,11 +20,12 @@ class TagFilter extends CoveredCollectionFilter {
|
|||
}
|
||||
}
|
||||
|
||||
TagFilter.fromMap(Map<String, dynamic> json)
|
||||
: this(
|
||||
json['tag'],
|
||||
not: json['not'] ?? false,
|
||||
);
|
||||
factory TagFilter.fromMap(Map<String, dynamic> json) {
|
||||
return TagFilter(
|
||||
json['tag'],
|
||||
not: json['not'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() => {
|
||||
|
|
|
@ -59,10 +59,11 @@ class TypeFilter extends CollectionFilter {
|
|||
}
|
||||
}
|
||||
|
||||
TypeFilter.fromMap(Map<String, dynamic> json)
|
||||
: this._private(
|
||||
json['itemType'],
|
||||
);
|
||||
factory TypeFilter.fromMap(Map<String, dynamic> json) {
|
||||
return TypeFilter._private(
|
||||
json['itemType'],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
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