#1323 preserve favourite status when converting items
This commit is contained in:
parent
0a3a792a7e
commit
598b705b36
4 changed files with 44 additions and 26 deletions
|
@ -10,9 +10,10 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- improved subsampling and filter quality strategy
|
- Viewer: improved subsampling and filter quality strategy
|
||||||
- ignore moving an item to its current directory
|
- Collection: ignore moving an item to its current directory
|
||||||
- keep selection when action on several items is interrupted before processing
|
- Collection: keep selection when action on several items is interrupted before processing
|
||||||
|
- Collection: preserve favourite status when converting items
|
||||||
- upgraded Flutter to stable v3.27.3
|
- upgraded Flutter to stable v3.27.3
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -341,9 +341,9 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
itemCount: todoCount,
|
itemCount: todoCount,
|
||||||
onCancel: () => mediaEditService.cancelFileOp(opId),
|
onCancel: () => mediaEditService.cancelFileOp(opId),
|
||||||
onDone: (processed) async {
|
onDone: (processed) async {
|
||||||
final successOps = processed.where((e) => e.success).toSet();
|
final successOps = processed.where((op) => op.success).toSet();
|
||||||
final deletedOps = successOps.where((e) => !e.skipped).toSet();
|
final deletedOps = successOps.where((op) => !op.skipped).toSet();
|
||||||
final deletedUris = deletedOps.map((event) => event.uri).toSet();
|
final deletedUris = deletedOps.map((op) => op.uri).toSet();
|
||||||
await source.removeEntries(deletedUris, includeTrash: true);
|
await source.removeEntries(deletedUris, includeTrash: true);
|
||||||
source.resumeMonitoring();
|
source.resumeMonitoring();
|
||||||
|
|
||||||
|
@ -460,11 +460,11 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
itemCount: todoCount,
|
itemCount: todoCount,
|
||||||
onCancel: () => cancelled = true,
|
onCancel: () => cancelled = true,
|
||||||
onDone: (processed) async {
|
onDone: (processed) async {
|
||||||
final successOps = processed.where((e) => e.success).toSet();
|
final successOps = processed.where((op) => op.success).toSet();
|
||||||
final editedOps = successOps.where((e) => !e.skipped).toSet();
|
final editedOps = successOps.where((op) => !op.skipped).toSet();
|
||||||
source.resumeMonitoring();
|
source.resumeMonitoring();
|
||||||
|
|
||||||
unawaited(source.refreshUris(editedOps.map((v) => v.uri).toSet()).then((_) {
|
unawaited(source.refreshUris(editedOps.map((op) => op.uri).toSet()).then((_) {
|
||||||
// invalidate filters derived from values before edition
|
// invalidate filters derived from values before edition
|
||||||
// this invalidation must happen after the source is refreshed,
|
// this invalidation must happen after the source is refreshed,
|
||||||
// otherwise filter chips may eagerly rebuild in between with the old state
|
// otherwise filter chips may eagerly rebuild in between with the old state
|
||||||
|
|
|
@ -3,8 +3,10 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
|
import 'package:aves/model/entry/extensions/favourites.dart';
|
||||||
import 'package:aves/model/entry/extensions/multipage.dart';
|
import 'package:aves/model/entry/extensions/multipage.dart';
|
||||||
import 'package:aves/model/entry/extensions/props.dart';
|
import 'package:aves/model/entry/extensions/props.dart';
|
||||||
|
import 'package:aves/model/favourites.dart';
|
||||||
import 'package:aves/model/filters/covered/stored_album.dart';
|
import 'package:aves/model/filters/covered/stored_album.dart';
|
||||||
import 'package:aves/model/filters/trash.dart';
|
import 'package:aves/model/filters/trash.dart';
|
||||||
import 'package:aves/model/highlight.dart';
|
import 'package:aves/model/highlight.dart';
|
||||||
|
@ -107,13 +109,28 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin {
|
||||||
),
|
),
|
||||||
itemCount: selectionCount,
|
itemCount: selectionCount,
|
||||||
onDone: (processed) async {
|
onDone: (processed) async {
|
||||||
final successOps = processed.where((e) => e.success).toSet();
|
final successOps = processed.where((op) => op.success).toSet();
|
||||||
final exportedOps = successOps.where((e) => !e.skipped).toSet();
|
final exportedOps = successOps.where((op) => !op.skipped && op.newFields['uri'] != null).toSet();
|
||||||
final newUris = exportedOps.map((v) => v.newFields['uri'] as String?).nonNulls.toSet();
|
final newUris = exportedOps.map((op) => op.newFields['uri'] as String).toSet();
|
||||||
final isMainMode = context.read<ValueNotifier<AppMode>>().value == AppMode.main;
|
final isMainMode = context.read<ValueNotifier<AppMode>>().value == AppMode.main;
|
||||||
|
|
||||||
|
// check source favourite status
|
||||||
|
final favouriteSourceUris = selection.where((entry) => entry.isFavourite).map((entry) => entry.uri).toSet();
|
||||||
|
final favouriteNewUris = <String>{};
|
||||||
|
exportedOps.forEach((op) {
|
||||||
|
final sourceUri = op.uri;
|
||||||
|
if (favouriteSourceUris.contains(sourceUri)) {
|
||||||
|
final newUri = op.newFields['uri'] as String;
|
||||||
|
favouriteNewUris.add(newUri);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
source.resumeMonitoring();
|
source.resumeMonitoring();
|
||||||
unawaited(source.refreshUris(newUris));
|
unawaited(source.refreshUris(newUris).then((_) {
|
||||||
|
// transfer favourite status on exports
|
||||||
|
final newFavouriteEntries = source.allEntries.where((entry) => favouriteNewUris.contains(entry.uri)).toSet();
|
||||||
|
favourites.add(newFavouriteEntries);
|
||||||
|
}));
|
||||||
|
|
||||||
// get navigator beforehand because
|
// get navigator beforehand because
|
||||||
// local context may be deactivated when action is triggered after navigation
|
// local context may be deactivated when action is triggered after navigation
|
||||||
|
@ -241,11 +258,11 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin {
|
||||||
itemCount: todoCount,
|
itemCount: todoCount,
|
||||||
onCancel: () => mediaEditService.cancelFileOp(opId),
|
onCancel: () => mediaEditService.cancelFileOp(opId),
|
||||||
onDone: (processed) async {
|
onDone: (processed) async {
|
||||||
final successOps = processed.where((v) => v.success).toSet();
|
final successOps = processed.where((op) => op.success).toSet();
|
||||||
|
|
||||||
// move
|
// move
|
||||||
final movedOps = successOps.where((v) => !v.skipped && !v.deleted).toSet();
|
final movedOps = successOps.where((op) => !op.skipped && !op.deleted).toSet();
|
||||||
final movedEntries = movedOps.map((v) => v.uri).map((uri) => entries.firstWhereOrNull((entry) => entry.uri == uri)).nonNulls.toSet();
|
final movedEntries = movedOps.map((op) => op.uri).map((uri) => entries.firstWhereOrNull((entry) => entry.uri == uri)).nonNulls.toSet();
|
||||||
await source.updateAfterMove(
|
await source.updateAfterMove(
|
||||||
todoEntries: entries,
|
todoEntries: entries,
|
||||||
moveType: moveType,
|
moveType: moveType,
|
||||||
|
@ -254,8 +271,8 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin {
|
||||||
);
|
);
|
||||||
|
|
||||||
// delete (when trying to move to bin obsolete entries)
|
// delete (when trying to move to bin obsolete entries)
|
||||||
final deletedOps = successOps.where((v) => v.deleted).toSet();
|
final deletedOps = successOps.where((op) => op.deleted).toSet();
|
||||||
final deletedUris = deletedOps.map((event) => event.uri).toSet();
|
final deletedUris = deletedOps.map((op) => op.uri).toSet();
|
||||||
await source.removeEntries(deletedUris, includeTrash: true);
|
await source.removeEntries(deletedUris, includeTrash: true);
|
||||||
|
|
||||||
source.resumeMonitoring();
|
source.resumeMonitoring();
|
||||||
|
@ -405,8 +422,8 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin {
|
||||||
itemCount: todoCount,
|
itemCount: todoCount,
|
||||||
onCancel: () => mediaEditService.cancelFileOp(opId),
|
onCancel: () => mediaEditService.cancelFileOp(opId),
|
||||||
onDone: (processed) async {
|
onDone: (processed) async {
|
||||||
final successOps = processed.where((e) => e.success).toSet();
|
final successOps = processed.where((op) => op.success).toSet();
|
||||||
final movedOps = successOps.where((e) => !e.skipped).toSet();
|
final movedOps = successOps.where((op) => !op.skipped).toSet();
|
||||||
await source.updateAfterRename(
|
await source.updateAfterRename(
|
||||||
todoEntries: entries,
|
todoEntries: entries,
|
||||||
movedOps: movedOps,
|
movedOps: movedOps,
|
||||||
|
@ -466,7 +483,7 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin {
|
||||||
Set<String> destinationAlbums,
|
Set<String> destinationAlbums,
|
||||||
Set<MoveOpEvent> movedOps,
|
Set<MoveOpEvent> movedOps,
|
||||||
) async {
|
) async {
|
||||||
final newUris = movedOps.map((v) => v.newFields['uri'] as String?).toSet();
|
final newUris = movedOps.map((op) => op.newFields['uri'] as String?).toSet();
|
||||||
bool highlightTest(AvesEntry entry) => newUris.contains(entry.uri);
|
bool highlightTest(AvesEntry entry) => newUris.contains(entry.uri);
|
||||||
|
|
||||||
final collection = context.read<CollectionLens?>();
|
final collection = context.read<CollectionLens?>();
|
||||||
|
|
|
@ -382,9 +382,9 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumBaseFilter>
|
||||||
itemCount: todoCount,
|
itemCount: todoCount,
|
||||||
onCancel: () => mediaEditService.cancelFileOp(opId),
|
onCancel: () => mediaEditService.cancelFileOp(opId),
|
||||||
onDone: (processed) async {
|
onDone: (processed) async {
|
||||||
final successOps = processed.where((event) => event.success);
|
final successOps = processed.where((op) => op.success);
|
||||||
final deletedOps = successOps.where((e) => !e.skipped).toSet();
|
final deletedOps = successOps.where((op) => !op.skipped).toSet();
|
||||||
final deletedUris = deletedOps.map((event) => event.uri).toSet();
|
final deletedUris = deletedOps.map((op) => op.uri).toSet();
|
||||||
await source.removeEntries(deletedUris, includeTrash: true);
|
await source.removeEntries(deletedUris, includeTrash: true);
|
||||||
browse(context);
|
browse(context);
|
||||||
source.resumeMonitoring();
|
source.resumeMonitoring();
|
||||||
|
@ -547,8 +547,8 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumBaseFilter>
|
||||||
itemCount: todoCount,
|
itemCount: todoCount,
|
||||||
onCancel: () => mediaEditService.cancelFileOp(opId),
|
onCancel: () => mediaEditService.cancelFileOp(opId),
|
||||||
onDone: (processed) async {
|
onDone: (processed) async {
|
||||||
final successOps = processed.where((e) => e.success).toSet();
|
final successOps = processed.where((op) => op.success).toSet();
|
||||||
final movedOps = successOps.where((e) => !e.skipped).toSet();
|
final movedOps = successOps.where((op) => !op.skipped).toSet();
|
||||||
await source.renameStoredAlbum(album, destinationAlbum, todoEntries, movedOps);
|
await source.renameStoredAlbum(album, destinationAlbum, todoEntries, movedOps);
|
||||||
browse(context);
|
browse(context);
|
||||||
source.resumeMonitoring();
|
source.resumeMonitoring();
|
||||||
|
|
Loading…
Reference in a new issue