#1012 show chip selection in collection via or
filter
This commit is contained in:
parent
ece28db3f8
commit
fe0c2e345b
26 changed files with 139 additions and 56 deletions
|
@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## <a id="unreleased"></a>[Unreleased]
|
## <a id="unreleased"></a>[Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Albums / Countries / Tags: show selection in Collection
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Screen saver: black background, consistent with slideshow
|
- Screen saver: black background, consistent with slideshow
|
||||||
|
|
|
@ -32,7 +32,10 @@ extension ExtraAppMode on AppMode {
|
||||||
AppMode.pickMultipleMediaExternal,
|
AppMode.pickMultipleMediaExternal,
|
||||||
}.contains(this);
|
}.contains(this);
|
||||||
|
|
||||||
bool get canSelectFilter => this == AppMode.main;
|
bool get canSelectFilter => {
|
||||||
|
AppMode.main,
|
||||||
|
AppMode.pickCollectionFiltersExternal,
|
||||||
|
}.contains(this);
|
||||||
|
|
||||||
bool get canCreateFilter => {
|
bool get canCreateFilter => {
|
||||||
AppMode.main,
|
AppMode.main,
|
||||||
|
|
|
@ -85,6 +85,7 @@
|
||||||
"sourceStateLocatingPlaces": "Locating places",
|
"sourceStateLocatingPlaces": "Locating places",
|
||||||
|
|
||||||
"chipActionDelete": "Delete",
|
"chipActionDelete": "Delete",
|
||||||
|
"chipActionShowCollection": "Show in Collection",
|
||||||
"chipActionGoToAlbumPage": "Show in Albums",
|
"chipActionGoToAlbumPage": "Show in Albums",
|
||||||
"chipActionGoToCountryPage": "Show in Countries",
|
"chipActionGoToCountryPage": "Show in Countries",
|
||||||
"chipActionGoToPlacePage": "Show in Places",
|
"chipActionGoToPlacePage": "Show in Places",
|
||||||
|
|
|
@ -68,9 +68,7 @@ class AspectRatioFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.aspectRatio, size: size);
|
||||||
return Icon(AIcons.aspectRatio, size: size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
|
@ -69,7 +69,7 @@ class CoordinateFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.geoBounds, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.geoBounds, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
|
@ -122,9 +122,7 @@ class DateFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.date, size: size);
|
||||||
return Icon(AIcons.date, size: size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
|
@ -45,7 +45,7 @@ class FavouriteFilter extends CollectionFilter {
|
||||||
String getLabel(BuildContext context) => context.l10n.filterFavouriteLabel;
|
String getLabel(BuildContext context) => context.l10n.filterFavouriteLabel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.favourite, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.favourite, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Color> color(BuildContext context) {
|
Future<Color> color(BuildContext context) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import 'package:aves/model/filters/favourite.dart';
|
||||||
import 'package:aves/model/filters/location.dart';
|
import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/filters/mime.dart';
|
import 'package:aves/model/filters/mime.dart';
|
||||||
import 'package:aves/model/filters/missing.dart';
|
import 'package:aves/model/filters/missing.dart';
|
||||||
|
import 'package:aves/model/filters/or.dart';
|
||||||
import 'package:aves/model/filters/path.dart';
|
import 'package:aves/model/filters/path.dart';
|
||||||
import 'package:aves/model/filters/placeholder.dart';
|
import 'package:aves/model/filters/placeholder.dart';
|
||||||
import 'package:aves/model/filters/query.dart';
|
import 'package:aves/model/filters/query.dart';
|
||||||
|
@ -43,6 +44,7 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
|
||||||
AspectRatioFilter.type,
|
AspectRatioFilter.type,
|
||||||
MissingFilter.type,
|
MissingFilter.type,
|
||||||
PathFilter.type,
|
PathFilter.type,
|
||||||
|
OrFilter.type,
|
||||||
];
|
];
|
||||||
|
|
||||||
final bool reversed;
|
final bool reversed;
|
||||||
|
@ -68,6 +70,8 @@ abstract class CollectionFilter extends Equatable implements Comparable<Collecti
|
||||||
return MimeFilter.fromMap(jsonMap);
|
return MimeFilter.fromMap(jsonMap);
|
||||||
case MissingFilter.type:
|
case MissingFilter.type:
|
||||||
return MissingFilter.fromMap(jsonMap);
|
return MissingFilter.fromMap(jsonMap);
|
||||||
|
case OrFilter.type:
|
||||||
|
return OrFilter.fromMap(jsonMap);
|
||||||
case PathFilter.type:
|
case PathFilter.type:
|
||||||
return PathFilter.fromMap(jsonMap);
|
return PathFilter.fromMap(jsonMap);
|
||||||
case PlaceholderFilter.type:
|
case PlaceholderFilter.type:
|
||||||
|
|
|
@ -89,7 +89,7 @@ class LocationFilter extends CoveredCollectionFilter {
|
||||||
String getLabel(BuildContext context) => _isUnlocated ? context.l10n.filterNoLocationLabel : _location;
|
String getLabel(BuildContext context) => _isUnlocated ? context.l10n.filterNoLocationLabel : _location;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
||||||
if (_isUnlocated) {
|
if (_isUnlocated) {
|
||||||
return Icon(AIcons.locationUnlocated, size: size);
|
return Icon(AIcons.locationUnlocated, size: size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ class MimeFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Color> color(BuildContext context) {
|
Future<Color> color(BuildContext context) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ class MissingFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
72
lib/model/filters/or.dart
Normal file
72
lib/model/filters/or.dart
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import 'package:aves/model/filters/album.dart';
|
||||||
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
import 'package:aves/model/filters/location.dart';
|
||||||
|
import 'package:aves/theme/icons.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class OrFilter extends CollectionFilter {
|
||||||
|
static const type = 'or';
|
||||||
|
|
||||||
|
late final List<CollectionFilter> _filters;
|
||||||
|
|
||||||
|
late final EntryFilter _test;
|
||||||
|
late final IconData? _genericIcon;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [_filters, reversed];
|
||||||
|
|
||||||
|
CollectionFilter get _first => _filters.first;
|
||||||
|
|
||||||
|
OrFilter(Set<CollectionFilter> filters, {super.reversed = false}) {
|
||||||
|
_filters = filters.toList().sorted();
|
||||||
|
_test = (entry) => _filters.any((v) => v.test(entry));
|
||||||
|
switch (_first) {
|
||||||
|
case AlbumFilter():
|
||||||
|
_genericIcon = AIcons.album;
|
||||||
|
case LocationFilter(level: LocationLevel.country):
|
||||||
|
_genericIcon = AIcons.country;
|
||||||
|
case LocationFilter(level: LocationLevel.state):
|
||||||
|
_genericIcon = AIcons.state;
|
||||||
|
default:
|
||||||
|
_genericIcon = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
factory OrFilter.fromMap(Map<String, dynamic> json) {
|
||||||
|
return OrFilter(
|
||||||
|
(json['filters'] as List).cast<String>().map(CollectionFilter.fromJson).whereNotNull().toSet(),
|
||||||
|
reversed: json['reversed'] ?? false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toMap() => {
|
||||||
|
'type': type,
|
||||||
|
'filters': _filters.map((v) => v.toJson()).toList(),
|
||||||
|
'reversed': reversed,
|
||||||
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
EntryFilter get positiveTest => _test;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get exclusiveProp => false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get universalLabel => _filters.map((v) => v.universalLabel).join(', ');
|
||||||
|
|
||||||
|
@override
|
||||||
|
String getLabel(BuildContext context) => _filters.map((v) => v.getLabel(context)).join(', ');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
||||||
|
return _genericIcon != null ? Icon(_genericIcon, size: size) : _first.iconBuilder(context, size, showGenericIcon: showGenericIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get category => _first.category;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get key => '$type-$reversed-${_filters.map((v) => v.key)}';
|
||||||
|
}
|
|
@ -96,7 +96,7 @@ class PlaceholderFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
|
@ -82,7 +82,7 @@ class QueryFilter extends CollectionFilter {
|
||||||
String get universalLabel => query;
|
String get universalLabel => query;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.text, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.text, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Color> color(BuildContext context) {
|
Future<Color> color(BuildContext context) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ class RecentlyAddedFilter extends CollectionFilter {
|
||||||
String getLabel(BuildContext context) => context.l10n.filterRecentlyAddedLabel;
|
String getLabel(BuildContext context) => context.l10n.filterRecentlyAddedLabel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.dateRecent, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.dateRecent, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
|
@ -47,7 +47,9 @@ class TagFilter extends CoveredCollectionFilter {
|
||||||
String getLabel(BuildContext context) => tag.isEmpty ? context.l10n.filterNoTagLabel : tag;
|
String getLabel(BuildContext context) => tag.isEmpty ? context.l10n.filterNoTagLabel : tag;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => showGenericIcon ? Icon(tag.isEmpty ? AIcons.tagUntagged : AIcons.tag, size: size) : null;
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
||||||
|
return showGenericIcon ? Icon(tag.isEmpty ? AIcons.tagUntagged : AIcons.tag, size: size) : null;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
|
@ -41,7 +41,7 @@ class TrashFilter extends CollectionFilter {
|
||||||
String getLabel(BuildContext context) => context.l10n.filterBinLabel;
|
String getLabel(BuildContext context) => context.l10n.filterBinLabel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.bin, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.bin, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get category => type;
|
String get category => type;
|
||||||
|
|
|
@ -99,7 +99,7 @@ class TypeFilter extends CollectionFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
Widget? iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Color> color(BuildContext context) {
|
Future<Color> color(BuildContext context) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ extension ExtraChipSetActionView on ChipSetAction {
|
||||||
ChipSetAction.unpin => l10n.chipActionUnpin,
|
ChipSetAction.unpin => l10n.chipActionUnpin,
|
||||||
ChipSetAction.lockVault => l10n.chipActionLock,
|
ChipSetAction.lockVault => l10n.chipActionLock,
|
||||||
ChipSetAction.showCountryStates => l10n.chipActionShowCountryStates,
|
ChipSetAction.showCountryStates => l10n.chipActionShowCountryStates,
|
||||||
|
ChipSetAction.showCollection => l10n.chipActionShowCollection,
|
||||||
// selecting (single filter)
|
// selecting (single filter)
|
||||||
ChipSetAction.rename => l10n.chipActionRename,
|
ChipSetAction.rename => l10n.chipActionRename,
|
||||||
ChipSetAction.setCover => l10n.chipActionSetCover,
|
ChipSetAction.setCover => l10n.chipActionSetCover,
|
||||||
|
@ -64,6 +65,7 @@ extension ExtraChipSetActionView on ChipSetAction {
|
||||||
ChipSetAction.unpin => AIcons.unpin,
|
ChipSetAction.unpin => AIcons.unpin,
|
||||||
ChipSetAction.lockVault => AIcons.vaultLock,
|
ChipSetAction.lockVault => AIcons.vaultLock,
|
||||||
ChipSetAction.showCountryStates => AIcons.state,
|
ChipSetAction.showCountryStates => AIcons.state,
|
||||||
|
ChipSetAction.showCollection => AIcons.allCollection,
|
||||||
// selecting (single filter)
|
// selecting (single filter)
|
||||||
ChipSetAction.rename => AIcons.name,
|
ChipSetAction.rename => AIcons.name,
|
||||||
ChipSetAction.setCover => AIcons.setCover,
|
ChipSetAction.setCover => AIcons.setCover,
|
||||||
|
|
|
@ -385,7 +385,6 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
case AppMode.pickSingleMediaExternal:
|
case AppMode.pickSingleMediaExternal:
|
||||||
case AppMode.pickMultipleMediaExternal:
|
case AppMode.pickMultipleMediaExternal:
|
||||||
_saveTopEntries();
|
_saveTopEntries();
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -393,7 +392,6 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
availability.onResume();
|
availability.onResume();
|
||||||
RecentlyAddedFilter.updateNow();
|
RecentlyAddedFilter.updateNow();
|
||||||
_mediaStoreSource.checkForChanges();
|
_mediaStoreSource.checkForChanges();
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -639,10 +637,8 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
case AppMode.screenSaver:
|
case AppMode.screenSaver:
|
||||||
// we cannot modify brightness without access to the activity
|
// we cannot modify brightness without access to the activity
|
||||||
_screenBrightness = null;
|
_screenBrightness = null;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
_screenBrightness = ScreenBrightness();
|
_screenBrightness = ScreenBrightness();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,16 +133,12 @@ class AvesFilterChip extends StatefulWidget {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ChipAction.reverse:
|
case ChipAction.reverse:
|
||||||
text = filter.reversed ? context.l10n.chipActionFilterIn : context.l10n.chipActionFilterOut;
|
text = filter.reversed ? context.l10n.chipActionFilterIn : context.l10n.chipActionFilterOut;
|
||||||
break;
|
|
||||||
case ChipAction.ratingOrGreater:
|
case ChipAction.ratingOrGreater:
|
||||||
text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrGreater);
|
text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrGreater);
|
||||||
break;
|
|
||||||
case ChipAction.ratingOrLower:
|
case ChipAction.ratingOrLower:
|
||||||
text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrLower);
|
text = RatingFilter.formatRatingRange(context, (filter as RatingFilter).rating, RatingFilter.opOrLower);
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
text = action.getText(context);
|
text = action.getText(context);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return PopupMenuItem(
|
return PopupMenuItem(
|
||||||
value: action,
|
value: action,
|
||||||
|
|
|
@ -414,10 +414,8 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
|
||||||
case TransformActivity.pan:
|
case TransformActivity.pan:
|
||||||
case TransformActivity.resize:
|
case TransformActivity.resize:
|
||||||
_gridDivisionNotifier.value = panResizeGridDivision;
|
_gridDivisionNotifier.value = panResizeGridDivision;
|
||||||
break;
|
|
||||||
case TransformActivity.straighten:
|
case TransformActivity.straighten:
|
||||||
_gridDivisionNotifier.value = straightenGridDivision;
|
_gridDivisionNotifier.value = straightenGridDivision;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (activity == TransformActivity.none) {
|
if (activity == TransformActivity.none) {
|
||||||
_gridAnimationController.reverse();
|
_gridAnimationController.reverse();
|
||||||
|
@ -452,12 +450,10 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
|
||||||
case ChangeSource.internal:
|
case ChangeSource.internal:
|
||||||
case ChangeSource.animation:
|
case ChangeSource.animation:
|
||||||
_setOutline(currentOutline);
|
_setOutline(currentOutline);
|
||||||
break;
|
|
||||||
case ChangeSource.gesture:
|
case ChangeSource.gesture:
|
||||||
// TODO TLAD [crop] use other strat
|
// TODO TLAD [crop] use other strat
|
||||||
_setOutline(_applyCropRatioToOutline(currentOutline, _RatioStrategy.contain));
|
_setOutline(_applyCropRatioToOutline(currentOutline, _RatioStrategy.contain));
|
||||||
_updateCropRegion();
|
_updateCropRegion();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,19 +580,15 @@ class _CropperState extends State<Cropper> with SingleTickerProviderStateMixin {
|
||||||
case CropAspectRatio.original:
|
case CropAspectRatio.original:
|
||||||
longCoef = contentSize.longestSide.round();
|
longCoef = contentSize.longestSide.round();
|
||||||
shortCoef = contentSize.shortestSide.round();
|
shortCoef = contentSize.shortestSide.round();
|
||||||
break;
|
|
||||||
case CropAspectRatio.square:
|
case CropAspectRatio.square:
|
||||||
longCoef = 1;
|
longCoef = 1;
|
||||||
shortCoef = 1;
|
shortCoef = 1;
|
||||||
break;
|
|
||||||
case CropAspectRatio.ar_16_9:
|
case CropAspectRatio.ar_16_9:
|
||||||
longCoef = 16;
|
longCoef = 16;
|
||||||
shortCoef = 9;
|
shortCoef = 9;
|
||||||
break;
|
|
||||||
case CropAspectRatio.ar_4_3:
|
case CropAspectRatio.ar_4_3:
|
||||||
longCoef = 4;
|
longCoef = 4;
|
||||||
shortCoef = 3;
|
shortCoef = 3;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final contentRect = Offset.zero & contentSize;
|
final contentRect = Offset.zero & contentSize;
|
||||||
|
|
|
@ -49,27 +49,20 @@ class Transformation extends Equatable {
|
||||||
break;
|
break;
|
||||||
case TransformOrientation.rotate90:
|
case TransformOrientation.rotate90:
|
||||||
matrix.rotateZ(math.pi / 2);
|
matrix.rotateZ(math.pi / 2);
|
||||||
break;
|
|
||||||
case TransformOrientation.rotate180:
|
case TransformOrientation.rotate180:
|
||||||
matrix.rotateZ(math.pi);
|
matrix.rotateZ(math.pi);
|
||||||
break;
|
|
||||||
case TransformOrientation.rotate270:
|
case TransformOrientation.rotate270:
|
||||||
matrix.rotateZ(3 * math.pi / 2);
|
matrix.rotateZ(3 * math.pi / 2);
|
||||||
break;
|
|
||||||
case TransformOrientation.transverse:
|
case TransformOrientation.transverse:
|
||||||
matrix.scale(-1.0, 1.0, 1.0);
|
matrix.scale(-1.0, 1.0, 1.0);
|
||||||
matrix.rotateZ(-3 * math.pi / 2);
|
matrix.rotateZ(-3 * math.pi / 2);
|
||||||
break;
|
|
||||||
case TransformOrientation.flipVertical:
|
case TransformOrientation.flipVertical:
|
||||||
matrix.scale(1.0, -1.0, 1.0);
|
matrix.scale(1.0, -1.0, 1.0);
|
||||||
break;
|
|
||||||
case TransformOrientation.transpose:
|
case TransformOrientation.transpose:
|
||||||
matrix.scale(-1.0, 1.0, 1.0);
|
matrix.scale(-1.0, 1.0, 1.0);
|
||||||
matrix.rotateZ(-1 * math.pi / 2);
|
matrix.rotateZ(-1 * math.pi / 2);
|
||||||
break;
|
|
||||||
case TransformOrientation.flipHorizontal:
|
case TransformOrientation.flipHorizontal:
|
||||||
matrix.scale(-1.0, 1.0, 1.0);
|
matrix.scale(-1.0, 1.0, 1.0);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/model/covers.dart';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/filters/album.dart';
|
import 'package:aves/model/filters/album.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
import 'package:aves/model/filters/or.dart';
|
||||||
import 'package:aves/model/query.dart';
|
import 'package:aves/model/query.dart';
|
||||||
import 'package:aves/model/selection.dart';
|
import 'package:aves/model/selection.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
@ -13,6 +14,7 @@ import 'package:aves/theme/colors.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/theme/themes.dart';
|
import 'package:aves/theme/themes.dart';
|
||||||
import 'package:aves/view/view.dart';
|
import 'package:aves/view/view.dart';
|
||||||
|
import 'package:aves/widgets/collection/collection_page.dart';
|
||||||
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
||||||
import 'package:aves/widgets/common/action_mixins/permission_aware.dart';
|
import 'package:aves/widgets/common/action_mixins/permission_aware.dart';
|
||||||
import 'package:aves/widgets/common/action_mixins/size_aware.dart';
|
import 'package:aves/widgets/common/action_mixins/size_aware.dart';
|
||||||
|
@ -99,9 +101,11 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
case ChipSetAction.hide:
|
case ChipSetAction.hide:
|
||||||
return isMain;
|
return isMain;
|
||||||
case ChipSetAction.pin:
|
case ChipSetAction.pin:
|
||||||
return !hasSelection || !settings.pinnedFilters.containsAll(selectedFilters);
|
return isMain && (!hasSelection || !settings.pinnedFilters.containsAll(selectedFilters));
|
||||||
case ChipSetAction.unpin:
|
case ChipSetAction.unpin:
|
||||||
return hasSelection && settings.pinnedFilters.containsAll(selectedFilters);
|
return isMain && (hasSelection && settings.pinnedFilters.containsAll(selectedFilters));
|
||||||
|
case ChipSetAction.showCollection:
|
||||||
|
return appMode.canNavigate;
|
||||||
case ChipSetAction.delete:
|
case ChipSetAction.delete:
|
||||||
case ChipSetAction.lockVault:
|
case ChipSetAction.lockVault:
|
||||||
case ChipSetAction.showCountryStates:
|
case ChipSetAction.showCountryStates:
|
||||||
|
@ -149,6 +153,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
case ChipSetAction.unpin:
|
case ChipSetAction.unpin:
|
||||||
case ChipSetAction.lockVault:
|
case ChipSetAction.lockVault:
|
||||||
case ChipSetAction.showCountryStates:
|
case ChipSetAction.showCountryStates:
|
||||||
|
case ChipSetAction.showCollection:
|
||||||
return hasSelection;
|
return hasSelection;
|
||||||
// selecting (single filter)
|
// selecting (single filter)
|
||||||
case ChipSetAction.rename:
|
case ChipSetAction.rename:
|
||||||
|
@ -194,6 +199,8 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
case ChipSetAction.unpin:
|
case ChipSetAction.unpin:
|
||||||
settings.pinnedFilters = settings.pinnedFilters..removeAll(getSelectedFilters(context));
|
settings.pinnedFilters = settings.pinnedFilters..removeAll(getSelectedFilters(context));
|
||||||
browse(context);
|
browse(context);
|
||||||
|
case ChipSetAction.showCollection:
|
||||||
|
_goToCollection(context);
|
||||||
case ChipSetAction.delete:
|
case ChipSetAction.delete:
|
||||||
case ChipSetAction.lockVault:
|
case ChipSetAction.lockVault:
|
||||||
case ChipSetAction.showCountryStates:
|
case ChipSetAction.showCountryStates:
|
||||||
|
@ -251,6 +258,22 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _goToCollection(context) async {
|
||||||
|
final filters = getSelectedFilters(context);
|
||||||
|
if (filters.isEmpty) return;
|
||||||
|
|
||||||
|
final filter = filters.length > 1 ? OrFilter(filters) : filters.first;
|
||||||
|
await Navigator.maybeOf(context)?.push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
settings: const RouteSettings(name: CollectionPage.routeName),
|
||||||
|
builder: (context) => CollectionPage(
|
||||||
|
source: context.read<CollectionSource>(),
|
||||||
|
filters: {filter},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _goToMap(BuildContext context) async {
|
Future<void> _goToMap(BuildContext context) async {
|
||||||
final mapCollection = CollectionLens(
|
final mapCollection = CollectionLens(
|
||||||
source: context.read<CollectionSource>(),
|
source: context.read<CollectionSource>(),
|
||||||
|
@ -264,9 +287,9 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _goToSlideshow(BuildContext context) {
|
Future<void> _goToSlideshow(BuildContext context) async {
|
||||||
final entries = _selectedEntries(context).toList();
|
final entries = _selectedEntries(context).toList();
|
||||||
Navigator.maybeOf(context)?.push(
|
await Navigator.maybeOf(context)?.push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
settings: const RouteSettings(name: SlideshowPage.routeName),
|
settings: const RouteSettings(name: SlideshowPage.routeName),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
@ -281,9 +304,9 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _goToStats(BuildContext context) {
|
Future<void> _goToStats(BuildContext context) async {
|
||||||
final entries = _selectedEntries(context).toSet();
|
final entries = _selectedEntries(context).toSet();
|
||||||
Navigator.maybeOf(context)?.push(
|
await Navigator.maybeOf(context)?.push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
settings: const RouteSettings(name: StatsPage.routeName),
|
settings: const RouteSettings(name: StatsPage.routeName),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
@ -296,8 +319,8 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _goToSearch(BuildContext context) {
|
Future<void> _goToSearch(BuildContext context) async {
|
||||||
Navigator.maybeOf(context)?.push(
|
await Navigator.maybeOf(context)?.push(
|
||||||
SearchPageRoute(
|
SearchPageRoute(
|
||||||
delegate: CollectionSearchDelegate(
|
delegate: CollectionSearchDelegate(
|
||||||
searchFieldLabel: context.l10n.searchCollectionFieldHint,
|
searchFieldLabel: context.l10n.searchCollectionFieldHint,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/services/intent_service.dart';
|
||||||
import 'package:aves/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
import 'package:aves/widgets/collection/filter_bar.dart';
|
import 'package:aves/widgets/collection/filter_bar.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
import 'package:aves/widgets/common/identity/aves_caption.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SettingsCollectionTile extends StatelessWidget {
|
class SettingsCollectionTile extends StatelessWidget {
|
||||||
|
@ -19,7 +20,6 @@ class SettingsCollectionTile extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final textTheme = theme.textTheme;
|
|
||||||
final hasSubtitle = filters.isEmpty;
|
final hasSubtitle = filters.isEmpty;
|
||||||
|
|
||||||
// size and padding to match `ListTile`
|
// size and padding to match `ListTile`
|
||||||
|
@ -39,13 +39,10 @@ class SettingsCollectionTile extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.settingsCollectionTile,
|
l10n.settingsCollectionTile,
|
||||||
style: textTheme.titleMedium!,
|
// fallback to `ListTile` M3 default style
|
||||||
|
style: theme.listTileTheme.titleTextStyle ?? theme.textTheme.bodyLarge!.copyWith(color: theme.colorScheme.onSurface),
|
||||||
),
|
),
|
||||||
if (hasSubtitle)
|
if (hasSubtitle) AvesCaption(l10n.drawerCollectionAll),
|
||||||
Text(
|
|
||||||
l10n.drawerCollectionAll,
|
|
||||||
style: textTheme.bodyMedium!.copyWith(color: theme.colorScheme.onSurfaceVariant),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
|
|
@ -20,6 +20,7 @@ enum ChipSetAction {
|
||||||
unpin,
|
unpin,
|
||||||
lockVault,
|
lockVault,
|
||||||
showCountryStates,
|
showCountryStates,
|
||||||
|
showCollection,
|
||||||
// selecting (single filter)
|
// selecting (single filter)
|
||||||
rename,
|
rename,
|
||||||
setCover,
|
setCover,
|
||||||
|
@ -57,6 +58,7 @@ class ChipSetActions {
|
||||||
ChipSetAction.showCountryStates,
|
ChipSetAction.showCountryStates,
|
||||||
ChipSetAction.hide,
|
ChipSetAction.hide,
|
||||||
null,
|
null,
|
||||||
|
ChipSetAction.showCollection,
|
||||||
ChipSetAction.map,
|
ChipSetAction.map,
|
||||||
ChipSetAction.slideshow,
|
ChipSetAction.slideshow,
|
||||||
ChipSetAction.stats,
|
ChipSetAction.stats,
|
||||||
|
|
Loading…
Reference in a new issue