Fix draft email when close composer on browser

This commit is contained in:
dab246
2022-03-18 18:07:49 +07:00
committed by Dat H. Pham
parent 49c64dea72
commit cd6874faa7
6 changed files with 79 additions and 47 deletions
@@ -60,7 +60,7 @@ class ComposerController extends BaseController {
final isEnableEmailSendButton = false.obs; final isEnableEmailSendButton = false.obs;
final isInitialRecipient = false.obs; final isInitialRecipient = false.obs;
final attachments = <Attachment>[].obs; final attachments = <Attachment>[].obs;
final emailContents = <EmailContent>[].obs; final emailContents = Rxn<List<EmailContent>>();
final subjectEmail = Rxn<String>(); final subjectEmail = Rxn<String>();
final screenDisplayMode = ScreenDisplayMode.normal.obs; final screenDisplayMode = ScreenDisplayMode.normal.obs;
@@ -84,7 +84,7 @@ class ComposerController extends BaseController {
List<EmailAddress> listBccEmailAddress = <EmailAddress>[]; List<EmailAddress> listBccEmailAddress = <EmailAddress>[];
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.localContact; ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.localContact;
HtmlEditorApi? htmlEditorApi; HtmlEditorApi? htmlEditorApi;
final HtmlEditorBrowser.HtmlEditorController htmlControllerBrowser = HtmlEditorBrowser.HtmlEditorController(); final HtmlEditorBrowser.HtmlEditorController htmlControllerBrowser = HtmlEditorBrowser.HtmlEditorController(processNewLineAsBr: true);
final subjectEmailInputController = TextEditingController(); final subjectEmailInputController = TextEditingController();
final toEmailAddressController = TextEditingController(); final toEmailAddressController = TextEditingController();
@@ -92,11 +92,11 @@ class ComposerController extends BaseController {
final bccEmailAddressController = TextEditingController(); final bccEmailAddressController = TextEditingController();
List<Attachment> initialAttachments = <Attachment>[]; List<Attachment> initialAttachments = <Attachment>[];
String? _textEditor; String? _textEditorWeb;
void setTextEditor(String? text) => _textEditor = text; void setTextEditorWeb(String? text) => _textEditorWeb = text;
String? get textEditor => _textEditor; String? get textEditorWeb => _textEditorWeb;
void setSubjectEmail(String subject) => subjectEmail.value = subject; void setSubjectEmail(String subject) => subjectEmail.value = subject;
@@ -193,6 +193,7 @@ class ComposerController extends BaseController {
void _initEmail() { void _initEmail() {
final arguments = kIsWeb ? mailboxDashBoardController.routerArguments : Get.arguments; final arguments = kIsWeb ? mailboxDashBoardController.routerArguments : Get.arguments;
if (arguments is ComposerArguments) { if (arguments is ComposerArguments) {
log('ComposerController::_initEmail(): arguments: ${arguments.props}');
composerArguments.value = arguments; composerArguments.value = arguments;
if (arguments.emailActionType == EmailActionType.edit) { if (arguments.emailActionType == EmailActionType.edit) {
_getEmailContentAction(arguments); _getEmailContentAction(arguments);
@@ -211,31 +212,24 @@ class ComposerController extends BaseController {
} }
} }
String getContentEmail() { String? getContentEmail(BuildContext context) {
if (composerArguments.value != null if (composerArguments.value != null) {
&& composerArguments.value!.emailActionType != EmailActionType.compose switch(composerArguments.value!.emailActionType) {
&& Get.context != null) { case EmailActionType.reply:
if (composerArguments.value?.emailActionType == EmailActionType.edit) { case EmailActionType.forward:
return _getOldEmailContentAsHtml(); case EmailActionType.replyAll:
} else { return getEmailContentQuotedAsHtml(context, composerArguments.value!);
return _getBodyEmailQuotedAsHtml(Get.context!, composerArguments.value!); case EmailActionType.edit:
return getEmailContentDraftsAsHtml();
default:
return '';
} }
} }
return ''; return '';
} }
String? get initTextEditorComposer {
if (composerArguments.value?.emailActionType == EmailActionType.compose) {
return textEditor;
} else {
return textEditor ?? getContentEmail();
}
}
void setFullScreenEditor() { void setFullScreenEditor() {
Future.delayed(const Duration(milliseconds: 1000), () { htmlControllerBrowser.setFullScreen();
htmlControllerBrowser.setFullScreen();
});
} }
Tuple2<String, String>? _getHeaderEmailQuoted(String locale, ComposerArguments arguments) { Tuple2<String, String>? _getHeaderEmailQuoted(String locale, ComposerArguments arguments) {
@@ -306,7 +300,7 @@ class ComposerController extends BaseController {
} }
} }
String _getBodyEmailQuotedAsHtml(BuildContext context, ComposerArguments arguments) { String getEmailContentQuotedAsHtml(BuildContext context, ComposerArguments arguments) {
final headerEmailQuoted = _getHeaderEmailQuoted(Localizations.localeOf(context).toLanguageTag(), arguments); final headerEmailQuoted = _getHeaderEmailQuoted(Localizations.localeOf(context).toLanguageTag(), arguments);
final headerEmailQuotedAsHtml = headerEmailQuoted != null final headerEmailQuotedAsHtml = headerEmailQuoted != null
@@ -538,10 +532,17 @@ class ComposerController extends BaseController {
attachments.removeWhere((attachment) => attachment == attachmentRemoved); attachments.removeWhere((attachment) => attachment == attachmentRemoved);
} }
Future<bool> _isEmailChanged(ComposerArguments arguments) async { Future<bool> _isEmailChanged(BuildContext context, ComposerArguments arguments) async {
final newEmailBody = await _getEmailBodyText(onlyText: true); final newEmailBody = await _getEmailBodyText(onlyText: true);
final oldEmailBody = kIsWeb ? getContentEmail() : '\n${getContentEmail()}\n'; log('ComposerController::_isEmailChanged(): newEmailBody: $newEmailBody');
final isEmailBodyChanged = !oldEmailBody.isSame(newEmailBody); var oldEmailBody = '';
final contentEmail = getContentEmail(context);
if (arguments.emailActionType != EmailActionType.compose && contentEmail != null && contentEmail.isNotEmpty) {
oldEmailBody = kIsWeb ? contentEmail : '\n$contentEmail\n';
}
log('ComposerController::_isEmailChanged(): oldEmailBody: $oldEmailBody');
final isEmailBodyChanged = !oldEmailBody.trim().isSame(newEmailBody.trim());
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() ?? '';
@@ -583,10 +584,11 @@ class ComposerController extends BaseController {
final userProfile = mailboxDashBoardController.userProfile.value; final userProfile = mailboxDashBoardController.userProfile.value;
final session = mailboxDashBoardController.sessionCurrent; final session = mailboxDashBoardController.sessionCurrent;
if (arguments != null && Get.context != null && mapDefaultMailboxId.isNotEmpty if (arguments != null && mapDefaultMailboxId.isNotEmpty && userProfile != null && session != null) {
&& userProfile != null && session != null) { log('ComposerController::saveEmailAsDrafts(): saveEmailAsDrafts START');
final isChanged = await _isEmailChanged(arguments); final isChanged = await _isEmailChanged(context, arguments);
if (isChanged) { if (isChanged) {
log('ComposerController::saveEmailAsDrafts(): saveEmailAsDrafts isChanged: $isChanged');
_saveEmailAddress(); _saveEmailAddress();
final newEmail = await _generateEmail(mapDefaultMailboxId, userProfile, asDrafts: true); final newEmail = await _generateEmail(mapDefaultMailboxId, userProfile, asDrafts: true);
@@ -617,15 +619,15 @@ class ComposerController extends BaseController {
initialAttachments = success.attachments; initialAttachments = success.attachments;
} }
String _getOldEmailContentAsHtml() { String? getEmailContentDraftsAsHtml() {
if (emailContents.isNotEmpty) { final listContents = emailContents.value;
final trustAsHtml = emailContents if (listContents != null) {
.map((emailContent) => emailContent.content) return listContents.isNotEmpty
.toList() ? listContents.map((emailContent) => emailContent.content).toList().join('</br>')
.join('</br>'); : '';
return trustAsHtml; } else {
return null;
} }
return '';
} }
String getEmailAddressSender() { String getEmailAddressSender() {
@@ -304,8 +304,8 @@ class ComposerView extends GetWidget<ComposerController> {
minHeight: 550, minHeight: 550,
onCreated: (editorApi) => controller.htmlEditorApi = editorApi); onCreated: (editorApi) => controller.htmlEditorApi = editorApi);
} else { } else {
final message = controller.getContentEmail(); final message = controller.getContentEmail(context);
return message.isNotEmpty return message != null && message.isNotEmpty
? HtmlEditor( ? HtmlEditor(
key: Key('composer_editor'), key: Key('composer_editor'),
minHeight: 550, minHeight: 550,
@@ -409,18 +409,46 @@ class ComposerView extends GetWidget<ComposerController> {
padding: EdgeInsets.only(bottom: 8, left: 10, right: 10), padding: EdgeInsets.only(bottom: 8, left: 10, right: 10),
child: _buildAttachmentsList(context, controller.attachments, controller.expandModeAttachments.value)) child: _buildAttachmentsList(context, controller.attachments, controller.expandModeAttachments.value))
: SizedBox.shrink()), : SizedBox.shrink()),
Expanded(child: Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: _buildEditor(context))), Obx(() {
if (controller.composerArguments.value != null) {
if (controller.composerArguments.value?.emailActionType == EmailActionType.compose) {
final initContent = controller.textEditorWeb ?? '';
log('ComposerView::_buildEditorAndAttachments(): initContent: $initContent');
return Expanded(child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: _buildEditor(context, initContent)));
} else if (controller.composerArguments.value?.emailActionType == EmailActionType.edit) {
final initContent = controller.getEmailContentDraftsAsHtml();
log('ComposerView::_buildEditorAndAttachments(): initContent: $initContent');
if (initContent != null) {
return Expanded(child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: _buildEditor(context, initContent)));
} else {
return SizedBox.shrink();
}
} else {
final initContent = controller.getEmailContentQuotedAsHtml(context, controller.composerArguments.value!);
log('ComposerView::_buildEditorAndAttachments(): initContent: $initContent');
return Expanded(child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: _buildEditor(context, initContent)));
}
} else {
return SizedBox.shrink();
}
}),
] ]
); );
} }
Widget _buildEditor(BuildContext context) { Widget _buildEditor(BuildContext context, String initContent) {
return HtmlEditorBrowser.HtmlEditor( return HtmlEditorBrowser.HtmlEditor(
key: Key('composer_editor_web'), key: Key('composer_editor_web'),
controller: controller.htmlControllerBrowser, controller: controller.htmlControllerBrowser,
htmlEditorOptions: HtmlEditorBrowser.HtmlEditorOptions( htmlEditorOptions: HtmlEditorBrowser.HtmlEditorOptions(
hint: '<p></p>', hint: '<p></p>',
initialText: controller.initTextEditorComposer, initialText: initContent,
darkMode: false, darkMode: false,
), ),
htmlToolbarOptions: HtmlEditorBrowser.HtmlToolbarOptions( htmlToolbarOptions: HtmlEditorBrowser.HtmlToolbarOptions(
@@ -430,10 +458,10 @@ class ComposerView extends GetWidget<ComposerController> {
callbacks: HtmlEditorBrowser.Callbacks( callbacks: HtmlEditorBrowser.Callbacks(
onBeforeCommand: (String? currentHtml) { onBeforeCommand: (String? currentHtml) {
log('ComposerView::_buildComposerEditor(): onBeforeCommand'); log('ComposerView::_buildComposerEditor(): onBeforeCommand');
controller.setTextEditor(currentHtml); controller.setTextEditorWeb(currentHtml);
}, onChangeContent: (String? changed) { }, onChangeContent: (String? changed) {
log('ComposerView::_buildComposerEditor(): onChangeContent'); log('ComposerView::_buildComposerEditor(): onChangeContent');
controller.setTextEditor(changed); controller.setTextEditorWeb(changed);
}, onInit: () { }, onInit: () {
log('ComposerView::_buildComposerEditor(): onInit'); log('ComposerView::_buildComposerEditor(): onInit');
controller.setFullScreenEditor(); controller.setFullScreenEditor();
@@ -23,7 +23,7 @@ class EmailAddressInputBuilder {
final AppToast _appToast; final AppToast _appToast;
final ExpandMode expandMode; final ExpandMode expandMode;
final PrefixEmailAddress _prefixEmailAddress; final PrefixEmailAddress _prefixEmailAddress;
final List<EmailAddress> _listEmailAddress; List<EmailAddress> _listEmailAddress;
final TextEditingController? controller; final TextEditingController? controller;
final bool? isInitial; final bool? isInitial;
final bool hasAvatar; final bool hasAvatar;
@@ -24,6 +24,7 @@ class ComposerArguments extends RouterArguments {
@override @override
List<Object?> get props => [ List<Object?> get props => [
emailActionType, emailActionType,
presentationEmail,
emailContents, emailContents,
attachments, attachments,
mailboxRole, mailboxRole,
@@ -108,6 +108,7 @@ class MailboxDashBoardController extends ReloadableController {
} }
clearState(); clearState();
} else if (success is SaveEmailAsDraftsSuccess) { } else if (success is SaveEmailAsDraftsSuccess) {
log('MailboxDashBoardController::onDone(): SaveEmailAsDraftsSuccess');
_saveEmailAsDraftsSuccess(success); _saveEmailAsDraftsSuccess(success);
clearState(); clearState();
} else if (success is RemoveEmailDraftsSuccess } else if (success is RemoveEmailDraftsSuccess