2022-07-05 22:20:24 +02:00
|
|
|
import 'package:drift/drift.dart' as sql;
|
2022-01-25 11:08:13 +01:00
|
|
|
import 'package:event_bus/event_bus.dart';
|
|
|
|
import 'package:kiwi/kiwi.dart';
|
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'package:nc_photos/account.dart';
|
|
|
|
import 'package:nc_photos/di_container.dart';
|
|
|
|
import 'package:nc_photos/entity/file.dart';
|
2022-07-05 22:20:24 +02:00
|
|
|
import 'package:nc_photos/entity/sqlite_table.dart' as sql;
|
|
|
|
import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql;
|
2022-01-25 11:08:13 +01:00
|
|
|
import 'package:nc_photos/event/event.dart';
|
|
|
|
import 'package:nc_photos/iterable_extension.dart';
|
|
|
|
import 'package:nc_photos/list_util.dart' as list_util;
|
|
|
|
import 'package:nc_photos/use_case/list_favorite_offline.dart';
|
|
|
|
|
|
|
|
class CacheFavorite {
|
|
|
|
CacheFavorite(this._c)
|
|
|
|
: assert(require(_c)),
|
|
|
|
assert(ListFavoriteOffline.require(_c));
|
|
|
|
|
2022-07-05 22:20:24 +02:00
|
|
|
static bool require(DiContainer c) => DiContainer.has(c, DiType.sqliteDb);
|
2022-01-25 11:08:13 +01:00
|
|
|
|
|
|
|
/// Cache favorites
|
|
|
|
Future<void> call(
|
|
|
|
Account account,
|
|
|
|
List<File> remote, {
|
|
|
|
List<File>? cache,
|
|
|
|
}) async {
|
|
|
|
cache ??= await ListFavoriteOffline(_c)(account);
|
|
|
|
final remoteSorted =
|
|
|
|
remote.sorted((a, b) => a.fileId!.compareTo(b.fileId!));
|
|
|
|
final cacheSorted = cache.sorted((a, b) => a.fileId!.compareTo(b.fileId!));
|
|
|
|
final result = list_util.diffWith<File>(
|
|
|
|
cacheSorted, remoteSorted, (a, b) => a.fileId!.compareTo(b.fileId!));
|
|
|
|
final newFavorites = result.item1;
|
|
|
|
final removedFavorites =
|
|
|
|
result.item2.map((f) => f.copyWith(isFavorite: false)).toList();
|
2022-07-05 22:20:24 +02:00
|
|
|
final newFileIds = newFavorites.map((f) => f.fileId!).toList();
|
|
|
|
final removedFileIds = removedFavorites.map((f) => f.fileId!).toList();
|
|
|
|
if (newFileIds.isEmpty && removedFileIds.isEmpty) {
|
2022-01-25 11:08:13 +01:00
|
|
|
return;
|
|
|
|
}
|
2022-07-05 22:20:24 +02:00
|
|
|
await _c.sqliteDb.use((db) async {
|
|
|
|
final rowIds = await db.accountFileRowIdsByFileIds(
|
|
|
|
newFileIds + removedFileIds,
|
|
|
|
appAccount: account,
|
|
|
|
);
|
|
|
|
final rowIdsMap =
|
|
|
|
Map.fromEntries(rowIds.map((e) => MapEntry(e.fileId, e)));
|
|
|
|
await db.batch((batch) {
|
|
|
|
for (final id in newFileIds) {
|
2022-03-24 10:03:13 +01:00
|
|
|
try {
|
2022-07-05 22:20:24 +02:00
|
|
|
batch.update(
|
|
|
|
db.accountFiles,
|
|
|
|
const sql.AccountFilesCompanion(isFavorite: sql.Value(true)),
|
|
|
|
where: (sql.$AccountFilesTable t) =>
|
|
|
|
t.rowId.equals(rowIdsMap[id]!.accountFileRowId),
|
|
|
|
);
|
2022-03-24 10:03:13 +01:00
|
|
|
} catch (e, stackTrace) {
|
2022-07-05 22:20:24 +02:00
|
|
|
_log.shout("[call] File not found in DB: $id", e, stackTrace);
|
2022-03-24 10:03:13 +01:00
|
|
|
}
|
2022-07-05 22:20:24 +02:00
|
|
|
}
|
|
|
|
for (final id in removedFileIds) {
|
2022-03-24 10:03:13 +01:00
|
|
|
try {
|
2022-07-05 22:20:24 +02:00
|
|
|
batch.update(
|
|
|
|
db.accountFiles,
|
|
|
|
const sql.AccountFilesCompanion(isFavorite: sql.Value(null)),
|
|
|
|
where: (sql.$AccountFilesTable t) =>
|
|
|
|
t.rowId.equals(rowIdsMap[id]!.accountFileRowId),
|
|
|
|
);
|
2022-03-24 10:03:13 +01:00
|
|
|
} catch (e, stackTrace) {
|
2022-07-05 22:20:24 +02:00
|
|
|
_log.shout("[call] File not found in DB: $id", e, stackTrace);
|
2022-03-24 10:03:13 +01:00
|
|
|
}
|
2022-07-05 22:20:24 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2022-01-25 11:08:13 +01:00
|
|
|
|
|
|
|
KiwiContainer()
|
|
|
|
.resolve<EventBus>()
|
|
|
|
.fire(FavoriteResyncedEvent(account, newFavorites, removedFavorites));
|
|
|
|
}
|
|
|
|
|
|
|
|
final DiContainer _c;
|
|
|
|
|
|
|
|
static final _log = Logger("use_case.cache_favorite.CacheFavorite");
|
|
|
|
}
|