fixed collection update when editing entry metadata

This commit is contained in:
Thibault Deckers 2021-09-14 11:41:57 +09:00
parent f422f848f4
commit ffdbb6e857
12 changed files with 50 additions and 33 deletions

View file

@ -445,8 +445,8 @@
"@collectionActionCopy": {},
"collectionActionMove": "Move to album",
"@collectionActionMove": {},
"collectionActionRefreshMetadata": "Refresh metadata",
"@collectionActionRefreshMetadata": {},
"collectionActionRescan": "Rescan",
"@collectionActionRescan": {},
"collectionSortTitle": "Sort",
"@collectionSortTitle": {},

View file

@ -213,7 +213,7 @@
"collectionActionAddShortcut": "홈 화면에 추가",
"collectionActionCopy": "앨범으로 복사",
"collectionActionMove": "앨범으로 이동",
"collectionActionRefreshMetadata": "새로 분석",
"collectionActionRescan": "새로 분석",
"collectionSortTitle": "정렬",
"collectionSortDate": "날짜",

View file

@ -19,7 +19,7 @@ enum EntrySetAction {
delete,
copy,
move,
refreshMetadata,
rescan,
}
class EntrySetActions {
@ -28,7 +28,7 @@ class EntrySetActions {
EntrySetAction.delete,
EntrySetAction.copy,
EntrySetAction.move,
EntrySetAction.refreshMetadata,
EntrySetAction.rescan,
EntrySetAction.map,
EntrySetAction.stats,
];
@ -65,8 +65,8 @@ extension ExtraEntrySetAction on EntrySetAction {
return context.l10n.collectionActionCopy;
case EntrySetAction.move:
return context.l10n.collectionActionMove;
case EntrySetAction.refreshMetadata:
return context.l10n.collectionActionRefreshMetadata;
case EntrySetAction.rescan:
return context.l10n.collectionActionRescan;
}
}
@ -104,7 +104,7 @@ extension ExtraEntrySetAction on EntrySetAction {
return AIcons.copy;
case EntrySetAction.move:
return AIcons.move;
case EntrySetAction.refreshMetadata:
case EntrySetAction.rescan:
return AIcons.refresh;
}
}

View file

