selection: added menu item to refresh metadata

This commit is contained in:
Thibault Deckers 2020-06-14 10:37:32 +09:00
parent d2c11f2d92
commit 297da41c64
4 changed files with 74 additions and 43 deletions

View file

@ -73,7 +73,6 @@ class ImageEntry {
sourceDateTakenMillis: sourceDateTakenMillis,
durationMillis: durationMillis,
)
.._catalogDateMillis = _catalogDateMillis
.._catalogMetadata = _catalogMetadata?.copyWith(contentId: copyContentId)
.._addressDetails = _addressDetails?.copyWith(contentId: copyContentId);
@ -232,13 +231,17 @@ class ImageEntry {
}
set catalogMetadata(CatalogMetadata newMetadata) {
if (newMetadata == null) return;
catalogDateMillis = newMetadata.dateMillis;
catalogDateMillis = newMetadata?.dateMillis;
_catalogMetadata = newMetadata;
_bestTitle = null;
metadataChangeNotifier.notifyListeners();
}
void clearMetadata() {
catalogMetadata = null;
addressDetails = null;
}
Future<void> catalog() async {
if (isCatalogued) return;
catalogMetadata = await MetadataService.getCatalogMetadata(this);

View file

@ -206,44 +206,56 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
)),
Builder(
builder: (context) => PopupMenuButton<CollectionAction>(
itemBuilder: (context) => [
..._buildSortMenuItems(),
..._buildGroupMenuItems(),
if (collection.isBrowsing) ...[
if (AvesApp.mode == AppMode.main)
if (kDebugMode)
const PopupMenuItem(
value: CollectionAction.refresh,
child: MenuRow(text: 'Refresh', icon: AIcons.refresh),
),
const PopupMenuItem(
value: CollectionAction.select,
child: MenuRow(text: 'Select', icon: AIcons.select),
),
const PopupMenuItem(
value: CollectionAction.stats,
child: MenuRow(text: 'Stats', icon: AIcons.stats),
),
],
if (collection.isSelecting) ...[
const PopupMenuItem(
value: CollectionAction.copy,
child: MenuRow(text: 'Copy to album'),
),
const PopupMenuItem(
value: CollectionAction.move,
child: MenuRow(text: 'Move to album'),
),
const PopupMenuItem(
value: CollectionAction.selectAll,
child: MenuRow(text: 'Select all'),
),
const PopupMenuItem(
value: CollectionAction.selectNone,
child: MenuRow(text: 'Select none'),
),
]
],
itemBuilder: (context) {
final hasSelection = collection.selection.isNotEmpty;
return [
..._buildSortMenuItems(),
..._buildGroupMenuItems(),
if (collection.isBrowsing) ...[
if (AvesApp.mode == AppMode.main)
if (kDebugMode)
const PopupMenuItem(
value: CollectionAction.refresh,
child: MenuRow(text: 'Refresh', icon: AIcons.refresh),
),
const PopupMenuItem(
value: CollectionAction.select,
child: MenuRow(text: 'Select', icon: AIcons.select),
),
const PopupMenuItem(
value: CollectionAction.stats,
child: MenuRow(text: 'Stats', icon: AIcons.stats),
),
],
if (collection.isSelecting) ...[
PopupMenuItem(
value: CollectionAction.copy,
enabled: hasSelection,
child: const MenuRow(text: 'Copy to album'),
),
PopupMenuItem(
value: CollectionAction.move,
enabled: hasSelection,
child: const MenuRow(text: 'Move to album'),
),
PopupMenuItem(
value: CollectionAction.refreshMetadata,
enabled: hasSelection,
child: const MenuRow(text: 'Refresh metadata'),
),
const PopupMenuDivider(),
const PopupMenuItem(
value: CollectionAction.selectAll,
child: MenuRow(text: 'Select all'),
),
PopupMenuItem(
value: CollectionAction.selectNone,
enabled: hasSelection,
child: const MenuRow(text: 'Select none'),
),
]
];
},
onSelected: _onCollectionActionSelected,
),
),
@ -307,6 +319,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
switch (action) {
case CollectionAction.copy:
case CollectionAction.move:
case CollectionAction.refreshMetadata:
_actionDelegate.onCollectionActionSelected(context, action);
break;
case CollectionAction.refresh:
@ -378,6 +391,7 @@ enum CollectionAction {
copy,
move,
refresh,
refreshMetadata,
select,
selectAll,
selectNone,

View file

@ -5,6 +5,7 @@ import 'package:aves/model/filters/album.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/metadata_db.dart';
import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/collection_source.dart';
import 'package:aves/services/android_app_service.dart';
import 'package:aves/services/image_file_service.dart';
import 'package:aves/utils/durations.dart';
@ -52,6 +53,9 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin {
case CollectionAction.move:
_moveSelection(context, copy: false);
break;
case CollectionAction.refreshMetadata:
_refreshSelectionMetadata();
break;
default:
break;
}
@ -136,7 +140,7 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin {
await metadataDb.saveMetadata(movedEntries.map((entry) => entry.catalogMetadata));
await metadataDb.saveAddresses(movedEntries.map((entry) => entry.addressDetails));
} else {
await Future.forEach(movedOps, (movedOp) async {
await Future.forEach<MoveOpEvent>(movedOps, (movedOp) async {
final sourceUri = movedOp.uri;
final newFields = movedOp.newFields;
final entry = selection.firstWhere((entry) => entry.uri == sourceUri, orElse: () => null);
@ -168,6 +172,16 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin {
);
}
void _refreshSelectionMetadata() async {
collection.selection.forEach((entry) => entry.clearMetadata());
final source = collection.source;
source.stateNotifier.value = SourceState.cataloguing;
await source.catalogEntries();
source.stateNotifier.value = SourceState.locating;
await source.locateEntries();
source.stateNotifier.value = SourceState.ready;
}
void _showDeleteDialog(BuildContext context) async {
final selection = collection.selection.toList();
final count = selection.length;

View file

@ -523,7 +523,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
await ThumbnailProvider(entry: entry).evict();
// evict higher quality thumbnails (with powers of 2 from 32 to 1024 as specified extents)
final extents = List.generate(6, (index) => pow(2, index + 5).toDouble());
await Future.forEach(extents, (extent) => ThumbnailProvider(entry: entry, extent: extent).evict());
await Future.forEach<double>(extents, (extent) => ThumbnailProvider(entry: entry, extent: extent).evict());
await ThumbnailProvider(entry: entry).evict();
if (entry.path != null) await FileImage(File(entry.path)).evict();