selection: added menu item to refresh metadata
This commit is contained in:
parent
d2c11f2d92
commit
297da41c64
4 changed files with 74 additions and 43 deletions
|
@ -73,7 +73,6 @@ class ImageEntry {
|
||||||
sourceDateTakenMillis: sourceDateTakenMillis,
|
sourceDateTakenMillis: sourceDateTakenMillis,
|
||||||
durationMillis: durationMillis,
|
durationMillis: durationMillis,
|
||||||
)
|
)
|
||||||
.._catalogDateMillis = _catalogDateMillis
|
|
||||||
.._catalogMetadata = _catalogMetadata?.copyWith(contentId: copyContentId)
|
.._catalogMetadata = _catalogMetadata?.copyWith(contentId: copyContentId)
|
||||||
.._addressDetails = _addressDetails?.copyWith(contentId: copyContentId);
|
.._addressDetails = _addressDetails?.copyWith(contentId: copyContentId);
|
||||||
|
|
||||||
|
@ -232,13 +231,17 @@ class ImageEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
set catalogMetadata(CatalogMetadata newMetadata) {
|
set catalogMetadata(CatalogMetadata newMetadata) {
|
||||||
if (newMetadata == null) return;
|
catalogDateMillis = newMetadata?.dateMillis;
|
||||||
catalogDateMillis = newMetadata.dateMillis;
|
|
||||||
_catalogMetadata = newMetadata;
|
_catalogMetadata = newMetadata;
|
||||||
_bestTitle = null;
|
_bestTitle = null;
|
||||||
metadataChangeNotifier.notifyListeners();
|
metadataChangeNotifier.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearMetadata() {
|
||||||
|
catalogMetadata = null;
|
||||||
|
addressDetails = null;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> catalog() async {
|
Future<void> catalog() async {
|
||||||
if (isCatalogued) return;
|
if (isCatalogued) return;
|
||||||
catalogMetadata = await MetadataService.getCatalogMetadata(this);
|
catalogMetadata = await MetadataService.getCatalogMetadata(this);
|
||||||
|
|
|
@ -206,7 +206,9 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
)),
|
)),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) => PopupMenuButton<CollectionAction>(
|
builder: (context) => PopupMenuButton<CollectionAction>(
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) {
|
||||||
|
final hasSelection = collection.selection.isNotEmpty;
|
||||||
|
return [
|
||||||
..._buildSortMenuItems(),
|
..._buildSortMenuItems(),
|
||||||
..._buildGroupMenuItems(),
|
..._buildGroupMenuItems(),
|
||||||
if (collection.isBrowsing) ...[
|
if (collection.isBrowsing) ...[
|
||||||
|
@ -226,24 +228,34 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
if (collection.isSelecting) ...[
|
if (collection.isSelecting) ...[
|
||||||
const PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: CollectionAction.copy,
|
value: CollectionAction.copy,
|
||||||
child: MenuRow(text: 'Copy to album'),
|
enabled: hasSelection,
|
||||||
|
child: const MenuRow(text: 'Copy to album'),
|
||||||
),
|
),
|
||||||
const PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: CollectionAction.move,
|
value: CollectionAction.move,
|
||||||
child: MenuRow(text: 'Move to album'),
|
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(
|
const PopupMenuItem(
|
||||||
value: CollectionAction.selectAll,
|
value: CollectionAction.selectAll,
|
||||||
child: MenuRow(text: 'Select all'),
|
child: MenuRow(text: 'Select all'),
|
||||||
),
|
),
|
||||||
const PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: CollectionAction.selectNone,
|
value: CollectionAction.selectNone,
|
||||||
child: MenuRow(text: 'Select none'),
|
enabled: hasSelection,
|
||||||
|
child: const MenuRow(text: 'Select none'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
],
|
];
|
||||||
|
},
|
||||||
onSelected: _onCollectionActionSelected,
|
onSelected: _onCollectionActionSelected,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -307,6 +319,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case CollectionAction.copy:
|
case CollectionAction.copy:
|
||||||
case CollectionAction.move:
|
case CollectionAction.move:
|
||||||
|
case CollectionAction.refreshMetadata:
|
||||||
_actionDelegate.onCollectionActionSelected(context, action);
|
_actionDelegate.onCollectionActionSelected(context, action);
|
||||||
break;
|
break;
|
||||||
case CollectionAction.refresh:
|
case CollectionAction.refresh:
|
||||||
|
@ -378,6 +391,7 @@ enum CollectionAction {
|
||||||
copy,
|
copy,
|
||||||
move,
|
move,
|
||||||
refresh,
|
refresh,
|
||||||
|
refreshMetadata,
|
||||||
select,
|
select,
|
||||||
selectAll,
|
selectAll,
|
||||||
selectNone,
|
selectNone,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:aves/model/filters/album.dart';
|
||||||
import 'package:aves/model/image_entry.dart';
|
import 'package:aves/model/image_entry.dart';
|
||||||
import 'package:aves/model/metadata_db.dart';
|
import 'package:aves/model/metadata_db.dart';
|
||||||
import 'package:aves/model/source/collection_lens.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/android_app_service.dart';
|
||||||
import 'package:aves/services/image_file_service.dart';
|
import 'package:aves/services/image_file_service.dart';
|
||||||
import 'package:aves/utils/durations.dart';
|
import 'package:aves/utils/durations.dart';
|
||||||
|
@ -52,6 +53,9 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin {
|
||||||
case CollectionAction.move:
|
case CollectionAction.move:
|
||||||
_moveSelection(context, copy: false);
|
_moveSelection(context, copy: false);
|
||||||
break;
|
break;
|
||||||
|
case CollectionAction.refreshMetadata:
|
||||||
|
_refreshSelectionMetadata();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +140,7 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin {
|
||||||
await metadataDb.saveMetadata(movedEntries.map((entry) => entry.catalogMetadata));
|
await metadataDb.saveMetadata(movedEntries.map((entry) => entry.catalogMetadata));
|
||||||
await metadataDb.saveAddresses(movedEntries.map((entry) => entry.addressDetails));
|
await metadataDb.saveAddresses(movedEntries.map((entry) => entry.addressDetails));
|
||||||
} else {
|
} else {
|
||||||
await Future.forEach(movedOps, (movedOp) async {
|
await Future.forEach<MoveOpEvent>(movedOps, (movedOp) async {
|
||||||
final sourceUri = movedOp.uri;
|
final sourceUri = movedOp.uri;
|
||||||
final newFields = movedOp.newFields;
|
final newFields = movedOp.newFields;
|
||||||
final entry = selection.firstWhere((entry) => entry.uri == sourceUri, orElse: () => null);
|
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 {
|
void _showDeleteDialog(BuildContext context) async {
|
||||||
final selection = collection.selection.toList();
|
final selection = collection.selection.toList();
|
||||||
final count = selection.length;
|
final count = selection.length;
|
||||||
|
|
|
@ -523,7 +523,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
|
||||||
await ThumbnailProvider(entry: entry).evict();
|
await ThumbnailProvider(entry: entry).evict();
|
||||||
// evict higher quality thumbnails (with powers of 2 from 32 to 1024 as specified extents)
|
// 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());
|
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();
|
await ThumbnailProvider(entry: entry).evict();
|
||||||
if (entry.path != null) await FileImage(File(entry.path)).evict();
|
if (entry.path != null) await FileImage(File(entry.path)).evict();
|
||||||
|
|
Loading…
Reference in a new issue