|
@@ -1,16 +1,15 @@
|
|
|
import 'package:cancellation_token_http/http.dart';
|
|
|
-import 'package:dio/dio.dart';
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
import 'package:hive_flutter/hive_flutter.dart';
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
import 'package:immich_mobile/constants/hive_box.dart';
|
|
|
import 'package:immich_mobile/modules/backup/models/available_album.model.dart';
|
|
|
+import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
|
|
|
import 'package:immich_mobile/modules/backup/models/hive_backup_albums.model.dart';
|
|
|
+import 'package:immich_mobile/modules/backup/services/backup.service.dart';
|
|
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
|
|
-import 'package:immich_mobile/shared/services/server_info.service.dart';
|
|
|
-import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
|
|
|
import 'package:immich_mobile/shared/models/server_info.model.dart';
|
|
|
-import 'package:immich_mobile/modules/backup/services/backup.service.dart';
|
|
|
+import 'package:immich_mobile/shared/services/server_info.service.dart';
|
|
|
import 'package:photo_manager/photo_manager.dart';
|
|
|
|
|
|
class BackupNotifier extends StateNotifier<BackUpState> {
|
|
@@ -55,7 +54,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
removeExcludedAlbumForBackup(album);
|
|
|
}
|
|
|
|
|
|
- state = state.copyWith(selectedBackupAlbums: {...state.selectedBackupAlbums, album});
|
|
|
+ state = state
|
|
|
+ .copyWith(selectedBackupAlbums: {...state.selectedBackupAlbums, album});
|
|
|
_updateBackupAssetCount();
|
|
|
}
|
|
|
|
|
@@ -63,7 +63,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
if (state.selectedBackupAlbums.contains(album)) {
|
|
|
removeAlbumForBackup(album);
|
|
|
}
|
|
|
- state = state.copyWith(excludedBackupAlbums: {...state.excludedBackupAlbums, album});
|
|
|
+ state = state
|
|
|
+ .copyWith(excludedBackupAlbums: {...state.excludedBackupAlbums, album});
|
|
|
_updateBackupAssetCount();
|
|
|
}
|
|
|
|
|
@@ -94,16 +95,19 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
Future<void> getBackupAlbumsInfo() async {
|
|
|
// Get all albums on the device
|
|
|
List<AvailableAlbum> availableAlbums = [];
|
|
|
- List<AssetPathEntity> albums = await PhotoManager.getAssetPathList(hasAll: true, type: RequestType.common);
|
|
|
+ List<AssetPathEntity> albums = await PhotoManager.getAssetPathList(
|
|
|
+ hasAll: true, type: RequestType.common);
|
|
|
|
|
|
for (AssetPathEntity album in albums) {
|
|
|
AvailableAlbum availableAlbum = AvailableAlbum(albumEntity: album);
|
|
|
|
|
|
- var assetList = await album.getAssetListRange(start: 0, end: album.assetCount);
|
|
|
+ var assetList =
|
|
|
+ await album.getAssetListRange(start: 0, end: album.assetCount);
|
|
|
|
|
|
if (assetList.isNotEmpty) {
|
|
|
var thumbnailAsset = assetList.first;
|
|
|
- var thumbnailData = await thumbnailAsset.thumbnailDataWithSize(const ThumbnailSize(512, 512));
|
|
|
+ var thumbnailData = await thumbnailAsset
|
|
|
+ .thumbnailDataWithSize(const ThumbnailSize(512, 512));
|
|
|
availableAlbum = availableAlbum.copyWith(thumbnailData: thumbnailData);
|
|
|
}
|
|
|
|
|
@@ -114,7 +118,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
|
|
|
// Put persistent storage info into local state of the app
|
|
|
// Get local storage on selected backup album
|
|
|
- Box<HiveBackupAlbums> backupAlbumInfoBox = Hive.box<HiveBackupAlbums>(hiveBackupInfoBox);
|
|
|
+ Box<HiveBackupAlbums> backupAlbumInfoBox =
|
|
|
+ Hive.box<HiveBackupAlbums>(hiveBackupInfoBox);
|
|
|
HiveBackupAlbums? backupAlbumInfo = backupAlbumInfoBox.get(
|
|
|
backupInfoKey,
|
|
|
defaultValue: HiveBackupAlbums(
|
|
@@ -133,7 +138,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
debugPrint("First time backup setup recent album as default");
|
|
|
|
|
|
// Get album that contains all assets
|
|
|
- var list = await PhotoManager.getAssetPathList(hasAll: true, onlyAll: true, type: RequestType.common);
|
|
|
+ var list = await PhotoManager.getAssetPathList(
|
|
|
+ hasAll: true, onlyAll: true, type: RequestType.common);
|
|
|
AssetPathEntity albumHasAllAssets = list.first;
|
|
|
|
|
|
backupAlbumInfoBox.put(
|
|
@@ -151,12 +157,14 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
try {
|
|
|
for (var selectedAlbumId in backupAlbumInfo!.selectedAlbumIds) {
|
|
|
var albumAsset = await AssetPathEntity.fromId(selectedAlbumId);
|
|
|
- state = state.copyWith(selectedBackupAlbums: {...state.selectedBackupAlbums, albumAsset});
|
|
|
+ state = state.copyWith(
|
|
|
+ selectedBackupAlbums: {...state.selectedBackupAlbums, albumAsset});
|
|
|
}
|
|
|
|
|
|
for (var excludedAlbumId in backupAlbumInfo.excludedAlbumsIds) {
|
|
|
var albumAsset = await AssetPathEntity.fromId(excludedAlbumId);
|
|
|
- state = state.copyWith(excludedBackupAlbums: {...state.excludedBackupAlbums, albumAsset});
|
|
|
+ state = state.copyWith(
|
|
|
+ excludedBackupAlbums: {...state.excludedBackupAlbums, albumAsset});
|
|
|
}
|
|
|
} catch (e) {
|
|
|
debugPrint("[ERROR] Failed to generate album from id $e");
|
|
@@ -173,21 +181,27 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
Set<AssetEntity> assetsFromExcludedAlbums = {};
|
|
|
|
|
|
for (var album in state.selectedBackupAlbums) {
|
|
|
- var assets = await album.getAssetListRange(start: 0, end: album.assetCount);
|
|
|
+ var assets =
|
|
|
+ await album.getAssetListRange(start: 0, end: album.assetCount);
|
|
|
assetsFromSelectedAlbums.addAll(assets);
|
|
|
}
|
|
|
|
|
|
for (var album in state.excludedBackupAlbums) {
|
|
|
- var assets = await album.getAssetListRange(start: 0, end: album.assetCount);
|
|
|
+ var assets =
|
|
|
+ await album.getAssetListRange(start: 0, end: album.assetCount);
|
|
|
assetsFromExcludedAlbums.addAll(assets);
|
|
|
}
|
|
|
|
|
|
- Set<AssetEntity> allUniqueAssets = assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums);
|
|
|
- List<String> allAssetOnDatabase = await _backupService.getDeviceBackupAsset();
|
|
|
+ Set<AssetEntity> allUniqueAssets =
|
|
|
+ assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums);
|
|
|
+ List<String> allAssetOnDatabase =
|
|
|
+ await _backupService.getDeviceBackupAsset();
|
|
|
|
|
|
// Find asset that were backup from selected albums
|
|
|
- Set<String> selectedAlbumsBackupAssets = Set.from(allUniqueAssets.map((e) => e.id));
|
|
|
- selectedAlbumsBackupAssets.removeWhere((assetId) => !allAssetOnDatabase.contains(assetId));
|
|
|
+ Set<String> selectedAlbumsBackupAssets =
|
|
|
+ Set.from(allUniqueAssets.map((e) => e.id));
|
|
|
+ selectedAlbumsBackupAssets
|
|
|
+ .removeWhere((assetId) => !allAssetOnDatabase.contains(assetId));
|
|
|
|
|
|
if (allUniqueAssets.isEmpty) {
|
|
|
debugPrint("No Asset On Device");
|
|
@@ -226,7 +240,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
/// Hive database
|
|
|
///
|
|
|
void _updatePersistentAlbumsSelection() {
|
|
|
- Box<HiveBackupAlbums> backupAlbumInfoBox = Hive.box<HiveBackupAlbums>(hiveBackupInfoBox);
|
|
|
+ Box<HiveBackupAlbums> backupAlbumInfoBox =
|
|
|
+ Hive.box<HiveBackupAlbums>(hiveBackupInfoBox);
|
|
|
backupAlbumInfoBox.put(
|
|
|
backupInfoKey,
|
|
|
HiveBackupAlbums(
|
|
@@ -268,7 +283,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
|
|
|
// Perform Backup
|
|
|
state = state.copyWith(cancelToken: CancellationToken());
|
|
|
- _backupService.backupAsset(assetsWillBeBackup, state.cancelToken, _onAssetUploaded, _onUploadProgress);
|
|
|
+ _backupService.backupAsset(assetsWillBeBackup, state.cancelToken,
|
|
|
+ _onAssetUploaded, _onUploadProgress);
|
|
|
} else {
|
|
|
PhotoManager.openSetting();
|
|
|
}
|
|
@@ -276,23 +292,32 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
|
|
|
void cancelBackup() {
|
|
|
state.cancelToken.cancel();
|
|
|
- state = state.copyWith(backupProgress: BackUpProgressEnum.idle, progressInPercentage: 0.0);
|
|
|
+ state = state.copyWith(
|
|
|
+ backupProgress: BackUpProgressEnum.idle, progressInPercentage: 0.0);
|
|
|
}
|
|
|
|
|
|
void _onAssetUploaded(String deviceAssetId, String deviceId) {
|
|
|
- state = state.copyWith(
|
|
|
- selectedAlbumsBackupAssetsIds: {...state.selectedAlbumsBackupAssetsIds, deviceAssetId},
|
|
|
- allAssetOnDatabase: [...state.allAssetOnDatabase, deviceAssetId]);
|
|
|
-
|
|
|
- if (state.allUniqueAssets.length - state.selectedAlbumsBackupAssetsIds.length == 0) {
|
|
|
- state = state.copyWith(backupProgress: BackUpProgressEnum.done, progressInPercentage: 0.0);
|
|
|
+ state = state.copyWith(selectedAlbumsBackupAssetsIds: {
|
|
|
+ ...state.selectedAlbumsBackupAssetsIds,
|
|
|
+ deviceAssetId
|
|
|
+ }, allAssetOnDatabase: [
|
|
|
+ ...state.allAssetOnDatabase,
|
|
|
+ deviceAssetId
|
|
|
+ ]);
|
|
|
+
|
|
|
+ if (state.allUniqueAssets.length -
|
|
|
+ state.selectedAlbumsBackupAssetsIds.length ==
|
|
|
+ 0) {
|
|
|
+ state = state.copyWith(
|
|
|
+ backupProgress: BackUpProgressEnum.done, progressInPercentage: 0.0);
|
|
|
}
|
|
|
|
|
|
_updateServerInfo();
|
|
|
}
|
|
|
|
|
|
void _onUploadProgress(int sent, int total) {
|
|
|
- state = state.copyWith(progressInPercentage: (sent.toDouble() / total.toDouble() * 100));
|
|
|
+ state = state.copyWith(
|
|
|
+ progressInPercentage: (sent.toDouble() / total.toDouble() * 100));
|
|
|
}
|
|
|
|
|
|
void _updateServerInfo() async {
|
|
@@ -326,7 +351,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
}
|
|
|
|
|
|
// Check if this device is enable backup by the user
|
|
|
- if ((authState.deviceInfo.deviceId == authState.deviceId) && authState.deviceInfo.isAutoBackup) {
|
|
|
+ if ((authState.deviceInfo.deviceId == authState.deviceId) &&
|
|
|
+ authState.deviceInfo.isAutoBackup) {
|
|
|
// check if backup is alreayd in process - then return
|
|
|
if (state.backupProgress == BackUpProgressEnum.inProgress) {
|
|
|
debugPrint("[resumeBackup] Backup is already in progress - abort");
|
|
@@ -343,6 +369,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-final backupProvider = StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
|
|
|
+final backupProvider =
|
|
|
+ StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
|
|
|
return BackupNotifier(ref: ref);
|
|
|
});
|