feat(mobile): handle backup iCloud asset (#5508)

* feat(mobile): handle backup iCloud asset

* additional state

* Download progress

* Added a separate page for backup options

* handle ingore iCloud asset upload'

* fix init backup service

* PR feedback

* fix negative count

* get file title
This commit is contained in:
Alex 2023-12-07 09:53:15 -06:00 committed by GitHub
parent c25556bb08
commit 2e59b07cc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 730 additions and 503 deletions

View file

@ -10,6 +10,8 @@ import 'package:immich_mobile/modules/backup/models/backup_album.model.dart';
import 'package:immich_mobile/modules/backup/models/current_upload_asset.model.dart';
import 'package:immich_mobile/modules/backup/models/duplicated_asset.model.dart';
import 'package:immich_mobile/modules/backup/models/error_upload_asset.model.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/providers/api.provider.dart';
import 'package:immich_mobile/shared/providers/db.provider.dart';
@ -26,6 +28,7 @@ final backupServiceProvider = Provider(
(ref) => BackupService(
ref.watch(apiServiceProvider),
ref.watch(dbProvider),
ref.watch(appSettingsServiceProvider),
),
);
@ -34,8 +37,9 @@ class BackupService {
final ApiService _apiService;
final Isar _db;
final Logger _log = Logger("BackupService");
final AppSettingsService _appSetting;
BackupService(this._apiService, this._db);
BackupService(this._apiService, this._db, this._appSetting);
Future<List<String>?> getDeviceBackupAsset() async {
final String deviceId = Store.get(StoreKey.deviceId);
@ -202,12 +206,16 @@ class BackupService {
Future<bool> backupAsset(
Iterable<AssetEntity> assetList,
http.CancellationToken cancelToken,
PMProgressHandler pmProgressHandler,
Function(String, String, bool) uploadSuccessCb,
Function(int, int) uploadProgressCb,
Function(CurrentUploadAsset) setCurrentUploadAssetCb,
Function(ErrorUploadAsset) errorCb, {
bool sortAssets = false,
}) async {
final bool isIgnoreIcloudAssets =
_appSetting.getSetting(AppSettingsEnum.ignoreIcloudAssets);
if (Platform.isAndroid &&
!(await Permission.accessMediaLocation.status).isGranted) {
// double check that permission is granted here, to guard against
@ -241,10 +249,34 @@ class BackupService {
for (var entity in assetsToUpload) {
try {
if (entity.type == AssetType.video) {
file = await entity.originFile;
final isAvailableLocally = await entity.isLocallyAvailable();
// Handle getting files from iCloud
if (!isAvailableLocally && Platform.isIOS) {
// Skip iCloud assets if the user has disabled this feature
if (isIgnoreIcloudAssets) {
continue;
}
setCurrentUploadAssetCb(
CurrentUploadAsset(
id: entity.id,
fileCreatedAt: entity.createDateTime.year == 1970
? entity.modifiedDateTime
: entity.createDateTime,
fileName: await entity.titleAsync,
fileType: _getAssetType(entity.type),
iCloudAsset: true,
),
);
file = await entity.loadFile(progressHandler: pmProgressHandler);
} else {
file = await entity.originFile.timeout(const Duration(seconds: 5));
if (entity.type == AssetType.video) {
file = await entity.originFile;
} else {
file = await entity.originFile.timeout(const Duration(seconds: 5));
}
}
if (file != null) {
@ -286,6 +318,7 @@ class BackupService {
: entity.createDateTime,
fileName: originalFileName,
fileType: _getAssetType(entity.type),
iCloudAsset: false,
),
);