From b235852395604dab3c42345b1b982abecdf34d34 Mon Sep 17 00:00:00 2001 From: ngfchl Date: Sat, 18 Jul 2026 13:53:26 +0800 Subject: [PATCH] fix: preserve imported media artwork during scans --- lib/core/storage/media_library_store.dart | 48 ++++++++++++++++++++++- lib/providers/media_library_provider.dart | 6 ++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/lib/core/storage/media_library_store.dart b/lib/core/storage/media_library_store.dart index 9429469..b2b5763 100644 --- a/lib/core/storage/media_library_store.dart +++ b/lib/core/storage/media_library_store.dart @@ -160,9 +160,40 @@ class MediaLibraryStore { Future replaceItems(List items) async { final db = await _db; await db.transaction((txn) async { - await txn.delete('media_items'); + await txn.execute(''' + CREATE TEMP TABLE IF NOT EXISTS desired_media_items ( + library_id TEXT NOT NULL, + file_id TEXT NOT NULL, + PRIMARY KEY (library_id, file_id) + ) + '''); + await txn.delete('desired_media_items'); for (final item in items) { - await txn.insert('media_items', _itemRow(item)); + await txn.insert('desired_media_items', { + 'library_id': item.libraryID, + 'file_id': item.file.id, + }); + await _upsertItem(txn, item); + } + // Metadata updates deliberately omit poster/backdrop. Imported artwork is + // expensive to rebuild and remains valid while the resource still exists. + await txn.execute(''' + DELETE FROM media_items + WHERE NOT EXISTS ( + SELECT 1 FROM desired_media_items desired + WHERE desired.library_id = media_items.library_id + AND desired.file_id = media_items.file_id + ) + '''); + }); + } + + Future upsertItems(Iterable items) async { + final values = items.toList(); + if (values.isEmpty) return; + await (await _db).transaction((txn) async { + for (final item in values) { + await _upsertItem(txn, item); } }); } @@ -467,6 +498,19 @@ class MediaLibraryStore { 'updated_at': _epoch(item.updatedAt) ?? 0, }; + Future _upsertItem(Transaction txn, MediaLibraryItem item) async { + final values = _itemRow(item); + final updated = await txn.update( + 'media_items', + values, + where: 'library_id = ? AND file_id = ?', + whereArgs: [item.libraryID, item.file.id], + ); + if (updated == 0) { + await txn.insert('media_items', values); + } + } + static int? _asInt(Object? value) => value is int ? value : int.tryParse('$value'); diff --git a/lib/providers/media_library_provider.dart b/lib/providers/media_library_provider.dart index 54a68ac..03eeb0f 100644 --- a/lib/providers/media_library_provider.dart +++ b/lib/providers/media_library_provider.dart @@ -293,7 +293,7 @@ class MediaLibraryNotifier extends StateNotifier { a.title.toLowerCase().compareTo(b.title.toLowerCase()), ); pendingPersistence = pendingPersistence.then( - (_) => _saveAllItems([...initialItems, ...unique.values]), + (_) => _upsertItems([item]), ); await pendingPersistence; state = state.copyWith( @@ -768,6 +768,10 @@ class MediaLibraryNotifier extends StateNotifier { return _store.replaceItems(items); } + Future _upsertItems(Iterable items) { + return _store.upsertItems(items); + } + /* List _loadLibraries() { final raw = StorageManager.get(StorageKeys.mediaLibraries);