diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 65ab024418..26381cae62 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -594,6 +594,19 @@ class ComposerController extends BaseController ); 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: _initEmailAddress( presentationEmail: arguments.presentationEmail!, diff --git a/lib/features/composer/presentation/extensions/email_action_type_extension.dart b/lib/features/composer/presentation/extensions/email_action_type_extension.dart index b58370c9de..09c773a99a 100644 --- a/lib/features/composer/presentation/extensions/email_action_type_extension.dart +++ b/lib/features/composer/presentation/extensions/email_action_type_extension.dart @@ -31,6 +31,7 @@ extension EmailActionTypeExtension on EmailActionType { case EmailActionType.editDraft: case EmailActionType.editSendingEmail: case EmailActionType.reopenComposerBrowser: + case EmailActionType.composeFromPresentationEmail: return subject; default: return ''; @@ -143,6 +144,8 @@ extension EmailActionTypeExtension on EmailActionType { return imagePaths.icMailboxArchived; case EmailActionType.downloadMessageAsEML: return imagePaths.icDownloadAttachment; + case EmailActionType.composeFromPresentationEmail: + return imagePaths.icEdit; default: return ''; } @@ -164,6 +167,8 @@ extension EmailActionTypeExtension on EmailActionType { return AppLocalizations.of(context).archiveMessage; case EmailActionType.downloadMessageAsEML: return AppLocalizations.of(context).downloadMessageAsEML; + case EmailActionType.composeFromPresentationEmail: + return AppLocalizations.of(context).editAsNewEmail; default: return ''; } diff --git a/lib/features/composer/presentation/view/mobile/mobile_editor_view.dart b/lib/features/composer/presentation/view/mobile/mobile_editor_view.dart index 1859f9026f..af0a8d92b3 100644 --- a/lib/features/composer/presentation/view/mobile/mobile_editor_view.dart +++ b/lib/features/composer/presentation/view/mobile/mobile_editor_view.dart @@ -50,6 +50,7 @@ class MobileEditorView extends StatelessWidget with EditorViewMixin { case EmailActionType.reopenComposerBrowser: case EmailActionType.composeFromMailtoUri: case EmailActionType.composeFromUnsubscribeMailtoLink: + case EmailActionType.composeFromPresentationEmail: if (contentViewState == null) { return const SizedBox.shrink(); } @@ -64,9 +65,12 @@ class MobileEditorView extends StatelessWidget with EditorViewMixin { if (success is GetEmailContentLoading) { return const CupertinoLoadingWidget(padding: EdgeInsets.all(16.0)); } else { - var newContent = success is GetEmailContentSuccess - ? success.htmlEmailContent - : HtmlExtension.editorStartTags; + var newContent = HtmlExtension.editorStartTags; + if (success is GetEmailContentSuccess) { + newContent = success.htmlEmailContent; + } else if (success is GetEmailContentFromCacheSuccess) { + newContent = success.htmlEmailContent; + } if (newContent.isEmpty) { newContent = HtmlExtension.editorStartTags; } diff --git a/lib/features/composer/presentation/view/web/web_editor_view.dart b/lib/features/composer/presentation/view/web/web_editor_view.dart index e06e3e84c2..40a21c16c9 100644 --- a/lib/features/composer/presentation/view/web/web_editor_view.dart +++ b/lib/features/composer/presentation/view/web/web_editor_view.dart @@ -94,6 +94,7 @@ class WebEditorView extends StatelessWidget with EditorViewMixin { case EmailActionType.reopenComposerBrowser: case EmailActionType.composeFromUnsubscribeMailtoLink: case EmailActionType.composeFromMailtoUri: + case EmailActionType.composeFromPresentationEmail: if (contentViewState == null) { return const SizedBox.shrink(); } diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart index 92b83c34d2..7c7b738247 100644 --- a/lib/features/email/presentation/controller/single_email_controller.dart +++ b/lib/features/email/presentation/controller/single_email_controller.dart @@ -1186,6 +1186,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin { case EmailActionType.downloadMessageAsEML: _downloadMessageAsEML(presentationEmail); break; + case EmailActionType.composeFromPresentationEmail: + _composeFromPresentationEmail(presentationEmail); + break; default: break; } @@ -1871,6 +1874,14 @@ class SingleEmailController extends BaseController with AppLoaderMixin { downloadAttachmentForWeb(emlAttachment); } + void _composeFromPresentationEmail(PresentationEmail presentationEmail) { + if (accountId == null || session == null) return; + + mailboxDashBoardController.goToComposer( + ComposerArguments.fromPresentationEmail(presentationEmail), + ); + } + void handleDownloadAttachmentAction(BuildContext context, Attachment attachment) { if (PlatformInfo.isWeb) { downloadAttachmentForWeb(attachment); diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index 3f111a6209..7ca9e793f2 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -504,7 +504,8 @@ class EmailView extends GetWidget { if (mailboxContain?.isArchive == false) EmailActionType.archiveMessage, if (PlatformInfo.isWeb && PlatformInfo.isCanvasKit) - EmailActionType.downloadMessageAsEML + EmailActionType.downloadMessageAsEML, + EmailActionType.composeFromPresentationEmail, ]; if (position == null) { diff --git a/lib/features/email/presentation/model/composer_arguments.dart b/lib/features/email/presentation/model/composer_arguments.dart index 479d0e617a..dbc63963e5 100644 --- a/lib/features/email/presentation/model/composer_arguments.dart +++ b/lib/features/email/presentation/model/composer_arguments.dart @@ -100,6 +100,12 @@ class ComposerArguments extends RouterArguments { emailActionType: EmailActionType.editDraft, presentationEmail: presentationEmail, ); + + factory ComposerArguments.fromPresentationEmail(PresentationEmail presentationEmail) => + ComposerArguments( + emailActionType: EmailActionType.composeFromPresentationEmail, + presentationEmail: presentationEmail, + ); factory ComposerArguments.fromSessionStorageBrowser(ComposerCache composerCache) => ComposerArguments( diff --git a/lib/features/search/email/presentation/search_email_view.dart b/lib/features/search/email/presentation/search_email_view.dart index 262e6deb75..2e95dbe37e 100644 --- a/lib/features/search/email/presentation/search_email_view.dart +++ b/lib/features/search/email/presentation/search_email_view.dart @@ -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' 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/routes/route_navigation.dart'; class SearchEmailView extends GetWidget with AppLoaderMixin { @@ -746,6 +747,8 @@ class SearchEmailView extends GetWidget List _contextMenuActionTile(BuildContext context, PresentationEmail email) { return [ _markAsEmailSpamOrUnSpamAction(context, email), + if (email.mailboxContain?.isDrafts == false) + _editAsNewEmailContextMenuItemAction(context, email), ]; } @@ -778,11 +781,44 @@ class SearchEmailView extends GetWidget .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 _popupMenuActionTile(BuildContext context, PresentationEmail email) { return [ PopupMenuItem( padding: const EdgeInsets.symmetric(horizontal: 8), child: _markAsEmailSpamOrUnSpamAction(context, email)), + if (email.mailboxContain?.isDrafts == false) + PopupMenuItem( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: _editAsNewEmailContextMenuItemAction(context, email)), ]; } diff --git a/lib/features/thread/presentation/mixin/email_action_controller.dart b/lib/features/thread/presentation/mixin/email_action_controller.dart index 64e4b1e724..280337c0ca 100644 --- a/lib/features/thread/presentation/mixin/email_action_controller.dart +++ b/lib/features/thread/presentation/mixin/email_action_controller.dart @@ -43,6 +43,12 @@ mixin EmailActionController { mailboxDashBoardController.goToComposer(ComposerArguments.editDraftEmail(presentationEmail)); } + void editAsNewEmail(PresentationEmail presentationEmail) { + mailboxDashBoardController.goToComposer( + ComposerArguments.fromPresentationEmail(presentationEmail), + ); + } + void previewEmail(PresentationEmail presentationEmail) { log('EmailActionController::previewEmail():presentationEmailId: ${presentationEmail.id}'); mailboxDashBoardController.openEmailDetailedView(presentationEmail); diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index 6ab3605c1d..acb1556ca5 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -1127,6 +1127,9 @@ class ThreadController extends BaseController with EmailActionController { case EmailActionType.preview: if (mailboxContain?.isDrafts == true) { editDraftEmail(selectedEmail); + } else if (mailboxContain?.isTemplates == true) { + popBack(); + editAsNewEmail(selectedEmail); } else { previewEmail(selectedEmail); } diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index 5d8924ac2f..95e8ec5e1b 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -697,6 +697,8 @@ class ThreadView extends GetWidget _markAsEmailSpamOrUnSpamContextMenuItemAction(context, email, mailboxContain), if (mailboxContain?.isArchive == false) _archiveMessageContextMenuItemAction(context, email), + if (mailboxContain?.isDrafts == false) + _editAsNewEmailContextMenuItemAction(context, email), ]; } @@ -770,7 +772,7 @@ class ThreadView extends GetWidget email, iconLeftPadding: controller.responsiveUtils.isMobile(context) ? const EdgeInsetsDirectional.only(start: 12, end: 16) - : const EdgeInsetsDirectional.only(start: 12), + : const EdgeInsetsDirectional.only(end: 12), iconRightPadding: controller.responsiveUtils.isMobile(context) ? const EdgeInsetsDirectional.only(start: 12) : EdgeInsets.zero @@ -779,6 +781,35 @@ class ThreadView extends GetWidget ).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 _popupMenuActionTile(BuildContext context, PresentationEmail email) { final mailboxContain = email.mailboxContain; @@ -788,6 +819,8 @@ class ThreadView extends GetWidget _buildMarkAsSpamPopupMenuItem(context, email, mailboxContain), if (mailboxContain?.isArchive == false) _buildArchiveMessagePopupMenuItem(context, email), + if (mailboxContain?.isDrafts == false) + _buildEditAsNewEmailPopupMenuItem(AppLocalizations.of(context), email), ]; } @@ -865,6 +898,29 @@ class ThreadView extends GetWidget ); } + 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) { return Obx(() { return _MailboxActionProgressBanner( diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 872b3c5611..aa823f9164 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -4211,5 +4211,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "editAsNewEmail": "Edit as new email", + "@editAsNewEmail": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 6d1666dfbc..6d42751ebd 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -4422,4 +4422,10 @@ class AppLocalizations { ); } + String get editAsNewEmail { + return Intl.message( + 'Edit as new email', + name: 'editAsNewEmail', + ); + } } diff --git a/model/lib/email/email_action_type.dart b/model/lib/email/email_action_type.dart index a125b4c3ae..84bed58967 100644 --- a/model/lib/email/email_action_type.dart +++ b/model/lib/email/email_action_type.dart @@ -15,6 +15,7 @@ enum EmailActionType { composeFromFileShared, composeFromEmailAddress, composeFromMailtoUri, + composeFromPresentationEmail, reopenComposerBrowser, moveToTrash, deletePermanently,