mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
chore(mobile): use Drift @DriftAccessor() and collapse some providers
This commit is contained in:
parent
35c2a90fca
commit
bc09be718a
92 changed files with 439 additions and 402 deletions
|
|
@ -18,8 +18,7 @@ targets:
|
|||
generate_for: &drift_generate_for
|
||||
- lib/infrastructure/entities/*.dart
|
||||
- lib/infrastructure/entities/*.drift
|
||||
- lib/infrastructure/repositories/db.repository.dart
|
||||
- lib/infrastructure/repositories/logger_db.repository.dart
|
||||
- lib/infrastructure/repositories/*.repository.dart
|
||||
drift_dev:modular:
|
||||
enabled: true
|
||||
options: *drift_options
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ import 'package:maplibre_gl/maplibre_gl.dart';
|
|||
class AssetService {
|
||||
final RemoteAssetRepository _remoteRepository;
|
||||
final RemoteExifRepository _exifRepository;
|
||||
final DriftLocalAssetRepository _localRepository;
|
||||
final LocalAssetRepository _localRepository;
|
||||
final AssetApiRepository _apiRepository;
|
||||
final AssetMediaRepository _mediaRepository;
|
||||
final DriftTrashedLocalAssetRepository _trashedLocalRepository;
|
||||
final TrashedLocalAssetRepository _trashedLocalRepository;
|
||||
|
||||
const AssetService({
|
||||
required this._remoteRepository,
|
||||
|
|
@ -136,13 +136,13 @@ class AssetService {
|
|||
location: location,
|
||||
dateTimeOriginal: dateTime,
|
||||
);
|
||||
await _remoteRepository.update(
|
||||
await _remoteRepository.updateAssets(
|
||||
remoteIds,
|
||||
isFavorite: isFavorite,
|
||||
visibility: visibility,
|
||||
createdAt: parsedDateTime,
|
||||
);
|
||||
await _exifRepository.update(
|
||||
await _exifRepository.updateExif(
|
||||
remoteIds,
|
||||
location: location,
|
||||
dateTimeOriginal: parsedDateTime,
|
||||
|
|
@ -165,7 +165,7 @@ class AssetService {
|
|||
}
|
||||
|
||||
await _apiRepository.delete(remoteIds, true);
|
||||
await _remoteRepository.delete(remoteIds);
|
||||
await _remoteRepository.deleteAssets(remoteIds);
|
||||
}
|
||||
|
||||
Future<void> applyEdits(String remoteId, List<AssetEdit> edits) async {
|
||||
|
|
@ -189,7 +189,7 @@ class AssetService {
|
|||
if (CurrentPlatform.isAndroid && Store.get(StoreKey.manageLocalMediaAndroid, false)) {
|
||||
await _trashedLocalRepository.applyTrashedAssets(deletedIds);
|
||||
} else {
|
||||
await _localRepository.delete(deletedIds);
|
||||
await _localRepository.deleteAssets(deletedIds);
|
||||
}
|
||||
return deletedIds.length;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ import 'package:immich_mobile/platform/background_worker_api.g.dart';
|
|||
import 'package:immich_mobile/platform/background_worker_lock_api.g.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/drift_backup.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/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/sync.provider.dart';
|
||||
|
|
@ -76,31 +74,32 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi {
|
|||
: _backgroundHostApi = BackgroundWorkerBgHostApi() {
|
||||
final ref = ProviderContainer(overrides: [driftProvider.overrideWith(driftOverride(_drift))]);
|
||||
_ref = ref;
|
||||
final db = ref.read(driftProvider);
|
||||
_localSyncService = LocalSyncService(
|
||||
localAlbumRepository: ref.read(localAlbumRepository),
|
||||
localAssetRepository: ref.read(localAssetRepository),
|
||||
localAlbumRepository: db.localAlbumRepository,
|
||||
localAssetRepository: db.localAssetRepository,
|
||||
nativeSyncApi: ref.read(nativeSyncApiProvider),
|
||||
trashedLocalAssetRepository: ref.read(trashedLocalAssetRepository),
|
||||
trashedLocalAssetRepository: db.trashedLocalAssetRepository,
|
||||
assetMediaRepository: ref.read(assetMediaRepositoryProvider),
|
||||
permissionRepository: ref.read(permissionRepositoryProvider),
|
||||
cancellation: _cancellationToken,
|
||||
);
|
||||
_remoteSyncService = SyncStreamService(
|
||||
syncApiRepository: ref.read(syncApiRepositoryProvider),
|
||||
syncStreamRepository: ref.read(syncStreamRepositoryProvider),
|
||||
localAssetRepository: ref.read(localAssetRepository),
|
||||
trashedLocalAssetRepository: ref.read(trashedLocalAssetRepository),
|
||||
syncStreamRepository: db.syncStreamRepository,
|
||||
localAssetRepository: db.localAssetRepository,
|
||||
trashedLocalAssetRepository: db.trashedLocalAssetRepository,
|
||||
assetMediaRepository: ref.read(assetMediaRepositoryProvider),
|
||||
permissionRepository: ref.read(permissionRepositoryProvider),
|
||||
syncMigrationRepository: ref.read(syncMigrationRepositoryProvider),
|
||||
syncMigrationRepository: db.syncMigrationRepository,
|
||||
api: ref.read(apiServiceProvider),
|
||||
cancellation: _cancellationToken,
|
||||
);
|
||||
_hashService = HashService(
|
||||
localAlbumRepository: ref.read(localAlbumRepository),
|
||||
localAssetRepository: ref.read(localAssetRepository),
|
||||
localAlbumRepository: db.localAlbumRepository,
|
||||
localAssetRepository: db.localAssetRepository,
|
||||
nativeSyncApi: ref.read(nativeSyncApiProvider),
|
||||
trashedLocalAssetRepository: ref.read(trashedLocalAssetRepository),
|
||||
trashedLocalAssetRepository: db.trashedLocalAssetRepository,
|
||||
cancellation: _cancellationToken,
|
||||
);
|
||||
BackgroundWorkerFlutterApi.setUp(this);
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ const String _kHashCancelledCode = "HASH_CANCELLED";
|
|||
|
||||
class HashService {
|
||||
final int _batchSize;
|
||||
final DriftLocalAlbumRepository _localAlbumRepository;
|
||||
final DriftLocalAssetRepository _localAssetRepository;
|
||||
final DriftTrashedLocalAssetRepository _trashedLocalAssetRepository;
|
||||
final LocalAlbumRepository _localAlbumRepository;
|
||||
final LocalAssetRepository _localAssetRepository;
|
||||
final TrashedLocalAssetRepository _trashedLocalAssetRepository;
|
||||
final NativeSyncApi _nativeSyncApi;
|
||||
final Completer<void>? _cancellation;
|
||||
final _log = Logger('HashService');
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||
|
||||
class LocalAlbumService {
|
||||
final DriftLocalAlbumRepository _repository;
|
||||
final LocalAlbumRepository _repository;
|
||||
|
||||
const LocalAlbumService(this._repository);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ import 'package:logging/logging.dart';
|
|||
const String _kSyncCancelledCode = "SYNC_CANCELLED";
|
||||
|
||||
class LocalSyncService {
|
||||
final DriftLocalAlbumRepository _localAlbumRepository;
|
||||
final LocalAlbumRepository _localAlbumRepository;
|
||||
// ignore: unused_field
|
||||
final DriftLocalAssetRepository _localAssetRepository;
|
||||
final LocalAssetRepository _localAssetRepository;
|
||||
final NativeSyncApi _nativeSyncApi;
|
||||
final DriftTrashedLocalAssetRepository _trashedLocalAssetRepository;
|
||||
final TrashedLocalAssetRepository _trashedLocalAssetRepository;
|
||||
final AssetMediaRepository _assetMediaRepository;
|
||||
final DevicePermissionRepository _permissionRepository;
|
||||
final Completer<void>? _cancellation;
|
||||
|
|
@ -186,7 +186,7 @@ class LocalSyncService {
|
|||
_log.fine("Removing device album ${a.name}");
|
||||
try {
|
||||
// Asset deletion is handled in the repository
|
||||
await _localAlbumRepository.delete(a.id);
|
||||
await _localAlbumRepository.deleteAlbum(a.id);
|
||||
} catch (e, s) {
|
||||
_log.warning("Error while removing device album", e, s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ typedef MapMarkerSource = Future<List<Marker>> Function(LatLngBounds? bounds);
|
|||
typedef MapQuery = ({MapMarkerSource markerSource});
|
||||
|
||||
class MapFactory {
|
||||
final DriftMapRepository _mapRepository;
|
||||
final MapRepository _mapRepository;
|
||||
|
||||
const MapFactory({required this._mapRepository});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'package:logging/logging.dart';
|
|||
class DriftMemoryService {
|
||||
final log = Logger("DriftMemoryService");
|
||||
|
||||
final DriftMemoryRepository _repository;
|
||||
final MemoryRepository _repository;
|
||||
|
||||
DriftMemoryService(this._repository);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class PartnerService {
|
|||
|
||||
Future<void> update({required String sharedById, required String sharedWithId, required bool inTimeline}) async {
|
||||
await _partnerApiRepository.update(sharedById, inTimeline: inTimeline);
|
||||
await _partnerRepository.update(sharedById: sharedById, sharedWithId: sharedWithId, inTimeline: inTimeline);
|
||||
await _partnerRepository.updatePartner(sharedById: sharedById, sharedWithId: sharedWithId, inTimeline: inTimeline);
|
||||
}
|
||||
|
||||
Future<void> create({required String sharedById, required String sharedWithId, bool inTimeline = false}) async {
|
||||
|
|
@ -37,6 +37,6 @@ class PartnerService {
|
|||
|
||||
Future<void> delete({required String sharedById, required String sharedWithId}) async {
|
||||
await _partnerApiRepository.delete(sharedWithId);
|
||||
await _partnerRepository.delete(sharedById: sharedById, sharedWithId: sharedWithId);
|
||||
await _partnerRepository.deletePartner(sharedById: sharedById, sharedWithId: sharedWithId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'package:immich_mobile/infrastructure/repositories/people.repository.dart
|
|||
import 'package:immich_mobile/repositories/person_api.repository.dart';
|
||||
|
||||
class DriftPeopleService {
|
||||
final DriftPeopleRepository _repository;
|
||||
final PeopleRepository _repository;
|
||||
final PersonApiRepository _personApiRepository;
|
||||
|
||||
const DriftPeopleService(this._repository, this._personApiRepository);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class AlbumAssetCandidates {
|
|||
class RemoteAlbumService {
|
||||
static final _logger = Logger('RemoteAlbumService');
|
||||
|
||||
final DriftRemoteAlbumRepository _repository;
|
||||
final RemoteAlbumRepository _repository;
|
||||
final DriftAlbumApiRepository _albumApiRepository;
|
||||
final ForegroundUploadService _uploadService;
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ class RemoteAlbumService {
|
|||
);
|
||||
|
||||
// Update the local database
|
||||
await _repository.update(updatedAlbum);
|
||||
await _repository.updateAlbum(updatedAlbum);
|
||||
|
||||
return updatedAlbum;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'
|
|||
/// Provides access to a persistent key-value store with an in-memory cache.
|
||||
/// Listens for repository changes to keep the cache updated.
|
||||
class StoreService {
|
||||
final DriftStoreRepository _storeRepository;
|
||||
final StoreRepository _storeRepository;
|
||||
|
||||
/// In-memory cache. Keys are [StoreKey.id]
|
||||
final Map<int, Object?> _cache = {};
|
||||
StreamSubscription<List<StoreDto>>? _storeUpdateSubscription;
|
||||
|
||||
StoreService._({required DriftStoreRepository isarStoreRepository}) : _storeRepository = isarStoreRepository;
|
||||
StoreService._({required StoreRepository isarStoreRepository}) : _storeRepository = isarStoreRepository;
|
||||
|
||||
// TODO: Temporary typedef to make minimal changes. Remove this and make the presentation layer access store through a provider
|
||||
static StoreService? _instance;
|
||||
|
|
@ -24,12 +24,12 @@ class StoreService {
|
|||
}
|
||||
|
||||
// TODO: Replace the implementation with the one from create after removing the typedef
|
||||
static Future<StoreService> init({required DriftStoreRepository storeRepository, bool listenUpdates = true}) async {
|
||||
static Future<StoreService> init({required StoreRepository storeRepository, bool listenUpdates = true}) async {
|
||||
_instance ??= await create(storeRepository: storeRepository, listenUpdates: listenUpdates);
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
static Future<StoreService> create({required DriftStoreRepository storeRepository, bool listenUpdates = true}) async {
|
||||
static Future<StoreService> create({required StoreRepository storeRepository, bool listenUpdates = true}) async {
|
||||
final instance = StoreService._(isarStoreRepository: storeRepository);
|
||||
await instance.populateCache();
|
||||
if (listenUpdates) {
|
||||
|
|
@ -90,7 +90,7 @@ class StoreService {
|
|||
|
||||
/// Removes the value for [key]
|
||||
Future<void> delete<T>(StoreKey<T> key) async {
|
||||
await _storeRepository.delete(key);
|
||||
await _storeRepository.deleteValue(key);
|
||||
_cache.remove(key.id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,24 +6,25 @@ import 'package:immich_mobile/domain/models/store.model.dart';
|
|||
import 'package:immich_mobile/domain/services/store.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
|
||||
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
||||
import 'package:immich_mobile/utils/debug_print.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
final syncLinkedAlbumServiceProvider = Provider(
|
||||
(ref) => SyncLinkedAlbumService(
|
||||
ref.watch(localAlbumRepository),
|
||||
ref.watch(remoteAlbumRepository),
|
||||
final syncLinkedAlbumServiceProvider = Provider((ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
return SyncLinkedAlbumService(
|
||||
db.localAlbumRepository,
|
||||
db.remoteAlbumRepository,
|
||||
ref.watch(driftAlbumApiRepositoryProvider),
|
||||
ref.watch(storeServiceProvider),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
class SyncLinkedAlbumService {
|
||||
final DriftLocalAlbumRepository _localAlbumRepository;
|
||||
final DriftRemoteAlbumRepository _remoteAlbumRepository;
|
||||
final LocalAlbumRepository _localAlbumRepository;
|
||||
final RemoteAlbumRepository _remoteAlbumRepository;
|
||||
final DriftAlbumApiRepository _albumApiRepository;
|
||||
final StoreService _storeService;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ class SyncStreamService {
|
|||
|
||||
final SyncApiRepository _syncApiRepository;
|
||||
final SyncStreamRepository _syncStreamRepository;
|
||||
final DriftLocalAssetRepository _localAssetRepository;
|
||||
final DriftTrashedLocalAssetRepository _trashedLocalAssetRepository;
|
||||
final LocalAssetRepository _localAssetRepository;
|
||||
final TrashedLocalAssetRepository _trashedLocalAssetRepository;
|
||||
final AssetMediaRepository _assetMediaRepository;
|
||||
final DevicePermissionRepository _permissionRepository;
|
||||
final SyncMigrationRepository _syncMigrationRepository;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ enum TimelineOrigin {
|
|||
}
|
||||
|
||||
class TimelineFactory {
|
||||
final DriftTimelineRepository _timelineRepository;
|
||||
final TimelineRepository _timelineRepository;
|
||||
final SettingsRepository _settingsRepository;
|
||||
|
||||
const TimelineFactory({required this._timelineRepository, required this._settingsRepository});
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ Future<void> _populateCloudIds(Drift drift) async {
|
|||
);
|
||||
}
|
||||
}
|
||||
await DriftLocalAlbumRepository(drift).updateCloudMapping(cloudMapping);
|
||||
await LocalAlbumRepository(drift).updateCloudMapping(cloudMapping);
|
||||
}
|
||||
|
||||
typedef _CloudIdMapping = ({String remoteAssetId, LocalAsset localAsset});
|
||||
|
|
|
|||
|
|
@ -1,21 +1,18 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/backup.repository.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
|
||||
final backupRepositoryProvider = Provider<DriftBackupRepository>(
|
||||
(ref) => DriftBackupRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
@DriftAccessor()
|
||||
class BackupRepository extends DatabaseAccessor<Drift> with $BackupRepositoryMixin {
|
||||
BackupRepository(super.attachedDatabase);
|
||||
|
||||
class DriftBackupRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftBackupRepository(this._db) : super(_db);
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
JoinedSelectStatement<$LocalAlbumAssetEntityTable, LocalAlbumAssetEntityData> _getExcludedSubquery() {
|
||||
return _db.localAlbumAssetEntity.selectOnly()
|
||||
|
|
|
|||
|
|
@ -32,8 +32,27 @@ import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity
|
|||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.steps.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/map.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/memory.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/ocr.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/partner.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/people.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_exif.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/stack.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/sync_migration.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/trashed_local_asset.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user_metadata.repository.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
|
@ -69,6 +88,28 @@ import 'package:sqlite_async/sqlite_async.dart';
|
|||
AssetOcrEntity,
|
||||
],
|
||||
include: {'package:immich_mobile/infrastructure/entities/merged_asset.drift'},
|
||||
daos: [
|
||||
AuthUserRepository,
|
||||
BackupRepository,
|
||||
LocalAlbumRepository,
|
||||
LocalAssetRepository,
|
||||
MapRepository,
|
||||
MemoryRepository,
|
||||
OcrRepository,
|
||||
PartnerRepository,
|
||||
PeopleRepository,
|
||||
RemoteAlbumRepository,
|
||||
RemoteAssetRepository,
|
||||
RemoteExifRepository,
|
||||
StackRepository,
|
||||
StoreRepository,
|
||||
SyncMigrationRepository,
|
||||
SyncStreamRepository,
|
||||
TimelineRepository,
|
||||
TrashedLocalAssetRepository,
|
||||
UserMetadataRepository,
|
||||
UserRepository,
|
||||
],
|
||||
)
|
||||
class Drift extends $Drift {
|
||||
final SqliteConnectionPool? _updatePool;
|
||||
|
|
@ -344,13 +385,6 @@ class Drift extends $Drift {
|
|||
);
|
||||
}
|
||||
|
||||
class DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftDatabaseRepository(this._db);
|
||||
|
||||
Future<T> transaction<T>(Future<T> Function() callback) => _db.transaction(callback);
|
||||
}
|
||||
|
||||
// ignore: invalid_use_of_internal_member
|
||||
final class _DriftPoolStreamQueries extends StreamQueryStore {
|
||||
_DriftPoolStreamQueries(this._pool);
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.d
|
|||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.drift.dart';
|
||||
|
||||
enum SortLocalAlbumsBy { id, backupSelection, isIosSharedAlbum, name, assetCount, newestAsset }
|
||||
|
||||
class DriftLocalAlbumRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class LocalAlbumRepository extends DatabaseAccessor<Drift> with $LocalAlbumRepositoryMixin {
|
||||
LocalAlbumRepository(super.attachedDatabase);
|
||||
|
||||
const DriftLocalAlbumRepository(this._db) : super(_db);
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<List<LocalAlbum>> getAll({Set<SortLocalAlbumsBy> sortBy = const {}}) {
|
||||
final assetCount = _db.localAlbumAssetEntity.assetId.count();
|
||||
|
|
@ -57,7 +59,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
|
|||
return query.map((row) => row.toDto()).get();
|
||||
}
|
||||
|
||||
Future<void> delete(String albumId) => transaction(() async {
|
||||
Future<void> deleteAlbum(String albumId) => transaction(() async {
|
||||
// Remove all assets that are only in this particular album
|
||||
// We cannot remove all assets in the album because they might be in other albums in iOS
|
||||
// That is not the case on Android since asset <-> album has one:one mapping
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.drift.dart';
|
||||
|
||||
class RemovalCandidatesResult {
|
||||
final List<LocalAsset> assets;
|
||||
|
|
@ -18,10 +19,12 @@ class RemovalCandidatesResult {
|
|||
const RemovalCandidatesResult({required this.assets, required this.totalBytes});
|
||||
}
|
||||
|
||||
class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class LocalAssetRepository extends DatabaseAccessor<Drift> with $LocalAssetRepositoryMixin {
|
||||
|
||||
const DriftLocalAssetRepository(this._db) : super(_db);
|
||||
LocalAssetRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
SingleOrNullSelectable<LocalAsset?> _assetSelectable(String id) {
|
||||
final query =
|
||||
|
|
@ -72,7 +75,7 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
|||
});
|
||||
}
|
||||
|
||||
Future<void> delete(List<String> ids) {
|
||||
Future<void> deleteAssets(List<String> ids) {
|
||||
if (ids.isEmpty) {
|
||||
return Future.value();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,16 @@ import 'package:immich_mobile/domain/services/map.service.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/map.repository.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
|
||||
class DriftMapRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class MapRepository extends DatabaseAccessor<Drift> with $MapRepositoryMixin {
|
||||
|
||||
const DriftMapRepository(super._db) : _db = _db;
|
||||
MapRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
MapQuery remote(List<String> ownerIds, TimelineMapOptions options) => _mapQueryBuilder(
|
||||
assetFilter: (row) {
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@ import 'package:immich_mobile/domain/models/memory.model.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/memory.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/memory.repository.drift.dart';
|
||||
|
||||
class DriftMemoryRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftMemoryRepository(this._db) : super(_db);
|
||||
@DriftAccessor()
|
||||
class MemoryRepository extends DatabaseAccessor<Drift> with $MemoryRepositoryMixin {
|
||||
MemoryRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<List<DriftMemory>> getAll(String ownerId) async {
|
||||
final now = DateTime.now();
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@ import 'package:drift/drift.dart';
|
|||
import 'package:immich_mobile/domain/models/ocr.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/asset_ocr.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/ocr.repository.drift.dart';
|
||||
|
||||
class OcrRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const OcrRepository(this._db) : super(_db);
|
||||
@DriftAccessor()
|
||||
class OcrRepository extends DatabaseAccessor<Drift> with $OcrRepositoryMixin {
|
||||
OcrRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<List<Ocr>> get(String assetId) async {
|
||||
final query = _db.select(_db.assetOcrEntity)
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@ import 'package:immich_mobile/domain/models/user.model.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/partner.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/mapper.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/partner.repository.drift.dart';
|
||||
|
||||
class PartnerRepository {
|
||||
final Drift _db;
|
||||
const PartnerRepository(this._db);
|
||||
@DriftAccessor()
|
||||
class PartnerRepository extends DatabaseAccessor<Drift> with $PartnerRepositoryMixin {
|
||||
PartnerRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<Partner> get({required String sharedById, required String sharedWithId}) =>
|
||||
(_db.select(_db.partnerEntity).join([
|
||||
|
|
@ -46,11 +49,11 @@ class PartnerRepository {
|
|||
),
|
||||
);
|
||||
|
||||
Future<void> update({required String sharedById, required String sharedWithId, required bool inTimeline}) =>
|
||||
Future<void> updatePartner({required String sharedById, required String sharedWithId, required bool inTimeline}) =>
|
||||
(_db.partnerEntity.update()..where((t) => t.sharedById.equals(sharedById) & t.sharedWithId.equals(sharedWithId)))
|
||||
.write(PartnerEntityCompanion(inTimeline: Value(inTimeline)));
|
||||
|
||||
Future<void> delete({required String sharedById, required String sharedWithId}) =>
|
||||
Future<void> deletePartner({required String sharedById, required String sharedWithId}) =>
|
||||
(_db.partnerEntity.delete()..where((t) => t.sharedById.equals(sharedById) & t.sharedWithId.equals(sharedWithId)))
|
||||
.go();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|||
import 'package:immich_mobile/domain/models/person.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/person.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/people.repository.drift.dart';
|
||||
|
||||
class DriftPeopleRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftPeopleRepository(this._db) : super(_db);
|
||||
@DriftAccessor()
|
||||
class PeopleRepository extends DatabaseAccessor<Drift> with $PeopleRepositoryMixin {
|
||||
PeopleRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<DriftPerson?> get(String personId) async {
|
||||
final query = _db.select(_db.personEntity)..where((row) => row.id.equals(personId));
|
||||
|
|
|
|||
|
|
@ -12,12 +12,15 @@ import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.d
|
|||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.drift.dart';
|
||||
|
||||
enum SortRemoteAlbumsBy { id, updatedAt }
|
||||
|
||||
class DriftRemoteAlbumRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftRemoteAlbumRepository(this._db) : super(_db);
|
||||
@DriftAccessor()
|
||||
class RemoteAlbumRepository extends DatabaseAccessor<Drift> with $RemoteAlbumRepositoryMixin {
|
||||
RemoteAlbumRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<List<RemoteAlbum>> getAll({Set<SortRemoteAlbumsBy> sortBy = const {SortRemoteAlbumsBy.updatedAt}}) {
|
||||
// Count non-trashed assets via the joined asset table. Filtering trashed assets in the
|
||||
|
|
@ -191,7 +194,7 @@ class DriftRemoteAlbumRepository extends DriftDatabaseRepository {
|
|||
});
|
||||
}
|
||||
|
||||
Future<void> update(RemoteAlbum album) async {
|
||||
Future<void> updateAlbum(RemoteAlbum album) async {
|
||||
await _db.remoteAlbumEntity.update().replace(
|
||||
RemoteAlbumEntityCompanion(
|
||||
id: Value(album.id),
|
||||
|
|
|
|||
|
|
@ -10,13 +10,16 @@ import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.drift.dart';
|
||||
import 'package:immich_mobile/utils/option.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
|
||||
class RemoteAssetRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class RemoteAssetRepository extends DatabaseAccessor<Drift> with $RemoteAssetRepositoryMixin {
|
||||
|
||||
const RemoteAssetRepository(this._db) : super(_db);
|
||||
RemoteAssetRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
/// For testing purposes
|
||||
Future<List<RemoteAsset>> getSome(String userId) {
|
||||
|
|
@ -163,7 +166,7 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> delete(List<String> ids) {
|
||||
Future<void> deleteAssets(List<String> ids) {
|
||||
return _db.batch((batch) {
|
||||
for (final id in ids) {
|
||||
batch.deleteWhere(_db.remoteAssetEntity, (row) => row.id.equals(id));
|
||||
|
|
@ -244,7 +247,7 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
|
|||
return query.map((row) => row.toDto()!).get();
|
||||
}
|
||||
|
||||
Future<void> update(
|
||||
Future<void> updateAssets(
|
||||
List<String> remoteIds, {
|
||||
Option<bool> isFavorite = const .none(),
|
||||
Option<AssetVisibility> visibility = const .none(),
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_exif.repository.drift.dart';
|
||||
import 'package:immich_mobile/utils/option.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
|
||||
class RemoteExifRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class RemoteExifRepository extends DatabaseAccessor<Drift> with $RemoteExifRepositoryMixin {
|
||||
RemoteExifRepository(super.attachedDatabase);
|
||||
|
||||
const RemoteExifRepository(this._db) : super(_db);
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<void> update(
|
||||
Future<void> updateExif(
|
||||
List<String> ids, {
|
||||
Option<DateTime> dateTimeOriginal = const .none(),
|
||||
Option<String> timeZone = const .none(),
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@ import 'package:drift/drift.dart';
|
|||
import 'package:immich_mobile/domain/models/stack.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/stack.repository.drift.dart';
|
||||
|
||||
class DriftStackRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftStackRepository(this._db) : super(_db);
|
||||
@DriftAccessor()
|
||||
class StackRepository extends DatabaseAccessor<Drift> with $StackRepositoryMixin {
|
||||
StackRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<List<Stack>> getAll(String userId) {
|
||||
final query = _db.stackEntity.select()..where((e) => e.ownerId.equals(userId));
|
||||
|
|
|
|||
|
|
@ -3,13 +3,16 @@ import 'package:immich_mobile/domain/models/store.model.dart';
|
|||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/store.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||
|
||||
class DriftStoreRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class StoreRepository extends DatabaseAccessor<Drift> with $StoreRepositoryMixin {
|
||||
final validStoreKeys = StoreKey.values.map((e) => e.id).toSet();
|
||||
|
||||
DriftStoreRepository(super.db) : _db = db;
|
||||
StoreRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<bool> deleteAll() async {
|
||||
await _db.storeEntity.deleteAll();
|
||||
|
|
@ -27,7 +30,7 @@ class DriftStoreRepository extends DriftDatabaseRepository {
|
|||
return query.asyncMap((entity) => _toUpdateEvent(entity)).watch();
|
||||
}
|
||||
|
||||
Future<void> delete<T>(StoreKey<T> key) async {
|
||||
Future<void> deleteValue<T>(StoreKey<T> key) async {
|
||||
await _db.storeEntity.deleteWhere((entity) => entity.id.equals(key.id));
|
||||
return;
|
||||
}
|
||||
|
|
@ -64,7 +67,7 @@ class DriftStoreRepository extends DriftDatabaseRepository {
|
|||
const (bool) => entity.intValue == 1,
|
||||
const (DateTime) => entity.intValue == null ? null : DateTime.fromMillisecondsSinceEpoch(entity.intValue!),
|
||||
const (UserDto) =>
|
||||
entity.stringValue == null ? null : await DriftAuthUserRepository(_db).get(entity.stringValue!),
|
||||
entity.stringValue == null ? null : await AuthUserRepository(_db).get(entity.stringValue!),
|
||||
_ => null,
|
||||
}
|
||||
as T?;
|
||||
|
|
@ -75,7 +78,7 @@ class DriftStoreRepository extends DriftDatabaseRepository {
|
|||
const (String) => (null, value as String),
|
||||
const (bool) => ((value as bool) ? 1 : 0, null),
|
||||
const (DateTime) => ((value as DateTime).millisecondsSinceEpoch, null),
|
||||
const (UserDto) => (null, (await DriftAuthUserRepository(_db).upsert(value as UserDto)).id),
|
||||
const (UserDto) => (null, (await AuthUserRepository(_db).upsert(value as UserDto)).id),
|
||||
_ => throw UnsupportedError("Unsupported primitive type: ${key.type} for key: ${key.name}"),
|
||||
};
|
||||
return StoreEntityCompanion(id: Value(key.id), intValue: Value(intValue), stringValue: Value(strValue));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/sync_migration.repository.drift.dart';
|
||||
|
||||
class SyncMigrationRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class SyncMigrationRepository extends DatabaseAccessor<Drift> with $SyncMigrationRepositoryMixin {
|
||||
|
||||
const SyncMigrationRepository(super.db) : _db = db;
|
||||
SyncMigrationRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<void> v20260128CopyExifWidthHeightToAsset() async {
|
||||
await _db.customStatement('''
|
||||
|
|
|
|||
|
|
@ -29,16 +29,19 @@ import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/utils/exif.converter.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:openapi/api.dart' as api show AlbumUserRole, AssetEditAction, AssetVisibility, UserMetadataKey;
|
||||
import 'package:openapi/api.dart' hide AlbumUserRole, AssetEditAction, AssetVisibility, UserMetadataKey;
|
||||
|
||||
class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
final Logger _logger = Logger('DriftSyncStreamRepository');
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class SyncStreamRepository extends DatabaseAccessor<Drift> with $SyncStreamRepositoryMixin {
|
||||
final Logger _logger = Logger('SyncStreamRepository');
|
||||
|
||||
SyncStreamRepository(super.db) : _db = db;
|
||||
SyncStreamRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<void> reset() async {
|
||||
_logger.fine("SyncResetV1 received. Resetting remote entities");
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/map.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.drift.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
import 'package:stream_transform/stream_transform.dart';
|
||||
|
||||
|
|
@ -33,10 +34,12 @@ class TimelineMapOptions {
|
|||
});
|
||||
}
|
||||
|
||||
class DriftTimelineRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class TimelineRepository extends DatabaseAccessor<Drift> with $TimelineRepositoryMixin {
|
||||
|
||||
const DriftTimelineRepository(super._db) : _db = _db;
|
||||
TimelineRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Stream<List<String>> watchTimelineUserIds(String userId) {
|
||||
final query = _db.partnerEntity.selectOnly()
|
||||
|
|
|
|||
|
|
@ -8,13 +8,16 @@ import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.d
|
|||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/trashed_local_asset.repository.drift.dart';
|
||||
|
||||
typedef TrashedAsset = ({String albumId, LocalAsset asset});
|
||||
|
||||
class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
@DriftAccessor()
|
||||
class TrashedLocalAssetRepository extends DatabaseAccessor<Drift> with $TrashedLocalAssetRepositoryMixin {
|
||||
|
||||
const DriftTrashedLocalAssetRepository(this._db) : super(_db);
|
||||
TrashedLocalAssetRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
/// Matches remote_asset_entity rows owned by the current user. The asset is unique over (owner, checksum),
|
||||
/// so partners can have a duplicate checksum
|
||||
|
|
|
|||
|
|
@ -4,18 +4,23 @@ import 'package:immich_mobile/domain/models/user_metadata.model.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/auth_user.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/mapper.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user_metadata.repository.dart';
|
||||
|
||||
class UserRepository {
|
||||
final Drift _db;
|
||||
const UserRepository(this._db);
|
||||
@DriftAccessor()
|
||||
class UserRepository extends DatabaseAccessor<Drift> with $UserRepositoryMixin {
|
||||
UserRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Stream<Iterable<User>> getAll() => _db.select(_db.userEntity).map(mapToUser).watch();
|
||||
}
|
||||
|
||||
class DriftAuthUserRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftAuthUserRepository(super.db) : _db = db;
|
||||
@DriftAccessor()
|
||||
class AuthUserRepository extends DatabaseAccessor<Drift> with $AuthUserRepositoryMixin {
|
||||
AuthUserRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<UserDto?> get(String id) async {
|
||||
final user = await _db.managers.authUserEntity.filter((user) => user.id.equals(id)).getSingleOrNull();
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@ import 'package:immich_mobile/domain/models/user_metadata.model.dart';
|
|||
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
|
||||
class DriftUserMetadataRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftUserMetadataRepository(this._db) : super(_db);
|
||||
@DriftAccessor()
|
||||
class UserMetadataRepository extends DatabaseAccessor<Drift> {
|
||||
UserMetadataRepository(super.attachedDatabase);
|
||||
|
||||
Drift get _db => attachedDatabase;
|
||||
|
||||
Future<List<UserMetadata>> getUserMetadata(String userId) {
|
||||
final query = _db.userMetadataEntity.select()..where((e) => e.userId.equals(userId));
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
|||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
||||
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/utils/bytes_units.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
|
|
@ -530,7 +530,7 @@ class _CurrentUploadThumbnail extends ConsumerWidget {
|
|||
|
||||
Future<LocalAsset?> _getAsset(WidgetRef ref) async {
|
||||
try {
|
||||
return await ref.read(localAssetRepository).getById(taskId);
|
||||
return await ref.read(driftProvider).localAssetRepository.getById(taskId);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -667,7 +667,7 @@ class FileDetailDialog extends ConsumerWidget {
|
|||
|
||||
Future<LocalAsset?> _getAssetDetails(WidgetRef ref, String localAssetId) async {
|
||||
try {
|
||||
return await ref.read(localAssetRepository).getById(localAssetId);
|
||||
return await ref.read(driftProvider).localAssetRepository.getById(localAssetId);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import 'package:immich_mobile/presentation/actions/action.dart';
|
|||
import 'package:immich_mobile/presentation/pages/edit/editor.provider.dart';
|
||||
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
||||
import 'package:immich_mobile/providers/websocket.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
|
|
@ -50,7 +51,7 @@ class EditAssetAction extends AssetActionBuilder {
|
|||
|
||||
try {
|
||||
// TODO(shenlong): Move all EXIF and Apply Edits logic onto the Route
|
||||
final repository = ref.read(remoteAssetRepositoryProvider);
|
||||
final repository = ref.read(driftProvider).remoteAssetRepository;
|
||||
final (edits, exif) = await (repository.getAssetEdits(asset.id), repository.getExif(asset.id)).wait;
|
||||
if (exif == null || !context.mounted) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:immich_mobile/generated/translations.g.dart';
|
|||
import 'package:immich_mobile/presentation/actions/action.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset_viewer/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/toast.provider.dart';
|
||||
import 'package:immich_mobile/utils/error_handler.dart';
|
||||
import 'package:immich_mobile/utils/timezone.dart';
|
||||
|
|
@ -46,7 +47,7 @@ class EditDateTimeAction extends AssetActionBuilder {
|
|||
}
|
||||
|
||||
final (:assetIds, :origin) = state;
|
||||
final remoteAssetRepository = ref.read(remoteAssetRepositoryProvider);
|
||||
final remoteAssetRepository = ref.read(driftProvider).remoteAssetRepository;
|
||||
final clearSelection = ref.read(clearSelectionProvider(source));
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:immich_mobile/generated/translations.g.dart';
|
|||
import 'package:immich_mobile/presentation/actions/action.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset_viewer/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/toast.provider.dart';
|
||||
import 'package:immich_mobile/utils/error_handler.dart';
|
||||
import 'package:immich_mobile/widgets/common/location_picker.dart';
|
||||
|
|
@ -46,7 +47,7 @@ class EditLocationAction extends AssetActionBuilder {
|
|||
}
|
||||
|
||||
final (:assetIds, :origin) = state;
|
||||
final remoteAssetRepository = ref.read(remoteAssetRepositoryProvider);
|
||||
final remoteAssetRepository = ref.read(driftProvider).remoteAssetRepository;
|
||||
final clearSelection = ref.read(clearSelectionProvider(source));
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ class LocalMediaSummaryPage extends StatelessWidget {
|
|||
body: Consumer(
|
||||
builder: (ctx, ref, __) {
|
||||
final db = ref.watch(driftProvider);
|
||||
final albumsFuture = ref.watch(localAlbumRepository).getAll();
|
||||
final albumsFuture = db.localAlbumRepository.getAll();
|
||||
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
|
|
@ -140,7 +139,7 @@ class RemoteMediaSummaryPage extends StatelessWidget {
|
|||
body: Consumer(
|
||||
builder: (ctx, ref, __) {
|
||||
final db = ref.watch(driftProvider);
|
||||
final albumsFuture = ref.watch(remoteAlbumRepository).getAll();
|
||||
final albumsFuture = db.remoteAlbumRepository.getAll();
|
||||
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||
import 'package:immich_mobile/domain/services/local_album.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
|
||||
final backupAlbumProvider = StateNotifierProvider<BackupAlbumNotifier, List<LocalAlbum>>(
|
||||
(ref) => BackupAlbumNotifier(ref.watch(localAlbumServiceProvider)),
|
||||
(ref) => BackupAlbumNotifier(LocalAlbumService(ref.watch(driftProvider).localAlbumRepository)),
|
||||
);
|
||||
|
||||
class BackupAlbumNotifier extends StateNotifier<List<LocalAlbum>> {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||
import 'package:immich_mobile/constants/constants.dart';
|
||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
import 'package:immich_mobile/services/background_upload.service.dart';
|
||||
import 'package:immich_mobile/services/foreground_upload.service.dart';
|
||||
|
|
@ -367,5 +367,8 @@ final driftCandidateBackupAlbumInfoProvider = FutureProvider.autoDispose.family<
|
|||
ref,
|
||||
assetId,
|
||||
) {
|
||||
return ref.read(localAssetRepository).getSourceAlbums(assetId, backupSelection: BackupSelection.selected);
|
||||
return ref
|
||||
.read(driftProvider)
|
||||
.localAssetRepository
|
||||
.getSourceAlbums(assetId, backupSelection: BackupSelection.selected);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,41 +5,27 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|||
import 'package:immich_mobile/domain/services/local_album.service.dart';
|
||||
import 'package:immich_mobile/domain/services/remote_album.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/remote_album.provider.dart';
|
||||
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
||||
import 'package:immich_mobile/services/foreground_upload.service.dart';
|
||||
|
||||
final localAlbumRepository = Provider<DriftLocalAlbumRepository>(
|
||||
(ref) => DriftLocalAlbumRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final localAlbumServiceProvider = Provider<LocalAlbumService>(
|
||||
(ref) => LocalAlbumService(ref.watch(localAlbumRepository)),
|
||||
);
|
||||
|
||||
final localAlbumProvider = FutureProvider<List<LocalAlbum>>(
|
||||
(ref) => LocalAlbumService(ref.watch(localAlbumRepository))
|
||||
(ref) => LocalAlbumService(ref.watch(driftProvider).localAlbumRepository)
|
||||
.getAll(sortBy: {SortLocalAlbumsBy.newestAsset})
|
||||
.then((albums) => albums.where((album) => album.assetCount > 0).toList()),
|
||||
);
|
||||
|
||||
final localAlbumThumbnailProvider = FutureProvider.family<LocalAsset?, String>(
|
||||
(ref, albumId) => LocalAlbumService(ref.watch(localAlbumRepository)).getThumbnail(albumId),
|
||||
);
|
||||
|
||||
final remoteAlbumRepository = Provider<DriftRemoteAlbumRepository>(
|
||||
(ref) => DriftRemoteAlbumRepository(ref.watch(driftProvider)),
|
||||
(ref, albumId) => LocalAlbumService(ref.watch(driftProvider).localAlbumRepository).getThumbnail(albumId),
|
||||
);
|
||||
|
||||
final remoteAlbumServiceProvider = Provider<RemoteAlbumService>(
|
||||
(ref) => RemoteAlbumService(
|
||||
ref.watch(remoteAlbumRepository),
|
||||
ref.watch(driftProvider).remoteAlbumRepository,
|
||||
ref.watch(driftAlbumApiRepositoryProvider),
|
||||
ref.watch(foregroundUploadServiceProvider),
|
||||
),
|
||||
dependencies: [remoteAlbumRepository],
|
||||
);
|
||||
|
||||
final remoteAlbumProvider = NotifierProvider<RemoteAlbumNotifier, RemoteAlbumState>(
|
||||
|
|
|
|||
|
|
@ -1,38 +1,21 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/services/asset.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_exif.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/trashed_local_asset.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset_api.repository.dart';
|
||||
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
||||
|
||||
final localAssetRepository = Provider<DriftLocalAssetRepository>(
|
||||
(ref) => DriftLocalAssetRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final remoteAssetRepositoryProvider = Provider<RemoteAssetRepository>(
|
||||
(ref) => RemoteAssetRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final remoteExifRepositoryProvider = Provider((ref) => RemoteExifRepository(ref.watch(driftProvider)));
|
||||
|
||||
final trashedLocalAssetRepository = Provider<DriftTrashedLocalAssetRepository>(
|
||||
(ref) => DriftTrashedLocalAssetRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final assetServiceProvider = Provider(
|
||||
(ref) => AssetService(
|
||||
remoteRepository: ref.watch(remoteAssetRepositoryProvider),
|
||||
exifRepository: ref.watch(remoteExifRepositoryProvider),
|
||||
localRepository: ref.watch(localAssetRepository),
|
||||
final assetServiceProvider = Provider((ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
return AssetService(
|
||||
remoteRepository: db.remoteAssetRepository,
|
||||
exifRepository: db.remoteExifRepository,
|
||||
localRepository: db.localAssetRepository,
|
||||
apiRepository: ref.watch(assetApiRepositoryProvider),
|
||||
mediaRepository: ref.watch(assetMediaRepositoryProvider),
|
||||
trashedLocalRepository: ref.watch(trashedLocalAssetRepository),
|
||||
),
|
||||
);
|
||||
trashedLocalRepository: db.trashedLocalAssetRepository,
|
||||
);
|
||||
});
|
||||
|
||||
final placesProvider = FutureProvider<List<(String, String)>>((ref) {
|
||||
final assetService = ref.watch(assetServiceProvider);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/services/map.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/map.repository.dart';
|
||||
import 'package:immich_mobile/presentation/widgets/map/map.state.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
|
||||
final mapRepositoryProvider = Provider<DriftMapRepository>((ref) => DriftMapRepository(ref.watch(driftProvider)));
|
||||
|
||||
final mapServiceProvider = Provider<MapService>(
|
||||
(ref) {
|
||||
final user = ref.watch(currentUserProvider);
|
||||
|
|
@ -19,12 +16,11 @@ final mapServiceProvider = Provider<MapService>(
|
|||
? ref.watch(timelineUsersProvider).valueOrNull ?? [user.id]
|
||||
: [user.id];
|
||||
|
||||
final mapService = ref.watch(mapFactoryProvider).remote(users, ref.watch(mapStateProvider).toOptions());
|
||||
final mapFactory = MapFactory(mapRepository: ref.watch(driftProvider).mapRepository);
|
||||
final mapService = mapFactory.remote(users, ref.watch(mapStateProvider).toOptions());
|
||||
return mapService;
|
||||
},
|
||||
// Empty dependencies to inform the framework that this provider
|
||||
// might be used in a ProviderScope
|
||||
dependencies: const [],
|
||||
);
|
||||
|
||||
final mapFactoryProvider = Provider<MapFactory>((ref) => MapFactory(mapRepository: ref.watch(mapRepositoryProvider)));
|
||||
|
|
|
|||
|
|
@ -3,18 +3,9 @@ import 'dart:async';
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/memory.model.dart';
|
||||
import 'package:immich_mobile/domain/services/memory.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/memory.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
|
||||
final driftMemoryRepositoryProvider = Provider<DriftMemoryRepository>(
|
||||
(ref) => DriftMemoryRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final driftMemoryServiceProvider = Provider<DriftMemoryService>(
|
||||
(ref) => DriftMemoryService(ref.watch(driftMemoryRepositoryProvider)),
|
||||
);
|
||||
|
||||
final driftMemoryFutureProvider = FutureProvider.autoDispose<List<DriftMemory>>((ref) {
|
||||
final (userId, enabled) = ref.watch(currentUserProvider.select((user) => (user?.id, user?.memoryEnabled ?? true)));
|
||||
if (userId == null || !enabled) {
|
||||
|
|
@ -26,6 +17,6 @@ final driftMemoryFutureProvider = FutureProvider.autoDispose<List<DriftMemory>>(
|
|||
final timer = Timer(nextMidnight.difference(now) + const Duration(seconds: 5), ref.invalidateSelf);
|
||||
ref.onDispose(timer.cancel);
|
||||
|
||||
final service = ref.watch(driftMemoryServiceProvider);
|
||||
final service = DriftMemoryService(ref.watch(driftProvider).memoryRepository);
|
||||
return service.getMemoryLane(userId);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/ocr.model.dart';
|
||||
import 'package:immich_mobile/domain/services/ocr.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/ocr.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
|
||||
final ocrRepositoryProvider = Provider<OcrRepository>((ref) => OcrRepository(ref.watch(driftProvider)));
|
||||
|
||||
final ocrServiceProvider = Provider<OcrService>((ref) => OcrService(ref.watch(ocrRepositoryProvider)));
|
||||
|
||||
final ocrAssetProvider = FutureProvider.autoDispose.family<List<Ocr>?, String>((ref, assetId) async {
|
||||
final service = ref.watch(ocrServiceProvider);
|
||||
final service = OcrService(ref.watch(driftProvider).ocrRepository);
|
||||
return service.get(assetId);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/person.model.dart';
|
||||
import 'package:immich_mobile/domain/services/people.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/people.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/user_metadata.provider.dart';
|
||||
import 'package:immich_mobile/repositories/person_api.repository.dart';
|
||||
|
||||
final driftPeopleRepositoryProvider = Provider<DriftPeopleRepository>(
|
||||
(ref) => DriftPeopleRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final driftPeopleServiceProvider = Provider<DriftPeopleService>(
|
||||
(ref) => DriftPeopleService(ref.watch(driftPeopleRepositoryProvider), ref.watch(personApiRepositoryProvider)),
|
||||
(ref) => DriftPeopleService(ref.watch(driftProvider).peopleRepository, ref.watch(personApiRepositoryProvider)),
|
||||
);
|
||||
|
||||
final driftPeopleAssetProvider = FutureProvider.family<List<DriftPerson>, String>((ref, assetId) async {
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/stack.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
|
||||
final driftStackProvider = Provider<DriftStackRepository>((ref) => DriftStackRepository(ref.watch(driftProvider)));
|
||||
|
|
@ -3,55 +3,50 @@ import 'package:immich_mobile/domain/services/hash.service.dart';
|
|||
import 'package:immich_mobile/domain/services/local_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_migration.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';
|
||||
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
||||
import 'package:immich_mobile/repositories/permission.repository.dart';
|
||||
|
||||
final syncMigrationRepositoryProvider = Provider((ref) => SyncMigrationRepository(ref.watch(driftProvider)));
|
||||
|
||||
final syncStreamServiceProvider = Provider(
|
||||
(ref) => SyncStreamService(
|
||||
final syncStreamServiceProvider = Provider((ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
return SyncStreamService(
|
||||
syncApiRepository: ref.watch(syncApiRepositoryProvider),
|
||||
syncStreamRepository: ref.watch(syncStreamRepositoryProvider),
|
||||
localAssetRepository: ref.watch(localAssetRepository),
|
||||
trashedLocalAssetRepository: ref.watch(trashedLocalAssetRepository),
|
||||
syncStreamRepository: db.syncStreamRepository,
|
||||
localAssetRepository: db.localAssetRepository,
|
||||
trashedLocalAssetRepository: db.trashedLocalAssetRepository,
|
||||
assetMediaRepository: ref.watch(assetMediaRepositoryProvider),
|
||||
permissionRepository: ref.watch(permissionRepositoryProvider),
|
||||
syncMigrationRepository: ref.watch(syncMigrationRepositoryProvider),
|
||||
syncMigrationRepository: db.syncMigrationRepository,
|
||||
api: ref.watch(apiServiceProvider),
|
||||
cancellation: ref.watch(cancellationProvider),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
final syncApiRepositoryProvider = Provider((ref) => SyncApiRepository(ref.watch(apiServiceProvider)));
|
||||
|
||||
final syncStreamRepositoryProvider = Provider((ref) => SyncStreamRepository(ref.watch(driftProvider)));
|
||||
|
||||
final localSyncServiceProvider = Provider(
|
||||
(ref) => LocalSyncService(
|
||||
localAlbumRepository: ref.watch(localAlbumRepository),
|
||||
localAssetRepository: ref.watch(localAssetRepository),
|
||||
trashedLocalAssetRepository: ref.watch(trashedLocalAssetRepository),
|
||||
final localSyncServiceProvider = Provider((ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
return LocalSyncService(
|
||||
localAlbumRepository: db.localAlbumRepository,
|
||||
localAssetRepository: db.localAssetRepository,
|
||||
trashedLocalAssetRepository: db.trashedLocalAssetRepository,
|
||||
assetMediaRepository: ref.watch(assetMediaRepositoryProvider),
|
||||
permissionRepository: ref.watch(permissionRepositoryProvider),
|
||||
nativeSyncApi: ref.watch(nativeSyncApiProvider),
|
||||
cancellation: ref.watch(cancellationProvider),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
final hashServiceProvider = Provider(
|
||||
(ref) => HashService(
|
||||
localAlbumRepository: ref.watch(localAlbumRepository),
|
||||
localAssetRepository: ref.watch(localAssetRepository),
|
||||
final hashServiceProvider = Provider((ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
return HashService(
|
||||
localAlbumRepository: db.localAlbumRepository,
|
||||
localAssetRepository: db.localAssetRepository,
|
||||
nativeSyncApi: ref.watch(nativeSyncApiProvider),
|
||||
trashedLocalAssetRepository: ref.watch(trashedLocalAssetRepository),
|
||||
trashedLocalAssetRepository: db.trashedLocalAssetRepository,
|
||||
cancellation: ref.watch(cancellationProvider),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
||||
import 'package:immich_mobile/presentation/widgets/timeline/timeline.state.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/settings.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
|
||||
final timelineRepositoryProvider = Provider<DriftTimelineRepository>(
|
||||
(ref) => DriftTimelineRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final timelineArgsProvider = Provider.autoDispose<TimelineArgs>(
|
||||
(ref) => throw UnimplementedError('Will be overridden through a ProviderScope.'),
|
||||
);
|
||||
|
|
@ -29,7 +24,7 @@ final timelineServiceProvider = Provider<TimelineService>(
|
|||
|
||||
final timelineFactoryProvider = Provider<TimelineFactory>(
|
||||
(ref) => TimelineFactory(
|
||||
timelineRepository: ref.watch(timelineRepositoryProvider),
|
||||
timelineRepository: ref.watch(driftProvider).timelineRepository,
|
||||
settingsRepository: ref.watch(settingsProvider),
|
||||
),
|
||||
);
|
||||
|
|
@ -43,7 +38,7 @@ final timelineUsersProvider = StreamProvider<List<String>>((ref) {
|
|||
// Drift re-emits a fresh but content-identical list on unrelated table updates,
|
||||
// which would dispose and rebuild the timeline service mid-load
|
||||
return ref
|
||||
.watch(timelineRepositoryProvider)
|
||||
.watch(driftProvider).timelineRepository
|
||||
.watchTimelineUserIds(currentUserId)
|
||||
.distinct(const ListEquality<String>().equals);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:async/async.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
|
||||
typedef TrashedAssetsCount = ({int total, int hashed});
|
||||
|
||||
final trashedAssetsCountProvider = StreamProvider<TrashedAssetsCount>((ref) {
|
||||
final repo = ref.watch(trashedLocalAssetRepository);
|
||||
final repo = ref.watch(driftProvider).trashedLocalAssetRepository;
|
||||
final total$ = repo.watchCount();
|
||||
final hashed$ = repo.watchHashedCount();
|
||||
return StreamZip<int>([total$, hashed$]).map((values) => (total: values[0], hashed: values[1]));
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/services/partner.service.dart';
|
||||
import 'package:immich_mobile/domain/services/user.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/partner.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user_api.repository.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
|
||||
import 'package:immich_mobile/repositories/partner_api.repository.dart';
|
||||
|
||||
final userRepositoryProvider = Provider((ref) => UserRepository(ref.watch(driftProvider)));
|
||||
|
||||
final userApiRepositoryProvider = Provider((ref) => UserApiRepository(ref.watch(apiServiceProvider).usersApi));
|
||||
|
||||
final userServiceProvider = Provider(
|
||||
|
|
@ -20,12 +16,7 @@ final userServiceProvider = Provider(
|
|||
),
|
||||
);
|
||||
|
||||
final partnerRepositoryProvider = Provider<PartnerRepository>((ref) => PartnerRepository(ref.watch(driftProvider)));
|
||||
|
||||
final partnerServiceProvider = Provider<PartnerService>(
|
||||
(ref) => PartnerService(
|
||||
ref.watch(userRepositoryProvider),
|
||||
ref.watch(partnerRepositoryProvider),
|
||||
ref.watch(partnerApiRepositoryProvider),
|
||||
),
|
||||
);
|
||||
final partnerServiceProvider = Provider<PartnerService>((ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
return PartnerService(db.userRepository, db.partnerRepository, ref.watch(partnerApiRepositoryProvider));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/user_metadata.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user_metadata.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
|
||||
final userMetadataRepository = Provider<DriftUserMetadataRepository>(
|
||||
(ref) => DriftUserMetadataRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
||||
final userMetadataProvider = FutureProvider<List<UserMetadata>>((ref) async {
|
||||
final repository = ref.watch(userMetadataRepository);
|
||||
final repository = ref.watch(driftProvider).userMetadataRepository;
|
||||
final user = ref.watch(currentUserProvider);
|
||||
if (user == null) {
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ import 'dart:async';
|
|||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset_api.repository.dart';
|
||||
|
||||
final actionServiceProvider = Provider<ActionService>(
|
||||
(ref) => ActionService(ref.watch(assetApiRepositoryProvider), ref.watch(remoteAssetRepositoryProvider)),
|
||||
(ref) => ActionService(ref.watch(assetApiRepositoryProvider), ref.watch(driftProvider).remoteAssetRepository),
|
||||
);
|
||||
|
||||
class ActionService {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart
|
|||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/storage.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
||||
import 'package:immich_mobile/repositories/upload.repository.dart';
|
||||
|
|
@ -26,11 +26,12 @@ import 'package:openapi/api.dart' as api;
|
|||
import 'package:path/path.dart' as p;
|
||||
|
||||
final backgroundUploadServiceProvider = Provider((ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
final service = BackgroundUploadService(
|
||||
ref.watch(uploadRepositoryProvider),
|
||||
ref.watch(storageRepositoryProvider),
|
||||
ref.watch(localAssetRepository),
|
||||
ref.watch(backupRepositoryProvider),
|
||||
db.localAssetRepository,
|
||||
db.backupRepository,
|
||||
ref.watch(assetMediaRepositoryProvider),
|
||||
);
|
||||
|
||||
|
|
@ -112,8 +113,8 @@ class BackgroundUploadService {
|
|||
|
||||
final UploadRepository _uploadRepository;
|
||||
final StorageRepository _storageRepository;
|
||||
final DriftLocalAssetRepository _localAssetRepository;
|
||||
final DriftBackupRepository _backupRepository;
|
||||
final LocalAssetRepository _localAssetRepository;
|
||||
final BackupRepository _backupRepository;
|
||||
final AssetMediaRepository _assetMediaRepository;
|
||||
final Logger _logger = Logger('BackgroundUploadService');
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||
import 'package:immich_mobile/constants/enums.dart';
|
||||
import 'package:immich_mobile/extensions/platform_extensions.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
||||
|
||||
final cleanupServiceProvider = Provider<CleanupService>((ref) {
|
||||
return CleanupService(ref.watch(localAssetRepository), ref.watch(assetMediaRepositoryProvider));
|
||||
return CleanupService(ref.watch(driftProvider).localAssetRepository, ref.watch(assetMediaRepositoryProvider));
|
||||
});
|
||||
|
||||
class CleanupService {
|
||||
static final int _deleteBatchSize = CurrentPlatform.isAndroid ? 2000 : 10000;
|
||||
|
||||
final DriftLocalAssetRepository _localAssetRepository;
|
||||
final LocalAssetRepository _localAssetRepository;
|
||||
final AssetMediaRepository _assetMediaRepository;
|
||||
|
||||
const CleanupService(this._localAssetRepository, this._assetMediaRepository);
|
||||
|
|
@ -46,7 +46,7 @@ class CleanupService {
|
|||
|
||||
final deletedIds = await _assetMediaRepository.deleteAll(batch);
|
||||
if (deletedIds.isNotEmpty) {
|
||||
await _localAssetRepository.delete(deletedIds);
|
||||
await _localAssetRepository.deleteAssets(deletedIds);
|
||||
deletedCount += deletedIds.length;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import 'package:immich_mobile/domain/services/timeline.service.dart';
|
|||
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.page.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart' as beta_asset_provider;
|
||||
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/people.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
|
|
@ -21,7 +21,7 @@ final deepLinkServiceProvider = Provider(
|
|||
ref.watch(timelineFactoryProvider),
|
||||
ref.watch(beta_asset_provider.assetServiceProvider),
|
||||
ref.watch(remoteAlbumServiceProvider),
|
||||
ref.watch(driftMemoryServiceProvider),
|
||||
DriftMemoryService(ref.watch(driftProvider).memoryRepository),
|
||||
ref.watch(driftPeopleServiceProvider),
|
||||
ref.watch(currentUserProvider),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart
|
|||
import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||
import 'package:immich_mobile/platform/connectivity_api.g.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/storage.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
||||
|
|
@ -39,7 +40,7 @@ final foregroundUploadServiceProvider = Provider((ref) {
|
|||
return ForegroundUploadService(
|
||||
ref.watch(uploadRepositoryProvider),
|
||||
ref.watch(storageRepositoryProvider),
|
||||
ref.watch(backupRepositoryProvider),
|
||||
ref.watch(driftProvider).backupRepository,
|
||||
ref.watch(connectivityApiProvider),
|
||||
ref.watch(assetMediaRepositoryProvider),
|
||||
);
|
||||
|
|
@ -61,7 +62,7 @@ class ForegroundUploadService {
|
|||
|
||||
final UploadRepository _uploadRepository;
|
||||
final StorageRepository _storageRepository;
|
||||
final DriftBackupRepository _backupRepository;
|
||||
final BackupRepository _backupRepository;
|
||||
final ConnectivityApi _connectivityApi;
|
||||
final AssetMediaRepository _assetMediaRepository;
|
||||
final Logger _logger = Logger('ForegroundUploadService');
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:immich_mobile/domain/services/timeline.service.dart';
|
|||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||
import 'package:immich_mobile/models/view_intent/view_intent_payload.extension.dart';
|
||||
import 'package:immich_mobile/platform/view_intent_api.g.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
|
|
@ -19,13 +19,13 @@ class ViewIntentResolvedAsset {
|
|||
|
||||
final viewIntentAssetResolverProvider = Provider<ViewIntentAssetResolver>(
|
||||
(ref) => ViewIntentAssetResolver(
|
||||
localAssetRepository: ref.read(localAssetRepository),
|
||||
localAssetRepository: ref.read(driftProvider).localAssetRepository,
|
||||
timelineFactory: ref.read(timelineFactoryProvider),
|
||||
),
|
||||
);
|
||||
|
||||
class ViewIntentAssetResolver {
|
||||
final DriftLocalAssetRepository _localAssetRepository;
|
||||
final LocalAssetRepository _localAssetRepository;
|
||||
final TimelineFactory _timelineFactory;
|
||||
static final Logger _logger = Logger('ViewIntentAssetResolver');
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ abstract final class Bootstrap {
|
|||
await configureSqliteCache();
|
||||
final (db, updatePool) = await openSqliteConnectionWithUpdatePool(name: 'immich');
|
||||
final drift = Drift.sqlite(db, updatePool);
|
||||
final DriftStoreRepository storeRepo = DriftStoreRepository(drift);
|
||||
final StoreRepository storeRepo = StoreRepository(drift);
|
||||
|
||||
await StoreService.init(storeRepository: storeRepo, listenUpdates: listenStoreUpdates);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import 'dart:io';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/services/local_album.service.dart';
|
||||
import 'package:immich_mobile/domain/services/memory.service.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/platform_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||
|
|
@ -12,7 +14,6 @@ import 'package:immich_mobile/providers/background_sync.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/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/storage.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/trash_sync.provider.dart';
|
||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
||||
|
|
@ -230,10 +231,11 @@ class _SyncStatsCounts extends ConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final db = ref.watch(driftProvider);
|
||||
final assetService = ref.watch(assetServiceProvider);
|
||||
final localAlbumService = ref.watch(localAlbumServiceProvider);
|
||||
final localAlbumService = LocalAlbumService(db.localAlbumRepository);
|
||||
final remoteAlbumService = ref.watch(remoteAlbumServiceProvider);
|
||||
final memoryService = ref.watch(driftMemoryServiceProvider);
|
||||
final memoryService = DriftMemoryService(db.memoryRepository);
|
||||
final appSettingsService = ref.watch(appSettingsServiceProvider);
|
||||
|
||||
Future<List<dynamic>> loadCounts() async {
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ import '../../service.mocks.dart';
|
|||
|
||||
void main() {
|
||||
late LocalSyncService sut;
|
||||
late DriftLocalAlbumRepository mockLocalAlbumRepository;
|
||||
late DriftLocalAssetRepository mockLocalAssetRepository;
|
||||
late DriftTrashedLocalAssetRepository mockTrashedLocalAssetRepository;
|
||||
late LocalAlbumRepository mockLocalAlbumRepository;
|
||||
late LocalAssetRepository mockLocalAssetRepository;
|
||||
late TrashedLocalAssetRepository mockTrashedLocalAssetRepository;
|
||||
late AssetMediaRepository mockAssetMediaRepository;
|
||||
late MockPermissionRepository mockPermissionRepository;
|
||||
late MockNativeSyncApi mockNativeSyncApi;
|
||||
|
|
@ -36,7 +36,7 @@ void main() {
|
|||
debugDefaultTargetPlatformOverride = TargetPlatform.android;
|
||||
|
||||
db = Drift(drift.DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ const _kVersion = 2;
|
|||
|
||||
void main() {
|
||||
late StoreService sut;
|
||||
late DriftStoreRepository mockDriftStoreRepo;
|
||||
late StoreRepository mockDriftStoreRepo;
|
||||
late StreamController<List<StoreDto<Object>>> controller;
|
||||
|
||||
setUp(() async {
|
||||
controller = StreamController<List<StoreDto<Object>>>.broadcast();
|
||||
mockDriftStoreRepo = MockDriftStoreRepository();
|
||||
mockDriftStoreRepo = MockStoreRepository();
|
||||
// For generics, we need to provide fallback to each concrete type to avoid runtime errors
|
||||
registerFallbackValue(StoreKey.accessToken);
|
||||
registerFallbackValue(StoreKey.version);
|
||||
|
|
@ -124,12 +124,12 @@ void main() {
|
|||
|
||||
group('Store Service delete:', () {
|
||||
setUp(() {
|
||||
when(() => mockDriftStoreRepo.delete<String>(any<StoreKey<String>>())).thenAnswer((_) async => true);
|
||||
when(() => mockDriftStoreRepo.deleteValue<String>(any<StoreKey<String>>())).thenAnswer((_) async => true);
|
||||
});
|
||||
|
||||
test('Removes the value from the DB', () async {
|
||||
await sut.delete(StoreKey.accessToken);
|
||||
verify(() => mockDriftStoreRepo.delete<String>(StoreKey.accessToken)).called(1);
|
||||
verify(() => mockDriftStoreRepo.deleteValue<String>(StoreKey.accessToken)).called(1);
|
||||
});
|
||||
|
||||
test('Removes the value from the cache', () async {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/services/sync_linked_album.service.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
|
||||
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import '../../infrastructure/repository.mock.dart';
|
||||
import '../../service.mocks.dart';
|
||||
|
|
@ -13,10 +14,12 @@ void main() {
|
|||
// alone, i.e. the root (main) isolate, where cancellationProvider has no
|
||||
// override and throws if read. The UI reads this provider here.
|
||||
ProviderContainer rootContainer() {
|
||||
final drift = MockDrift();
|
||||
when(() => drift.localAlbumRepository).thenReturn(MockLocalAlbumRepository());
|
||||
when(() => drift.remoteAlbumRepository).thenReturn(MockRemoteAlbumRepository());
|
||||
final container = ProviderContainer(
|
||||
overrides: [
|
||||
localAlbumRepository.overrideWithValue(MockLocalAlbumRepository()),
|
||||
remoteAlbumRepository.overrideWithValue(MockRemoteAlbumRepository()),
|
||||
driftProvider.overrideWithValue(drift),
|
||||
driftAlbumApiRepositoryProvider.overrideWithValue(MockDriftAlbumApiRepository()),
|
||||
storeServiceProvider.overrideWithValue(MockStoreService()),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ void main() {
|
|||
late SyncStreamService sut;
|
||||
late SyncStreamRepository mockSyncStreamRepo;
|
||||
late SyncApiRepository mockSyncApiRepo;
|
||||
late DriftLocalAssetRepository mockLocalAssetRepo;
|
||||
late DriftTrashedLocalAssetRepository mockTrashedLocalAssetRepo;
|
||||
late LocalAssetRepository mockLocalAssetRepo;
|
||||
late TrashedLocalAssetRepository mockTrashedLocalAssetRepo;
|
||||
late AssetMediaRepository mockAssetMediaRepo;
|
||||
late MockPermissionRepository mockPermissionRepo;
|
||||
late MockApiService mockApi;
|
||||
|
|
@ -60,7 +60,7 @@ void main() {
|
|||
registerFallbackValue(const SemVer(major: 2, minor: 5, patch: 0));
|
||||
|
||||
db = Drift(drift.DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ void main() {
|
|||
|
||||
group('getAll', () {
|
||||
test('sorts albums by backupSelection & isIosSharedAlbum', () async {
|
||||
final localAlbumRepo = mediumFactory.getRepository<DriftLocalAlbumRepository>();
|
||||
final localAlbumRepo = mediumFactory.getRepository<LocalAlbumRepository>();
|
||||
await localAlbumRepo.upsert(mediumFactory.localAlbum(id: '1', backupSelection: BackupSelection.none));
|
||||
await localAlbumRepo.upsert(mediumFactory.localAlbum(id: '2', backupSelection: BackupSelection.excluded));
|
||||
await localAlbumRepo.upsert(
|
||||
|
|
@ -46,7 +46,7 @@ void main() {
|
|||
// Android was dropped. The delta reports only the asset's new album, and the
|
||||
// stale link to its old album made the per-album delete sweep wipe the asset.
|
||||
test('keeps an asset moved to another album that still holds other assets', () async {
|
||||
final localAlbumRepo = mediumFactory.getRepository<DriftLocalAlbumRepository>();
|
||||
final localAlbumRepo = mediumFactory.getRepository<LocalAlbumRepository>();
|
||||
|
||||
final moved = _localAsset('moved');
|
||||
final other = _localAsset('other');
|
||||
|
|
@ -83,7 +83,7 @@ void main() {
|
|||
});
|
||||
|
||||
test('replaces album membership with exactly what the delta reports', () async {
|
||||
final localAlbumRepo = mediumFactory.getRepository<DriftLocalAlbumRepository>();
|
||||
final localAlbumRepo = mediumFactory.getRepository<LocalAlbumRepository>();
|
||||
|
||||
final moved = _localAsset('moved');
|
||||
await localAlbumRepo.upsert(mediumFactory.localAlbum(id: 'src'), toUpsert: [moved]);
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ Future<void> _populateStore(Drift db) async {
|
|||
|
||||
void main() {
|
||||
late Drift db;
|
||||
late DriftStoreRepository sut;
|
||||
late StoreRepository sut;
|
||||
|
||||
setUp(() async {
|
||||
db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
sut = DriftStoreRepository(db);
|
||||
sut = StoreRepository(db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
@ -100,7 +100,7 @@ void main() {
|
|||
test('delete()', () async {
|
||||
bool? advancedTroubleshooting = await sut.tryGet(StoreKey.advancedTroubleshooting);
|
||||
expect(advancedTroubleshooting, isFalse);
|
||||
await sut.delete(StoreKey.advancedTroubleshooting);
|
||||
await sut.deleteValue(StoreKey.advancedTroubleshooting);
|
||||
advancedTroubleshooting = await sut.tryGet(StoreKey.advancedTroubleshooting);
|
||||
expect(advancedTroubleshooting, isNull);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ void main() {
|
|||
|
||||
setUpAll(() async {
|
||||
final db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/memory.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/partner.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart';
|
||||
|
|
@ -18,7 +20,11 @@ import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
|||
import 'package:immich_mobile/repositories/upload.repository.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockDriftStoreRepository extends Mock implements DriftStoreRepository {}
|
||||
class MockDrift extends Mock implements Drift {}
|
||||
|
||||
class MockMemoryRepository extends Mock implements MemoryRepository {}
|
||||
|
||||
class MockStoreRepository extends Mock implements StoreRepository {}
|
||||
|
||||
class MockSettingsRepository extends Mock implements SettingsRepository {}
|
||||
|
||||
|
|
@ -26,21 +32,19 @@ class MockLogRepository extends Mock implements LogRepository {}
|
|||
|
||||
class MockSyncStreamRepository extends Mock implements SyncStreamRepository {}
|
||||
|
||||
class MockLocalAlbumRepository extends Mock implements DriftLocalAlbumRepository {}
|
||||
class MockLocalAlbumRepository extends Mock implements LocalAlbumRepository {}
|
||||
|
||||
class MockRemoteAlbumRepository extends Mock implements DriftRemoteAlbumRepository {}
|
||||
class MockRemoteAlbumRepository extends Mock implements RemoteAlbumRepository {}
|
||||
|
||||
class MockLocalAssetRepository extends Mock implements DriftLocalAssetRepository {}
|
||||
|
||||
class MockDriftLocalAssetRepository extends Mock implements DriftLocalAssetRepository {}
|
||||
class MockLocalAssetRepository extends Mock implements LocalAssetRepository {}
|
||||
|
||||
class MockRemoteAssetRepository extends Mock implements RemoteAssetRepository {}
|
||||
|
||||
class MockTrashedLocalAssetRepository extends Mock implements DriftTrashedLocalAssetRepository {}
|
||||
class MockTrashedLocalAssetRepository extends Mock implements TrashedLocalAssetRepository {}
|
||||
|
||||
class MockStorageRepository extends Mock implements StorageRepository {}
|
||||
|
||||
class MockDriftBackupRepository extends Mock implements DriftBackupRepository {}
|
||||
class MockBackupRepository extends Mock implements BackupRepository {}
|
||||
|
||||
class MockUploadRepository extends Mock implements UploadRepository {}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import '../repository_context.dart';
|
|||
|
||||
void main() {
|
||||
late MediumRepositoryContext ctx;
|
||||
late DriftBackupRepository sut;
|
||||
late BackupRepository sut;
|
||||
|
||||
setUp(() {
|
||||
ctx = MediumRepositoryContext();
|
||||
sut = DriftBackupRepository(ctx.db);
|
||||
sut = BackupRepository(ctx.db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import '../repository_context.dart';
|
|||
|
||||
void main() {
|
||||
late MediumRepositoryContext ctx;
|
||||
late DriftLocalAssetRepository sut;
|
||||
late LocalAssetRepository sut;
|
||||
|
||||
setUp(() {
|
||||
ctx = MediumRepositoryContext();
|
||||
sut = DriftLocalAssetRepository(ctx.db);
|
||||
sut = LocalAssetRepository(ctx.db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import '../repository_context.dart';
|
|||
|
||||
void main() {
|
||||
late MediumRepositoryContext ctx;
|
||||
late DriftMemoryRepository sut;
|
||||
late MemoryRepository sut;
|
||||
|
||||
setUp(() {
|
||||
ctx = MediumRepositoryContext();
|
||||
sut = DriftMemoryRepository(ctx.db);
|
||||
sut = MemoryRepository(ctx.db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void main() {
|
|||
final sharer = await ctx.newUser();
|
||||
await ctx.newPartner(sharedById: sharer.id, sharedWithId: me.id, inTimeline: false);
|
||||
|
||||
await sut.update(sharedById: sharer.id, sharedWithId: me.id, inTimeline: true);
|
||||
await sut.updatePartner(sharedById: sharer.id, sharedWithId: me.id, inTimeline: true);
|
||||
|
||||
final result = await sut.get(sharedById: sharer.id, sharedWithId: me.id);
|
||||
expect(result.inTimeline, isTrue);
|
||||
|
|
@ -91,7 +91,7 @@ void main() {
|
|||
final recipient = await ctx.newUser();
|
||||
await ctx.newPartner(sharedById: me.id, sharedWithId: recipient.id);
|
||||
|
||||
await sut.delete(sharedById: me.id, sharedWithId: recipient.id);
|
||||
await sut.deletePartner(sharedById: me.id, sharedWithId: recipient.id);
|
||||
|
||||
final rows = await ctx.db.select(ctx.db.partnerEntity).get();
|
||||
expect(rows, isEmpty);
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import '../repository_context.dart';
|
|||
|
||||
void main() {
|
||||
late MediumRepositoryContext ctx;
|
||||
late DriftPeopleRepository sut;
|
||||
late PeopleRepository sut;
|
||||
|
||||
setUp(() {
|
||||
ctx = MediumRepositoryContext();
|
||||
sut = DriftPeopleRepository(ctx.db);
|
||||
sut = PeopleRepository(ctx.db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ import '../repository_context.dart';
|
|||
|
||||
void main() {
|
||||
late MediumRepositoryContext ctx;
|
||||
late DriftRemoteAlbumRepository sut;
|
||||
late RemoteAlbumRepository sut;
|
||||
|
||||
setUp(() async {
|
||||
ctx = MediumRepositoryContext();
|
||||
sut = DriftRemoteAlbumRepository(ctx.db);
|
||||
sut = RemoteAlbumRepository(ctx.db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import '../repository_context.dart';
|
|||
|
||||
void main() {
|
||||
late MediumRepositoryContext ctx;
|
||||
late DriftTimelineRepository sut;
|
||||
late TimelineRepository sut;
|
||||
|
||||
setUpAll(() async {
|
||||
await initializeDateFormatting();
|
||||
|
|
@ -15,7 +15,7 @@ void main() {
|
|||
|
||||
setUp(() {
|
||||
ctx = MediumRepositoryContext();
|
||||
sut = DriftTimelineRepository(ctx.db);
|
||||
sut = TimelineRepository(ctx.db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ import '../repository_context.dart';
|
|||
|
||||
void main() {
|
||||
late MediumRepositoryContext ctx;
|
||||
late DriftTrashedLocalAssetRepository sut;
|
||||
late TrashedLocalAssetRepository sut;
|
||||
|
||||
setUp(() {
|
||||
ctx = MediumRepositoryContext();
|
||||
sut = DriftTrashedLocalAssetRepository(ctx.db);
|
||||
sut = TrashedLocalAssetRepository(ctx.db);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ void main() {
|
|||
setUp(() async {
|
||||
mapState = const MapState(themeMode: ThemeMode.dark);
|
||||
mapStateNotifier = MockMapStateNotifier(mapState);
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
overrides = [
|
||||
mapStateNotifierProvider.overrideWith(() => mapStateNotifier),
|
||||
localeProvider.overrideWithValue(const Locale("en")),
|
||||
|
|
|
|||
|
|
@ -2,18 +2,20 @@ import 'package:fake_async/fake_async.dart';
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/domain/services/memory.service.dart';
|
||||
import 'package:immich_mobile/domain/services/user.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/memory.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockDriftMemoryService extends Mock implements DriftMemoryService {}
|
||||
import '../../infrastructure/repository.mock.dart';
|
||||
|
||||
class MockUserService extends Mock implements UserService {}
|
||||
|
||||
void main() {
|
||||
late MockDriftMemoryService memoryService;
|
||||
late MockMemoryRepository memoryRepository;
|
||||
late MockUserService userService;
|
||||
|
||||
UserDto user({bool memoryEnabled = true}) => UserDto(
|
||||
|
|
@ -24,10 +26,16 @@ void main() {
|
|||
profileChangedAt: DateTime(2026),
|
||||
);
|
||||
|
||||
Drift mockDrift(MemoryRepository repository) {
|
||||
final drift = MockDrift();
|
||||
when(() => drift.memoryRepository).thenReturn(repository);
|
||||
return drift;
|
||||
}
|
||||
|
||||
ProviderContainer makeContainer() {
|
||||
final container = ProviderContainer(
|
||||
overrides: [
|
||||
driftMemoryServiceProvider.overrideWithValue(memoryService),
|
||||
driftProvider.overrideWithValue(mockDrift(memoryRepository)),
|
||||
currentUserProvider.overrideWith((ref) => CurrentUserProvider(userService)),
|
||||
],
|
||||
);
|
||||
|
|
@ -36,10 +44,10 @@ void main() {
|
|||
}
|
||||
|
||||
setUp(() {
|
||||
memoryService = MockDriftMemoryService();
|
||||
memoryRepository = MockMemoryRepository();
|
||||
userService = MockUserService();
|
||||
|
||||
when(() => memoryService.getMemoryLane('user-1')).thenAnswer((_) async => []);
|
||||
when(() => memoryRepository.getAll('user-1')).thenAnswer((_) async => []);
|
||||
when(() => userService.tryGetMyUser()).thenReturn(user());
|
||||
when(() => userService.watchMyUser()).thenAnswer((_) => const Stream.empty());
|
||||
});
|
||||
|
|
@ -51,15 +59,15 @@ void main() {
|
|||
container.listen(driftMemoryFutureProvider, (_, __) {});
|
||||
async.flushMicrotasks();
|
||||
|
||||
verify(() => memoryService.getMemoryLane('user-1')).called(1);
|
||||
verify(() => memoryRepository.getAll('user-1')).called(1);
|
||||
|
||||
async.elapse(const Duration(seconds: 4));
|
||||
async.flushMicrotasks();
|
||||
verifyNever(() => memoryService.getMemoryLane('user-1'));
|
||||
verifyNever(() => memoryRepository.getAll('user-1'));
|
||||
|
||||
async.elapse(const Duration(hours: 25));
|
||||
async.flushMicrotasks();
|
||||
verify(() => memoryService.getMemoryLane('user-1')).called(greaterThanOrEqualTo(1));
|
||||
verify(() => memoryRepository.getAll('user-1')).called(greaterThanOrEqualTo(1));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -68,13 +76,13 @@ void main() {
|
|||
final container = makeContainer();
|
||||
final subscription = container.listen(driftMemoryFutureProvider, (_, __) {});
|
||||
async.flushMicrotasks();
|
||||
verify(() => memoryService.getMemoryLane('user-1')).called(1);
|
||||
verify(() => memoryRepository.getAll('user-1')).called(1);
|
||||
|
||||
subscription.close();
|
||||
async.elapse(const Duration(hours: 25));
|
||||
async.flushMicrotasks();
|
||||
|
||||
verifyNever(() => memoryService.getMemoryLane('user-1'));
|
||||
verifyNever(() => memoryRepository.getAll('user-1'));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -89,7 +97,7 @@ void main() {
|
|||
async.elapse(const Duration(hours: 25));
|
||||
async.flushMicrotasks();
|
||||
|
||||
verifyNever(() => memoryService.getMemoryLane(any()));
|
||||
verifyNever(() => memoryRepository.getAll(any()));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ void main() {
|
|||
debugDefaultTargetPlatformOverride = TargetPlatform.android;
|
||||
|
||||
db = Drift(drift.DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ void main() {
|
|||
setUpAll(() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ void main() {
|
|||
late BackgroundUploadService sut;
|
||||
late MockUploadRepository mockUploadRepository;
|
||||
late MockStorageRepository mockStorageRepository;
|
||||
late MockDriftLocalAssetRepository mockLocalAssetRepository;
|
||||
late MockDriftBackupRepository mockBackupRepository;
|
||||
late MockLocalAssetRepository mockLocalAssetRepository;
|
||||
late MockBackupRepository mockBackupRepository;
|
||||
late MockAssetMediaRepository mockAssetMediaRepository;
|
||||
late Drift db;
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ void main() {
|
|||
(MethodCall methodCall) async => 'test',
|
||||
);
|
||||
db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
await SettingsRepository.ensureInitialized(db);
|
||||
|
||||
await Store.put(StoreKey.serverEndpoint, 'http://test-server.com');
|
||||
|
|
@ -47,8 +47,8 @@ void main() {
|
|||
setUp(() {
|
||||
mockUploadRepository = MockUploadRepository();
|
||||
mockStorageRepository = MockStorageRepository();
|
||||
mockLocalAssetRepository = MockDriftLocalAssetRepository();
|
||||
mockBackupRepository = MockDriftBackupRepository();
|
||||
mockLocalAssetRepository = MockLocalAssetRepository();
|
||||
mockBackupRepository = MockBackupRepository();
|
||||
mockAssetMediaRepository = MockAssetMediaRepository();
|
||||
|
||||
sut = BackgroundUploadService(
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ import '../repository.mocks.dart';
|
|||
void main() {
|
||||
late CleanupService sut;
|
||||
|
||||
late MockDriftLocalAssetRepository localAssetRepository;
|
||||
late MockLocalAssetRepository localAssetRepository;
|
||||
late MockAssetMediaRepository assetMediaRepository;
|
||||
|
||||
setUp(() {
|
||||
localAssetRepository = MockDriftLocalAssetRepository();
|
||||
localAssetRepository = MockLocalAssetRepository();
|
||||
assetMediaRepository = MockAssetMediaRepository();
|
||||
sut = CleanupService(localAssetRepository, assetMediaRepository);
|
||||
});
|
||||
|
|
@ -24,7 +24,7 @@ void main() {
|
|||
|
||||
expect(result, 0);
|
||||
verifyNever(() => assetMediaRepository.deleteAll(any()));
|
||||
verifyNever(() => localAssetRepository.delete(any()));
|
||||
verifyNever(() => localAssetRepository.deleteAssets(any()));
|
||||
});
|
||||
|
||||
test('deletes in a single batch when under limit', () async {
|
||||
|
|
@ -33,13 +33,13 @@ void main() {
|
|||
when(() => assetMediaRepository.deleteAll(any())).thenAnswer((invocation) async {
|
||||
return (invocation.positionalArguments.first as List<String>).toList();
|
||||
});
|
||||
when(() => localAssetRepository.delete(any())).thenAnswer((_) async {});
|
||||
when(() => localAssetRepository.deleteAssets(any())).thenAnswer((_) async {});
|
||||
|
||||
final result = await sut.deleteLocalAssets(ids);
|
||||
|
||||
expect(result, ids.length);
|
||||
verify(() => assetMediaRepository.deleteAll(ids)).called(1);
|
||||
verify(() => localAssetRepository.delete(ids)).called(1);
|
||||
verify(() => localAssetRepository.deleteAssets(ids)).called(1);
|
||||
});
|
||||
|
||||
test('deletes in platform-specific batches when over limit', () async {
|
||||
|
|
@ -52,7 +52,7 @@ void main() {
|
|||
capturedBatches.add(batch);
|
||||
return batch;
|
||||
});
|
||||
when(() => localAssetRepository.delete(any())).thenAnswer((_) async {});
|
||||
when(() => localAssetRepository.deleteAssets(any())).thenAnswer((_) async {});
|
||||
|
||||
final result = await sut.deleteLocalAssets(ids);
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ void main() {
|
|||
expect(capturedBatches[1].last, 'asset-${batchSize * 2 - 1}');
|
||||
expect(capturedBatches[2].first, 'asset-${batchSize * 2}');
|
||||
expect(capturedBatches[2].last, 'asset-${batchSize * 2 + 500}');
|
||||
verify(() => localAssetRepository.delete(any())).called(3);
|
||||
verify(() => localAssetRepository.deleteAssets(any())).called(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ void main() {
|
|||
late ForegroundUploadService sut;
|
||||
late MockUploadRepository mockUploadRepository;
|
||||
late MockStorageRepository mockStorageRepository;
|
||||
late MockDriftBackupRepository mockBackupRepository;
|
||||
late MockBackupRepository mockBackupRepository;
|
||||
late MockConnectivityApi mockConnectivityApi;
|
||||
late MockAssetMediaRepository mockAssetMediaRepository;
|
||||
late Drift db;
|
||||
|
|
@ -36,7 +36,7 @@ void main() {
|
|||
(MethodCall methodCall) async => 'test',
|
||||
);
|
||||
db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
||||
await StoreService.init(storeRepository: StoreRepository(db));
|
||||
await SettingsRepository.ensureInitialized(db);
|
||||
|
||||
await Store.put(StoreKey.serverEndpoint, 'http://demo.immich.app');
|
||||
|
|
@ -49,7 +49,7 @@ void main() {
|
|||
setUp(() {
|
||||
mockUploadRepository = MockUploadRepository();
|
||||
mockStorageRepository = MockStorageRepository();
|
||||
mockBackupRepository = MockDriftBackupRepository();
|
||||
mockBackupRepository = MockBackupRepository();
|
||||
mockConnectivityApi = MockConnectivityApi();
|
||||
mockAssetMediaRepository = MockAssetMediaRepository();
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|||
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
||||
import 'package:immich_mobile/platform/view_intent_api.g.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
import 'package:immich_mobile/services/view_intent_asset_resolver.service.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
|
@ -16,13 +16,13 @@ import '../infrastructure/repository.mock.dart';
|
|||
class MockTimelineFactory extends Mock implements TimelineFactory {}
|
||||
|
||||
void main() {
|
||||
late MockDriftLocalAssetRepository mockLocalAssetRepository;
|
||||
late MockLocalAssetRepository mockLocalAssetRepository;
|
||||
late MockTimelineFactory timelineFactory;
|
||||
late List<TimelineService> createdTimelineServices;
|
||||
late ProviderContainer container;
|
||||
|
||||
setUp(() {
|
||||
mockLocalAssetRepository = MockDriftLocalAssetRepository();
|
||||
mockLocalAssetRepository = MockLocalAssetRepository();
|
||||
timelineFactory = MockTimelineFactory();
|
||||
createdTimelineServices = [];
|
||||
|
||||
|
|
@ -33,9 +33,12 @@ void main() {
|
|||
return timelineService;
|
||||
});
|
||||
|
||||
final drift = MockDrift();
|
||||
when(() => drift.localAssetRepository).thenReturn(mockLocalAssetRepository);
|
||||
|
||||
container = ProviderContainer(
|
||||
overrides: [
|
||||
localAssetRepository.overrideWith((ref) => mockLocalAssetRepository),
|
||||
driftProvider.overrideWithValue(drift),
|
||||
timelineFactoryProvider.overrideWith((ref) => timelineFactory),
|
||||
],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ class MediumFactory {
|
|||
|
||||
T getRepository<T>() {
|
||||
switch (T) {
|
||||
case const (DriftLocalAlbumRepository):
|
||||
return DriftLocalAlbumRepository(_db) as T;
|
||||
case const (LocalAlbumRepository):
|
||||
return LocalAlbumRepository(_db) as T;
|
||||
default:
|
||||
throw Exception('Unknown repository: $T');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import 'factories/user_factory.dart';
|
|||
|
||||
class RepositoryMocks {
|
||||
final localAlbum = LocalAlbumRepositoryStub(MockLocalAlbumRepository());
|
||||
final localAsset = LocalAssetRepositoryStub(MockDriftLocalAssetRepository());
|
||||
final localAsset = LocalAssetRepositoryStub(MockLocalAssetRepository());
|
||||
final remoteAsset = RemoteAssetRepositoryStub(MockRemoteAssetRepository());
|
||||
final remoteExif = RemoteExifRepositoryStub(MockRemoteExifRepository());
|
||||
final trashedAsset = MockTrashedLocalAssetRepository();
|
||||
|
|
@ -247,8 +247,8 @@ extension type const LocalAlbumRepositoryStub(MockLocalAlbumRepository repo) imp
|
|||
() => repo.getAssetsToHash(any());
|
||||
}
|
||||
|
||||
extension type const LocalAssetRepositoryStub(MockDriftLocalAssetRepository repo)
|
||||
implements Stub<MockDriftLocalAssetRepository> {
|
||||
extension type const LocalAssetRepositoryStub(MockLocalAssetRepository repo)
|
||||
implements Stub<MockLocalAssetRepository> {
|
||||
Future<void> Function() get reconcileHashesFromCloudId =>
|
||||
() => repo.reconcileHashesFromCloudId();
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ extension type const RemoteAssetRepositoryStub(MockRemoteAssetRepository repo)
|
|||
() => repo.getAssetEdits(any());
|
||||
|
||||
Future<void> Function() get update =>
|
||||
() => repo.update(
|
||||
() => repo.updateAssets(
|
||||
any(),
|
||||
isFavorite: any(named: 'isFavorite'),
|
||||
visibility: any(named: 'visibility'),
|
||||
|
|
@ -275,7 +275,7 @@ extension type const RemoteAssetRepositoryStub(MockRemoteAssetRepository repo)
|
|||
|
||||
extension type const RemoteExifRepositoryStub(MockRemoteExifRepository repo) implements Stub<MockRemoteExifRepository> {
|
||||
Future<void> Function() get update =>
|
||||
() => repo.update(
|
||||
() => repo.updateExif(
|
||||
any(),
|
||||
dateTimeOriginal: any(named: 'dateTimeOriginal'),
|
||||
timeZone: any(named: 'timeZone'),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import 'package:immich_mobile/presentation/actions/action.dart';
|
|||
import 'package:immich_mobile/presentation/actions/action.widget.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/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
||||
import 'package:immich_mobile/providers/routes.provider.dart';
|
||||
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
||||
|
|
@ -28,6 +29,7 @@ import 'package:immich_mobile/services/server_info.service.dart';
|
|||
import 'package:immich_ui/immich_ui.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import '../../infrastructure/repository.mock.dart';
|
||||
import '../../test_utils.dart';
|
||||
import '../factories/user_factory.dart';
|
||||
import '../mocks.dart';
|
||||
|
|
@ -49,6 +51,7 @@ class PresentationContext {
|
|||
final RepositoryMocks repository;
|
||||
|
||||
List<Override> get overrides => [
|
||||
driftProvider.overrideWithValue(_mockDrift()),
|
||||
currentUserProvider.overrideWith((ref) => CurrentUserProvider(service.user.service)),
|
||||
assetServiceProvider.overrideWithValue(service.asset.service),
|
||||
cleanupServiceProvider.overrideWithValue(service.cleanup.service),
|
||||
|
|
@ -57,10 +60,15 @@ class PresentationContext {
|
|||
gCastServiceProvider.overrideWithValue(service.cast),
|
||||
serverInfoServiceProvider.overrideWithValue(service.serverInfo),
|
||||
inLockedViewProvider.overrideWithValue(false),
|
||||
remoteAssetRepositoryProvider.overrideWithValue(repository.remoteAsset.repo),
|
||||
assetMediaRepositoryProvider.overrideWithValue(repository.assetMedia.api),
|
||||
];
|
||||
|
||||
Drift _mockDrift() {
|
||||
final drift = MockDrift();
|
||||
when(() => drift.remoteAssetRepository).thenReturn(repository.remoteAsset.repo);
|
||||
return drift;
|
||||
}
|
||||
|
||||
List<Override> selected(Set<BaseAsset> assets) => [
|
||||
multiSelectProvider.overrideWith(
|
||||
() => MultiSelectNotifier(MultiSelectState(selectedAssets: assets, lockedSelectionAssets: const {})),
|
||||
|
|
@ -71,7 +79,7 @@ class PresentationContext {
|
|||
TestUtils.init();
|
||||
if (_db == null) {
|
||||
final db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db), listenUpdates: false);
|
||||
await StoreService.init(storeRepository: StoreRepository(db), listenUpdates: false);
|
||||
await StoreService.I.put(StoreKey.serverEndpoint, serverEndpoint);
|
||||
_db = db;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void main() {
|
|||
sut = AssetService(
|
||||
remoteRepository: remoteRepository,
|
||||
exifRepository: exifRepository,
|
||||
localRepository: MockDriftLocalAssetRepository(),
|
||||
localRepository: MockLocalAssetRepository(),
|
||||
apiRepository: apiRepository,
|
||||
mediaRepository: mocks.assetMedia.api,
|
||||
trashedLocalRepository: mocks.trashedAsset,
|
||||
|
|
@ -37,9 +37,9 @@ void main() {
|
|||
await sut.update(ids, dateTime: const .some(picked));
|
||||
|
||||
verify(() => apiRepository.update(ids, dateTimeOriginal: const .some(picked))).called(1);
|
||||
verify(() => remoteRepository.update(ids, createdAt: .some(DateTime.parse(picked)))).called(1);
|
||||
verify(() => remoteRepository.updateAssets(ids, createdAt: .some(DateTime.parse(picked)))).called(1);
|
||||
verify(
|
||||
() => exifRepository.update(
|
||||
() => exifRepository.updateExif(
|
||||
ids,
|
||||
dateTimeOriginal: .some(DateTime.parse(picked)),
|
||||
timeZone: const .some('UTC+06:00'),
|
||||
|
|
@ -51,9 +51,9 @@ void main() {
|
|||
const picked = '2026-01-05T08:00:00.000-05:30';
|
||||
await sut.update(ids, dateTime: const .some(picked));
|
||||
|
||||
verify(() => remoteRepository.update(ids, createdAt: .some(DateTime.parse(picked)))).called(1);
|
||||
verify(() => remoteRepository.updateAssets(ids, createdAt: .some(DateTime.parse(picked)))).called(1);
|
||||
verify(
|
||||
() => exifRepository.update(
|
||||
() => exifRepository.updateExif(
|
||||
ids,
|
||||
dateTimeOriginal: .some(DateTime.parse(picked)),
|
||||
timeZone: const .some('UTC-05:30'),
|
||||
|
|
@ -65,9 +65,9 @@ void main() {
|
|||
const picked = '2026-06-10T13:15:00.000Z';
|
||||
await sut.update(ids, dateTime: const .some(picked));
|
||||
|
||||
verify(() => remoteRepository.update(ids, createdAt: .some(DateTime.parse(picked)))).called(1);
|
||||
verify(() => remoteRepository.updateAssets(ids, createdAt: .some(DateTime.parse(picked)))).called(1);
|
||||
verify(
|
||||
() => exifRepository.update(ids, dateTimeOriginal: .some(DateTime.parse(picked)), timeZone: const .none()),
|
||||
() => exifRepository.updateExif(ids, dateTimeOriginal: .some(DateTime.parse(picked)), timeZone: const .none()),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ void main() {
|
|||
|
||||
setUpAll(() async {
|
||||
final db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db), listenUpdates: false);
|
||||
await StoreService.init(storeRepository: StoreRepository(db), listenUpdates: false);
|
||||
await StoreService.I.put(StoreKey.serverEndpoint, endpoint);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue