fix: asset count not populated for local albums

This commit is contained in:
shenlong-tanwen 2025-04-17 01:02:51 +05:30
parent c4047fd9b2
commit 24e80e667b
7 changed files with 77 additions and 10 deletions

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:collection/collection.dart';
import 'package:flutter/widgets.dart';
import 'package:immich_mobile/domain/interfaces/album_media.interface.dart';
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
@ -30,7 +31,8 @@ class SyncService {
// The deviceAlbums will not have the updatedAt field
// and the assetCount will be 0. They are refreshed later
// after the comparison
final deviceAlbums = await _albumMediaRepository.getAll();
final deviceAlbums =
(await _albumMediaRepository.getAll()).sortedBy((a) => a.id);
final dbAlbums =
await _localAlbumRepository.getAll(sortBy: SortLocalAlbumsBy.id);

View File

@ -2,12 +2,13 @@
import 'dart:async';
import 'package:immich_mobile/providers/infrastructure/sync_stream.provider.dart';
import 'package:immich_mobile/providers/infrastructure/sync.provider.dart';
import 'package:immich_mobile/utils/isolate.dart';
import 'package:worker_manager/worker_manager.dart';
class BackgroundSyncManager {
Cancelable<void>? _userSyncTask;
Cancelable<void>? _deviceAlbumSyncTask;
BackgroundSyncManager();
@ -21,6 +22,20 @@ class BackgroundSyncManager {
return Future.wait(futures);
}
// No need to cancel the task, as it can also be run when the user logs out
Future<void> syncDeviceAlbums() {
if (_deviceAlbumSyncTask != null) {
return _deviceAlbumSyncTask!.future;
}
_deviceAlbumSyncTask = runInIsolateGentle(
computation: (ref) => ref.read(syncServiceProvider).syncLocalAlbums(),
);
return _deviceAlbumSyncTask!.whenComplete(() {
_deviceAlbumSyncTask = null;
});
}
Future<void> syncUsers() {
if (_userSyncTask != null) {
return _userSyncTask!.future;
@ -29,9 +44,9 @@ class BackgroundSyncManager {
_userSyncTask = runInIsolateGentle(
computation: (ref) => ref.read(syncStreamServiceProvider).syncUsers(),
);
_userSyncTask!.whenComplete(() {
return _userSyncTask!
..whenComplete(() {
_userSyncTask = null;
});
return _userSyncTask!.future;
}
}

View File

@ -22,11 +22,12 @@ class LocalAlbumEntity extends Table with DriftDefaultsMixin {
}
extension LocalAlbumEntityX on LocalAlbumEntityData {
LocalAlbum toDto() {
LocalAlbum toDto({int assetCount = 0}) {
return LocalAlbum(
id: id,
name: name,
updatedAt: updatedAt,
assetCount: assetCount,
thumbnailId: thumbnailId,
backupSelection: backupSelection,
isAll: isAll,

View File

@ -20,11 +20,28 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
@override
Future<List<LocalAlbum>> getAll({SortLocalAlbumsBy? sortBy}) {
final query = _db.localAlbumEntity.select();
final assetCount = _db.localAlbumAssetEntity.assetId.count();
final query = _db.localAlbumEntity.select().join([
innerJoin(
_db.localAlbumAssetEntity,
_db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id),
useColumns: false,
),
]);
query
..addColumns([assetCount])
..groupBy([_db.localAlbumEntity.id]);
if (sortBy == SortLocalAlbumsBy.id) {
query.orderBy([(a) => OrderingTerm.asc(a.id)]);
query.orderBy([OrderingTerm.asc(_db.localAlbumEntity.id)]);
}
return query.map((a) => a.toDto()).get();
return query
.map(
(row) => row
.readTable(_db.localAlbumEntity)
.toDto(assetCount: row.read(assetCount) ?? 0),
)
.get();
}
@override

View File

@ -0,0 +1,13 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/interfaces/album_media.interface.dart';
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
import 'package:immich_mobile/infrastructure/repositories/album_media.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
final albumMediaRepositoryProvider =
Provider<IAlbumMediaRepository>((ref) => const AlbumMediaRepository());
final localAlbumRepository = Provider<ILocalAlbumRepository>(
(ref) => DriftLocalAlbumRepository(ref.watch(driftProvider)),
);

View File

@ -0,0 +1,8 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/interfaces/local_asset.interface.dart';
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
final localAssetProvider = Provider<ILocalAssetRepository>(
(ref) => DriftLocalAssetRepository(ref.watch(driftProvider)),
);

View File

@ -1,11 +1,22 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/services/sync.service.dart';
import 'package:immich_mobile/domain/services/sync_stream.service.dart';
import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
import 'package:immich_mobile/providers/infrastructure/cancel.provider.dart';
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
final syncServiceProvider = Provider(
(ref) => SyncService(
albumMediaRepository: ref.watch(albumMediaRepositoryProvider),
localAlbumRepository: ref.watch(localAlbumRepository),
localAssetRepository: ref.watch(localAssetProvider),
),
);
final syncStreamServiceProvider = Provider(
(ref) => SyncStreamService(
syncApiRepository: ref.watch(syncApiRepositoryProvider),