feat(mobile): lazy loading of assets (#2413)

This commit is contained in:
Fynn Petersen-Frey
2023-05-17 19:36:02 +02:00
committed by GitHub
parent 93863b0629
commit 0dde76bbbc
54 changed files with 1494 additions and 2328 deletions

View File

@@ -97,15 +97,18 @@ class AssetService {
/// the exif info from the server (remote assets only)
Future<Asset> loadExif(Asset a) async {
a.exifInfo ??= await _db.exifInfos.get(a.id);
if (a.exifInfo?.iso == null) {
// fileSize is always filled on the server but not set on client
if (a.exifInfo?.fileSize == null) {
if (a.isRemote) {
final dto = await _apiService.assetApi.getAssetById(a.remoteId!);
if (dto != null && dto.exifInfo != null) {
a.exifInfo = Asset.remote(dto).exifInfo!.copyWith(id: a.id);
if (a.isInDb) {
_db.writeTxn(() => a.put(_db));
} else {
debugPrint("[loadExif] parameter Asset is not from DB!");
final newExif = Asset.remote(dto).exifInfo!.copyWith(id: a.id);
if (newExif != a.exifInfo) {
if (a.isInDb) {
_db.writeTxn(() => a.put(_db));
} else {
debugPrint("[loadExif] parameter Asset is not from DB!");
}
}
}
} else {
@@ -115,27 +118,39 @@ class AssetService {
return a;
}
Future<Asset?> updateAsset(
Asset asset,
Future<List<Asset?>> updateAssets(
List<Asset> assets,
UpdateAssetDto updateAssetDto,
) async {
final dto =
await _apiService.assetApi.updateAsset(asset.remoteId!, updateAssetDto);
if (dto != null) {
final updated = asset.updatedCopy(Asset.remote(dto));
if (updated.isInDb) {
await _db.writeTxn(() => updated.put(_db));
final List<AssetResponseDto?> dtos = await Future.wait(
assets.map(
(a) => _apiService.assetApi.updateAsset(a.remoteId!, updateAssetDto),
),
);
bool allInDb = true;
for (int i = 0; i < assets.length; i++) {
final dto = dtos[i], old = assets[i];
if (dto != null) {
final remote = Asset.remote(dto);
if (old.canUpdate(remote)) {
assets[i] = old.updatedCopy(remote);
}
allInDb &= assets[i].isInDb;
}
return updated;
}
return null;
final toUpdate = allInDb ? assets : assets.where((e) => e.isInDb).toList();
await _syncService.upsertAssetsWithExif(toUpdate);
return assets;
}
Future<Asset?> changeFavoriteStatus(Asset asset, bool isFavorite) {
return updateAsset(asset, UpdateAssetDto(isFavorite: isFavorite));
Future<List<Asset?>> changeFavoriteStatus(
List<Asset> assets,
bool isFavorite,
) {
return updateAssets(assets, UpdateAssetDto(isFavorite: isFavorite));
}
Future<Asset?> changeArchiveStatus(Asset asset, bool isArchive) {
return updateAsset(asset, UpdateAssetDto(isArchived: isArchive));
Future<List<Asset?>> changeArchiveStatus(List<Asset> assets, bool isArchive) {
return updateAssets(assets, UpdateAssetDto(isArchived: isArchive));
}
}

View File

@@ -172,7 +172,7 @@ class SyncService {
final idsToDelete = diff.third.map((e) => e.id).toList();
try {
await _db.writeTxn(() => _db.assets.deleteAll(idsToDelete));
await _upsertAssetsWithExif(diff.first + diff.second);
await upsertAssetsWithExif(diff.first + diff.second);
} on IsarError catch (e) {
_log.severe("Failed to sync remote assets to db: $e");
}
@@ -272,7 +272,7 @@ class SyncService {
// for shared album: put missing album assets into local DB
final resultPair = await _linkWithExistingFromDb(toAdd);
await _upsertAssetsWithExif(resultPair.second);
await upsertAssetsWithExif(resultPair.second);
final assetsToLink = resultPair.first + resultPair.second;
final usersToLink = (await _db.users.getAllById(userIdsToAdd)).cast<User>();
@@ -329,7 +329,7 @@ class SyncService {
// put missing album assets into local DB
final result = await _linkWithExistingFromDb(dto.getAssets());
existing.addAll(result.first);
await _upsertAssetsWithExif(result.second);
await upsertAssetsWithExif(result.second);
final Album a = await Album.remote(dto);
await _db.writeTxn(() => _db.albums.store(a));
@@ -540,7 +540,7 @@ class SyncService {
_log.info(
"${result.first.length} assets already existed in DB, to upsert ${result.second.length}",
);
await _upsertAssetsWithExif(result.second);
await upsertAssetsWithExif(result.second);
existing.addAll(result.first);
a.assets.addAll(result.first);
a.assets.addAll(result.second);
@@ -600,7 +600,7 @@ class SyncService {
}
/// Inserts or updates the assets in the database with their ExifInfo (if any)
Future<void> _upsertAssetsWithExif(List<Asset> assets) async {
Future<void> upsertAssetsWithExif(List<Asset> assets) async {
if (assets.isEmpty) {
return;
}