diff --git a/core/lib/presentation/utils/theme_utils.dart b/core/lib/presentation/utils/theme_utils.dart index 1ca480027..3eb448c2c 100644 --- a/core/lib/presentation/utils/theme_utils.dart +++ b/core/lib/presentation/utils/theme_utils.dart @@ -75,7 +75,9 @@ class ThemeUtils { headlineSmall: TextStyle( fontFamily: ConstantsUI.fontApp, fontWeight: FontWeight.w600, - letterSpacing: 0.4, + fontSize: 24, + height: 32 / 24, + letterSpacing: 0.0, ), headlineLarge: TextStyle( fontFamily: ConstantsUI.fontApp, diff --git a/lib/features/base/widget/card_with_smart_interaction_overlay_view.dart b/lib/features/base/widget/card_with_smart_interaction_overlay_view.dart new file mode 100644 index 000000000..cc83b0619 --- /dev/null +++ b/lib/features/base/widget/card_with_smart_interaction_overlay_view.dart @@ -0,0 +1,121 @@ +import 'package:flutter/material.dart'; +import 'package:pointer_interceptor/pointer_interceptor.dart'; +import 'package:tmail_ui_user/features/base/widget/smart_interaction_widget.dart'; + +class CardWithSmartInteractionOverlayView extends StatefulWidget { + final Widget child; + final double overlayWidth; + final Widget Function(VoidCallback onClose) menuBuilder; + + const CardWithSmartInteractionOverlayView({ + super.key, + required this.child, + required this.menuBuilder, + this.overlayWidth = 361, + }); + + @override + State createState() => _CardWithSmartInteractionOverlayViewState(); +} + +class _CardWithSmartInteractionOverlayViewState + extends State + with SingleTickerProviderStateMixin { + final LayerLink _layerLink = LayerLink(); + OverlayEntry? _overlayEntry; + late AnimationController _controller; + bool _isDisposed = false; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(milliseconds: 200), + reverseDuration: const Duration(milliseconds: 100), + vsync: this, + ); + } + + void _showPopup() { + _overlayEntry = OverlayEntry( + builder: (context) => Stack( + children: [ + Positioned.fill( + child: PointerInterceptor( + child: GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: _removePopup, + ), + ), + ), + Positioned( + width: widget.overlayWidth, + child: CompositedTransformFollower( + link: _layerLink, + offset: const Offset(0, 40), + showWhenUnlinked: false, + child: FadeTransition( + opacity: CurvedAnimation( + parent: _controller, + curve: Curves.easeOut, + ), + child: ScaleTransition( + scale: CurvedAnimation( + parent: _controller, + curve: Curves.easeOutBack, + ), + alignment: Alignment.topLeft, + child: widget.menuBuilder(_removePopup), + ), + ), + ), + ), + ], + ), + ); + + Overlay.maybeOf(context)?.insert(_overlayEntry!); + _controller.forward(); + } + + Future _removePopup() async { + if (_overlayEntry == null) return; + + if (!_isDisposed && _controller.isAnimating == false) { + await _controller.reverse(); + } + + _overlayEntry?.remove(); + _overlayEntry = null; + } + + @override + void dispose() { + _isDisposed = true; + _controller.dispose(); + _overlayEntry?.remove(); + _overlayEntry = null; + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return CompositedTransformTarget( + link: _layerLink, + child: SmartInteractionWidget( + onRightMouseClickAction: ({RelativeRect? position}) => _togglePopup(), + onDoubleClickAction: ({RelativeRect? position}) => _togglePopup(), + onLongPressAction: _togglePopup, + child: widget.child, + ), + ); + } + + void _togglePopup() { + if (_overlayEntry == null) { + _showPopup(); + } else { + _removePopup(); + } + } +} diff --git a/lib/features/base/widget/smart_interaction_widget.dart b/lib/features/base/widget/smart_interaction_widget.dart index 7e2537a0c..97d2b83c4 100644 --- a/lib/features/base/widget/smart_interaction_widget.dart +++ b/lib/features/base/widget/smart_interaction_widget.dart @@ -5,12 +5,13 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart' hide OverlayEntry; import 'package:universal_html/html.dart' as html; -typedef OnRightMouseClickAction = void Function(RelativeRect position); -typedef OnDoubleClickAction = void Function(RelativeRect position); +typedef OnRightMouseClickAction = void Function({RelativeRect? position}); +typedef OnDoubleClickAction = void Function({RelativeRect? position}); typedef OnLongPressAction = void Function(); class SmartInteractionWidget extends StatefulWidget { final Widget child; + final bool usePosition; final OnRightMouseClickAction onRightMouseClickAction; final OnDoubleClickAction onDoubleClickAction; final OnLongPressAction onLongPressAction; @@ -21,6 +22,7 @@ class SmartInteractionWidget extends StatefulWidget { required this.onRightMouseClickAction, required this.onDoubleClickAction, required this.onLongPressAction, + this.usePosition = false, }); @override @@ -73,8 +75,12 @@ class _SmartInteractionWidgetState extends State { if (!mounted) return; - final relativeRect = _getRelativeRectFromOffset(context, localPosition); - widget.onRightMouseClickAction(relativeRect); + if (widget.usePosition) { + final relativeRect = _getRelativeRectFromOffset(context, localPosition); + widget.onRightMouseClickAction(position: relativeRect); + } else { + widget.onRightMouseClickAction(); + } } } @@ -113,12 +119,14 @@ class _SmartInteractionWidgetState extends State { } void _handleDoubleTap() { - if (_lastPointerEventOffset != null) { + if (widget.usePosition && _lastPointerEventOffset != null) { final relativeRect = _getRelativeRectFromOffset( context, _lastPointerEventOffset!, ); - widget.onDoubleClickAction(relativeRect); + widget.onDoubleClickAction(position: relativeRect); + } else { + widget.onDoubleClickAction(); } } @@ -127,19 +135,28 @@ class _SmartInteractionWidgetState extends State { @override Widget build(BuildContext context) { if (PlatformInfo.isWeb) { - return Listener( - key: _childKey, - onPointerDown: (event) { - if (event.kind == PointerDeviceKind.mouse || - event.kind == PointerDeviceKind.touch) { - _lastPointerEventOffset = event.position; - } - }, - child: GestureDetector( + if (widget.usePosition) { + return Listener( + key: _childKey, + onPointerDown: (event) { + if (event.kind == PointerDeviceKind.mouse || + event.kind == PointerDeviceKind.touch) { + _lastPointerEventOffset = event.position; + } + }, + child: GestureDetector( + onDoubleTap: _handleDoubleTap, + child: widget.child, + ), + ); + } else { + return GestureDetector( + key: _childKey, + behavior: HitTestBehavior.opaque, onDoubleTap: _handleDoubleTap, child: widget.child, - ), - ); + ); + } } else { return GestureDetector( onLongPress: _handleLongPress, diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 2cdd1dd6f..10d4623ef 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -1497,36 +1497,28 @@ class ComposerController extends BaseController } else { switch(prefixEmailAddress) { case PrefixEmailAddress.to: - if (mailboxDashBoardController.isPopupMenuOpened.isFalse) { - toAddressExpandMode.value = ExpandMode.COLLAPSE; - } + toAddressExpandMode.value = ExpandMode.COLLAPSE; final inputToEmail = toEmailAddressController.text; if (inputToEmail.trim().isNotEmpty) { autoCreateEmailTagForType(PrefixEmailAddress.to, inputToEmail); } break; case PrefixEmailAddress.cc: - if (mailboxDashBoardController.isPopupMenuOpened.isFalse) { - ccAddressExpandMode.value = ExpandMode.COLLAPSE; - } + ccAddressExpandMode.value = ExpandMode.COLLAPSE; final inputCcEmail = ccEmailAddressController.text; if (inputCcEmail.trim().isNotEmpty) { autoCreateEmailTagForType(PrefixEmailAddress.cc, inputCcEmail); } break; case PrefixEmailAddress.bcc: - if (mailboxDashBoardController.isPopupMenuOpened.isFalse) { - bccAddressExpandMode.value = ExpandMode.COLLAPSE; - } + bccAddressExpandMode.value = ExpandMode.COLLAPSE; final inputBccEmail = bccEmailAddressController.text; if (inputBccEmail.trim().isNotEmpty) { autoCreateEmailTagForType(PrefixEmailAddress.bcc, inputBccEmail); } break; case PrefixEmailAddress.replyTo: - if (mailboxDashBoardController.isPopupMenuOpened.isFalse) { - replyToAddressExpandMode.value = ExpandMode.COLLAPSE; - } + replyToAddressExpandMode.value = ExpandMode.COLLAPSE; final inputReplyToEmail = replyToEmailAddressController.text; if (inputReplyToEmail.trim().isNotEmpty) { autoCreateEmailTagForType(PrefixEmailAddress.replyTo, inputReplyToEmail); diff --git a/lib/features/composer/presentation/extensions/handle_edit_recipient_extension.dart b/lib/features/composer/presentation/extensions/handle_edit_recipient_extension.dart index 058856887..9c436ec76 100644 --- a/lib/features/composer/presentation/extensions/handle_edit_recipient_extension.dart +++ b/lib/features/composer/presentation/extensions/handle_edit_recipient_extension.dart @@ -1,17 +1,15 @@ +import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:model/email/prefix_email_address.dart'; import 'package:model/extensions/email_address_extension.dart'; import 'package:model/mailbox/expand_mode.dart'; -import 'package:tmail_ui_user/features/base/widget/popup_menu/popup_menu_item_action_widget.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/context_item_email_address_action_type.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart'; -import 'package:tmail_ui_user/features/composer/presentation/model/popup_menu_item_email_address_action_type.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_open_context_menu_extension.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; @@ -20,9 +18,9 @@ extension HandleEditRecipientExtension on ComposerController { BuildContext context, PrefixEmailAddress prefix, EmailAddress emailAddress, - RelativeRect? position, + EmailAddressActionType emailAddressActionType, ) { - if (position == null) { + if (PlatformInfo.isMobile) { clearFocus(context); final contextMenuActions = EmailAddressActionType.values @@ -47,34 +45,11 @@ extension HandleEditRecipientExtension on ComposerController { }, ); } else { - if (mailboxDashBoardController.isPopupMenuOpened.isTrue) return; - - final popupMenuItems = EmailAddressActionType.values.map((type) { - return PopupMenuItem( - padding: EdgeInsets.zero, - child: PopupMenuItemActionWidget( - menuAction: PopupMenuItemEmailAddressActionType( - type, - AppLocalizations.of(context), - imagePaths, - ), - menuActionClick: (menuAction) { - popBack(); - _handleEmailAddressActionTypeClick( - context, - menuAction.action, - prefix, - emailAddress, - ); - }, - ), - ); - }).toList(); - - mailboxDashBoardController.openPopupMenu( + _handleEmailAddressActionTypeClick( context, - position, - popupMenuItems, + emailAddressActionType, + prefix, + emailAddress, ); } } @@ -92,6 +67,9 @@ extension HandleEditRecipientExtension on ComposerController { case EmailAddressActionType.modify: _modifyEmailAddress(prefix, emailAddress); break; + case EmailAddressActionType.createRule: + _createRuleFromEmailAddress(emailAddress); + break; } } @@ -176,4 +154,10 @@ extension HandleEditRecipientExtension on ComposerController { break; } } + + Future _createRuleFromEmailAddress(EmailAddress emailAddress) async { + await mailboxDashBoardController.openCreateEmailRuleView( + emailAddress: emailAddress, + ); + } } \ No newline at end of file diff --git a/lib/features/composer/presentation/model/email_address_action_type.dart b/lib/features/composer/presentation/model/email_address_action_type.dart index 9be2d26ca..d83b15bd0 100644 --- a/lib/features/composer/presentation/model/email_address_action_type.dart +++ b/lib/features/composer/presentation/model/email_address_action_type.dart @@ -4,7 +4,8 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; enum EmailAddressActionType { copy, - modify; + modify, + createRule; String getContextMenuTitle(AppLocalizations appLocalizations) { switch(this) { @@ -12,6 +13,8 @@ enum EmailAddressActionType { return appLocalizations.copy; case EmailAddressActionType.modify: return appLocalizations.modifyEmailAddress; + case EmailAddressActionType.createRule: + return appLocalizations.createARule; } } @@ -21,6 +24,8 @@ enum EmailAddressActionType { return imagePaths.icCopy; case EmailAddressActionType.modify: return imagePaths.icEditRule; + case EmailAddressActionType.createRule: + return imagePaths.icQuickCreatingRule; } } } \ No newline at end of file diff --git a/lib/features/composer/presentation/view/edit_recipients_view.dart b/lib/features/composer/presentation/view/edit_recipients_view.dart new file mode 100644 index 000000000..f6c8341c6 --- /dev/null +++ b/lib/features/composer/presentation/view/edit_recipients_view.dart @@ -0,0 +1,159 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/extensions/string_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/theme_utils.dart'; +import 'package:core/presentation/views/button/tmail_button_widget.dart'; +import 'package:core/presentation/views/dialog/confirm_dialog_button.dart'; +import 'package:flutter/material.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:model/extensions/email_address_extension.dart'; +import 'package:pointer_interceptor/pointer_interceptor.dart'; +import 'package:tmail_ui_user/features/base/widget/email_address_with_copy_widget.dart'; +import 'package:tmail_ui_user/features/base/widget/user_avatar_builder.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class EditRecipientsView extends StatelessWidget { + final EmailAddress emailAddress; + final ImagePaths imagePaths; + final VoidCallback onCopyAction; + final VoidCallback onEditAction; + final VoidCallback onCreateRuleAction; + final VoidCallback onCloseAction; + + const EditRecipientsView({ + super.key, + required this.emailAddress, + required this.imagePaths, + required this.onCopyAction, + required this.onEditAction, + required this.onCreateRuleAction, + required this.onCloseAction, + }); + + @override + Widget build(BuildContext context) { + return PointerInterceptor( + child: Container( + width: 361, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(16)), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.15), + blurRadius: 8, + spreadRadius: 3, + offset: const Offset(0, 4), + ), + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 3, + offset: const Offset(0, 1), + ), + ], + ), + child: Stack( + children: [ + Padding( + padding: const EdgeInsetsDirectional.only( + start: 16, + end: 24, + top: 16, + bottom: 16, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + UserAvatarBuilder( + username: emailAddress.asString().firstLetterToUpperCase, + size: 67, + textStyle: ThemeUtils.textStyleInter500().copyWith( + fontSize: 33.5, + height: 50.25 / 33.5, + letterSpacing: 0.31, + color: AppColor.secondaryContrastText, + ), + padding: const EdgeInsetsDirectional.only(end: 21), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (emailAddress.displayName.isNotEmpty) + Padding( + padding: const EdgeInsetsDirectional.only(end: 12), + child: Text( + emailAddress.displayName, + style: Theme.of(context).textTheme.headlineSmall?.copyWith( + color: AppColor.textPrimary, + ), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + EmailAddressWithCopyWidget( + label: emailAddress.emailAddress, + copyLabelIcon: imagePaths.icCopy, + onCopyButtonAction: onCopyAction, + ), + ], + ), + ), + ], + ), + const SizedBox(height: 13), + Row( + children: [ + Expanded( + child: SizedBox( + width: double.infinity, + height: 48, + child: ConfirmDialogButton( + label: AppLocalizations.of(context).editEmail, + backgroundColor: AppColor.primaryMain, + textColor: Colors.white, + onTapAction: onEditAction, + ), + ), + ), + const SizedBox(width: 8), + Expanded( + child: SizedBox( + width: double.infinity, + height: 48, + child: ConfirmDialogButton( + label: AppLocalizations.of(context).createARule, + backgroundColor: Colors.white, + textColor: AppColor.primaryMain, + borderColor: AppColor.primaryMain, + onTapAction: onCreateRuleAction, + ), + ), + ), + ], + ) + ], + ), + ), + PositionedDirectional( + top: 0, + end: 0, + child: TMailButtonWidget.fromIcon( + icon: imagePaths.icCloseDialog, + iconSize: 24, + iconColor: AppColor.m3Tertiary, + padding: const EdgeInsets.all(10), + borderRadius: 24, + backgroundColor: Colors.transparent, + onTapActionCallback: onCloseAction, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart index 87b996ff6..6a575c9cf 100644 --- a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart @@ -20,6 +20,7 @@ import 'package:super_tag_editor/tag_editor.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/mail_address_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/draggable_email_address.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/prefix_recipient_state.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/suggestion_email_address.dart'; import 'package:tmail_ui_user/features/composer/presentation/styles/recipient_composer_widget_style.dart'; @@ -41,7 +42,7 @@ typedef OnEditRecipientAction = void Function( BuildContext context, PrefixEmailAddress prefix, EmailAddress emailAddress, - RelativeRect? position, + EmailAddressActionType emailAddressActionType, ); class RecipientComposerWidget extends StatefulWidget { diff --git a/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart b/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart index bbd0549e2..9cb713c4b 100644 --- a/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart @@ -10,9 +10,11 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:model/email/prefix_email_address.dart'; import 'package:model/extensions/email_address_extension.dart'; -import 'package:tmail_ui_user/features/base/widget/smart_interaction_widget.dart'; +import 'package:tmail_ui_user/features/base/widget/card_with_smart_interaction_overlay_view.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/draggable_email_address.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart'; import 'package:tmail_ui_user/features/composer/presentation/styles/recipient_tag_item_widget_style.dart'; +import 'package:tmail_ui_user/features/composer/presentation/view/edit_recipients_view.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/draggable_recipient_tag_widget.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_composer_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; @@ -56,16 +58,30 @@ class RecipientTagItemWidget extends StatelessWidget { @override Widget build(BuildContext context) { - Widget tagWidget = SmartInteractionWidget( - onRightMouseClickAction: (position) => _onEditRecipientAction( - context, - position: position, + Widget tagWidget = CardWithSmartInteractionOverlayView( + menuBuilder: (onClose) => EditRecipientsView( + emailAddress: currentEmailAddress, + imagePaths: imagePaths, + onCopyAction: () => _onEditRecipientAction( + context, + EmailAddressActionType.copy, + ), + onEditAction: () { + onClose(); + _onEditRecipientAction( + context, + EmailAddressActionType.modify, + ); + }, + onCreateRuleAction: () { + onClose(); + _onEditRecipientAction( + context, + EmailAddressActionType.createRule, + ); + }, + onCloseAction: onClose, ), - onDoubleClickAction: (position) => _onEditRecipientAction( - context, - position: position, - ), - onLongPressAction: () => _onEditRecipientAction(context), child: Chip( labelPadding: EdgeInsetsDirectional.symmetric( horizontal: 4, @@ -186,12 +202,15 @@ class RecipientTagItemWidget extends StatelessWidget { } } - void _onEditRecipientAction(BuildContext context, {RelativeRect? position}) { + void _onEditRecipientAction( + BuildContext context, + EmailAddressActionType emailAddressActionType, + ) { onEditRecipientAction?.call( context, prefix, currentEmailAddress, - position, + emailAddressActionType, ); } } \ No newline at end of file diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index a43583a56..fbbe63967 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -82,7 +82,7 @@ import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_ma import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_filter_for_folder.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/websocket/web_socket_message.dart'; @@ -1275,7 +1275,9 @@ class MailboxController extends BaseMailboxController goToCreateNewMailboxView(context, parentMailbox: mailbox); break; case MailboxActions.createFilter: - mailboxDashBoardController.openCreateEmailRuleView(mailbox); + mailboxDashBoardController.openCreateEmailRuleView( + presentationMailbox: mailbox, + ); break; case MailboxActions.recoverDeletedMessages: mailboxDashBoardController.gotoEmailRecovery(); diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index 59dd1bc04..b28db98ce 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -111,7 +111,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/cleanup_recent_search_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/delete_emails_in_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_clear_mailbox_extension.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_filter_for_folder.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_save_email_as_draft_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/initialize_app_language.dart'; diff --git a/lib/features/mailbox_dashboard/presentation/extensions/handle_create_filter_for_folder.dart b/lib/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart similarity index 90% rename from lib/features/mailbox_dashboard/presentation/extensions/handle_create_filter_for_folder.dart rename to lib/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart index 335537dfd..83079cef4 100644 --- a/lib/features/mailbox_dashboard/presentation/extensions/handle_create_filter_for_folder.dart +++ b/lib/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart @@ -2,6 +2,7 @@ import 'package:core/utils/platform_info.dart'; import 'package:dartz/dartz.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; @@ -14,11 +15,12 @@ import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/dialog_router.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; -extension HandleCreateFilterForFolder on MailboxDashBoardController { +extension HandleCreateNewRuleFilter on MailboxDashBoardController { - Future openCreateEmailRuleView( - PresentationMailbox presentationMailbox, - ) async { + Future openCreateEmailRuleView({ + PresentationMailbox? presentationMailbox, + EmailAddress? emailAddress, + }) async { final accountId = this.accountId.value; final session = sessionCurrent; @@ -38,6 +40,7 @@ extension HandleCreateFilterForFolder on MailboxDashBoardController { accountId, session, mailboxDestination: presentationMailbox, + emailAddress: emailAddress, ); final newRuleFilterRequest = PlatformInfo.isWeb diff --git a/lib/features/search/mailbox/presentation/search_mailbox_controller.dart b/lib/features/search/mailbox/presentation/search_mailbox_controller.dart index 706ebcca8..1573e55a2 100644 --- a/lib/features/search/mailbox/presentation/search_mailbox_controller.dart +++ b/lib/features/search/mailbox/presentation/search_mailbox_controller.dart @@ -64,7 +64,7 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_na import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_filter_for_folder.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_new_rule_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/search/mailbox/presentation/search_mailbox_bindings.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; @@ -349,7 +349,9 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa goToCreateNewMailboxView(context, parentMailbox: mailbox); break; case MailboxActions.createFilter: - dashboardController.openCreateEmailRuleView(mailbox); + dashboardController.openCreateEmailRuleView( + presentationMailbox: mailbox, + ); break; case MailboxActions.recoverDeletedMessages: dashboardController.gotoEmailRecovery(); diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 81bc5f526..71d6e67da 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2025-07-23T15:51:45.812311", + "@@last_modified": "2025-07-24T16:57:08.573149", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -4613,5 +4613,17 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "editEmail": "Edit email", + "@editEmail": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "createARule": "Create a rule", + "@createARule": { + "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 190a0d31e..372f07ca1 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -4862,4 +4862,18 @@ class AppLocalizations { name: 'modifyEmailAddress', ); } + + String get editEmail { + return Intl.message( + 'Edit email', + name: 'editEmail', + ); + } + + String get createARule { + return Intl.message( + 'Create a rule', + name: 'createARule', + ); + } }