import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/album/providers/album.provider.dart'; import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart'; import 'package:immich_mobile/modules/backup/background_service/background.service.dart'; import 'package:immich_mobile/modules/backup/models/backup_state.model.dart'; import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; import 'package:immich_mobile/modules/backup/providers/ios_background_settings.provider.dart'; import 'package:immich_mobile/modules/backup/providers/manual_upload.provider.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/modules/memories/providers/memory.provider.dart'; import 'package:immich_mobile/modules/onboarding/providers/gallery_permission.provider.dart'; import 'package:immich_mobile/modules/settings/providers/notification_permission.provider.dart'; import 'package:immich_mobile/shared/providers/asset.provider.dart'; import 'package:immich_mobile/shared/providers/release_info.provider.dart'; import 'package:immich_mobile/shared/providers/server_info.provider.dart'; import 'package:immich_mobile/shared/providers/tab.provider.dart'; import 'package:immich_mobile/shared/providers/websocket.provider.dart'; import 'package:immich_mobile/shared/services/immich_logger.service.dart'; import 'package:permission_handler/permission_handler.dart'; enum AppStateEnum { active, inactive, paused, resumed, detached, hidden, } class AppStateNotiifer extends StateNotifier { final Ref _ref; bool _wasPaused = false; AppStateNotiifer(this._ref) : super(AppStateEnum.active); AppStateEnum getAppState() { return state; } void handleAppResume() { state = AppStateEnum.resumed; // no need to resume because app was never really paused if (!_wasPaused) return; _wasPaused = false; final isAuthenticated = _ref.read(authenticationProvider).isAuthenticated; final permission = _ref.read(galleryPermissionNotifier); // Needs to be logged in and have gallery permissions if (isAuthenticated && (permission.isGranted || permission.isLimited)) { _ref.read(backupProvider.notifier).resumeBackup(); _ref.read(backgroundServiceProvider).resumeServiceIfEnabled(); _ref.read(serverInfoProvider.notifier).getServerVersion(); switch (_ref.read(tabProvider)) { case TabEnum.home: _ref.read(assetProvider.notifier).getAllAsset(); _ref.read(assetProvider.notifier).getPartnerAssets(); case TabEnum.search: // nothing to do case TabEnum.sharing: _ref.read(assetProvider.notifier).getPartnerAssets(); _ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums(); case TabEnum.library: _ref.read(albumProvider.notifier).getAllAlbums(); } } _ref.read(websocketProvider.notifier).connect(); _ref.read(releaseInfoProvider.notifier).checkGithubReleaseInfo(); _ref .read(notificationPermissionProvider.notifier) .getNotificationPermission(); _ref.read(galleryPermissionNotifier.notifier).getGalleryPermissionStatus(); _ref.read(iOSBackgroundSettingsProvider.notifier).refresh(); _ref.invalidate(memoryFutureProvider); } void handleAppInactivity() { state = AppStateEnum.inactive; // do not stop/clean up anything on inactivity: issued on every orientation change } void handleAppPause() { state = AppStateEnum.paused; _wasPaused = true; // Do not cancel backup if manual upload is in progress if (_ref.read(backupProvider.notifier).backupProgress != BackUpProgressEnum.manualInProgress) { _ref.read(backupProvider.notifier).cancelBackup(); } _ref.read(websocketProvider.notifier).disconnect(); ImmichLogger().flush(); } void handleAppDetached() { state = AppStateEnum.detached; // no guarantee this is called at all _ref.read(manualUploadProvider.notifier).cancelBackup(); } void handleAppHidden() { state = AppStateEnum.hidden; // do not stop/clean up anything on inactivity: issued on every orientation change } } final appStateProvider = StateNotifierProvider((ref) { return AppStateNotiifer(ref); });