handle onProgress

This commit is contained in:
mertalev
2026-02-05 15:52:47 -05:00
parent e7b7fe8ed8
commit 03afe8fb3e
3 changed files with 47 additions and 13 deletions

View File

@@ -94,14 +94,15 @@ class UploadRepository {
required Map<String, String> fields,
required Client httpClient,
required Completer cancelToken,
required void Function(int bytes, int totalBytes) onProgress, // TODO: use onProgress
void Function(int bytes, int totalBytes)? onProgress,
required String logContext,
}) async {
final String savedEndpoint = Store.get(StoreKey.serverEndpoint);
final baseRequest = AbortableMultipartRequest(
final baseRequest = ProgressMultipartRequest(
'POST',
Uri.parse('$savedEndpoint/assets'),
abortTrigger: cancelToken.future,
onProgress: onProgress,
);
try {
@@ -151,6 +152,34 @@ class UploadRepository {
}
}
class ProgressMultipartRequest extends MultipartRequest with Abortable {
ProgressMultipartRequest(super.method, super.url, {this.abortTrigger, this.onProgress});
@override
final Future<void>? abortTrigger;
final void Function(int bytes, int totalBytes)? onProgress;
@override
ByteStream finalize() {
final byteStream = super.finalize();
if (onProgress == null) return byteStream;
final total = contentLength;
var bytes = 0;
final stream = byteStream.transform(
StreamTransformer.fromHandlers(
handleData: (List<int> data, EventSink<List<int>> sink) {
bytes += data.length;
onProgress!(bytes, total);
sink.add(data);
},
),
);
return ByteStream(stream);
}
}
class UploadResult {
final bool isSuccess;
final bool isCancelled;

View File

@@ -11,6 +11,7 @@ import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/entities/backup_album.entity.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/infrastructure/repositories/network.repository.dart';
import 'package:immich_mobile/repositories/upload.repository.dart';
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
import 'package:immich_mobile/models/backup/current_upload_asset.model.dart';
import 'package:immich_mobile/models/backup/error_upload_asset.model.dart';
@@ -237,7 +238,7 @@ class BackupService {
bool isBackground = false,
PMProgressHandler? pmProgressHandler,
required void Function(SuccessUploadAsset result) onSuccess,
required void Function(int bytes, int totalBytes) onProgress, // TODO: use onProgress
required void Function(int bytes, int totalBytes) onProgress,
required void Function(CurrentUploadAsset asset) onCurrentAsset,
required void Function(ErrorUploadAsset error) onError,
}) async {
@@ -313,10 +314,11 @@ class BackupService {
filename: originalFileName,
);
final baseRequest = AbortableMultipartRequest(
final baseRequest = ProgressMultipartRequest(
'POST',
Uri.parse('$savedEndpoint/assets'),
abortTrigger: cancelToken.future,
onProgress: ((bytes, totalBytes) => onProgress(bytes, totalBytes)),
);
baseRequest.headers.addAll(ApiService.getRequestHeaders());
@@ -442,10 +444,9 @@ class BackupService {
livePhotoVideoFile.lengthSync(),
filename: livePhotoTitle,
);
final livePhotoReq =
AbortableMultipartRequest(baseRequest.method, baseRequest.url, abortTrigger: cancelToken.future)
..headers.addAll(baseRequest.headers)
..fields.addAll(baseRequest.fields);
final livePhotoReq = ProgressMultipartRequest(baseRequest.method, baseRequest.url, abortTrigger: cancelToken.future)
..headers.addAll(baseRequest.headers)
..fields.addAll(baseRequest.fields);
livePhotoReq.files.add(livePhotoRawUploadData);

View File

@@ -340,6 +340,7 @@ class ForegroundUploadService {
if (entity.isLivePhoto && livePhotoFile != null) {
final livePhotoTitle = p.setExtension(originalFileName, p.extension(livePhotoFile.path));
final onProgress = callbacks.onProgress;
final livePhotoResult = await _uploadRepository.uploadFile(
file: livePhotoFile,
originalFileName: livePhotoTitle,
@@ -347,8 +348,9 @@ class ForegroundUploadService {
fields: fields,
httpClient: NetworkRepository.client,
cancelToken: cancelToken,
onProgress: (bytes, totalBytes) =>
callbacks.onProgress?.call(asset.localId!, livePhotoTitle, bytes, totalBytes),
onProgress: onProgress != null
? (bytes, totalBytes) => onProgress(asset.localId!, livePhotoTitle, bytes, totalBytes)
: null,
logContext: 'livePhotoVideo[${asset.localId}]',
);
@@ -377,6 +379,7 @@ class ForegroundUploadService {
]);
}
final onProgress = callbacks.onProgress;
final result = await _uploadRepository.uploadFile(
file: file,
originalFileName: originalFileName,
@@ -384,8 +387,9 @@ class ForegroundUploadService {
fields: fields,
httpClient: NetworkRepository.client,
cancelToken: cancelToken,
onProgress: (bytes, totalBytes) =>
callbacks.onProgress?.call(asset.localId!, originalFileName, bytes, totalBytes),
onProgress: onProgress != null
? (bytes, totalBytes) => onProgress(asset.localId!, originalFileName, bytes, totalBytes)
: null,
logContext: 'asset[${asset.localId}]',
);
@@ -453,7 +457,7 @@ class ForegroundUploadService {
fields: fields,
httpClient: httpClient,
cancelToken: cancelToken,
onProgress: onProgress ?? (_, __) {},
onProgress: onProgress,
logContext: 'shareIntent[$deviceAssetId]',
);
} catch (e) {