import 'dart:async'; import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:core/utils/app_logger.dart'; import 'package:dartz/dartz.dart'; import 'package:equatable/equatable.dart'; import 'package:model/upload/file_info.dart'; import 'package:tmail_ui_user/features/upload/data/network/file_uploader.dart'; import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart'; import 'package:tmail_ui_user/features/upload/domain/state/attachment_upload_state.dart'; import 'package:dio/dio.dart'; class UploadAttachment with EquatableMixin { final UploadTaskId uploadTaskId; final FileInfo fileInfo; final Uri uploadUri; final FileUploader fileUploader; final CancelToken? cancelToken; final StreamController> _progressStateController = StreamController>.broadcast(); Stream> get progressState => _progressStateController.stream; UploadAttachment( this.uploadTaskId, this.fileInfo, this.uploadUri, this.fileUploader, {this.cancelToken}); void _updateEvent(Either flowUploadState) { _progressStateController.add(flowUploadState); } void upload() async { try { log('UploadFile::upload(): $uploadTaskId'); _updateEvent(Right(PendingAttachmentUploadState(uploadTaskId, 0, fileInfo.fileSize))); final attachment = await fileUploader.uploadAttachment( uploadTaskId, _progressStateController, fileInfo, uploadUri, cancelToken: cancelToken ); if (cancelToken?.isCancelled == true) { _updateEvent(Left(CancelAttachmentUploadState(uploadTaskId))); await _progressStateController.close(); return; } if (attachment != null) { _updateEvent(Right(SuccessAttachmentUploadState(uploadTaskId, attachment, fileInfo))); } else { _updateEvent(Left(ErrorAttachmentUploadState(uploadTaskId))); } } catch (e) { logError('UploadAttachment::upload():ERROR: $e'); _updateEvent(Left(ErrorAttachmentUploadState(uploadTaskId))); } finally { await _progressStateController.close(); } } @override List get props => [ uploadTaskId, fileInfo, uploadUri, fileUploader, cancelToken ]; }