#253 init: add entries without notifying before metadata loading

This commit is contained in:
Thibault Deckers 2022-05-19 17:48:41 +09:00
parent a470bb69d7
commit c7b19c5e49
5 changed files with 48 additions and 24 deletions

View file

@ -26,10 +26,12 @@ mixin AlbumMixin on SourceBase {
return compareAsciiUpperCase(va, vb); return compareAsciiUpperCase(va, vb);
} }
void _onAlbumChanged() { void _onAlbumChanged({bool notify = true}) {
invalidateAlbumDisplayNames(); invalidateAlbumDisplayNames();
if (notify) {
eventBus.fire(AlbumsChangedEvent()); eventBus.fire(AlbumsChangedEvent());
} }
}
Map<String, AvesEntry?> getAlbumEntries() { Map<String, AvesEntry?> getAlbumEntries() {
final entries = sortedEntriesByDate; final entries = sortedEntriesByDate;
@ -55,14 +57,14 @@ mixin AlbumMixin on SourceBase {
void updateDirectories() { void updateDirectories() {
final visibleDirectories = visibleEntries.map((entry) => entry.directory).toSet(); final visibleDirectories = visibleEntries.map((entry) => entry.directory).toSet();
addDirectories(visibleDirectories); addDirectories(albums: visibleDirectories);
cleanEmptyAlbums(); cleanEmptyAlbums();
} }
void addDirectories(Set<String?> albums) { void addDirectories({required Set<String?> albums, bool notify = true}) {
if (!_directories.containsAll(albums)) { if (!_directories.containsAll(albums)) {
_directories.addAll(albums); _directories.addAll(albums);
_onAlbumChanged(); _onAlbumChanged(notify: notify);
} }
} }
@ -92,7 +94,11 @@ mixin AlbumMixin on SourceBase {
final Map<String, int> _filterEntryCountMap = {}; final Map<String, int> _filterEntryCountMap = {};
final Map<String, AvesEntry?> _filterRecentEntryMap = {}; final Map<String, AvesEntry?> _filterRecentEntryMap = {};
void invalidateAlbumFilterSummary({Set<AvesEntry>? entries, Set<String?>? directories}) { void invalidateAlbumFilterSummary({
Set<AvesEntry>? entries,
Set<String?>? directories,
bool notify = true,
}) {
if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return; if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return;
if (entries == null && directories == null) { if (entries == null && directories == null) {
@ -108,8 +114,10 @@ mixin AlbumMixin on SourceBase {
_filterRecentEntryMap.remove(directory); _filterRecentEntryMap.remove(directory);
}); });
} }
if (notify) {
eventBus.fire(AlbumSummaryInvalidatedEvent(directories)); eventBus.fire(AlbumSummaryInvalidatedEvent(directories));
} }
}
int albumEntryCount(AlbumFilter filter) { int albumEntryCount(AlbumFilter filter) {
return _filterEntryCountMap.putIfAbsent(filter.album, () => visibleEntries.where(filter.test).length); return _filterEntryCountMap.putIfAbsent(filter.album, () => visibleEntries.where(filter.test).length);
@ -123,7 +131,7 @@ mixin AlbumMixin on SourceBase {
void createAlbum(String directory) { void createAlbum(String directory) {
_newAlbums.add(directory); _newAlbums.add(directory);
addDirectories({directory}); addDirectories(albums: {directory});
} }
void renameNewAlbum(String source, String destination) { void renameNewAlbum(String source, String destination) {

View file

@ -114,11 +114,11 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
return entries.where(TrashFilter.instance.test); return entries.where(TrashFilter.instance.test);
} }
void _invalidate([Set<AvesEntry>? entries]) { void _invalidate({Set<AvesEntry>? entries, bool notify = true}) {
invalidateEntries(); invalidateEntries();
invalidateAlbumFilterSummary(entries: entries); invalidateAlbumFilterSummary(entries: entries, notify: notify);
invalidateCountryFilterSummary(entries: entries); invalidateCountryFilterSummary(entries: entries, notify: notify);
invalidateTagFilterSummary(entries: entries); invalidateTagFilterSummary(entries: entries, notify: notify);
} }
@override @override
@ -129,7 +129,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
} }
void updateDerivedFilters([Set<AvesEntry>? entries]) { void updateDerivedFilters([Set<AvesEntry>? entries]) {
_invalidate(entries); _invalidate(entries: entries);
// it is possible for entries hidden by a filter type, to have an impact on other types // it is possible for entries hidden by a filter type, to have an impact on other types
// e.g. given a sole entry for country C and tag T, hiding T should make C disappear too // e.g. given a sole entry for country C and tag T, hiding T should make C disappear too
updateDirectories(); updateDirectories();
@ -137,7 +137,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
updateTags(); updateTags();
} }
void addEntries(Set<AvesEntry> entries) { void addEntries(Set<AvesEntry> entries, {bool notify = true}) {
if (entries.isEmpty) return; if (entries.isEmpty) return;
final newIdMapEntries = Map.fromEntries(entries.map((entry) => MapEntry(entry.id, entry))); final newIdMapEntries = Map.fromEntries(entries.map((entry) => MapEntry(entry.id, entry)));
@ -152,11 +152,13 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
_entryById.addAll(newIdMapEntries); _entryById.addAll(newIdMapEntries);
_rawEntries.addAll(entries); _rawEntries.addAll(entries);
_invalidate(entries); _invalidate(entries: entries, notify: notify);
addDirectories(_applyHiddenFilters(entries).map((entry) => entry.directory).toSet()); addDirectories(albums: _applyHiddenFilters(entries).map((entry) => entry.directory).toSet(), notify: notify);
if (notify) {
eventBus.fire(EntryAddedEvent(entries)); eventBus.fire(EntryAddedEvent(entries));
} }
}
Future<void> removeEntries(Set<String> uris, {required bool includeTrash}) async { Future<void> removeEntries(Set<String> uris, {required bool includeTrash}) async {
if (uris.isEmpty) return; if (uris.isEmpty) return;
@ -327,7 +329,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
case MoveType.move: case MoveType.move:
case MoveType.export: case MoveType.export:
cleanEmptyAlbums(fromAlbums); cleanEmptyAlbums(fromAlbums);
addDirectories(destinationAlbums); addDirectories(albums: destinationAlbums);
break; break;
case MoveType.toBin: case MoveType.toBin:
case MoveType.fromBin: case MoveType.fromBin:
@ -335,7 +337,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
break; break;
} }
invalidateAlbumFilterSummary(directories: fromAlbums); invalidateAlbumFilterSummary(directories: fromAlbums);
_invalidate(movedEntries); _invalidate(entries: movedEntries);
eventBus.fire(EntryMovedEvent(moveType, movedEntries)); eventBus.fire(EntryMovedEvent(moveType, movedEntries));
} }

