TF-1371 Update position of Identity in reply/forward

(cherry picked from commit 53b99854e15b2eea12572d5c18322b43f744609f)
This commit is contained in:
dab246
2023-03-15 10:56:11 +07:00
committed by Dat Vu
parent 2899e38555
commit a31f331e09
5 changed files with 101 additions and 93 deletions
@@ -24,10 +24,7 @@ extension HtmlExtension on String {
'blockquote', 'blockquote',
attribute: 'style="margin-left:8px;margin-right:8px;padding-left:12px;padding-right:12px;border-left:5px solid #eee;"'); attribute: 'style="margin-left:8px;margin-right:8px;padding-left:12px;padding-right:12px;border-left:5px solid #eee;"');
String asSignatureHtml() => '--<br><br>$this'; String asSignatureHtml() => '--<br>$this';
String toSignatureBlock() =>
'<br class="tmail-break-tag"><div class="tmail-signature">${asSignatureHtml()}</div><br class="tmail-break-tag">';
String removeEditorStartTag() { String removeEditorStartTag() {
if (trim() == editorStartTags) { if (trim() == editorStartTags) {
@@ -130,11 +130,22 @@ class ComposerController extends BaseController {
List<Attachment> initialAttachments = <Attachment>[]; List<Attachment> initialAttachments = <Attachment>[];
String? _textEditorWeb; String? _textEditorWeb;
String? _initTextEditor;
List<EmailContent>? _emailContents; List<EmailContent>? _emailContents;
double? maxWithEditor; double? maxWithEditor;
late Worker uploadInlineImageWorker; late Worker uploadInlineImageWorker;
void setTextEditorWeb(String? text) => _textEditorWeb = text; void onChangeTextEditorWeb(String? text) {
initTextEditor(text);
_textEditorWeb = text;
}
void initTextEditor(String? text) {
if (_initTextEditor == null) {
_initTextEditor = text;
log('ComposerController::initTextEditor():$_initTextEditor');
}
}
String? get textEditorWeb => _textEditorWeb; String? get textEditorWeb => _textEditorWeb;
@@ -164,9 +175,13 @@ class ComposerController extends BaseController {
if (changedEmail) { if (changedEmail) {
return newContentHtml; return newContentHtml;
} else if (_isMobileApp && identitySelected.value?.signatureAsString.isNotEmpty == true) { } else if (_isMobileApp && identitySelected.value?.signatureAsString.isNotEmpty == true) {
final contentHtmlWithSignature = await htmlEditorApi?.removeSignature();
'$newContentHtml${identitySelected.value?.signatureAsString.toSignatureBlock()}'; await htmlEditorApi?.insertSignature(identitySelected.value!.signatureAsString.asSignatureHtml());
contentHtml = await htmlEditorApi?.getText() ?? '';
final contentHtmlWithSignature = contentHtml.removeEditorStartTag();
log('ComposerController::_getEmailBodyText():MOBILE:SIGNATURE: $contentHtmlWithSignature'); log('ComposerController::_getEmailBodyText():MOBILE:SIGNATURE: $contentHtmlWithSignature');
return contentHtmlWithSignature; return contentHtmlWithSignature;
} else { } else {
return newContentHtml; return newContentHtml;
@@ -218,6 +233,7 @@ class ComposerController extends BaseController {
@override @override
void onClose() { void onClose() {
_initTextEditor = null;
if (!BuildUtils.isWeb) { if (!BuildUtils.isWeb) {
FkUserAgent.release(); FkUserAgent.release();
} }
@@ -326,7 +342,8 @@ class ComposerController extends BaseController {
}); });
} }
void initRichTextForMobile(BuildContext context, HtmlEditorApi editorApi) { void initRichTextForMobile(BuildContext context, HtmlEditorApi editorApi, String? content) {
initTextEditor(content);
richTextMobileTabletController.htmlEditorApi = editorApi; richTextMobileTabletController.htmlEditorApi = editorApi;
keyboardRichTextController.onCreateHTMLEditor( keyboardRichTextController.onCreateHTMLEditor(
editorApi, editorApi,
@@ -390,6 +407,7 @@ class ComposerController extends BaseController {
.toList(); .toList();
if (listIdentities.isNotEmpty) { if (listIdentities.isNotEmpty) {
_initTextEditor = null;
await selectIdentity(listIdentities.first); await selectIdentity(listIdentities.first);
} }
} }
@@ -550,7 +568,7 @@ class ComposerController extends BaseController {
final headerEmailQuotedAsHtml = headerEmailQuoted != null ? headerEmailQuoted.addBlockTag('cite') : ''; final headerEmailQuotedAsHtml = headerEmailQuoted != null ? headerEmailQuoted.addBlockTag('cite') : '';
final trustAsHtml = arguments.emailContents?.asHtmlString ?? ''; final trustAsHtml = arguments.emailContents?.asHtmlString ?? '';
final emailQuotedHtml = '<p></br></p>$headerEmailQuotedAsHtml${trustAsHtml.addBlockQuoteTag()}</br></br></br>'; final emailQuotedHtml = '${HtmlExtension.editorStartTags}$headerEmailQuotedAsHtml${trustAsHtml.addBlockQuoteTag()}';
return emailQuotedHtml; return emailQuotedHtml;
} }
@@ -905,44 +923,30 @@ class ComposerController extends BaseController {
) async { ) async {
final newEmailBody = await _getEmailBodyText(context, changedEmail: true); final newEmailBody = await _getEmailBodyText(context, changedEmail: true);
log('ComposerController::_isEmailChanged(): newEmailBody: $newEmailBody'); log('ComposerController::_isEmailChanged(): newEmailBody: $newEmailBody');
var oldEmailBody = ''; var oldEmailBody = _initTextEditor ?? '';
if (context.mounted) {
oldEmailBody = getContentEmail(context) ?? '';
}
log('ComposerController::_isEmailChanged(): getContentEmail: $oldEmailBody');
if (arguments.emailActionType != EmailActionType.compose &&
oldEmailBody.isNotEmpty) {
oldEmailBody = BuildUtils.isWeb ? oldEmailBody : '\n$oldEmailBody\n';
}
if (BuildUtils.isWeb) {
if (identitySelected.value?.signatureAsString.isNotEmpty == true) {
oldEmailBody = '$oldEmailBody${identitySelected.value?.signatureAsString.toSignatureBlock()}';
}
}
log('ComposerController::_isEmailChanged(): oldEmailBody: $oldEmailBody'); log('ComposerController::_isEmailChanged(): oldEmailBody: $oldEmailBody');
final isEmailBodyChanged = !oldEmailBody.trim().isSame(newEmailBody.trim()); final isEmailBodyChanged = !oldEmailBody.trim().isSame(newEmailBody.trim());
log('ComposerController::_isEmailChanged(): isEmailBodyChanged: $isEmailBodyChanged'); log('ComposerController::_isEmailChanged(): isEmailBodyChanged: $isEmailBodyChanged');
final newEmailSubject = subjectEmail.value; final newEmailSubject = subjectEmail.value ?? '';
final titleEmail = arguments.presentationEmail?.getEmailTitle().trim() ?? ''; final titleEmail = arguments.presentationEmail?.getEmailTitle().trim() ?? '';
final oldEmailSubject = arguments.emailActionType.getSubjectComposer(currentContext!, titleEmail); final oldEmailSubject = arguments.emailActionType == EmailActionType.edit ? titleEmail : '';
final isEmailSubjectChanged = !oldEmailSubject.isSame(newEmailSubject); final isEmailSubjectChanged = !oldEmailSubject.trim().isSame(newEmailSubject.trim());
final recipients = arguments.presentationEmail final recipients = arguments.presentationEmail
?.generateRecipientsEmailAddressForComposer(arguments.emailActionType, arguments.mailboxRole) ?.generateRecipientsEmailAddressForComposer(arguments.emailActionType, arguments.mailboxRole)
?? const Tuple3(<EmailAddress>[], <EmailAddress>[], <EmailAddress>[]); ?? const Tuple3(<EmailAddress>[], <EmailAddress>[], <EmailAddress>[]);
final newToEmailAddress = listToEmailAddress; final newToEmailAddress = listToEmailAddress;
final oldToEmailAddress = recipients.value1; final oldToEmailAddress = arguments.emailActionType == EmailActionType.edit ? recipients.value1 : [];
final isToEmailAddressChanged = !oldToEmailAddress.isSame(newToEmailAddress); final isToEmailAddressChanged = !oldToEmailAddress.isSame(newToEmailAddress);
final newCcEmailAddress = listToEmailAddress; final newCcEmailAddress = listCcEmailAddress;
final oldCcEmailAddress = recipients.value1; final oldCcEmailAddress = arguments.emailActionType == EmailActionType.edit ? recipients.value2 : [];
final isCcEmailAddressChanged = !oldCcEmailAddress.isSame(newCcEmailAddress); final isCcEmailAddressChanged = !oldCcEmailAddress.isSame(newCcEmailAddress);
final newBccEmailAddress = listToEmailAddress; final newBccEmailAddress = listBccEmailAddress;
final oldBccEmailAddress = recipients.value1; final oldBccEmailAddress = arguments.emailActionType == EmailActionType.edit ? recipients.value3 : [];
final isBccEmailAddressChanged = !oldBccEmailAddress.isSame(newBccEmailAddress); final isBccEmailAddressChanged = !oldBccEmailAddress.isSame(newBccEmailAddress);
final isAttachmentsChanged = !initialAttachments.isSame(uploadController.attachmentsUploaded.toList()); final isAttachmentsChanged = !initialAttachments.isSame(uploadController.attachmentsUploaded.toList());
@@ -1129,6 +1133,7 @@ class ComposerController extends BaseController {
_updateTextForEditor(); _updateTextForEditor();
screenDisplayMode.value = displayMode; screenDisplayMode.value = displayMode;
_autoFocusFieldWhenLauncher(); _autoFocusFieldWhenLauncher();
selectIdentity(identitySelected.value);
} }
void _updateTextForEditor() async { void _updateTextForEditor() async {
@@ -1335,7 +1340,7 @@ class ComposerController extends BaseController {
_removeBccEmailAddressFromFormerIdentity(formerIdentity.bcc!); _removeBccEmailAddressFromFormerIdentity(formerIdentity.bcc!);
} }
if (!_isMobileApp) { if (!_isMobileApp && newIdentity != formerIdentity) {
_removeSignature(); _removeSignature();
} }
} }
@@ -1345,8 +1350,10 @@ class ComposerController extends BaseController {
await _applyBccEmailAddressFromIdentity(newIdentity.bcc!); await _applyBccEmailAddressFromIdentity(newIdentity.bcc!);
} }
if (!_isMobileApp && newIdentity.signatureAsString.isNotEmpty == true) { if (!_isMobileApp
_applySignature(newIdentity.signatureAsString); && newIdentity != formerIdentity
&& newIdentity.signatureAsString.isNotEmpty == true) {
_applySignature(newIdentity.signatureAsString.asSignatureHtml());
} }
return Future.value(null); return Future.value(null);
@@ -1379,12 +1386,10 @@ class ComposerController extends BaseController {
} }
void _applySignature(String signature) { void _applySignature(String signature) {
final signatureAsHtml = '--<br><br>$signature';
log('ComposerController::_applySignature(): $signatureAsHtml');
if (BuildUtils.isWeb) { if (BuildUtils.isWeb) {
richTextWebController.editorController.insertSignature(signatureAsHtml); richTextWebController.editorController.insertSignature(signature);
} else { } else {
htmlEditorApi?.insertSignature(signatureAsHtml); htmlEditorApi?.insertSignature(signature);
} }
} }
@@ -1528,4 +1533,26 @@ class ComposerController extends BaseController {
); );
} }
} }
void handleInitHtmlEditorWeb(String initContent) {
onChangeTextEditorWeb(initContent);
richTextWebController.setEnableCodeView();
}
void handleOnFocusHtmlEditorWeb() {
FocusManager.instance.primaryFocus?.unfocus();
Future.delayed(const Duration(milliseconds: 500), () {
richTextWebController.editorController.setFocus();
});
richTextWebController.closeAllMenuPopup();
}
void handleOnUnFocusHtmlEditorWeb() {
onEditorFocusChange(false);
}
void handleOnMouseDownHtmlEditorWeb(BuildContext context) {
Navigator.maybePop(context);
onEditorFocusChange(true);
}
} }
@@ -622,7 +622,7 @@ class ComposerView extends GetWidget<ComposerController>
minHeight: 550, minHeight: 550,
addDefaultSelectionMenuItems: false, addDefaultSelectionMenuItems: false,
initialContent: initialContent ?? '', initialContent: initialContent ?? '',
onCreated: (editorApi) => controller.initRichTextForMobile(context, editorApi) onCreated: (editorApi) => controller.initRichTextForMobile(context, editorApi, initialContent)
), ),
); );
} }
@@ -774,52 +774,36 @@ class ComposerView extends GetWidget<ComposerController>
Widget _buildHtmlEditor(BuildContext context, String initContent) { Widget _buildHtmlEditor(BuildContext context, String initContent) {
log('ComposerView::_buildHtmlEditor(): initContent: $initContent'); log('ComposerView::_buildHtmlEditor(): initContent: $initContent');
return Expanded( return Expanded(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(horizontal: 10),
horizontal: responsiveUtils.isMobile(context) ? 8 : 10), child: HtmlEditor(
child: HtmlEditor( key: const Key('composer_editor_web'),
key: const Key('composer_editor_web'), controller: controller.richTextWebController.editorController,
controller: controller.richTextWebController.editorController, htmlEditorOptions: const HtmlEditorOptions(
htmlEditorOptions: const HtmlEditorOptions( shouldEnsureVisible: true,
shouldEnsureVisible: true, hint: '',
hint: '', darkMode: false,
darkMode: false, customBodyCssStyle: bodyCssStyleForEditor
customBodyCssStyle: bodyCssStyleForEditor), ),
blockQuotedContent: initContent, blockQuotedContent: initContent,
htmlToolbarOptions: const HtmlToolbarOptions( htmlToolbarOptions: const HtmlToolbarOptions(
toolbarType: ToolbarType.hide, toolbarType: ToolbarType.hide,
defaultToolbarButtons: []), toolbarPosition: ToolbarPosition.custom,
otherOptions: const OtherOptions(height: 550), defaultToolbarButtons: []
callbacks: Callbacks(onBeforeCommand: (currentHtml) { ),
log('ComposerView::_buildHtmlEditor(): onBeforeCommand : $currentHtml'); otherOptions: const OtherOptions(height: 550),
controller.setTextEditorWeb(currentHtml); callbacks: Callbacks(
}, onChangeContent: (changed) { onBeforeCommand: controller.onChangeTextEditorWeb,
log('ComposerView::_buildHtmlEditor(): onChangeContent : $changed'); onChangeContent: controller.onChangeTextEditorWeb,
controller.setTextEditorWeb(changed); onInit: () => controller.handleInitHtmlEditorWeb(initContent),
}, onInit: () { onFocus: controller.handleOnFocusHtmlEditorWeb,
log('ComposerView::_buildHtmlEditor(): onInit'); onBlur: controller.handleOnUnFocusHtmlEditorWeb,
controller.setTextEditorWeb(initContent); onMouseDown: () => controller.handleOnMouseDownHtmlEditorWeb(context),
controller.richTextWebController.setEnableCodeView(); onChangeSelection: controller.richTextWebController.onEditorSettingsChange,
}, onFocus: () { onChangeCodeview: controller.onChangeTextEditorWeb
log('ComposerView::_buildHtmlEditor(): onFocus'); ),
FocusManager.instance.primaryFocus?.unfocus();
Future.delayed(const Duration(milliseconds: 500), () {
controller.richTextWebController.editorController.setFocus();
});
controller.richTextWebController.closeAllMenuPopup();
}, onBlur: () {
controller.onEditorFocusChange(false);
}, onMouseDown: () {
Navigator.maybePop(context);
controller.onEditorFocusChange(true);
}, onChangeSelection: (settings) {
controller.richTextWebController.onEditorSettingsChange(settings);
}, onChangeCodeview: (contentChanged) {
log('ComposerView::_buildHtmlEditor(): onChangeCodeView : $contentChanged');
controller.setTextEditorWeb(contentChanged);
}),
)
) )
)
); );
} }
+8 -8
View File
@@ -365,7 +365,7 @@ packages:
description: description:
path: "." path: "."
ref: email_supported ref: email_supported
resolved-ref: cd9b1ed2667348f7663c8947bb41f0a9321e09d7 resolved-ref: "8eeda3863740f7e1961a7157dff474d20f3c5209"
url: "https://github.com/linagora/enough_html_editor.git" url: "https://github.com/linagora/enough_html_editor.git"
source: git source: git
version: "0.0.5" version: "0.0.5"
@@ -867,7 +867,7 @@ packages:
description: description:
path: "." path: "."
ref: email_supported ref: email_supported
resolved-ref: "750fc01e09b5a98b06463e336a4b30851d90fa70" resolved-ref: e9f24750953af0a3ec030affe2542c8261ce5f47
url: "https://github.com/linagora/html-editor-enhanced.git" url: "https://github.com/linagora/html-editor-enhanced.git"
source: git source: git
version: "2.5.1" version: "2.5.1"
@@ -1657,26 +1657,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics name: vector_graphics
sha256: "2f317d969a9f1eb59d1890643107da749698b7c08c4b0532fc95c8a7130d2803" sha256: "4cf8e60dbe4d3a693d37dff11255a172594c0793da542183cbfe7fe978ae4aaa"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.3" version: "1.1.4"
vector_graphics_codec: vector_graphics_codec:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics_codec name: vector_graphics_codec
sha256: "13cccfda2dd61232a19dfb769b7a907e2ab23aabfebb9053c81e29c6c11b1766" sha256: "278ad5f816f58b1967396d1f78ced470e3e58c9fe4b27010102c0a595c764468"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.3" version: "1.1.4"
vector_graphics_compiler: vector_graphics_compiler:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics_compiler name: vector_graphics_compiler
sha256: "524c9889a1327401124fe068840a8867f0d57987c1219a2a696ade629ec2bec3" sha256: "0bf61ad56e6fd6688a2865d3ceaea396bc6a0a90ea0d7ad5049b1b76c09d6163"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.3" version: "1.1.4"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description: