TF-105 [BUG] Fix long line should be wrapped
This commit is contained in:
@@ -28,7 +28,6 @@ import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_addre
|
||||
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/usecases/upload_mutiple_attachment_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/constants/email_constants.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/upload/domain/state/local_file_picker_state.dart';
|
||||
@@ -215,18 +214,11 @@ class ComposerController extends BaseController {
|
||||
final headerEmailQuoted = getHeaderEmailQuoted(Localizations.localeOf(context).toLanguageTag());
|
||||
|
||||
final headerEmailQuotedAsHtml = headerEmailQuoted != null
|
||||
? AppLocalizations.of(context).header_email_quoted(headerEmailQuoted.value1, headerEmailQuoted.value2)
|
||||
.addBlockTag('p', attribute: 'style=\"font-size:14px;font-style:italic;color:#182952;\"')
|
||||
: '';
|
||||
? AppLocalizations.of(context).header_email_quoted(headerEmailQuoted.value1, headerEmailQuoted.value2)
|
||||
.addBlockTag('p', attribute: 'style=\"font-size:14px;font-style:italic;color:#182952;\"')
|
||||
: '';
|
||||
|
||||
var trustAsHtml = '';
|
||||
|
||||
if (composerArguments.value != null) {
|
||||
final emailContents = composerArguments.value!.emailContents;
|
||||
if (emailContents != null && emailContents.isNotEmpty) {
|
||||
trustAsHtml = emailContents.first.content;
|
||||
}
|
||||
}
|
||||
final trustAsHtml = composerArguments.value?.emailContent?.content ?? '';
|
||||
|
||||
final emailQuotedHtml = '</br></br></br>$headerEmailQuotedAsHtml${trustAsHtml.addBlockQuoteTag()}</br>';
|
||||
|
||||
@@ -256,7 +248,7 @@ class ComposerController extends BaseController {
|
||||
EmailBodyPart(
|
||||
partId: generatePartId,
|
||||
blobId: generateBlobId,
|
||||
type: MediaType.parse(EmailConstants.HTML_TEXT)
|
||||
type: MediaType.parse('text/html')
|
||||
)},
|
||||
bodyValues: {
|
||||
generatePartId: EmailBodyValue(emailBodyText, false, false)
|
||||
|
||||
@@ -174,17 +174,23 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
Widget _buildComposerEditor(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (controller.composerArguments.value?.emailActionType == EmailActionType.compose) {
|
||||
return PackagedHtmlEditor(
|
||||
return HtmlEditor(
|
||||
key: Key('composer_editor'),
|
||||
minHeight: 400,
|
||||
supportZoom: true,
|
||||
disableHorizontalScroll: false,
|
||||
disableVerticalScroll: false,
|
||||
onCreated: (editorApi) => controller.htmlEditorApi = editorApi,
|
||||
);
|
||||
} else {
|
||||
final message = controller.getContentEmail();
|
||||
return message.isNotEmpty
|
||||
? PackagedHtmlEditor(
|
||||
? HtmlEditor(
|
||||
key: Key('composer_editor'),
|
||||
minHeight: 400,
|
||||
supportZoom: true,
|
||||
disableHorizontalScroll: false,
|
||||
disableVerticalScroll: false,
|
||||
onCreated: (editorApi) => controller.htmlEditorApi = editorApi,
|
||||
initialContent: message,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
import 'package:model/model.dart';
|
||||
|
||||
abstract class HtmlDataSource {
|
||||
Future<String> transformToHtml(EmailContent emailContent);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:model/email/email_content.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||
|
||||
class HtmlDataSourceImpl extends HtmlDataSource {
|
||||
|
||||
final HtmlAnalyzer _htmlAnalyzer;
|
||||
|
||||
HtmlDataSourceImpl(this._htmlAnalyzer);
|
||||
|
||||
@override
|
||||
Future<String> transformToHtml(EmailContent emailContent) {
|
||||
return Future.sync(() async {
|
||||
return await _htmlAnalyzer.transformToHtml(emailContent);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
import 'package:core/presentation/utils/html_transformer/html_transform.dart';
|
||||
import 'package:model/email/email_content_type.dart';
|
||||
import 'package:model/model.dart';
|
||||
|
||||
class HtmlAnalyzer {
|
||||
|
||||
Future<String> transformToHtml(EmailContent emailContent) async {
|
||||
switch(emailContent.type) {
|
||||
case EmailContentType.textHtml:
|
||||
final htmlTransform = HtmlTransform(emailContent.content);
|
||||
return htmlTransform.transformToHtml();
|
||||
default:
|
||||
return emailContent.content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,16 @@ import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/move_request.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||
|
||||
class EmailRepositoryImpl extends EmailRepository {
|
||||
|
||||
final EmailDataSource emailDataSource;
|
||||
final HtmlDataSource _htmlDataSource;
|
||||
|
||||
EmailRepositoryImpl(this.emailDataSource);
|
||||
EmailRepositoryImpl(this.emailDataSource, this._htmlDataSource);
|
||||
|
||||
@override
|
||||
Future<Email> getEmailContent(AccountId accountId, EmailId emailId) {
|
||||
@@ -68,4 +70,9 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
) {
|
||||
return emailDataSource.markAsStar(accountId, emails, markStarAction);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> transformEmailContentToHtml(EmailContent emailContent) {
|
||||
return _htmlDataSource.transformToHtml(emailContent);
|
||||
}
|
||||
}
|
||||
@@ -34,4 +34,6 @@ abstract class EmailRepository {
|
||||
List<Email> emails,
|
||||
MarkStarAction markStarAction
|
||||
);
|
||||
|
||||
Future<String> transformEmailContentToHtml(EmailContent emailContent);
|
||||
}
|
||||
@@ -2,13 +2,13 @@ import 'package:core/core.dart';
|
||||
import 'package:model/model.dart';
|
||||
|
||||
class GetEmailContentSuccess extends UIState {
|
||||
final List<EmailContent> emailContents;
|
||||
final EmailContent emailContent;
|
||||
final List<Attachment> attachments;
|
||||
|
||||
GetEmailContentSuccess(this.emailContents, this.attachments);
|
||||
GetEmailContentSuccess(this.emailContent, this.attachments);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [emailContents, attachments];
|
||||
List<Object?> get props => [emailContent, attachments];
|
||||
}
|
||||
|
||||
class GetEmailContentFailure extends FeatureFailure {
|
||||
|
||||
@@ -15,9 +15,20 @@ class GetEmailContentInteractor {
|
||||
try {
|
||||
yield Right<Failure, Success>(LoadingState());
|
||||
final email = await emailRepository.getEmailContent(accountId, emailId);
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess(
|
||||
email.emailContentList,
|
||||
email.allAttachments));
|
||||
|
||||
if (email.emailContentList.isNotEmpty) {
|
||||
final emailContent = email.emailContentList.first;
|
||||
if (emailContent.type == EmailContentType.textHtml) {
|
||||
final contentHtml = await emailRepository.transformEmailContentToHtml(emailContent);
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess(
|
||||
EmailContent(emailContent.type, contentHtml),
|
||||
email.allAttachments));
|
||||
} else {
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess(emailContent, email.allAttachments));
|
||||
}
|
||||
} else {
|
||||
yield Left(GetEmailContentFailure(null));
|
||||
}
|
||||
} catch (e) {
|
||||
yield Left(GetEmailContentFailure(e));
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
class EmailConstants {
|
||||
static const HTML_TEXT = 'text/html';
|
||||
static const PLAIN_TEXT = 'text/plain';
|
||||
}
|
||||
@@ -3,7 +3,10 @@ import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||
@@ -22,7 +25,11 @@ class EmailBindings extends Bindings {
|
||||
void dependencies() {
|
||||
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
|
||||
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
|
||||
Get.lazyPut(() => EmailRepositoryImpl(Get.find<EmailDataSource>()));
|
||||
Get.lazyPut(() => HtmlDataSourceImpl(Get.find<HtmlAnalyzer>()));
|
||||
Get.lazyPut<HtmlDataSource>(() => Get.find<HtmlDataSourceImpl>());
|
||||
Get.lazyPut(() => EmailRepositoryImpl(
|
||||
Get.find<EmailDataSource>(),
|
||||
Get.find<HtmlDataSource>()));
|
||||
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
|
||||
Get.put(SendEmailInteractor(Get.find<EmailRepository>()));
|
||||
Get.lazyPut(() => GetEmailContentInteractor(Get.find<EmailRepository>()));
|
||||
|
||||
@@ -49,7 +49,7 @@ class EmailController extends BaseController {
|
||||
|
||||
final emailAddressExpandMode = ExpandMode.COLLAPSE.obs;
|
||||
final attachmentsExpandMode = ExpandMode.COLLAPSE.obs;
|
||||
final emailContents = <EmailContent>[].obs;
|
||||
final emailContent = Rxn<EmailContent>();
|
||||
final attachments = <Attachment>[].obs;
|
||||
EmailId? _currentEmailId;
|
||||
|
||||
@@ -129,9 +129,9 @@ class EmailController extends BaseController {
|
||||
}
|
||||
|
||||
void _getEmailContentSuccess(GetEmailContentSuccess success) {
|
||||
emailContents.value = success.emailContents;
|
||||
emailContent.value = success.emailContent;
|
||||
attachments.value = success.attachments;
|
||||
if (emailContents.isNotEmpty) {
|
||||
if (emailContent.value != null && emailContent.value!.type == EmailContentType.textHtml) {
|
||||
dispatchState(Right(WebViewLoadingState()));
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ class EmailController extends BaseController {
|
||||
void _clearEmailContent() {
|
||||
toggleDisplayEmailAddressAction(expandMode: ExpandMode.COLLAPSE);
|
||||
attachmentsExpandMode.value = ExpandMode.COLLAPSE;
|
||||
emailContents.clear();
|
||||
emailContent.value = null;
|
||||
attachments.clear();
|
||||
}
|
||||
|
||||
@@ -347,24 +347,17 @@ class EmailController extends BaseController {
|
||||
&& mailboxDashBoardController.selectedEmail.value != null;
|
||||
|
||||
void backToThreadView() {
|
||||
if (emailContents.isNotEmpty) {
|
||||
dispatchState(Right(WebViewLoadCompletedState()));
|
||||
}
|
||||
popBack();
|
||||
}
|
||||
|
||||
void pressEmailAction(EmailActionType emailActionType) {
|
||||
if (canComposeEmail()) {
|
||||
if (emailContents.isNotEmpty) {
|
||||
clearState();
|
||||
}
|
||||
|
||||
push(
|
||||
AppRoutes.COMPOSER,
|
||||
arguments: ComposerArguments(
|
||||
emailActionType: emailActionType,
|
||||
presentationEmail: mailboxDashBoardController.selectedEmail.value!,
|
||||
emailContents: emailContents,
|
||||
emailContent: emailContent.value,
|
||||
attachments: attachments,
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role,
|
||||
session: mailboxDashBoardController.sessionCurrent!,
|
||||
|
||||
@@ -27,11 +27,6 @@ class EmailView extends GetView {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
emailController.viewState.value.map((success) {
|
||||
if (success is WebViewLoadCompletedState && emailController.emailContents.isNotEmpty) {
|
||||
emailController.dispatchState(Right(WebViewLoadingState()));
|
||||
}
|
||||
});
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: AppColor.primaryLightColor,
|
||||
@@ -279,11 +274,27 @@ class EmailView extends GetView {
|
||||
}
|
||||
|
||||
Widget _buildEmailContent() {
|
||||
return Obx(() => emailController.emailContents.isNotEmpty
|
||||
? HtmlContentViewer(
|
||||
message: emailController.emailContents.first.content,
|
||||
onWebViewLoadStop: (webController, uri) => emailController.dispatchState(Right(WebViewLoadCompletedState())),
|
||||
mailtoDelegate: (uri) async {})
|
||||
: SizedBox.shrink());
|
||||
return Obx(() {
|
||||
if (emailController.emailContent.value != null) {
|
||||
switch(emailController.emailContent.value!.type) {
|
||||
case EmailContentType.textHtml:
|
||||
return HtmlContentViewer(
|
||||
contentHtml: emailController.emailContent.value!.content,
|
||||
onLoadStart: (webController, uri) => emailController.dispatchState(Right(WebViewLoadingState())),
|
||||
onLoadStop: (webController, uri) => emailController.dispatchState(Right(WebViewLoadCompletedState())),
|
||||
mailtoDelegate: (uri) async {});
|
||||
case EmailContentType.textPlain:
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 16),
|
||||
child: Text(
|
||||
emailController.emailContent.value!.content,
|
||||
style: TextStyle(fontSize: 14, color: AppColor.nameUserColor)));
|
||||
case EmailContentType.other:
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import 'package:model/model.dart';
|
||||
class ComposerArguments with EquatableMixin {
|
||||
final EmailActionType emailActionType;
|
||||
final PresentationEmail? presentationEmail;
|
||||
final List<EmailContent>? emailContents;
|
||||
final EmailContent? emailContent;
|
||||
final List<Attachment>? attachments;
|
||||
final Session session;
|
||||
final UserProfile userProfile;
|
||||
@@ -17,7 +17,7 @@ class ComposerArguments with EquatableMixin {
|
||||
ComposerArguments({
|
||||
this.emailActionType = EmailActionType.compose,
|
||||
this.presentationEmail,
|
||||
this.emailContents,
|
||||
this.emailContent,
|
||||
this.attachments,
|
||||
this.mailboxRole,
|
||||
required this.session,
|
||||
@@ -29,7 +29,7 @@ class ComposerArguments with EquatableMixin {
|
||||
List<Object?> get props => [
|
||||
emailActionType,
|
||||
presentationEmail,
|
||||
emailContents,
|
||||
emailContent,
|
||||
attachments,
|
||||
mailboxRole,
|
||||
session,
|
||||
|
||||
@@ -4,7 +4,10 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/caching/state_cache_client.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||
@@ -48,7 +51,11 @@ class ThreadBindings extends Bindings {
|
||||
Get.lazyPut(() => ScrollController());
|
||||
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
|
||||
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
|
||||
Get.lazyPut(() => EmailRepositoryImpl(Get.find<EmailDataSource>()));
|
||||
Get.lazyPut(() => HtmlDataSourceImpl(Get.find<HtmlAnalyzer>()));
|
||||
Get.lazyPut<HtmlDataSource>(() => Get.find<HtmlDataSourceImpl>());
|
||||
Get.lazyPut(() => EmailRepositoryImpl(
|
||||
Get.find<EmailDataSource>(),
|
||||
Get.find<HtmlDataSource>()));
|
||||
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
|
||||
Get.lazyPut(() => MarkAsEmailReadInteractor(Get.find<EmailRepository>()));
|
||||
Get.lazyPut(() => MarkAsMultipleEmailReadInteractor(Get.find<EmailRepository>()));
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:core/presentation/utils/app_toast.dart';
|
||||
import 'package:device_info/device_info.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||
|
||||
class CoreBindings extends Bindings {
|
||||
|
||||
@@ -35,6 +36,7 @@ class CoreBindings extends Bindings {
|
||||
|
||||
void _bindingValidator() {
|
||||
Get.put(HtmlMessagePurifier());
|
||||
Get.put(HtmlAnalyzer());
|
||||
}
|
||||
|
||||
void _bindingToast() {
|
||||
|
||||
Reference in New Issue
Block a user