mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
refactor(mobile): backup provider (#16360)
* refactor(mobile): backup provider * refactor(mobile): backup provider
This commit is contained in:
parent
082471dfd9
commit
c70c9067b0
9 changed files with 109 additions and 81 deletions
|
|
@ -10,7 +10,7 @@ import 'package:immich_mobile/entities/album.entity.dart';
|
|||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/interfaces/album_media.interface.dart';
|
||||
import 'package:immich_mobile/interfaces/backup.interface.dart';
|
||||
import 'package:immich_mobile/interfaces/backup_album.interface.dart';
|
||||
import 'package:immich_mobile/interfaces/file_media.interface.dart';
|
||||
import 'package:immich_mobile/models/auth/auth_state.model.dart';
|
||||
import 'package:immich_mobile/models/backup/available_album.model.dart';
|
||||
|
|
@ -23,21 +23,34 @@ import 'package:immich_mobile/models/server_info/server_disk_info.model.dart';
|
|||
import 'package:immich_mobile/providers/app_life_cycle.provider.dart';
|
||||
import 'package:immich_mobile/providers/auth.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
|
||||
import 'package:immich_mobile/providers/db.provider.dart';
|
||||
import 'package:immich_mobile/providers/gallery_permission.provider.dart';
|
||||
import 'package:immich_mobile/repositories/album_media.repository.dart';
|
||||
import 'package:immich_mobile/repositories/backup.repository.dart';
|
||||
import 'package:immich_mobile/repositories/file_media.repository.dart';
|
||||
import 'package:immich_mobile/services/background.service.dart';
|
||||
import 'package:immich_mobile/services/backup.service.dart';
|
||||
import 'package:immich_mobile/services/backup_album.service.dart';
|
||||
import 'package:immich_mobile/services/server_info.service.dart';
|
||||
import 'package:immich_mobile/utils/backup_progress.dart';
|
||||
import 'package:immich_mobile/utils/diff.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:photo_manager/photo_manager.dart' show PMProgressHandler;
|
||||
|
||||
final backupProvider =
|
||||
StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
|
||||
return BackupNotifier(
|
||||
ref.watch(backupServiceProvider),
|
||||
ref.watch(serverInfoServiceProvider),
|
||||
ref.watch(authProvider),
|
||||
ref.watch(backgroundServiceProvider),
|
||||
ref.watch(galleryPermissionNotifier.notifier),
|
||||
ref.watch(albumMediaRepositoryProvider),
|
||||
ref.watch(fileMediaRepositoryProvider),
|
||||
ref.watch(backupAlbumServiceProvider),
|
||||
ref,
|
||||
);
|
||||
});
|
||||
|
||||
class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
BackupNotifier(
|
||||
this._backupService,
|
||||
|
|
@ -45,10 +58,9 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
this._authState,
|
||||
this._backgroundService,
|
||||
this._galleryPermissionNotifier,
|
||||
this._db,
|
||||
this._albumMediaRepository,
|
||||
this._fileMediaRepository,
|
||||
this._backupRepository,
|
||||
this._backupAlbumService,
|
||||
this.ref,
|
||||
) : super(
|
||||
BackUpState(
|
||||
|
|
@ -96,10 +108,9 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
final AuthState _authState;
|
||||
final BackgroundService _backgroundService;
|
||||
final GalleryPermissionNotifier _galleryPermissionNotifier;
|
||||
final Isar _db;
|
||||
final IAlbumMediaRepository _albumMediaRepository;
|
||||
final IFileMediaRepository _fileMediaRepository;
|
||||
final IBackupRepository _backupRepository;
|
||||
final BackupAlbumService _backupAlbumService;
|
||||
final Ref ref;
|
||||
|
||||
///
|
||||
|
|
@ -260,9 +271,9 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
state = state.copyWith(availableAlbums: availableAlbums);
|
||||
|
||||
final List<BackupAlbum> excludedBackupAlbums =
|
||||
await _backupRepository.getAllBySelection(BackupSelection.exclude);
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.exclude);
|
||||
final List<BackupAlbum> selectedBackupAlbums =
|
||||
await _backupRepository.getAllBySelection(BackupSelection.select);
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
|
||||
final Set<AvailableAlbum> selectedAlbums = {};
|
||||
for (final BackupAlbum ba in selectedBackupAlbums) {
|
||||
|
|
@ -439,7 +450,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
}
|
||||
|
||||
/// Save user selection of selected albums and excluded albums to database
|
||||
Future<void> _updatePersistentAlbumsSelection() {
|
||||
Future<void> _updatePersistentAlbumsSelection() async {
|
||||
final epoch = DateTime.fromMillisecondsSinceEpoch(0, isUtc: true);
|
||||
final selected = state.selectedBackupAlbums.map(
|
||||
(e) => BackupAlbum(e.id, e.lastBackup ?? epoch, BackupSelection.select),
|
||||
|
|
@ -447,29 +458,30 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
final excluded = state.excludedBackupAlbums.map(
|
||||
(e) => BackupAlbum(e.id, e.lastBackup ?? epoch, BackupSelection.exclude),
|
||||
);
|
||||
final backupAlbums = selected.followedBy(excluded).toList();
|
||||
backupAlbums.sortBy((e) => e.id);
|
||||
return _db.writeTxn(() async {
|
||||
final dbAlbums = await _db.backupAlbums.where().sortById().findAll();
|
||||
final List<int> toDelete = [];
|
||||
final List<BackupAlbum> toUpsert = [];
|
||||
// stores the most recent `lastBackup` per album but always keeps the `selection` the user just made
|
||||
diffSortedListsSync(
|
||||
dbAlbums,
|
||||
backupAlbums,
|
||||
compare: (BackupAlbum a, BackupAlbum b) => a.id.compareTo(b.id),
|
||||
both: (BackupAlbum a, BackupAlbum b) {
|
||||
b.lastBackup =
|
||||
a.lastBackup.isAfter(b.lastBackup) ? a.lastBackup : b.lastBackup;
|
||||
toUpsert.add(b);
|
||||
return true;
|
||||
},
|
||||
onlyFirst: (BackupAlbum a) => toDelete.add(a.isarId),
|
||||
onlySecond: (BackupAlbum b) => toUpsert.add(b),
|
||||
);
|
||||
await _db.backupAlbums.deleteAll(toDelete);
|
||||
await _db.backupAlbums.putAll(toUpsert);
|
||||
});
|
||||
final candidates = selected.followedBy(excluded).toList();
|
||||
candidates.sortBy((e) => e.id);
|
||||
|
||||
final savedBackupAlbums =
|
||||
await _backupAlbumService.getAll(sort: BackupAlbumSort.id);
|
||||
final List<int> toDelete = [];
|
||||
final List<BackupAlbum> toUpsert = [];
|
||||
|
||||
diffSortedListsSync(
|
||||
savedBackupAlbums,
|
||||
candidates,
|
||||
compare: (BackupAlbum a, BackupAlbum b) => a.id.compareTo(b.id),
|
||||
both: (BackupAlbum a, BackupAlbum b) {
|
||||
b.lastBackup =
|
||||
a.lastBackup.isAfter(b.lastBackup) ? a.lastBackup : b.lastBackup;
|
||||
toUpsert.add(b);
|
||||
return true;
|
||||
},
|
||||
onlyFirst: (BackupAlbum a) => toDelete.add(a.isarId),
|
||||
onlySecond: (BackupAlbum b) => toUpsert.add(b),
|
||||
);
|
||||
|
||||
await _backupAlbumService.deleteAll(toDelete);
|
||||
await _backupAlbumService.updateAll(toUpsert);
|
||||
}
|
||||
|
||||
/// Invoke backup process
|
||||
|
|
@ -686,14 +698,10 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
}
|
||||
|
||||
Future<void> resumeBackup() async {
|
||||
final List<BackupAlbum> selectedBackupAlbums = await _db.backupAlbums
|
||||
.filter()
|
||||
.selectionEqualTo(BackupSelection.select)
|
||||
.findAll();
|
||||
final List<BackupAlbum> excludedBackupAlbums = await _db.backupAlbums
|
||||
.filter()
|
||||
.selectionEqualTo(BackupSelection.exclude)
|
||||
.findAll();
|
||||
final List<BackupAlbum> selectedBackupAlbums =
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
final List<BackupAlbum> excludedBackupAlbums =
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.exclude);
|
||||
Set<AvailableAlbum> selectedAlbums = state.selectedBackupAlbums;
|
||||
Set<AvailableAlbum> excludedAlbums = state.excludedBackupAlbums;
|
||||
if (selectedAlbums.isNotEmpty) {
|
||||
|
|
@ -756,23 +764,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
}
|
||||
|
||||
BackUpProgressEnum get backupProgress => state.backupProgress;
|
||||
|
||||
void updateBackupProgress(BackUpProgressEnum backupProgress) {
|
||||
state = state.copyWith(backupProgress: backupProgress);
|
||||
}
|
||||
}
|
||||
|
||||
final backupProvider =
|
||||
StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
|
||||
return BackupNotifier(
|
||||
ref.watch(backupServiceProvider),
|
||||
ref.watch(serverInfoServiceProvider),
|
||||
ref.watch(authProvider),
|
||||
ref.watch(backgroundServiceProvider),
|
||||
ref.watch(galleryPermissionNotifier.notifier),
|
||||
ref.watch(dbProvider),
|
||||
ref.watch(albumMediaRepositoryProvider),
|
||||
ref.watch(fileMediaRepositoryProvider),
|
||||
ref.watch(backupRepositoryProvider),
|
||||
ref,
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
||||
import 'package:immich_mobile/models/backup/success_upload_asset.model.dart';
|
||||
import 'package:immich_mobile/repositories/backup.repository.dart';
|
||||
import 'package:immich_mobile/repositories/file_media.repository.dart';
|
||||
import 'package:immich_mobile/services/background.service.dart';
|
||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
||||
|
|
@ -24,6 +23,7 @@ import 'package:immich_mobile/providers/app_settings.provider.dart';
|
|||
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/providers/app_life_cycle.provider.dart';
|
||||
import 'package:immich_mobile/services/backup_album.service.dart';
|
||||
import 'package:immich_mobile/services/local_notification.service.dart';
|
||||
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
||||
import 'package:immich_mobile/utils/backup_progress.dart';
|
||||
|
|
@ -37,7 +37,7 @@ final manualUploadProvider =
|
|||
ref.watch(localNotificationService),
|
||||
ref.watch(backupProvider.notifier),
|
||||
ref.watch(backupServiceProvider),
|
||||
ref.watch(backupRepositoryProvider),
|
||||
ref.watch(backupAlbumServiceProvider),
|
||||
ref,
|
||||
);
|
||||
});
|
||||
|
|
@ -47,14 +47,14 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
|||
final LocalNotificationService _localNotificationService;
|
||||
final BackupNotifier _backupProvider;
|
||||
final BackupService _backupService;
|
||||
final BackupRepository _backupRepository;
|
||||
final BackupAlbumService _backupAlbumService;
|
||||
final Ref ref;
|
||||
|
||||
ManualUploadNotifier(
|
||||
this._localNotificationService,
|
||||
this._backupProvider,
|
||||
this._backupService,
|
||||
this._backupRepository,
|
||||
this._backupAlbumService,
|
||||
this.ref,
|
||||
) : super(
|
||||
ManualUploadState(
|
||||
|
|
@ -210,9 +210,9 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
|||
}
|
||||
|
||||
final selectedBackupAlbums =
|
||||
await _backupRepository.getAllBySelection(BackupSelection.select);
|
||||
final excludedBackupAlbums =
|
||||
await _backupRepository.getAllBySelection(BackupSelection.exclude);
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
final excludedBackupAlbums = await _backupAlbumService
|
||||
.getAllBySelection(BackupSelection.exclude);
|
||||
|
||||
// Get candidates from selected albums and excluded albums
|
||||
Set<BackupCandidate> candidates =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue