97 lines
3 KiB
Dart
97 lines
3 KiB
Dart
// lib/remote/collection_source_remote_ext.dart
|
|
|
|
import 'package:aves/model/entry/entry.dart';
|
|
import 'package:aves/model/source/collection_source.dart';
|
|
import 'package:aves/model/source/events.dart';
|
|
import 'package:aves/services/common/services.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'remote_origin.dart';
|
|
import 'package:aves/remote/remote_sync_bus.dart';
|
|
|
|
extension CollectionSourceRemoteExt on CollectionSource {
|
|
/// Sincronizza le entry remote in memoria con il DB:
|
|
/// - ADD: aggiunge solo i remoti nuovi
|
|
/// - DEL: rimuove solo i remoti spariti dal DB
|
|
///
|
|
/// Versione base: diff tra DB e in-memory, senza cache interna.
|
|
Future<void> appendRemoteEntriesFromDb() async {
|
|
// 1) carica dal DB tutte le entry remote
|
|
final Set<AvesEntry> remotiDb =
|
|
await localMediaDb.loadEntries(origin: RemoteOrigin.value);
|
|
final Map<String, AvesEntry> dbById = {
|
|
for (final e in remotiDb)
|
|
if (e.remoteId != null && e.remoteId!.isNotEmpty) e.remoteId!: e,
|
|
};
|
|
|
|
// 2) mappa in-memory dei remoti attuali
|
|
final Map<String, AvesEntry> memById = {
|
|
for (final e in allEntries)
|
|
if (e.origin == RemoteOrigin.value &&
|
|
!e.trashed &&
|
|
e.remoteId != null &&
|
|
e.remoteId!.isNotEmpty)
|
|
e.remoteId!: e,
|
|
};
|
|
|
|
// 3) calcola differenze
|
|
final Set<String> idsDb = dbById.keys.toSet();
|
|
final Set<String> idsMem = memById.keys.toSet();
|
|
|
|
final Set<String> toAddIds = idsDb.difference(idsMem);
|
|
final Set<String> toRemoveIds = idsMem.difference(idsDb);
|
|
|
|
final List<AvesEntry> toAdd = [
|
|
for (final id in toAddIds) dbById[id]!,
|
|
];
|
|
|
|
final List<AvesEntry> toRemove = [
|
|
for (final id in toRemoveIds) memById[id]!,
|
|
];
|
|
|
|
debugPrint('[remote-diff] add=${toAdd.length} del=${toRemove.length}');
|
|
|
|
// 4) applica differenze
|
|
if (toRemove.isNotEmpty) {
|
|
removeEntries(
|
|
toRemove.map((e) => e.uri).whereType<String>().toSet(),
|
|
includeTrash: false,
|
|
);
|
|
}
|
|
|
|
if (toAdd.isNotEmpty) {
|
|
addEntries(toAdd.toSet());
|
|
}
|
|
|
|
// 5) notifica la CollectionLens
|
|
if (toAdd.isNotEmpty) {
|
|
try {
|
|
eventBus.fire(EntryAddedEvent(toAdd.toSet()));
|
|
} catch (e) {
|
|
debugPrint('[remote-diff] fire EntryAddedEvent failed: $e');
|
|
}
|
|
}
|
|
if (toRemove.isNotEmpty) {
|
|
try {
|
|
eventBus.fire(EntryRefreshedEvent(const <AvesEntry>{}));
|
|
} catch (e) {
|
|
debugPrint('[remote-diff] fire EntryRefreshedEvent failed: $e');
|
|
}
|
|
}
|
|
|
|
final remotesMem = allEntries
|
|
.where((e) => e.origin == RemoteOrigin.value && !e.trashed)
|
|
.length;
|
|
|
|
debugPrint('[remote-diff] done: remotesMem=$remotesMem');
|
|
}
|
|
}
|
|
|
|
/// Visibilità dei remoti (usata da CollectionLens)
|
|
extension RemoteVisibilityExt on CollectionSource {
|
|
bool get remoteVisible {
|
|
final state = RemoteSyncBus.instance.stateNotifier.value;
|
|
return state == RemoteSyncState.syncing ||
|
|
state == RemoteSyncState.upToDate;
|
|
}
|
|
}
|