From 8fa425fbf7fa450f62e773110bef52c7f6690cfd Mon Sep 17 00:00:00 2001 From: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Date: Wed, 13 May 2026 00:56:56 +0530 Subject: [PATCH] split singleton into a different class --- .../services/background_worker.service.dart | 4 +- .../repositories/metadata.repository.dart | 41 +++++++++++-------- .../drift_backup_album_selection.page.dart | 2 +- .../backup/drift_backup_options.page.dart | 2 +- .../lib/pages/common/splash_screen.page.dart | 4 +- .../widgets/images/image_provider.dart | 4 +- .../widgets/images/local_image_provider.dart | 2 +- .../widgets/images/remote_image_provider.dart | 2 +- mobile/lib/providers/auth.provider.dart | 2 +- .../infrastructure/metadata.provider.dart | 2 +- mobile/lib/services/api.service.dart | 4 +- mobile/lib/services/auth.service.dart | 2 +- .../services/background_upload.service.dart | 2 +- .../services/foreground_upload.service.dart | 4 +- mobile/lib/utils/bootstrap.dart | 2 +- .../lib/widgets/forms/login/login_form.dart | 2 +- .../metadata_repository_test.dart | 10 ++--- .../background_upload.service_test.dart | 2 +- 18 files changed, 48 insertions(+), 45 deletions(-) diff --git a/mobile/lib/domain/services/background_worker.service.dart b/mobile/lib/domain/services/background_worker.service.dart index bb84d7957f..a1a15d30da 100644 --- a/mobile/lib/domain/services/background_worker.service.dart +++ b/mobile/lib/domain/services/background_worker.service.dart @@ -39,7 +39,7 @@ class BackgroundWorkerFgService { _foregroundHostApi.saveNotificationMessage(title, body); Future configure({int? minimumDelaySeconds, bool? requireCharging}) { - final backup = MetadataRepository.instance.appConfig.backup; + final backup = MetadataStore.appConfig.backup; return _foregroundHostApi.configure( BackgroundWorkerSettings( minimumDelaySeconds: minimumDelaySeconds ?? backup.triggerDelay, @@ -69,7 +69,7 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { BackgroundWorkerFlutterApi.setUp(this); } - bool get _isBackupEnabled => MetadataRepository.instance.appConfig.backup.enabled; + bool get _isBackupEnabled => MetadataStore.appConfig.backup.enabled; Future init() async { try { diff --git a/mobile/lib/infrastructure/repositories/metadata.repository.dart b/mobile/lib/infrastructure/repositories/metadata.repository.dart index 5193626536..4d5f516828 100644 --- a/mobile/lib/infrastructure/repositories/metadata.repository.dart +++ b/mobile/lib/infrastructure/repositories/metadata.repository.dart @@ -6,12 +6,7 @@ import 'package:immich_mobile/extensions/string_extensions.dart'; import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; -class MetadataRepository extends DriftDatabaseRepository { - final Drift _db; - final Map _cache = {}; - - MetadataRepository._(this._db) : super(_db); - +abstract final class MetadataStore { static MetadataRepository? _instance; static MetadataRepository get instance { @@ -22,26 +17,36 @@ class MetadataRepository extends DriftDatabaseRepository { return instance; } - AppConfig _appConfig = const .new(); - AppConfig get appConfig => _appConfig; - - SystemConfig _systemConfig = const .new(); - SystemConfig get systemConfig => _systemConfig; - static Future ensureInitialized(Drift db) async { if (_instance == null) { - final instance = MetadataRepository._(db); + final instance = MetadataRepository(db); await instance._hydrate(); _instance = instance; } return _instance!; } - static Future refresh() async { - instance._cache.clear(); - instance._appConfig = const .new(); - instance._systemConfig = const .new(); - await instance._hydrate(); + static AppConfig get appConfig => instance.appConfig; + static SystemConfig get systemConfig => instance.systemConfig; +} + +class MetadataRepository extends DriftDatabaseRepository { + final Drift _db; + final Map _cache = {}; + + MetadataRepository(this._db) : super(_db); + + AppConfig _appConfig = const .new(); + AppConfig get appConfig => _appConfig; + + SystemConfig _systemConfig = const .new(); + SystemConfig get systemConfig => _systemConfig; + + Future refresh() async { + _cache.clear(); + _appConfig = const .new(); + _systemConfig = const .new(); + await _hydrate(); } Future _hydrate() async => _hydrateCache(await _db.select(_db.metadataEntity).get()); diff --git a/mobile/lib/pages/backup/drift_backup_album_selection.page.dart b/mobile/lib/pages/backup/drift_backup_album_selection.page.dart index ff63365136..82f92742df 100644 --- a/mobile/lib/pages/backup/drift_backup_album_selection.page.dart +++ b/mobile/lib/pages/backup/drift_backup_album_selection.page.dart @@ -101,7 +101,7 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState p.totalCount)); final totalChanged = currentTotalAssetCount != _initialTotalAssetCount; diff --git a/mobile/lib/pages/backup/drift_backup_options.page.dart b/mobile/lib/pages/backup/drift_backup_options.page.dart index 4e8a185955..7d42161558 100644 --- a/mobile/lib/pages/backup/drift_backup_options.page.dart +++ b/mobile/lib/pages/backup/drift_backup_options.page.dart @@ -45,7 +45,7 @@ class DriftBackupOptionsPage extends ConsumerWidget { } await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); - final isBackupEnabled = MetadataRepository.instance.appConfig.backup.enabled; + final isBackupEnabled = MetadataStore.appConfig.backup.enabled; if (!isBackupEnabled) { return; } diff --git a/mobile/lib/pages/common/splash_screen.page.dart b/mobile/lib/pages/common/splash_screen.page.dart index 7b49d98307..144bbabe35 100644 --- a/mobile/lib/pages/common/splash_screen.page.dart +++ b/mobile/lib/pages/common/splash_screen.page.dart @@ -341,7 +341,7 @@ class SplashScreenPageState extends ConsumerState { await backgroundManager.hashAssets(); } - if (MetadataRepository.instance.appConfig.backup.syncAlbums) { + if (MetadataStore.appConfig.backup.syncAlbums) { await backgroundManager.syncLinkedAlbum(); } } catch (e) { @@ -370,7 +370,7 @@ class SplashScreenPageState extends ConsumerState { } Future _resumeBackup(DriftBackupNotifier notifier) async { - final isEnableBackup = MetadataRepository.instance.appConfig.backup.enabled; + final isEnableBackup = MetadataStore.appConfig.backup.enabled; if (isEnableBackup) { final currentUser = Store.tryGet(StoreKey.currentUser); diff --git a/mobile/lib/presentation/widgets/images/image_provider.dart b/mobile/lib/presentation/widgets/images/image_provider.dart index 9364fdd091..431ff01a1d 100644 --- a/mobile/lib/presentation/widgets/images/image_provider.dart +++ b/mobile/lib/presentation/widgets/images/image_provider.dart @@ -188,6 +188,4 @@ ImageProvider? getThumbnailImageProvider(BaseAsset asset, {Size size = kThumbnai } bool _shouldUseLocalAsset(BaseAsset asset) => - asset.hasLocal && - (!asset.hasRemote || !MetadataRepository.instance.appConfig.image.preferRemote) && - !asset.isEdited; + asset.hasLocal && (!asset.hasRemote || !MetadataStore.appConfig.image.preferRemote) && !asset.isEdited; diff --git a/mobile/lib/presentation/widgets/images/local_image_provider.dart b/mobile/lib/presentation/widgets/images/local_image_provider.dart index 91b0eb5f7c..80b066ee87 100644 --- a/mobile/lib/presentation/widgets/images/local_image_provider.dart +++ b/mobile/lib/presentation/widgets/images/local_image_provider.dart @@ -102,7 +102,7 @@ class LocalFullImageProvider extends CancellableImageProvider { await _apiService.updateHeaders(); final serverEndpoint = Store.get(StoreKey.serverEndpoint); - final headerMap = MetadataRepository.instance.systemConfig.network.customHeaders; + final headerMap = MetadataStore.systemConfig.network.customHeaders; final customHeaders = headerMap.isEmpty ? null : jsonEncode(headerMap); await _widgetService.writeCredentials(serverEndpoint, accessToken, customHeaders); diff --git a/mobile/lib/providers/infrastructure/metadata.provider.dart b/mobile/lib/providers/infrastructure/metadata.provider.dart index 46ff1069f9..03f15a4a81 100644 --- a/mobile/lib/providers/infrastructure/metadata.provider.dart +++ b/mobile/lib/providers/infrastructure/metadata.provider.dart @@ -3,7 +3,7 @@ import 'package:immich_mobile/domain/models/config/app_config.dart'; import 'package:immich_mobile/domain/models/config/system_config.dart'; import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; -final metadataProvider = Provider.autoDispose((_) => MetadataRepository.instance); +final metadataProvider = Provider.autoDispose((_) => MetadataStore.instance); final appConfigProvider = Provider.autoDispose((ref) { final repo = ref.watch(metadataProvider); diff --git a/mobile/lib/services/api.service.dart b/mobile/lib/services/api.service.dart index ed23834e46..df09994d0f 100644 --- a/mobile/lib/services/api.service.dart +++ b/mobile/lib/services/api.service.dart @@ -177,7 +177,7 @@ class ApiService { if (serverEndpoint != null && serverEndpoint.isNotEmpty) { urls.add(serverEndpoint); } - final network = MetadataRepository.instance.systemConfig.network; + final network = MetadataStore.systemConfig.network; final localEndpoint = network.localEndpoint; if (localEndpoint != null) { urls.add(localEndpoint); @@ -189,7 +189,7 @@ class ApiService { } static Map getRequestHeaders() { - return MetadataRepository.instance.systemConfig.network.customHeaders; + return MetadataStore.systemConfig.network.customHeaders; } ApiClient get apiClient => _apiClient; diff --git a/mobile/lib/services/auth.service.dart b/mobile/lib/services/auth.service.dart index 7d470ecd7a..312b1540c2 100644 --- a/mobile/lib/services/auth.service.dart +++ b/mobile/lib/services/auth.service.dart @@ -100,7 +100,7 @@ class AuthService { _log.severe("Error clearing local data", error, stackTrace); }); - await MetadataRepository.instance.write(MetadataKey.backupEnabled, false); + await MetadataStore.instance.write(MetadataKey.backupEnabled, false); } } diff --git a/mobile/lib/services/background_upload.service.dart b/mobile/lib/services/background_upload.service.dart index 10615f7c03..eb6c0eeafe 100644 --- a/mobile/lib/services/background_upload.service.dart +++ b/mobile/lib/services/background_upload.service.dart @@ -357,7 +357,7 @@ class BackgroundUploadService { } bool _shouldRequireWiFi(LocalAsset asset) { - final backup = MetadataRepository.instance.appConfig.backup; + final backup = MetadataStore.appConfig.backup; if (asset.isVideo && backup.useCellularForVideos) return false; if (!asset.isVideo && backup.useCellularForPhotos) return false; return true; diff --git a/mobile/lib/services/foreground_upload.service.dart b/mobile/lib/services/foreground_upload.service.dart index 5a79cf8f93..a31d6c989b 100644 --- a/mobile/lib/services/foreground_upload.service.dart +++ b/mobile/lib/services/foreground_upload.service.dart @@ -7,8 +7,8 @@ import 'package:immich_mobile/domain/models/asset/asset_metadata.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; -import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/extensions/network_capability_extensions.dart'; +import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; @@ -449,7 +449,7 @@ class ForegroundUploadService { } bool _shouldRequireWiFi(LocalAsset asset) { - final backup = MetadataRepository.instance.appConfig.backup; + final backup = MetadataStore.appConfig.backup; if (asset.isVideo && backup.useCellularForVideos) return false; if (!asset.isVideo && backup.useCellularForPhotos) return false; return true; diff --git a/mobile/lib/utils/bootstrap.dart b/mobile/lib/utils/bootstrap.dart index 68ebfe9c9f..9d46fc8483 100644 --- a/mobile/lib/utils/bootstrap.dart +++ b/mobile/lib/utils/bootstrap.dart @@ -49,7 +49,7 @@ abstract final class Bootstrap { await StoreService.init(storeRepository: storeRepo, listenUpdates: listenStoreUpdates); - final metadataRepo = await MetadataRepository.ensureInitialized(drift); + final metadataRepo = await MetadataStore.ensureInitialized(drift); await LogService.init( logRepository: LogRepository(logDb), diff --git a/mobile/lib/widgets/forms/login/login_form.dart b/mobile/lib/widgets/forms/login/login_form.dart index f8d0172dbd..07a06b72d0 100644 --- a/mobile/lib/widgets/forms/login/login_form.dart +++ b/mobile/lib/widgets/forms/login/login_form.dart @@ -179,7 +179,7 @@ class LoginForm extends HookConsumerWidget { await backgroundManager.syncRemote(); await backgroundManager.hashAssets(); - if (MetadataRepository.instance.appConfig.backup.syncAlbums) { + if (MetadataStore.appConfig.backup.syncAlbums) { await backgroundManager.syncLinkedAlbum(); } } diff --git a/mobile/test/medium/repositories/metadata_repository_test.dart b/mobile/test/medium/repositories/metadata_repository_test.dart index 7b185f3bec..8c12bfa72e 100644 --- a/mobile/test/medium/repositories/metadata_repository_test.dart +++ b/mobile/test/medium/repositories/metadata_repository_test.dart @@ -14,7 +14,7 @@ void main() { setUpAll(() async { ctx = MediumRepositoryContext(); - sut = await MetadataRepository.ensureInitialized(ctx.db); + sut = MetadataRepository(ctx.db); }); tearDownAll(() async { @@ -23,7 +23,7 @@ void main() { setUp(() async { await ctx.db.delete(ctx.db.metadataEntity).go(); - await MetadataRepository.refresh(); + await sut.refresh(); }); group('defaults', () { @@ -78,7 +78,7 @@ void main() { // Cache hasn't seen this row yet — view still returns the default. expect(sut.appConfig.theme.mode, ThemeMode.system); - await MetadataRepository.refresh(); + await sut.refresh(); expect(sut.appConfig.theme.mode, ThemeMode.dark); }); @@ -88,7 +88,7 @@ void main() { await ctx.db.delete(ctx.db.metadataEntity).go(); expect(sut.appConfig.theme.mode, ThemeMode.dark); - await MetadataRepository.refresh(); + await sut.refresh(); expect(sut.appConfig.theme.mode, ThemeMode.system); }); @@ -103,7 +103,7 @@ void main() { ), ); - await MetadataRepository.refresh(); + await sut.refresh(); expect(sut.appConfig.theme.mode, ThemeMode.system); }); }); diff --git a/mobile/test/services/background_upload.service_test.dart b/mobile/test/services/background_upload.service_test.dart index dd19f2b1cc..5e218d016e 100644 --- a/mobile/test/services/background_upload.service_test.dart +++ b/mobile/test/services/background_upload.service_test.dart @@ -38,7 +38,7 @@ void main() { ); db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true)); await StoreService.init(storeRepository: DriftStoreRepository(db)); - await MetadataRepository.ensureInitialized(db); + await MetadataStore.ensureInitialized(db); await Store.put(StoreKey.serverEndpoint, 'http://test-server.com'); await Store.put(StoreKey.deviceId, 'test-device-id');