Add information for uploading asset and error indication with error message for each failed upload. (#315)

* Added info box

* Fixed upload endpoint doesn't report error status code

* Added chip to show update error

* Added chip to show failed upload

* Add duplication check for upload

* Better duplication-checking placement

* Remove check for duplicated asset

* Added failed backup status route

* added page

* Display error card with thumbnail

* Improved styling

* Set thumbnail with better quality

* Remove force upload error
This commit is contained in:
Alex 2022-07-06 16:12:55 -05:00 committed by GitHub
parent 357f7d1c31
commit 58ec7553ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 706 additions and 87 deletions

View file

@ -7,6 +7,9 @@ import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/hive_box.dart';
import 'package:immich_mobile/modules/backup/models/check_duplicate_asset_response.model.dart';
import 'package:immich_mobile/modules/backup/models/current_upload_asset.model.dart';
import 'package:immich_mobile/modules/backup/models/error_upload_asset.model.dart';
import 'package:immich_mobile/shared/services/network.service.dart';
import 'package:immich_mobile/shared/models/device_info.model.dart';
import 'package:immich_mobile/utils/files_helper.dart';
@ -20,6 +23,7 @@ final backupServiceProvider =
class BackupService {
final NetworkService _networkService;
BackupService(this._networkService);
Future<List<String>> getDeviceBackupAsset() async {
@ -32,17 +36,40 @@ class BackupService {
return result.cast<String>();
}
Future<bool> checkDuplicateAsset(String deviceAssetId) async {
String deviceId = Hive.box(userInfoBox).get(deviceIdKey);
try {
Response response =
await _networkService.postRequest(url: "asset/check", data: {
"deviceId": deviceId,
"deviceAssetId": deviceAssetId,
});
if (response.statusCode == 200) {
var result = CheckDuplicateAssetResponse.fromJson(response.toString());
return result.isExist;
} else {
return false;
}
} catch (e) {
return false;
}
}
backupAsset(
Set<AssetEntity> assetList,
http.CancellationToken cancelToken,
Function(String, String) singleAssetDoneCb,
Function(int, int) uploadProgress) async {
Set<AssetEntity> assetList,
http.CancellationToken cancelToken,
Function(String, String) singleAssetDoneCb,
Function(int, int) uploadProgressCb,
Function(CurrentUploadAsset) setCurrentUploadAssetCb,
Function(ErrorUploadAsset) errorCb,
) async {
String deviceId = Hive.box(userInfoBox).get(deviceIdKey);
String savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey);
File? file;
http.MultipartFile? thumbnailUploadData;
for (var entity in assetList) {
try {
if (entity.type == AssetType.video) {
@ -74,7 +101,7 @@ class BackupService {
var req = MultipartRequest(
'POST', Uri.parse('$savedEndpoint/asset/upload'),
onProgress: ((bytes, totalBytes) =>
uploadProgress(bytes, totalBytes)));
uploadProgressCb(bytes, totalBytes)));
req.headers["Authorization"] = "Bearer ${box.get(accessTokenKey)}";
req.fields['deviceAssetId'] = entity.id;
@ -88,10 +115,35 @@ class BackupService {
req.files.add(assetRawUploadData);
var res = await req.send(cancellationToken: cancelToken);
setCurrentUploadAssetCb(
CurrentUploadAsset(
id: entity.id,
createdAt: entity.createDateTime,
fileName: originalFileName,
fileType: _getAssetType(entity.type),
),
);
if (res.statusCode == 201) {
var response = await req.send(cancellationToken: cancelToken);
if (response.statusCode == 201) {
singleAssetDoneCb(entity.id, deviceId);
} else {
var data = await response.stream.bytesToString();
var error = jsonDecode(data);
debugPrint(
"Error(${error['statusCode']}) uploading ${entity.id} | $originalFileName | Created on ${entity.createDateTime} | ${error['error']}");
errorCb(ErrorUploadAsset(
asset: entity,
id: entity.id,
createdAt: entity.createDateTime,
fileName: originalFileName,
fileType: _getAssetType(entity.type),
errorMessage: error['error'],
));
continue;
}
}
} on http.CancelledException {
@ -108,6 +160,8 @@ class BackupService {
}
}
void sendBackupRequest(AssetEntity entity) {}
String _getAssetType(AssetType assetType) {
switch (assetType) {
case AssetType.audio: