TF-3406 Add edit as new email feature
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -570,6 +570,19 @@ class ComposerController extends BaseController
|
|||||||
);
|
);
|
||||||
|
|
||||||
switch(arguments.emailActionType) {
|
switch(arguments.emailActionType) {
|
||||||
|
case EmailActionType.composeFromPresentationEmail:
|
||||||
|
_initEmailAddress(
|
||||||
|
presentationEmail: arguments.presentationEmail!,
|
||||||
|
actionType: EmailActionType.composeFromPresentationEmail
|
||||||
|
);
|
||||||
|
_initSubjectEmail(
|
||||||
|
presentationEmail: arguments.presentationEmail!,
|
||||||
|
actionType: EmailActionType.composeFromPresentationEmail
|
||||||
|
);
|
||||||
|
_getEmailContentOfEmailDrafts(
|
||||||
|
emailId: arguments.presentationEmail!.id!,
|
||||||
|
);
|
||||||
|
break;
|
||||||
case EmailActionType.editDraft:
|
case EmailActionType.editDraft:
|
||||||
_initEmailAddress(
|
_initEmailAddress(
|
||||||
presentationEmail: arguments.presentationEmail!,
|
presentationEmail: arguments.presentationEmail!,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ extension EmailActionTypeExtension on EmailActionType {
|
|||||||
case EmailActionType.editDraft:
|
case EmailActionType.editDraft:
|
||||||
case EmailActionType.editSendingEmail:
|
case EmailActionType.editSendingEmail:
|
||||||
case EmailActionType.reopenComposerBrowser:
|
case EmailActionType.reopenComposerBrowser:
|
||||||
|
case EmailActionType.composeFromPresentationEmail:
|
||||||
return subject;
|
return subject;
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
@@ -138,6 +139,8 @@ extension EmailActionTypeExtension on EmailActionType {
|
|||||||
return imagePaths.icMailboxArchived;
|
return imagePaths.icMailboxArchived;
|
||||||
case EmailActionType.downloadMessageAsEML:
|
case EmailActionType.downloadMessageAsEML:
|
||||||
return imagePaths.icDownloadAttachment;
|
return imagePaths.icDownloadAttachment;
|
||||||
|
case EmailActionType.composeFromPresentationEmail:
|
||||||
|
return imagePaths.icEdit;
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -159,6 +162,8 @@ extension EmailActionTypeExtension on EmailActionType {
|
|||||||
return AppLocalizations.of(context).archiveMessage;
|
return AppLocalizations.of(context).archiveMessage;
|
||||||
case EmailActionType.downloadMessageAsEML:
|
case EmailActionType.downloadMessageAsEML:
|
||||||
return AppLocalizations.of(context).downloadMessageAsEML;
|
return AppLocalizations.of(context).downloadMessageAsEML;
|
||||||
|
case EmailActionType.composeFromPresentationEmail:
|
||||||
|
return AppLocalizations.of(context).editAsNewEmail;
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class MobileEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
case EmailActionType.reopenComposerBrowser:
|
case EmailActionType.reopenComposerBrowser:
|
||||||
case EmailActionType.composeFromMailtoUri:
|
case EmailActionType.composeFromMailtoUri:
|
||||||
case EmailActionType.composeFromUnsubscribeMailtoLink:
|
case EmailActionType.composeFromUnsubscribeMailtoLink:
|
||||||
|
case EmailActionType.composeFromPresentationEmail:
|
||||||
if (contentViewState == null) {
|
if (contentViewState == null) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
@@ -64,9 +65,12 @@ class MobileEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
if (success is GetEmailContentLoading) {
|
if (success is GetEmailContentLoading) {
|
||||||
return const CupertinoLoadingWidget(padding: EdgeInsets.all(16.0));
|
return const CupertinoLoadingWidget(padding: EdgeInsets.all(16.0));
|
||||||
} else {
|
} else {
|
||||||
var newContent = success is GetEmailContentSuccess
|
var newContent = HtmlExtension.editorStartTags;
|
||||||
? success.htmlEmailContent
|
if (success is GetEmailContentSuccess) {
|
||||||
: HtmlExtension.editorStartTags;
|
newContent = success.htmlEmailContent;
|
||||||
|
} else if (success is GetEmailContentFromCacheSuccess) {
|
||||||
|
newContent = success.htmlEmailContent;
|
||||||
|
}
|
||||||
if (newContent.isEmpty) {
|
if (newContent.isEmpty) {
|
||||||
newContent = HtmlExtension.editorStartTags;
|
newContent = HtmlExtension.editorStartTags;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
case EmailActionType.reopenComposerBrowser:
|
case EmailActionType.reopenComposerBrowser:
|
||||||
case EmailActionType.composeFromUnsubscribeMailtoLink:
|
case EmailActionType.composeFromUnsubscribeMailtoLink:
|
||||||
case EmailActionType.composeFromMailtoUri:
|
case EmailActionType.composeFromMailtoUri:
|
||||||
|
case EmailActionType.composeFromPresentationEmail:
|
||||||
if (contentViewState == null) {
|
if (contentViewState == null) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1205,6 +1205,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
|||||||
case EmailActionType.downloadMessageAsEML:
|
case EmailActionType.downloadMessageAsEML:
|
||||||
_downloadMessageAsEML(presentationEmail);
|
_downloadMessageAsEML(presentationEmail);
|
||||||
break;
|
break;
|
||||||
|
case EmailActionType.composeFromPresentationEmail:
|
||||||
|
_composeFromPresentationEmail(presentationEmail);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1906,6 +1909,14 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
|||||||
downloadAttachmentForWeb(emlAttachment);
|
downloadAttachmentForWeb(emlAttachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _composeFromPresentationEmail(PresentationEmail presentationEmail) {
|
||||||
|
if (accountId == null || session == null) return;
|
||||||
|
|
||||||
|
mailboxDashBoardController.goToComposer(
|
||||||
|
ComposerArguments.fromPresentationEmail(presentationEmail),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void handleDownloadAttachmentAction(BuildContext context, Attachment attachment) {
|
void handleDownloadAttachmentAction(BuildContext context, Attachment attachment) {
|
||||||
if (PlatformInfo.isWeb) {
|
if (PlatformInfo.isWeb) {
|
||||||
downloadAttachmentForWeb(attachment);
|
downloadAttachmentForWeb(attachment);
|
||||||
|
|||||||
@@ -503,7 +503,8 @@ class EmailView extends GetWidget<SingleEmailController> {
|
|||||||
if (mailboxContain?.isArchive == false)
|
if (mailboxContain?.isArchive == false)
|
||||||
EmailActionType.archiveMessage,
|
EmailActionType.archiveMessage,
|
||||||
if (PlatformInfo.isWeb && PlatformInfo.isCanvasKit)
|
if (PlatformInfo.isWeb && PlatformInfo.isCanvasKit)
|
||||||
EmailActionType.downloadMessageAsEML
|
EmailActionType.downloadMessageAsEML,
|
||||||
|
EmailActionType.composeFromPresentationEmail,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (position == null) {
|
if (position == null) {
|
||||||
|
|||||||
@@ -102,6 +102,12 @@ class ComposerArguments extends RouterArguments {
|
|||||||
emailActionType: EmailActionType.editDraft,
|
emailActionType: EmailActionType.editDraft,
|
||||||
presentationEmail: presentationEmail,
|
presentationEmail: presentationEmail,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
factory ComposerArguments.fromPresentationEmail(PresentationEmail presentationEmail) =>
|
||||||
|
ComposerArguments(
|
||||||
|
emailActionType: EmailActionType.composeFromPresentationEmail,
|
||||||
|
presentationEmail: presentationEmail,
|
||||||
|
);
|
||||||
|
|
||||||
factory ComposerArguments.fromSessionStorageBrowser(ComposerCache composerCache) =>
|
factory ComposerArguments.fromSessionStorageBrowser(ComposerCache composerCache) =>
|
||||||
ComposerArguments(
|
ComposerArguments(
|
||||||
|
|||||||
+1
-3
@@ -83,9 +83,7 @@ extension UpdateCurrentEmailsFlagsExtension on MailboxDashBoardController {
|
|||||||
setSelectedEmail(newEmail);
|
setSelectedEmail(newEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emailsInCurrentMailbox.isNotEmpty) {
|
updateEmailFlagByEmailIds([emailId], markAsAnswered: true);
|
||||||
updateEmailFlagByEmailIds([emailId], markAsAnswered: true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateEmailForwarded(EmailId emailId) {
|
void updateEmailForwarded(EmailId emailId) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_til
|
|||||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart'
|
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart'
|
||||||
if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart';
|
if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||||
|
|
||||||
class SearchEmailView extends GetWidget<SearchEmailController>
|
class SearchEmailView extends GetWidget<SearchEmailController>
|
||||||
with AppLoaderMixin {
|
with AppLoaderMixin {
|
||||||
@@ -745,6 +746,8 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
|||||||
List<Widget> _contextMenuActionTile(BuildContext context, PresentationEmail email) {
|
List<Widget> _contextMenuActionTile(BuildContext context, PresentationEmail email) {
|
||||||
return <Widget>[
|
return <Widget>[
|
||||||
_markAsEmailSpamOrUnSpamAction(context, email),
|
_markAsEmailSpamOrUnSpamAction(context, email),
|
||||||
|
if (email.mailboxContain?.isDrafts == false)
|
||||||
|
_editAsNewEmailContextMenuItemAction(context, email),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,11 +780,44 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _editAsNewEmailContextMenuItemAction(
|
||||||
|
BuildContext context,
|
||||||
|
PresentationEmail email,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
EmailActionCupertinoActionSheetActionBuilder(
|
||||||
|
const Key('edit_as_new_email_action'),
|
||||||
|
SvgPicture.asset(
|
||||||
|
controller.imagePaths.icEdit,
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
colorFilter: AppColor.colorTextButton.asFilter()
|
||||||
|
),
|
||||||
|
AppLocalizations.of(context).editAsNewEmail,
|
||||||
|
email,
|
||||||
|
iconLeftPadding: controller.responsiveUtils.isMobile(context)
|
||||||
|
? const EdgeInsetsDirectional.only(start: 12, end: 16)
|
||||||
|
: const EdgeInsetsDirectional.only(end: 12),
|
||||||
|
iconRightPadding: controller.responsiveUtils.isMobile(context)
|
||||||
|
? const EdgeInsetsDirectional.only(start: 12)
|
||||||
|
: EdgeInsets.zero)
|
||||||
|
..onActionClick((email) {
|
||||||
|
popBack();
|
||||||
|
controller.editAsNewEmail(email);
|
||||||
|
})
|
||||||
|
).build();
|
||||||
|
}
|
||||||
|
|
||||||
List<PopupMenuEntry> _popupMenuActionTile(BuildContext context, PresentationEmail email) {
|
List<PopupMenuEntry> _popupMenuActionTile(BuildContext context, PresentationEmail email) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: _markAsEmailSpamOrUnSpamAction(context, email)),
|
child: _markAsEmailSpamOrUnSpamAction(context, email)),
|
||||||
|
if (email.mailboxContain?.isDrafts == false)
|
||||||
|
PopupMenuItem(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child: _editAsNewEmailContextMenuItemAction(context, email)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ mixin EmailActionController {
|
|||||||
mailboxDashBoardController.goToComposer(ComposerArguments.editDraftEmail(presentationEmail));
|
mailboxDashBoardController.goToComposer(ComposerArguments.editDraftEmail(presentationEmail));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void editAsNewEmail(PresentationEmail presentationEmail) {
|
||||||
|
mailboxDashBoardController.goToComposer(
|
||||||
|
ComposerArguments.fromPresentationEmail(presentationEmail),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void previewEmail(PresentationEmail presentationEmail) {
|
void previewEmail(PresentationEmail presentationEmail) {
|
||||||
log('EmailActionController::previewEmail():presentationEmailId: ${presentationEmail.id}');
|
log('EmailActionController::previewEmail():presentationEmailId: ${presentationEmail.id}');
|
||||||
mailboxDashBoardController.openEmailDetailedView(presentationEmail);
|
mailboxDashBoardController.openEmailDetailedView(presentationEmail);
|
||||||
|
|||||||
@@ -1152,6 +1152,8 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
case EmailActionType.preview:
|
case EmailActionType.preview:
|
||||||
if (mailboxContain?.isDrafts == true) {
|
if (mailboxContain?.isDrafts == true) {
|
||||||
editDraftEmail(selectedEmail);
|
editDraftEmail(selectedEmail);
|
||||||
|
} else if (mailboxContain?.isTemplates == true) {
|
||||||
|
editAsNewEmail(selectedEmail);
|
||||||
} else {
|
} else {
|
||||||
previewEmail(selectedEmail);
|
previewEmail(selectedEmail);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -697,6 +697,8 @@ class ThreadView extends GetWidget<ThreadController>
|
|||||||
_markAsEmailSpamOrUnSpamContextMenuItemAction(context, email, mailboxContain),
|
_markAsEmailSpamOrUnSpamContextMenuItemAction(context, email, mailboxContain),
|
||||||
if (mailboxContain?.isArchive == false)
|
if (mailboxContain?.isArchive == false)
|
||||||
_archiveMessageContextMenuItemAction(context, email),
|
_archiveMessageContextMenuItemAction(context, email),
|
||||||
|
if (mailboxContain?.isDrafts == false)
|
||||||
|
_editAsNewEmailContextMenuItemAction(context, email),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,7 +772,7 @@ class ThreadView extends GetWidget<ThreadController>
|
|||||||
email,
|
email,
|
||||||
iconLeftPadding: controller.responsiveUtils.isMobile(context)
|
iconLeftPadding: controller.responsiveUtils.isMobile(context)
|
||||||
? const EdgeInsetsDirectional.only(start: 12, end: 16)
|
? const EdgeInsetsDirectional.only(start: 12, end: 16)
|
||||||
: const EdgeInsetsDirectional.only(start: 12),
|
: const EdgeInsetsDirectional.only(end: 12),
|
||||||
iconRightPadding: controller.responsiveUtils.isMobile(context)
|
iconRightPadding: controller.responsiveUtils.isMobile(context)
|
||||||
? const EdgeInsetsDirectional.only(start: 12)
|
? const EdgeInsetsDirectional.only(start: 12)
|
||||||
: EdgeInsets.zero
|
: EdgeInsets.zero
|
||||||
@@ -779,6 +781,35 @@ class ThreadView extends GetWidget<ThreadController>
|
|||||||
).build();
|
).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _editAsNewEmailContextMenuItemAction(
|
||||||
|
BuildContext context,
|
||||||
|
PresentationEmail email,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
EmailActionCupertinoActionSheetActionBuilder(
|
||||||
|
const Key('edit_as_new_email_action'),
|
||||||
|
SvgPicture.asset(
|
||||||
|
controller.imagePaths.icEdit,
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
colorFilter: AppColor.colorTextButton.asFilter()
|
||||||
|
),
|
||||||
|
AppLocalizations.of(context).editAsNewEmail,
|
||||||
|
email,
|
||||||
|
iconLeftPadding: controller.responsiveUtils.isMobile(context)
|
||||||
|
? const EdgeInsetsDirectional.only(start: 12, end: 16)
|
||||||
|
: const EdgeInsetsDirectional.only(end: 12),
|
||||||
|
iconRightPadding: controller.responsiveUtils.isMobile(context)
|
||||||
|
? const EdgeInsetsDirectional.only(start: 12)
|
||||||
|
: EdgeInsets.zero)
|
||||||
|
..onActionClick((email) {
|
||||||
|
popBack();
|
||||||
|
controller.editAsNewEmail(email);
|
||||||
|
})
|
||||||
|
).build();
|
||||||
|
}
|
||||||
|
|
||||||
List<PopupMenuEntry> _popupMenuActionTile(BuildContext context, PresentationEmail email) {
|
List<PopupMenuEntry> _popupMenuActionTile(BuildContext context, PresentationEmail email) {
|
||||||
final mailboxContain = email.mailboxContain;
|
final mailboxContain = email.mailboxContain;
|
||||||
|
|
||||||
@@ -788,6 +819,8 @@ class ThreadView extends GetWidget<ThreadController>
|
|||||||
_buildMarkAsSpamPopupMenuItem(context, email, mailboxContain),
|
_buildMarkAsSpamPopupMenuItem(context, email, mailboxContain),
|
||||||
if (mailboxContain?.isArchive == false)
|
if (mailboxContain?.isArchive == false)
|
||||||
_buildArchiveMessagePopupMenuItem(context, email),
|
_buildArchiveMessagePopupMenuItem(context, email),
|
||||||
|
if (mailboxContain?.isDrafts == false)
|
||||||
|
_buildEditAsNewEmailPopupMenuItem(AppLocalizations.of(context), email),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -865,6 +898,29 @@ class ThreadView extends GetWidget<ThreadController>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PopupMenuEntry _buildEditAsNewEmailPopupMenuItem(
|
||||||
|
AppLocalizations appLocalizations,
|
||||||
|
PresentationEmail email,
|
||||||
|
) {
|
||||||
|
return PopupMenuItem(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
child: popupItem(
|
||||||
|
controller.imagePaths.icEdit,
|
||||||
|
appLocalizations.editAsNewEmail,
|
||||||
|
colorIcon: AppColor.colorTextButton,
|
||||||
|
styleName: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 16,
|
||||||
|
color: Colors.black
|
||||||
|
),
|
||||||
|
onCallbackAction: () {
|
||||||
|
popBack();
|
||||||
|
controller.editAsNewEmail(email);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildMailboxActionProgressBanner(BuildContext context) {
|
Widget _buildMailboxActionProgressBanner(BuildContext context) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
return _MailboxActionProgressBanner(
|
return _MailboxActionProgressBanner(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"@@last_modified": "2025-01-14T12:52:43.828907",
|
"@@last_modified": "2025-01-20T18:53:16.325121",
|
||||||
"initializing_data": "Initializing data...",
|
"initializing_data": "Initializing data...",
|
||||||
"@initializing_data": {
|
"@initializing_data": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -4113,5 +4113,11 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"editAsNewEmail": "Edit as new email",
|
||||||
|
"@editAsNewEmail": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4321,4 +4321,10 @@ class AppLocalizations {
|
|||||||
name: 'downloadAttachmentInEMLPreviewWarningMessage',
|
name: 'downloadAttachmentInEMLPreviewWarningMessage',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
String get editAsNewEmail {
|
||||||
|
return Intl.message(
|
||||||
|
'Edit as new email',
|
||||||
|
name: 'editAsNewEmail',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum EmailActionType {
|
|||||||
composeFromFileShared,
|
composeFromFileShared,
|
||||||
composeFromEmailAddress,
|
composeFromEmailAddress,
|
||||||
composeFromMailtoUri,
|
composeFromMailtoUri,
|
||||||
|
composeFromPresentationEmail,
|
||||||
reopenComposerBrowser,
|
reopenComposerBrowser,
|
||||||
moveToTrash,
|
moveToTrash,
|
||||||
deletePermanently,
|
deletePermanently,
|
||||||
|
|||||||
Reference in New Issue
Block a user