TF-475 Fix save a draft email
This commit is contained in:
@@ -32,4 +32,17 @@ extension HtmlExtension on String {
|
||||
String addBlockQuoteTag() => addBlockTag(
|
||||
'blockquote',
|
||||
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 toSignatureBlock() =>
|
||||
'<br class="tmail-break-tag"><div class="tmail-signature">${asSignatureHtml()}</div><br class="tmail-break-tag">';
|
||||
|
||||
String removeEditorDefaultSpace() {
|
||||
return replaceAll('<p><br><br><br></p>', '');
|
||||
}
|
||||
|
||||
String addEditorDefaultSpace() {
|
||||
return '<p><br><br><br></p>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
|
||||
class SaveEmailAsDraftsLoading extends UIState {
|
||||
|
||||
SaveEmailAsDraftsLoading();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class SaveEmailAsDraftsSuccess extends UIState {
|
||||
|
||||
final Email emailAsDrafts;
|
||||
|
||||
@@ -12,6 +12,7 @@ class SaveEmailAsDraftsInteractor {
|
||||
|
||||
Stream<Either<Failure, Success>> execute(AccountId accountId, Email email) async* {
|
||||
try {
|
||||
yield Right<Failure, Success>(SaveEmailAsDraftsLoading());
|
||||
final emailAsDrafts = await emailRepository.saveEmailAsDrafts(accountId, email);
|
||||
if (emailAsDrafts != null) {
|
||||
yield Right<Failure, Success>(SaveEmailAsDraftsSuccess(emailAsDrafts));
|
||||
|
||||
@@ -116,7 +116,7 @@ class ComposerController extends BaseController {
|
||||
} else {
|
||||
final content = await htmlEditorApi?.getText() ?? '';
|
||||
if (_isMobileApp && identitySelected.value?.textSignature?.value.isNotEmpty == true) {
|
||||
final newContent = '$content<br><br><br>--<br><br><div>${identitySelected.value?.textSignature?.value}</div><br>';
|
||||
final newContent = '$content${identitySelected.value?.textSignature?.value.toSignatureBlock()}';
|
||||
log('ComposerController::_generateEmail()_MOBILE: $newContent');
|
||||
return newContent;
|
||||
} else {
|
||||
@@ -143,9 +143,11 @@ class ComposerController extends BaseController {
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) async {
|
||||
await FkUserAgent.init();
|
||||
});
|
||||
if (!BuildUtils.isWeb) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) async {
|
||||
await FkUserAgent.init();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -161,11 +163,19 @@ class ComposerController extends BaseController {
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
if (!BuildUtils.isWeb) {
|
||||
FkUserAgent.release();
|
||||
}
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
subjectEmailInputController.dispose();
|
||||
toEmailAddressController.dispose();
|
||||
ccEmailAddressController.dispose();
|
||||
bccEmailAddressController.dispose();
|
||||
super.onClose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -435,6 +445,7 @@ class ComposerController extends BaseController {
|
||||
var emailBodyText = await _getEmailBodyText();
|
||||
log('ComposerController::_generateEmail(): $emailBodyText');
|
||||
final userAgent = await userAgentPlatform;
|
||||
log('ComposerController::_generateEmail(): userAgent: $userAgent');
|
||||
|
||||
return Email(
|
||||
generateEmailId,
|
||||
@@ -708,14 +719,22 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
|
||||
Future<bool> _isEmailChanged(BuildContext context, ComposerArguments arguments) async {
|
||||
final newEmailBody = (await _getEmailBodyText(changedEmail: true))
|
||||
.replaceAll('<p><br><br><br></p>', '');
|
||||
final currentTextInComposer = await _getEmailBodyText(changedEmail: true);
|
||||
final newEmailBody = currentTextInComposer.removeEditorDefaultSpace();
|
||||
log('ComposerController::_isEmailChanged(): newEmailBody: $newEmailBody');
|
||||
var oldEmailBody = '';
|
||||
final contentEmail = getContentEmail(context);
|
||||
if (arguments.emailActionType != EmailActionType.compose && contentEmail != null && contentEmail.isNotEmpty) {
|
||||
oldEmailBody = kIsWeb ? contentEmail : '\n$contentEmail\n';
|
||||
}
|
||||
if (BuildUtils.isWeb) {
|
||||
if (identitySelected.value?.htmlSignature?.value.isNotEmpty == true) {
|
||||
oldEmailBody = '$oldEmailBody${identitySelected.value?.htmlSignature?.value.toSignatureBlock()}';
|
||||
} else if (identitySelected.value?.textSignature?.value.isNotEmpty == true) {
|
||||
oldEmailBody = '$oldEmailBody${identitySelected.value?.textSignature?.value.toSignatureBlock()}';
|
||||
}
|
||||
}
|
||||
|
||||
log('ComposerController::_isEmailChanged(): oldEmailBody: $oldEmailBody');
|
||||
final isEmailBodyChanged = !oldEmailBody.trim().isSame(newEmailBody.trim());
|
||||
log('ComposerController::_isEmailChanged(): isEmailBodyChanged: $isEmailBodyChanged');
|
||||
@@ -752,7 +771,8 @@ class ComposerController extends BaseController {
|
||||
return false;
|
||||
}
|
||||
|
||||
void saveEmailAsDrafts(BuildContext context) async {
|
||||
void saveEmailAsDrafts(BuildContext context, {bool canPop = true}) async {
|
||||
log('ComposerController::saveEmailAsDrafts():');
|
||||
clearFocusEditor(context);
|
||||
|
||||
final arguments = composerArguments.value;
|
||||
@@ -763,8 +783,8 @@ class ComposerController extends BaseController {
|
||||
if (arguments != null && mapDefaultMailboxId.isNotEmpty && userProfile != null && session != null) {
|
||||
log('ComposerController::saveEmailAsDrafts(): saveEmailAsDrafts START');
|
||||
final isChanged = await _isEmailChanged(context, arguments);
|
||||
log('ComposerController::saveEmailAsDrafts(): saveEmailAsDrafts isChanged: $isChanged');
|
||||
if (isChanged) {
|
||||
log('ComposerController::saveEmailAsDrafts(): saveEmailAsDrafts isChanged: $isChanged');
|
||||
final newEmail = await _generateEmail(mapDefaultMailboxId, userProfile, asDrafts: true);
|
||||
final accountId = session.accounts.keys.first;
|
||||
final oldEmail = arguments.presentationEmail;
|
||||
@@ -778,6 +798,12 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BuildUtils.isWeb) {
|
||||
mailboxDashBoardController.dispatchAction(CloseComposeEmailAction());
|
||||
} else {
|
||||
if (canPop) popBack();
|
||||
}
|
||||
}
|
||||
|
||||
void _getEmailContentAction(ComposerArguments arguments) async {
|
||||
@@ -819,7 +845,6 @@ class ComposerController extends BaseController {
|
||||
void clearFocusEditor(BuildContext context) {
|
||||
if (!kIsWeb) {
|
||||
htmlEditorApi?.unfocus(context);
|
||||
htmlControllerBrowser.clearFocus();
|
||||
}
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
Widget _buildComposerViewForMobile(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.saveEmailAsDrafts(context, canPop: false);
|
||||
return true;
|
||||
},
|
||||
child: GestureDetector(
|
||||
@@ -68,7 +68,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
Widget _buildComposerViewForTablet(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.saveEmailAsDrafts(context, canPop: false);
|
||||
return true;
|
||||
},
|
||||
child: GestureDetector(
|
||||
@@ -119,12 +119,9 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
icon: SvgPicture.asset(imagePaths.icClose, width: 30, height: 30, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).close,
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onTap: () {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.closeComposer();
|
||||
}),
|
||||
onTap: () => controller.saveEmailAsDrafts(context)),
|
||||
Expanded(child: _buildTitleComposer(context)),
|
||||
if (responsiveUtils.isMobile(context))
|
||||
if (responsiveUtils.isScreenWithShortestSide(context))
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
isEnableSendButton ? imagePaths.icSendMobile : imagePaths.icSendDisable,
|
||||
@@ -158,10 +155,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
width: 150,
|
||||
height: 44,
|
||||
radius: 10,
|
||||
onTap: () {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.closeComposer();
|
||||
}),
|
||||
onTap: () => controller.saveEmailAsDrafts(context)),
|
||||
const SizedBox(width: 12),
|
||||
buildTextButton(
|
||||
AppLocalizations.of(context).send,
|
||||
@@ -487,7 +481,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
return HtmlEditor(
|
||||
key: const Key('composer_editor'),
|
||||
minHeight: 550,
|
||||
initialContent: '<p><br><br><br></p>',
|
||||
initialContent: ''.addEditorDefaultSpace(),
|
||||
onCreated: (editorApi) => controller.htmlEditorApi = editorApi);
|
||||
} else {
|
||||
final message = controller.getContentEmail(context);
|
||||
|
||||
@@ -91,10 +91,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
child: buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icCloseMailbox, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).close,
|
||||
onTap: () {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.closeComposerWeb();
|
||||
}
|
||||
onTap: () => controller.saveEmailAsDrafts(context)
|
||||
)),
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icFullScreenComposer, fit: BoxFit.fill),
|
||||
@@ -174,10 +171,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icCloseMailbox, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).close,
|
||||
onTap: () {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.closeComposerWeb();
|
||||
}),
|
||||
onTap: () => controller.saveEmailAsDrafts(context)),
|
||||
if (responsiveUtils.isDesktop(context))
|
||||
Obx(() => buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
@@ -210,10 +204,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
icon: SvgPicture.asset(imagePaths.icClose, width: 30, height: 30, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).close,
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onTap: () {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.closeComposerWeb();
|
||||
}),
|
||||
onTap: () => controller.saveEmailAsDrafts(context)),
|
||||
Expanded(child: _buildTitleComposer(context)),
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
@@ -248,10 +239,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
width: 150,
|
||||
height: 44,
|
||||
radius: 10,
|
||||
onTap: () {
|
||||
controller.saveEmailAsDrafts(context);
|
||||
controller.closeComposerWeb();
|
||||
}),
|
||||
onTap: () => controller.saveEmailAsDrafts(context)),
|
||||
const SizedBox(width: 12),
|
||||
buildTextButton(
|
||||
AppLocalizations.of(context).send,
|
||||
@@ -518,7 +506,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
Obx(() {
|
||||
if (controller.composerArguments.value != null) {
|
||||
if (controller.composerArguments.value?.emailActionType == EmailActionType.compose) {
|
||||
final initContent = controller.textEditorWeb ?? '<p><br><br><br></p>';
|
||||
final initContent = controller.textEditorWeb ?? ''.addEditorDefaultSpace();
|
||||
return Expanded(child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: responsiveUtils.isMobile(context) ? 8 : 10),
|
||||
child: _buildEditor(context, initContent)));
|
||||
|
||||
Reference in New Issue
Block a user