From 514bc578ec9b8d6ef9b024c064ae97968c7b0cd6 Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 23 Feb 2024 11:57:54 +0700 Subject: [PATCH] TF-2602 Set charset for attachment with `mimeType=text/plain` when sent email on mobile Signed-off-by: dab246 --- .../presentation/composer_bindings.dart | 6 ++- .../data/model/upload_file_arguments.dart | 4 ++ .../upload/data/network/file_uploader.dart | 47 +++++++++++++------ .../domain/model/upload_attachment.dart | 10 ++-- model/lib/email/attachment.dart | 13 ++++- .../lib/extensions/attachment_extension.dart | 5 +- .../extensions/email_body_part_extension.dart | 1 + model/lib/upload/upload_response.dart | 10 +++- 8 files changed, 70 insertions(+), 26 deletions(-) diff --git a/lib/features/composer/presentation/composer_bindings.dart b/lib/features/composer/presentation/composer_bindings.dart index 83a655661..8c401aba8 100644 --- a/lib/features/composer/presentation/composer_bindings.dart +++ b/lib/features/composer/presentation/composer_bindings.dart @@ -81,7 +81,11 @@ class ComposerBindings extends BaseBindings { } void _bindingsUtils() { - Get.lazyPut(() => FileUploader(Get.find(tag: BindingTag.isolateTag), Get.find())); + Get.lazyPut(() => FileUploader( + Get.find(tag: BindingTag.isolateTag), + Get.find(), + Get.find(), + )); } @override diff --git a/lib/features/upload/data/model/upload_file_arguments.dart b/lib/features/upload/data/model/upload_file_arguments.dart index d030b1f99..3ec427fb8 100644 --- a/lib/features/upload/data/model/upload_file_arguments.dart +++ b/lib/features/upload/data/model/upload_file_arguments.dart @@ -1,5 +1,6 @@ import 'package:core/data/network/dio_client.dart'; +import 'package:core/utils/file_utils.dart'; import 'package:equatable/equatable.dart'; import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger.dart'; import 'package:tmail_ui_user/features/upload/domain/model/mobile_file_upload.dart'; @@ -8,6 +9,7 @@ import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart'; class UploadFileArguments with EquatableMixin { final DioClient dioClient; + final FileUtils fileUtils; final UploadTaskId uploadId; final MobileFileUpload mobileFileUpload; final Uri uploadUri; @@ -15,6 +17,7 @@ class UploadFileArguments with EquatableMixin { UploadFileArguments( this.dioClient, + this.fileUtils, this.uploadId, this.mobileFileUpload, this.uploadUri, @@ -24,6 +27,7 @@ class UploadFileArguments with EquatableMixin { @override List get props => [ dioClient, + fileUtils, uploadId, mobileFileUpload, uploadUri, diff --git a/lib/features/upload/data/network/file_uploader.dart b/lib/features/upload/data/network/file_uploader.dart index 6ea27b476..5d5d02d9e 100644 --- a/lib/features/upload/data/network/file_uploader.dart +++ b/lib/features/upload/data/network/file_uploader.dart @@ -7,6 +7,7 @@ import 'package:core/data/network/dio_client.dart'; import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:core/utils/app_logger.dart'; +import 'package:core/utils/file_utils.dart'; import 'package:core/utils/platform_info.dart'; import 'package:dartz/dartz.dart'; import 'package:dio/dio.dart'; @@ -32,10 +33,15 @@ class FileUploader { final DioClient _dioClient; final worker.Executor _isolateExecutor; + final FileUtils _fileUtils; - FileUploader(this._dioClient, this._isolateExecutor); + FileUploader( + this._dioClient, + this._isolateExecutor, + this._fileUtils, + ); - Future uploadAttachment( + Future uploadAttachment( UploadTaskId uploadId, StreamController> onSendController, FileInfo fileInfo, @@ -59,6 +65,7 @@ class FileUploader { return await _isolateExecutor.execute( arg1: UploadFileArguments( _dioClient, + _fileUtils, uploadId, mobileFileUpload, uploadUri, @@ -77,7 +84,7 @@ class FileUploader { } } - static Future _handleUploadAttachmentAction( + static Future _handleUploadAttachmentAction( UploadFileArguments argsUpload, worker.TypeSendPort sendPort ) async { @@ -104,7 +111,7 @@ class FileUploader { ), data: File(argsUpload.mobileFileUpload.filePath).openRead(), onSendProgress: (count, total) { - log('FileUploader::_handleUploadAttachmentAction():onSendProgress: [${argsUpload.uploadId.id}] = $count'); + log('FileUploader::_handleUploadAttachmentAction():onSendProgress: FILE[${argsUpload.uploadId.id}] : { PROGRESS = $count | TOTAL = $total}'); sendPort.send( UploadingAttachmentUploadState( argsUpload.uploadId, @@ -114,11 +121,18 @@ class FileUploader { ); } ); - log('FileUploader::_handleUploadAttachmentAction():resultJson: $resultJson'); - return _parsingResponse( - resultJson: resultJson, - fileName: argsUpload.mobileFileUpload.fileName - ); + log('FileUploader::_handleUploadAttachmentAction(): RESULT_JSON = $resultJson'); + if (argsUpload.mobileFileUpload.mimeType == FileUtils.TEXT_PLAIN_MIME_TYPE) { + final fileCharset = await argsUpload.fileUtils.getFileCharset(argsUpload.mobileFileUpload.filePath); + return _parsingResponse( + resultJson: resultJson, + fileName: argsUpload.mobileFileUpload.fileName, + fileCharset: fileCharset); + } else { + return _parsingResponse( + resultJson: resultJson, + fileName: argsUpload.mobileFileUpload.fileName); + } } on DioError catch (exception) { logError('FileUploader::_handleUploadAttachmentAction():DioError: $exception'); @@ -131,7 +145,7 @@ class FileUploader { } } - Future _handleUploadAttachmentActionOnWeb( + Future _handleUploadAttachmentActionOnWeb( UploadTaskId uploadId, StreamController> onSendController, FileInfo fileInfo, @@ -171,13 +185,18 @@ class FileUploader { return _parsingResponse(resultJson: resultJson, fileName: fileInfo.fileName); } - static Attachment? _parsingResponse({dynamic resultJson, required String fileName}) { - log('FileUploader::_parsingResponse():resultJson: $resultJson'); + static Attachment _parsingResponse({ + dynamic resultJson, + required String fileName, + String? fileCharset + }) { if (resultJson != null) { final decodeJson = resultJson is Map ? resultJson : jsonDecode(resultJson); final uploadResponse = UploadResponse.fromJson(decodeJson); - log('FileUploader::_parsingResponse():uploadResponse: ${uploadResponse.toString()}'); - return uploadResponse.toAttachment(fileName); + log('FileUploader::_parsingResponse(): UploadResponse = $uploadResponse'); + return uploadResponse.toAttachment( + nameFile: fileName, + charset: fileCharset); } else { logError('FileUploader::_parsingResponse(): DataResponseIsNullException'); throw DataResponseIsNullException(); diff --git a/lib/features/upload/domain/model/upload_attachment.dart b/lib/features/upload/domain/model/upload_attachment.dart index e9a3204f3..eece6dcb2 100644 --- a/lib/features/upload/domain/model/upload_attachment.dart +++ b/lib/features/upload/domain/model/upload_attachment.dart @@ -5,12 +5,12 @@ 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:dio/dio.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 { @@ -48,17 +48,15 @@ class UploadAttachment with EquatableMixin { cancelToken: cancelToken ); + log('UploadAttachment::upload: ATTACHMENT_UPLOADED = $attachment'); + 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(uploadId: uploadTaskId))); - } + _updateEvent(Right(SuccessAttachmentUploadState(uploadTaskId, attachment, fileInfo))); } catch (e) { logError('UploadAttachment::upload():ERROR: $e'); if (e is DioError && e.type == DioErrorType.cancel) { diff --git a/model/lib/email/attachment.dart b/model/lib/email/attachment.dart index 4347b829f..4a8c690ee 100644 --- a/model/lib/email/attachment.dart +++ b/model/lib/email/attachment.dart @@ -20,6 +20,7 @@ class Attachment with EquatableMixin { final MediaType? type; final String? cid; final ContentDisposition? disposition; + final String? charset; Attachment({ this.partId, @@ -29,6 +30,7 @@ class Attachment with EquatableMixin { this.type, this.cid, this.disposition, + this.charset, }); bool noCid() => cid == null || cid?.isEmpty == true; @@ -59,7 +61,16 @@ class Attachment with EquatableMixin { } @override - List get props => [partId, blobId, size, name, type, cid, disposition]; + List get props => [ + partId, + blobId, + size, + name, + type, + cid, + disposition, + charset + ]; } enum ContentDisposition { diff --git a/model/lib/extensions/attachment_extension.dart b/model/lib/extensions/attachment_extension.dart index 8b5d63162..aa0fcbde8 100644 --- a/model/lib/extensions/attachment_extension.dart +++ b/model/lib/extensions/attachment_extension.dart @@ -11,7 +11,7 @@ extension AttachmentExtension on Attachment { name: name, type: type, cid: cid, - charset: charset, + charset: charset ?? this.charset, disposition: disposition?.name ?? ContentDisposition.attachment.name); Attachment toAttachmentWithDisposition({ @@ -25,7 +25,8 @@ extension AttachmentExtension on Attachment { name: name, type: type, cid: cid ?? this.cid, - disposition: disposition ?? this.disposition + disposition: disposition ?? this.disposition, + charset: charset ); } diff --git a/model/lib/extensions/email_body_part_extension.dart b/model/lib/extensions/email_body_part_extension.dart index 9cfc214fa..8db9e468c 100644 --- a/model/lib/extensions/email_body_part_extension.dart +++ b/model/lib/extensions/email_body_part_extension.dart @@ -9,5 +9,6 @@ extension EmailBodyPartExtension on EmailBodyPart { name: name, type: type, cid: cid, + charset: charset, disposition: disposition.toContentDisposition()); } diff --git a/model/lib/upload/upload_response.dart b/model/lib/upload/upload_response.dart index b714bdd78..2e806f370 100644 --- a/model/lib/upload/upload_response.dart +++ b/model/lib/upload/upload_response.dart @@ -34,7 +34,13 @@ class UploadResponse with EquatableMixin { } extension UploadResponseExtension on UploadResponse { - Attachment toAttachment(String nameFile) { - return Attachment(blobId: blobId, size: UnsignedInt(size), name: nameFile, type: type); + Attachment toAttachment({required String nameFile, String? charset}) { + return Attachment( + blobId: blobId, + size: UnsignedInt(size), + name: nameFile, + type: type, + charset: charset + ); } } \ No newline at end of file