@ -638,20 +638,14 @@ class AvesEntry {
return true;
}
Future<bool> editDate(DateModifier modifier, {required bool persist}) async {
Future<bool> editDate(DateModifier modifier) async {
final newFields = await metadataEditService.editDate(this, modifier);
if (newFields.isEmpty) return false;
await refresh(persist: persist);
return true;
return newFields.isNotEmpty;
}
Future<bool> removeMetadata(Set<MetadataType> types, {required bool persist}) async {
Future<bool> removeMetadata(Set<MetadataType> types) async {
final newFields = await metadataEditService.removeTypes(this, types);
if (newFields.isEmpty) return false;
await refresh(persist: persist);
return true;
return newFields.isNotEmpty;
}
Future<bool> delete() {

View file

@ -171,7 +171,7 @@ class SqfliteMetadataDb implements MetadataDb {
Future<void> removeIds(Set<int> contentIds, {required bool metadataOnly}) async {
if (contentIds.isEmpty) return;
final stopwatch = Stopwatch()..start();
// final stopwatch = Stopwatch()..start();
final db = await _database;
// using array in `whereArgs` and using it with `where contentId IN ?` is a pain, so we prefer `batch` instead
final batch = db.batch();
@ -188,7 +188,7 @@ class SqfliteMetadataDb implements MetadataDb {
}
});
await batch.commit(noResult: true);
debugPrint('$runtimeType removeIds complete in ${stopwatch.elapsed.inMilliseconds}ms for ${contentIds.length} entries');
// debugPrint('$runtimeType removeIds complete in ${stopwatch.elapsed.inMilliseconds}ms for ${contentIds.length} entries');
}
// entries

View file

@ -122,7 +122,7 @@ class Settings extends ChangeNotifier {
if (includeInternalKeys) {
await _prefs!.clear();
} else {
await Future.forEach(_prefs!.getKeys().whereNot(internalKeys.contains), _prefs!.remove);
await Future.forEach<String>(_prefs!.getKeys().whereNot(internalKeys.contains), _prefs!.remove);
}
}

View file

@ -47,6 +47,7 @@ class CollectionLens with ChangeNotifier {
_subscriptions.add(sourceEvents.on<EntryAddedEvent>().listen((e) => onEntryAdded(e.entries)));
_subscriptions.add(sourceEvents.on<EntryRemovedEvent>().listen((e) => onEntryRemoved(e.entries)));
_subscriptions.add(sourceEvents.on<EntryMovedEvent>().listen((e) => _refresh()));
_subscriptions.add(sourceEvents.on<EntryRefreshedEvent>().listen((e) => _refresh()));
_subscriptions.add(sourceEvents.on<FilterVisibilityChangedEvent>().listen((e) => _refresh()));
_subscriptions.add(sourceEvents.on<CatalogMetadataChangedEvent>().listen((e) => _refresh()));
_subscriptions.add(sourceEvents.on<AddressMetadataChangedEvent>().listen((e) {

View file

@ -254,7 +254,17 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
Future<void> refresh();
Future<void> refreshMetadata(Set<AvesEntry> entries);
Future<void> rescan(Set<AvesEntry> entries);
Future<void> refreshMetadata(Set<AvesEntry> entries) async {
await Future.forEach<AvesEntry>(entries, (entry) => entry.refresh(persist: true));
_invalidate(entries);
updateLocations();
updateTags();
eventBus.fire(EntryRefreshedEvent(entries));
}
// monitoring
@ -334,6 +344,12 @@ class EntryMovedEvent {
const EntryMovedEvent(this.entries);
}
class EntryRefreshedEvent {
final Set<AvesEntry> entries;
const EntryRefreshedEvent(this.entries);
}
class FilterVisibilityChangedEvent {
final Set<CollectionFilter> filters;
final bool visible;

View file

@ -189,9 +189,9 @@ class MediaStoreSource extends CollectionSource {
}
@override
Future<void> refreshMetadata(Set<AvesEntry> entries) {
Future<void> rescan(Set<AvesEntry> entries) async {
final contentIds = entries.map((entry) => entry.contentId).whereNotNull().toSet();
metadataDb.removeIds(contentIds, metadataOnly: true);
await metadataDb.removeIds(contentIds, metadataOnly: true);
return refresh();
}
}

View file

@ -289,7 +289,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
case EntrySetAction.delete:
case EntrySetAction.copy:
case EntrySetAction.move:
case EntrySetAction.refreshMetadata:
case EntrySetAction.rescan:
case EntrySetAction.map:
case EntrySetAction.stats:
_actionDelegate.onActionSelected(context, action);

View file

@ -42,8 +42,8 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
case EntrySetAction.move:
_moveSelection(context, moveType: MoveType.move);
break;
case EntrySetAction.refreshMetadata:
_refreshMetadata(context);
case EntrySetAction.rescan:
_rescan(context);
break;
case EntrySetAction.map:
_goToMap(context);
@ -68,12 +68,12 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
});
}
void _refreshMetadata(BuildContext context) {
void _rescan(BuildContext context) {
final source = context.read<CollectionSource>();
final selection = context.read<Selection<AvesEntry>>();
final selectedItems = _getExpandedSelectedItems(selection);
source.refreshMetadata(selectedItems);
source.rescan(selectedItems);
selection.browse();
}

View file

@ -34,13 +34,19 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin {
Future<void> _edit(BuildContext context, Future<bool> Function() apply) async {
if (!await checkStoragePermission(context, {entry})) return;
final l10n = context.l10n;
final source = context.read<CollectionSource?>();
source?.pauseMonitoring();
final success = await apply();
if (success) {
showFeedback(context, context.l10n.genericSuccessFeedback);
if (_isMainMode(context) && source != null) {
await source.refreshMetadata({entry});
} else {
await entry.refresh(persist: false);
}
showFeedback(context, l10n.genericSuccessFeedback);
} else {
showFeedback(context, context.l10n.genericFailureFeedback);
showFeedback(context, l10n.genericFailureFeedback);
}
source?.resumeMonitoring();
}
@ -52,7 +58,7 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin {
);
if (modifier == null) return;
await _edit(context, () => entry.editDate(modifier, persist: _isMainMode(context)));
await _edit(context, () => entry.editDate(modifier));
}
Future<void> _showMetadataRemovalDialog(BuildContext context) async {
@ -85,6 +91,6 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin {
if (proceed == null || !proceed) return;
}
await _edit(context, () => entry.removeMetadata(types, persist: _isMainMode(context)));
await _edit(context, () => entry.removeMetadata(types));
}
}