mosaic: refresh layout on aspect ratio change

This commit is contained in:
Thibault Deckers 2022-10-02 11:43:53 +02:00
parent ba2c06f2ea
commit a80cbfa8f5
5 changed files with 77 additions and 47 deletions

View file

@ -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

View file

@ -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<Set<EntryDataType>> removeMetadata(Set<MetadataType> types) async {
final Set<EntryDataType> dataTypes = {};
final newFields = await metadataEditService.removeTypes(this, types);
return newFields.isEmpty
? {}
: {
if (newFields.isNotEmpty) {
dataTypes.addAll({
EntryDataType.basic,
EntryDataType.aspectRatio,
EntryDataType.catalog,
EntryDataType.address,
};
});
}
return dataTypes;
}
static void editIptcValues(List<Map<String, dynamic>> iptc, int record, int tag, Set<String> values) {

View file

@ -395,16 +395,25 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
Future<void> refreshEntry(AvesEntry entry, Set<EntryDataType> 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 Future.forEach(EntryDataType.values, (dataType) async {
switch (dataType) {
case EntryDataType.aspectRatio:
onAspectRatioChanged();
break;
case EntryDataType.catalog:
await metadataDb.updateCatalogMetadata(id, entry.catalogMetadata);
onCatalogMetadataChanged();
}
if (dataTypes.contains(EntryDataType.address)) {
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 {}

View file

@ -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<SourceState>(
valueListenable: collection.source.stateNotifier,
valueListenable: source.stateNotifier,
builder: (context, sourceState, child) {
late final Duration tileAnimationDelay;
if (sourceState == SourceState.ready) {
@ -132,7 +134,10 @@ class _CollectionGridContent extends StatelessWidget {
} else {
tileAnimationDelay = Duration.zero;
}
return SectionedEntryListLayoutProvider(
return StreamBuilder(
stream: source.eventBus.on<AspectRatioChangedEvent>(),
builder: (context, snapshot) => SectionedEntryListLayoutProvider(
collection: collection,
selectable: selectable,
scrollableWidth: scrollableWidth,
@ -159,6 +164,7 @@ class _CollectionGridContent extends StatelessWidget {
},
tileAnimationDelay: tileAnimationDelay,
child: child!,
),
);
},
child: child,

View file

@ -370,6 +370,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
Set<String> obsoleteTags = todoItems.expand((entry) => entry.tags).toSet();
Set<String> obsoleteCountryCodes = todoItems.where((entry) => entry.hasAddress).map((entry) => entry.addressDetails?.countryCode).whereNotNull().toSet();
final Set<EntryDataType> dataTypes = {};
final source = context.read<CollectionSource>();
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;