diff --git a/lib/model/entry.dart b/lib/model/entry.dart index 6f9f3290b..0922c3694 100644 --- a/lib/model/entry.dart +++ b/lib/model/entry.dart @@ -26,7 +26,7 @@ import 'package:country_code/country_code.dart'; import 'package:flutter/foundation.dart'; import 'package:latlong2/latlong.dart'; -enum EntryDataType { basic, catalog, address, references } +enum EntryDataType { basic, aspectRatio, catalog, address, references } class AvesEntry { // `sizeBytes`, `dateModifiedSecs` can be missing in viewer mode diff --git a/lib/model/entry_metadata_edition.dart b/lib/model/entry_metadata_edition.dart index 1659b20bb..7692ef761 100644 --- a/lib/model/entry_metadata_edition.dart +++ b/lib/model/entry_metadata_edition.dart @@ -126,6 +126,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry { if (newFields.isNotEmpty) { dataTypes.addAll({ EntryDataType.basic, + EntryDataType.aspectRatio, EntryDataType.catalog, }); } @@ -309,14 +310,18 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry { } Future> removeMetadata(Set types) async { + final Set dataTypes = {}; + final newFields = await metadataEditService.removeTypes(this, types); - return newFields.isEmpty - ? {} - : { - EntryDataType.basic, - EntryDataType.catalog, - EntryDataType.address, - }; + if (newFields.isNotEmpty) { + dataTypes.addAll({ + EntryDataType.basic, + EntryDataType.aspectRatio, + EntryDataType.catalog, + EntryDataType.address, + }); + } + return dataTypes; } static void editIptcValues(List> iptc, int record, int tag, Set values) { diff --git a/lib/model/source/collection_source.dart b/lib/model/source/collection_source.dart index 20b3a5063..a22626a98 100644 --- a/lib/model/source/collection_source.dart +++ b/lib/model/source/collection_source.dart @@ -395,16 +395,25 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM Future refreshEntry(AvesEntry entry, Set dataTypes) async { await entry.refresh(background: false, persist: true, dataTypes: dataTypes, geocoderLocale: settings.appliedLocale); - // update/delete in DB final id = entry.id; - if (dataTypes.contains(EntryDataType.catalog)) { - await metadataDb.updateCatalogMetadata(id, entry.catalogMetadata); - onCatalogMetadataChanged(); - } - if (dataTypes.contains(EntryDataType.address)) { - await metadataDb.updateAddress(id, entry.addressDetails); - onAddressMetadataChanged(); - } + await Future.forEach(EntryDataType.values, (dataType) async { + switch (dataType) { + case EntryDataType.aspectRatio: + onAspectRatioChanged(); + break; + case EntryDataType.catalog: + await metadataDb.updateCatalogMetadata(id, entry.catalogMetadata); + onCatalogMetadataChanged(); + break; + case EntryDataType.address: + await metadataDb.updateAddress(id, entry.addressDetails); + onAddressMetadataChanged(); + break; + case EntryDataType.basic: + case EntryDataType.references: + break; + } + }); updateDerivedFilters({entry}); eventBus.fire(EntryRefreshedEvent({entry})); @@ -449,6 +458,8 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM state = SourceState.ready; } + void onAspectRatioChanged() => eventBus.fire(AspectRatioChangedEvent()); + // monitoring bool _monitoring = true; @@ -502,3 +513,5 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM } } } + +class AspectRatioChangedEvent {} diff --git a/lib/widgets/collection/collection_grid.dart b/lib/widgets/collection/collection_grid.dart index d72303eb4..c75778274 100644 --- a/lib/widgets/collection/collection_grid.dart +++ b/lib/widgets/collection/collection_grid.dart @@ -7,6 +7,7 @@ import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; +import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/enums/enums.dart'; import 'package:aves/model/source/section_keys.dart'; import 'package:aves/ref/mime_types.dart'; @@ -117,12 +118,13 @@ class _CollectionGridContent extends StatelessWidget { final columnCount = c.item2; final tileSpacing = c.item3; final horizontalPadding = c.item4; + final source = collection.source; return GridTheme( extent: thumbnailExtent, child: EntryListDetailsTheme( extent: thumbnailExtent, child: ValueListenableBuilder( - valueListenable: collection.source.stateNotifier, + valueListenable: source.stateNotifier, builder: (context, sourceState, child) { late final Duration tileAnimationDelay; if (sourceState == SourceState.ready) { @@ -132,33 +134,37 @@ class _CollectionGridContent extends StatelessWidget { } else { tileAnimationDelay = Duration.zero; } - return SectionedEntryListLayoutProvider( - collection: collection, - selectable: selectable, - scrollableWidth: scrollableWidth, - tileLayout: tileLayout, - columnCount: columnCount, - spacing: tileSpacing, - horizontalPadding: horizontalPadding, - tileExtent: thumbnailExtent, - tileBuilder: (entry, tileSize) { - final extent = tileSize.shortestSide; - return AnimatedBuilder( - animation: favourites, - builder: (context, child) { - return InteractiveTile( - key: ValueKey(entry.id), - collection: collection, - entry: entry, - thumbnailExtent: extent, - tileLayout: tileLayout, - isScrollingNotifier: _isScrollingNotifier, - ); - }, - ); - }, - tileAnimationDelay: tileAnimationDelay, - child: child!, + + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) => SectionedEntryListLayoutProvider( + collection: collection, + selectable: selectable, + scrollableWidth: scrollableWidth, + tileLayout: tileLayout, + columnCount: columnCount, + spacing: tileSpacing, + horizontalPadding: horizontalPadding, + tileExtent: thumbnailExtent, + tileBuilder: (entry, tileSize) { + final extent = tileSize.shortestSide; + return AnimatedBuilder( + animation: favourites, + builder: (context, child) { + return InteractiveTile( + key: ValueKey(entry.id), + collection: collection, + entry: entry, + thumbnailExtent: extent, + tileLayout: tileLayout, + isScrollingNotifier: _isScrollingNotifier, + ); + }, + ); + }, + tileAnimationDelay: tileAnimationDelay, + child: child!, + ), ); }, child: child, diff --git a/lib/widgets/collection/entry_set_action_delegate.dart b/lib/widgets/collection/entry_set_action_delegate.dart index c21691f17..420faab2d 100644 --- a/lib/widgets/collection/entry_set_action_delegate.dart +++ b/lib/widgets/collection/entry_set_action_delegate.dart @@ -370,6 +370,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware Set obsoleteTags = todoItems.expand((entry) => entry.tags).toSet(); Set obsoleteCountryCodes = todoItems.where((entry) => entry.hasAddress).map((entry) => entry.addressDetails?.countryCode).whereNotNull().toSet(); + final Set dataTypes = {}; final source = context.read(); source.pauseMonitoring(); var cancelled = false; @@ -379,8 +380,9 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware if (cancelled) { return ImageOpEvent(success: true, skipped: true, uri: entry.uri); } else { - final dataTypes = await op(entry); - return ImageOpEvent(success: dataTypes.isNotEmpty, skipped: false, uri: entry.uri); + final opDataTypes = await op(entry); + dataTypes.addAll(opDataTypes); + return ImageOpEvent(success: opDataTypes.isNotEmpty, skipped: false, uri: entry.uri); } }).asBroadcastStream(), itemCount: todoCount, @@ -402,6 +404,10 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware } })); + if (dataTypes.contains(EntryDataType.aspectRatio)) { + source.onAspectRatioChanged(); + } + if (showResult) { final l10n = context.l10n; final successCount = successOps.length;