View file

@ -183,7 +183,11 @@ mixin LocationMixin on SourceBase {
final Map<String, int> _filterEntryCountMap = {}; final Map<String, int> _filterEntryCountMap = {};
final Map<String, AvesEntry?> _filterRecentEntryMap = {}; final Map<String, AvesEntry?> _filterRecentEntryMap = {};
void invalidateCountryFilterSummary({Set<AvesEntry>? entries, Set<String>? countryCodes}) { void invalidateCountryFilterSummary({
Set<AvesEntry>? entries,
Set<String>? countryCodes,
bool notify = true,
}) {
if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return; if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return;
if (entries == null && countryCodes == null) { if (entries == null && countryCodes == null) {
@ -199,8 +203,10 @@ mixin LocationMixin on SourceBase {
_filterRecentEntryMap.remove(countryCode); _filterRecentEntryMap.remove(countryCode);
}); });
} }
if (notify) {
eventBus.fire(CountrySummaryInvalidatedEvent(countryCodes)); eventBus.fire(CountrySummaryInvalidatedEvent(countryCodes));
} }
}
int countryEntryCount(LocationFilter filter) { int countryEntryCount(LocationFilter filter) {
final countryCode = filter.countryCode; final countryCode = filter.countryCode;

View file

@ -96,7 +96,9 @@ class MediaStoreSource extends CollectionSource {
// show known entries // show known entries
debugPrint('$runtimeType refresh ${stopwatch.elapsed} add known entries'); debugPrint('$runtimeType refresh ${stopwatch.elapsed} add known entries');
addEntries(knownEntries); // add entries without notifying, so that the collection is not refreshed
// with items that may be hidden right away because of their metadata
addEntries(knownEntries, notify: false);
debugPrint('$runtimeType refresh ${stopwatch.elapsed} load metadata'); debugPrint('$runtimeType refresh ${stopwatch.elapsed} load metadata');
if (directory != null) { if (directory != null) {

View file

@ -78,7 +78,11 @@ mixin TagMixin on SourceBase {
final Map<String, int> _filterEntryCountMap = {}; final Map<String, int> _filterEntryCountMap = {};
final Map<String, AvesEntry?> _filterRecentEntryMap = {}; final Map<String, AvesEntry?> _filterRecentEntryMap = {};
void invalidateTagFilterSummary({Set<AvesEntry>? entries, Set<String>? tags}) { void invalidateTagFilterSummary({
Set<AvesEntry>? entries,
Set<String>? tags,
bool notify = true,
}) {
if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return; if (_filterEntryCountMap.isEmpty && _filterRecentEntryMap.isEmpty) return;
if (entries == null && tags == null) { if (entries == null && tags == null) {
@ -94,8 +98,10 @@ mixin TagMixin on SourceBase {
_filterRecentEntryMap.remove(tag); _filterRecentEntryMap.remove(tag);
}); });
} }
if (notify) {
eventBus.fire(TagSummaryInvalidatedEvent(tags)); eventBus.fire(TagSummaryInvalidatedEvent(tags));
} }
}
int tagEntryCount(TagFilter filter) { int tagEntryCount(TagFilter filter) {
return _filterEntryCountMap.putIfAbsent(filter.tag, () => visibleEntries.where(filter.test).length); return _filterEntryCountMap.putIfAbsent(filter.tag, () => visibleEntries.where(filter.test).length);