immich/mobile/lib/shared/providers/backup.provider.dart

172 lines
5.7 KiB
Dart
Raw Normal View History

2022-02-03 09:06:44 -07:00
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
2022-02-07 22:42:35 -07:00
import 'package:hive_flutter/hive_flutter.dart';
2022-02-03 09:06:44 -07:00
import 'package:hooks_riverpod/hooks_riverpod.dart';
2022-02-07 22:42:35 -07:00
import 'package:immich_mobile/constants/hive_box.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
2022-02-03 09:06:44 -07:00
import 'package:immich_mobile/shared/services/server_info.service.dart';
import 'package:immich_mobile/shared/models/backup_state.model.dart';
import 'package:immich_mobile/shared/models/server_info.model.dart';
import 'package:immich_mobile/shared/services/backup.service.dart';
import 'package:photo_manager/photo_manager.dart';
class BackupNotifier extends StateNotifier<BackUpState> {
2022-02-07 22:42:35 -07:00
BackupNotifier(this.ref)
2022-02-03 09:06:44 -07:00
: super(
BackUpState(
backupProgress: BackUpProgressEnum.idle,
backingUpAssetCount: 0,
assetOnDatabase: 0,
totalAssetCount: 0,
progressInPercentage: 0,
cancelToken: CancelToken(),
serverInfo: ServerInfo(
diskAvailable: "0",
diskAvailableRaw: 0,
diskSize: "0",
diskSizeRaw: 0,
diskUsagePercentage: 0.0,
diskUse: "0",
diskUseRaw: 0,
),
),
);
2022-02-07 22:42:35 -07:00
final Ref ref;
2022-02-03 09:06:44 -07:00
final BackupService _backupService = BackupService();
final ServerInfoService _serverInfoService = ServerInfoService();
void getBackupInfo() async {
_updateServerInfo();
List<AssetPathEntity> list = await PhotoManager.getAssetPathList(onlyAll: true, type: RequestType.common);
2022-02-03 09:06:44 -07:00
if (list.isEmpty) {
debugPrint("No Asset On Device");
return;
}
int totalAsset = list[0].assetCount;
List<String> didBackupAsset = await _backupService.getDeviceBackupAsset();
state = state.copyWith(totalAssetCount: totalAsset, assetOnDatabase: didBackupAsset.length);
}
void startBackupProcess() async {
_updateServerInfo();
state = state.copyWith(backupProgress: BackUpProgressEnum.inProgress);
var authResult = await PhotoManager.requestPermissionExtend();
if (authResult.isAuth) {
await PhotoManager.clearFileCache();
// await PhotoManager.presentLimited();
// Gather assets info
List<AssetPathEntity> list =
await PhotoManager.getAssetPathList(hasAll: true, onlyAll: true, type: RequestType.common);
2022-02-03 09:06:44 -07:00
if (list.isEmpty) {
debugPrint("No Asset On Device - Abort Backup Process");
return;
}
int totalAsset = list[0].assetCount;
List<AssetEntity> currentAssets = await list[0].getAssetListRange(start: 0, end: totalAsset);
// Get device assets info from database
// Compare and find different assets that has not been backing up
// Backup those assets
List<String> backupAsset = await _backupService.getDeviceBackupAsset();
state = state.copyWith(totalAssetCount: totalAsset, assetOnDatabase: backupAsset.length);
// Remove item that has already been backed up
for (var backupAssetId in backupAsset) {
currentAssets.removeWhere((e) => e.id == backupAssetId);
}
if (currentAssets.isEmpty) {
state = state.copyWith(backupProgress: BackUpProgressEnum.idle);
}
state = state.copyWith(backingUpAssetCount: currentAssets.length);
// Perform Packup
state = state.copyWith(cancelToken: CancelToken());
_backupService.backupAsset(currentAssets, state.cancelToken, _onAssetUploaded, _onUploadProgress);
} else {
PhotoManager.openSetting();
}
}
void cancelBackup() {
state.cancelToken.cancel('Cancel Backup');
2022-02-07 22:42:35 -07:00
state = state.copyWith(backupProgress: BackUpProgressEnum.idle, progressInPercentage: 0.0);
2022-02-03 09:06:44 -07:00
}
void _onAssetUploaded() {
state =
state.copyWith(backingUpAssetCount: state.backingUpAssetCount - 1, assetOnDatabase: state.assetOnDatabase + 1);
if (state.backingUpAssetCount == 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));
}
void _updateServerInfo() async {
var serverInfo = await _serverInfoService.getServerInfo();
// Update server info
state = state.copyWith(
serverInfo: ServerInfo(
diskSize: serverInfo.diskSize,
diskUse: serverInfo.diskUse,
diskAvailable: serverInfo.diskAvailable,
diskSizeRaw: serverInfo.diskSizeRaw,
diskUseRaw: serverInfo.diskUseRaw,
diskAvailableRaw: serverInfo.diskAvailableRaw,
diskUsagePercentage: serverInfo.diskUsagePercentage,
),
);
}
2022-02-07 22:42:35 -07:00
void resumeBackup() {
debugPrint("[resumeBackup]");
var authState = ref.read(authenticationProvider);
// Check if user is login
var accessKey = Hive.box(userInfoBox).get(accessTokenKey);
// User has been logged out return
if (accessKey == null || !authState.isAuthenticated) {
debugPrint("[resumeBackup] not authenticated - abort");
return;
}
// Check if this device is enable backup by the user
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");
return;
}
// Run backup
debugPrint("[resumeBackup] Start back up");
startBackupProcess();
}
debugPrint("[resumeBackup] User disables auto backup");
return;
}
2022-02-03 09:06:44 -07:00
}
final backupProvider = StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
2022-02-07 22:42:35 -07:00
return BackupNotifier(ref);
2022-02-03 09:06:44 -07:00
});