diff --git a/core/lib/presentation/extensions/html_extension.dart b/core/lib/presentation/extensions/html_extension.dart index 03199d13a..3753a0997 100644 --- a/core/lib/presentation/extensions/html_extension.dart +++ b/core/lib/presentation/extensions/html_extension.dart @@ -26,4 +26,8 @@ extension HtmlExtension on String { } return htmlString; } + + String addBlockQuoteTag() => addBlockTag( + 'blockquote', + attribute: 'style=\"margin-left:8px;margin-right:8px;padding-left:12px;padding-right:12px;border-left:5px solid #eee;\"'); } diff --git a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart index 1a5055881..920b80b8e 100644 --- a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart +++ b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart @@ -52,7 +52,7 @@ class _HtmlContentViewState extends State { String? _htmlData; bool? _wereExternalImagesBlocked; bool _isGenerating = false; - double? _webViewContentHeight; + double? _webViewContentHeight = 1.0; @override void initState() { @@ -114,7 +114,7 @@ class _HtmlContentViewState extends State { final size = MediaQuery.of(context).size; return SizedBox( - height: _webViewContentHeight ?? size.height, + height: _webViewContentHeight, width: size.width, child: Padding( padding: EdgeInsets.only(top: 16), diff --git a/core/pubspec.yaml b/core/pubspec.yaml index 32430f257..b01bc26d1 100644 --- a/core/pubspec.yaml +++ b/core/pubspec.yaml @@ -59,12 +59,11 @@ dependencies: # getwidget getwidget: 2.0.4 - # Used to fix bugs in the official version of flutter_inappwebview: https://githubmemory.com/repo/pichillilorenzo/flutter_inappwebview/issues/873 - # flutter_inappwebview - flutter_inappwebview: + # enough_html_editor + enough_html_editor: git: - url: git://github.com/robert-virkus/flutter_inappwebview.git - ref: master + url: git://github.com/dab246/enough_html_editor.git + ref: fix_bug_enough_platform_widgets dev_dependencies: flutter_test: diff --git a/lib/features/composer/presentation/composer_bindings.dart b/lib/features/composer/presentation/composer_bindings.dart index d7b4adb8a..df13c3714 100644 --- a/lib/features/composer/presentation/composer_bindings.dart +++ b/lib/features/composer/presentation/composer_bindings.dart @@ -2,7 +2,6 @@ import 'package:core/core.dart'; import 'package:core/presentation/utils/app_toast.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; -import 'package:html_editor_enhanced/html_editor.dart'; import 'package:tmail_ui_user/features/composer/data/datasource/autocomplete_datasource.dart'; import 'package:tmail_ui_user/features/composer/data/datasource/composer_datasource.dart'; import 'package:tmail_ui_user/features/composer/data/datasource/contact_datasource.dart'; @@ -53,7 +52,6 @@ class ComposerBindings extends Bindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => GetAutoCompleteInteractor(Get.find())); Get.lazyPut(() => Uuid()); - Get.lazyPut(() => HtmlEditorController()); Get.lazyPut(() => TextEditingController()); Get.lazyPut(() => ContactDataSourceImpl()); Get.lazyPut(() => Get.find()); @@ -74,7 +72,6 @@ class ComposerBindings extends Bindings { Get.find(), Get.find(), Get.find(), - Get.find(), Get.find(), Get.find(), Get.find(), diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index c83a7160d..152b5b499 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -4,10 +4,10 @@ import 'dart:async'; import 'package:core/core.dart'; import 'package:core/presentation/utils/app_toast.dart'; import 'package:dartz/dartz.dart'; +import 'package:enough_html_editor/enough_html_editor.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; -import 'package:html_editor_enhanced/html_editor.dart'; import 'package:http_parser/http_parser.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; @@ -55,7 +55,6 @@ class ComposerController extends BaseController { final GetAutoCompleteWithDeviceContactInteractor _getAutoCompleteWithDeviceContactInteractor; final AppToast _appToast; final Uuid _uuid; - final HtmlEditorController composerEditorController; final TextEditingController subjectEmailInputController; final HtmlMessagePurifier _htmlMessagePurifier; final LocalFilePickerInteractor _localFilePickerInteractor; @@ -66,6 +65,7 @@ class ComposerController extends BaseController { List listBccEmailAddress = []; String? _subjectEmail; ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.localContact; + HtmlEditorApi? htmlEditorApi; void setSubjectEmail(String subject) => _subjectEmail = subject; @@ -76,7 +76,6 @@ class ComposerController extends BaseController { this._getAutoCompleteWithDeviceContactInteractor, this._appToast, this._uuid, - this.composerEditorController, this.subjectEmailInputController, this._htmlMessagePurifier, this._localFilePickerInteractor, @@ -139,13 +138,14 @@ class ComposerController extends BaseController { } } - void initContentEmail() { + String getContentEmail() { if (composerArguments.value != null && composerArguments.value!.emailActionType != EmailActionType.compose && Get.context != null) { final contentEmailQuoted = _getBodyEmailQuotedAsHtml(Get.context!, _htmlMessagePurifier); - composerEditorController.setText(contentEmailQuoted); + return contentEmailQuoted; } + return ''; } Tuple2? getHeaderEmailQuoted(String locale) { @@ -238,24 +238,11 @@ class ComposerController extends BaseController { var trustAsHtml = ''; if (contentEmail != null && contentEmail.value1.isNotEmpty) { - final messageContent = contentEmail.value1.first; - final attachmentInlines = contentEmail.value2; - final session = contentEmail.value3; - final baseDownloadUrl = session.getDownloadUrl(); - final accountId = session.accounts.keys.first; - - final message = (attachmentInlines.isNotEmpty && messageContent.hasImageInlineWithCid()) - ? '${messageContent.getContentHasInlineAttachment(baseDownloadUrl, accountId, attachmentInlines)}' - : '${messageContent.content}'; - - trustAsHtml = htmlMessagePurifier.purifyHtmlMessage(message, allowAttributes: {'style', 'input', 'form'}) - .addBlockTag('div', attribute: 'style=\"margin-left:8px;margin-right:8px;padding-left:12px;padding-right:12px;border-left:6px solid #EFEFEF;\"') - .addNewLineTag(count: 2); + trustAsHtml = messageContent.content; } - final emailQuotedHtml = '$headerEmailQuotedAsHtml$trustAsHtml' - .addBlockTag('div', attribute: 'style=\"padding-right:16px;padding-left:16px;background-color:#FBFBFF;width:100%\"'); + final emailQuotedHtml = '


$headerEmailQuotedAsHtml${trustAsHtml.addBlockQuoteTag()}
'; return emailQuotedHtml; } @@ -269,7 +256,7 @@ class ComposerController extends BaseController { final generatePartId = PartId(_uuid.v1()); final generateBlobId = Id(_uuid.v1()); - final emailBodyText = await composerEditorController.getText(); + final emailBodyText = (await htmlEditorApi?.getFullHtml()) ?? ''; return Email( generateEmailId, diff --git a/lib/features/composer/presentation/composer_view.dart b/lib/features/composer/presentation/composer_view.dart index 4bece3a2f..188860a8e 100644 --- a/lib/features/composer/presentation/composer_view.dart +++ b/lib/features/composer/presentation/composer_view.dart @@ -1,11 +1,11 @@ import 'package:core/core.dart'; +import 'package:enough_html_editor/enough_html_editor.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:html_editor_enhanced/html_editor.dart'; -import 'package:model/email/attachment.dart'; +import 'package:model/model.dart'; import 'package:tmail_ui_user/features/composer/domain/state/upload_attachment_state.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/email_address_composer_widget_builder.dart'; @@ -22,7 +22,10 @@ class ComposerView extends GetWidget { @override Widget build(BuildContext context) { return GestureDetector( - onTap: () => FocusManager.instance.primaryFocus?.unfocus(), + onTap: () { + FocusManager.instance.primaryFocus?.unfocus(); + controller.htmlEditorApi?.unfocus(); + }, child: Scaffold( resizeToAvoidBottomInset: false, backgroundColor: AppColor.primaryLightColor, @@ -148,34 +151,46 @@ class ComposerView extends GetWidget { child: Column( children: [ _buildEmailHeader(context), - Padding( - padding: EdgeInsets.only(bottom: 30, top: 16, left: 16, right: 16), - child: _buildComposerEditor(context), - ), - _buildAttachmentsLoadingView(), - _buildAttachments(context), + Container( + color: AppColor.primaryLightColor, + margin: EdgeInsets.zero, + padding: EdgeInsets.zero, + alignment: Alignment.topCenter, + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 8, left: 16, right: 16, bottom: 30), + child: _buildComposerEditor(context)), + _buildAttachmentsLoadingView(), + _buildAttachments(context), + ], + ), + ) ] ) ); } Widget _buildComposerEditor(BuildContext context) { - return HtmlEditor( - key: Key('email_body_editor_quoted'), - controller: controller.composerEditorController, - htmlEditorOptions: HtmlEditorOptions( - hint: AppLocalizations.of(context).hint_content_email_composer, - shouldEnsureVisible: true), - otherOptions: OtherOptions(decoration: BoxDecoration()), - callbacks: Callbacks( - onFocus: () { - FocusManager.instance.primaryFocus?.unfocus(); - }, - onInit: () { - controller.initContentEmail(); - } - ), - ); + return Obx(() { + if (controller.composerArguments.value?.emailActionType == EmailActionType.compose) { + return PackagedHtmlEditor( + key: Key('composer_editor'), + minHeight: 400, + onCreated: (editorApi) => controller.htmlEditorApi = editorApi, + ); + } else { + final message = controller.getContentEmail(); + return message.isNotEmpty + ? PackagedHtmlEditor( + key: Key('composer_editor'), + minHeight: 400, + onCreated: (editorApi) => controller.htmlEditorApi = editorApi, + initialContent: message, + ) + : SizedBox.shrink(); + } + }); } Widget _buildAttachmentsLoadingView() { diff --git a/pubspec.yaml b/pubspec.yaml index 2b5766182..a2d0d167d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,12 +86,6 @@ dependencies: url: git://github.com/dab246/flutter_chips_input.git ref: master - # html_editor_enhanced - html_editor_enhanced: - git: - url: git://github.com/dab246/html-editor-enhanced.git - ref: master - # uuid uuid: 3.0.4 @@ -125,6 +119,12 @@ dependencies: # hive hive: 2.0.4 + # enough_html_editor + enough_html_editor: + git: + url: git://github.com/dab246/enough_html_editor.git + ref: fix_bug_enough_platform_widgets + dev_dependencies: flutter_test: sdk: flutter