TF-2666 Apply new UI for edit recipient card on mobile

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-07-25 12:59:09 +07:00
committed by Dat H. Pham
parent 7f7dba14fb
commit 84616f210c
17 changed files with 503 additions and 254 deletions
@@ -102,6 +102,8 @@ class ThemeUtils {
fontFamily: ConstantsUI.fontApp, fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
letterSpacing: 0.1, letterSpacing: 0.1,
fontSize: 14,
height: 20 / 14,
), ),
); );
} }
@@ -1,3 +1,4 @@
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/widget/smart_interaction_widget.dart'; import 'package:tmail_ui_user/features/base/widget/smart_interaction_widget.dart';
@@ -6,12 +7,14 @@ class CardWithSmartInteractionOverlayView extends StatefulWidget {
final Widget child; final Widget child;
final double overlayWidth; final double overlayWidth;
final Widget Function(VoidCallback onClose) menuBuilder; final Widget Function(VoidCallback onClose) menuBuilder;
final VoidCallback? onClearFocusAction;
const CardWithSmartInteractionOverlayView({ const CardWithSmartInteractionOverlayView({
super.key, super.key,
required this.child, required this.child,
required this.menuBuilder, required this.menuBuilder,
this.overlayWidth = 361, this.overlayWidth = 361,
this.onClearFocusAction,
}); });
@override @override
@@ -52,7 +55,10 @@ class _CardWithSmartInteractionOverlayViewState
width: widget.overlayWidth, width: widget.overlayWidth,
child: CompositedTransformFollower( child: CompositedTransformFollower(
link: _layerLink, link: _layerLink,
offset: const Offset(0, 40), offset: Offset(
0,
PlatformInfo.isWeb ? 40 : 50,
),
showWhenUnlinked: false, showWhenUnlinked: false,
child: FadeTransition( child: FadeTransition(
opacity: CurvedAnimation( opacity: CurvedAnimation(
@@ -112,6 +118,8 @@ class _CardWithSmartInteractionOverlayViewState
} }
void _togglePopup() { void _togglePopup() {
widget.onClearFocusAction?.call();
if (_overlayEntry == null) { if (_overlayEntry == null) {
_showPopup(); _showPopup();
} else { } else {
@@ -142,6 +142,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction, onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
)), )),
Obx(() { Obx(() {
if (controller.ccRecipientState.value == PrefixRecipientState.enabled) { if (controller.ccRecipientState.value == PrefixRecipientState.enabled) {
@@ -166,6 +167,7 @@ class ComposerView extends GetWidget<ComposerController> {
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
); );
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
@@ -194,6 +196,7 @@ class ComposerView extends GetWidget<ComposerController> {
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
); );
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
@@ -222,6 +225,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction, onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
); );
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
@@ -346,6 +350,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction, onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.ccRecipientState.value == PrefixRecipientState.enabled) if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -369,6 +374,7 @@ class ComposerView extends GetWidget<ComposerController> {
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.bccRecipientState.value == PrefixRecipientState.enabled) if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -392,6 +398,7 @@ class ComposerView extends GetWidget<ComposerController> {
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled) if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -414,6 +421,7 @@ class ComposerView extends GetWidget<ComposerController> {
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
], ],
)), )),
@@ -122,6 +122,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.ccRecipientState.value == PrefixRecipientState.enabled) if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -148,6 +149,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.bccRecipientState.value == PrefixRecipientState.enabled) if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -174,6 +176,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled) if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -199,6 +202,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
], ],
)), )),
@@ -395,6 +399,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.ccRecipientState.value == PrefixRecipientState.enabled) if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -421,6 +426,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.bccRecipientState.value == PrefixRecipientState.enabled) if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -447,6 +453,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled) if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -472,6 +479,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
], ],
)), )),
@@ -711,6 +719,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.ccRecipientState.value == PrefixRecipientState.enabled) if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -737,6 +746,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.bccRecipientState.value == PrefixRecipientState.enabled) if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -763,6 +773,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled) if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget( RecipientComposerWidget(
@@ -788,6 +799,7 @@ class ComposerView extends GetWidget<ComposerController> {
onFocusNextAddressAction: controller.handleFocusNextAddressAction, onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
onEditRecipientAction: controller.onEditRecipient, onEditRecipientAction: controller.onEditRecipient,
onClearFocusAction: controller.onClearFocusAction,
), ),
], ],
)), )),
@@ -7,11 +7,9 @@ import 'package:model/email/prefix_email_address.dart';
import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/email_address_extension.dart';
import 'package:model/mailbox/expand_mode.dart'; import 'package:model/mailbox/expand_mode.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.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/email_address_action_type.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_create_new_rule_filter.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';
extension HandleEditRecipientExtension on ComposerController { extension HandleEditRecipientExtension on ComposerController {
void onEditRecipient( void onEditRecipient(
@@ -20,38 +18,12 @@ extension HandleEditRecipientExtension on ComposerController {
EmailAddress emailAddress, EmailAddress emailAddress,
EmailAddressActionType emailAddressActionType, EmailAddressActionType emailAddressActionType,
) { ) {
if (PlatformInfo.isMobile) { _handleEmailAddressActionTypeClick(
clearFocus(context); context,
emailAddressActionType,
final contextMenuActions = EmailAddressActionType.values prefix,
.map((action) => ContextItemEmailAddressActionType( emailAddress,
action, );
AppLocalizations.of(context),
imagePaths
))
.toList();
openBottomSheetContextMenuAction(
context: context,
itemActions: contextMenuActions,
onContextMenuActionClick: (menuAction) {
popBack();
_handleEmailAddressActionTypeClick(
context,
menuAction.action,
prefix,
emailAddress,
);
},
);
} else {
_handleEmailAddressActionTypeClick(
context,
emailAddressActionType,
prefix,
emailAddress,
);
}
} }
void _handleEmailAddressActionTypeClick( void _handleEmailAddressActionTypeClick(
@@ -64,7 +36,7 @@ extension HandleEditRecipientExtension on ComposerController {
case EmailAddressActionType.copy: case EmailAddressActionType.copy:
_copyEmailAddress(context, emailAddress); _copyEmailAddress(context, emailAddress);
break; break;
case EmailAddressActionType.modify: case EmailAddressActionType.edit:
_modifyEmailAddress(prefix, emailAddress); _modifyEmailAddress(prefix, emailAddress);
break; break;
case EmailAddressActionType.createRule: case EmailAddressActionType.createRule:
@@ -151,4 +123,10 @@ extension HandleEditRecipientExtension on ComposerController {
emailAddress: emailAddress, emailAddress: emailAddress,
); );
} }
void onClearFocusAction() {
if (PlatformInfo.isMobile) {
htmlEditorApi?.unfocus();
}
}
} }
@@ -1,22 +0,0 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class ContextItemEmailAddressActionType
extends ContextMenuItemActionRequiredIcon<EmailAddressActionType> {
final AppLocalizations appLocalizations;
final ImagePaths imagePaths;
ContextItemEmailAddressActionType(
super.action,
this.appLocalizations,
this.imagePaths,
);
@override
String get actionIcon => action.getContextMenuIcon(imagePaths);
@override
String get actionName => action.getContextMenuTitle(appLocalizations);
}
@@ -4,15 +4,15 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum EmailAddressActionType { enum EmailAddressActionType {
copy, copy,
modify, edit,
createRule; createRule;
String getContextMenuTitle(AppLocalizations appLocalizations) { String getContextMenuTitle(AppLocalizations appLocalizations) {
switch(this) { switch(this) {
case EmailAddressActionType.copy: case EmailAddressActionType.copy:
return appLocalizations.copy; return appLocalizations.copy;
case EmailAddressActionType.modify: case EmailAddressActionType.edit:
return appLocalizations.modifyEmailAddress; return appLocalizations.edit;
case EmailAddressActionType.createRule: case EmailAddressActionType.createRule:
return appLocalizations.createARule; return appLocalizations.createARule;
} }
@@ -22,7 +22,7 @@ enum EmailAddressActionType {
switch(this) { switch(this) {
case EmailAddressActionType.copy: case EmailAddressActionType.copy:
return imagePaths.icCopy; return imagePaths.icCopy;
case EmailAddressActionType.modify: case EmailAddressActionType.edit:
return imagePaths.icEditRule; return imagePaths.icEditRule;
case EmailAddressActionType.createRule: case EmailAddressActionType.createRule:
return imagePaths.icQuickCreatingRule; return imagePaths.icQuickCreatingRule;
@@ -1,22 +0,0 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:tmail_ui_user/features/base/model/popup_menu_item_action.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class PopupMenuItemEmailAddressActionType
extends PopupMenuItemActionRequiredIcon<EmailAddressActionType> {
final AppLocalizations appLocalizations;
final ImagePaths imagePaths;
PopupMenuItemEmailAddressActionType(
super.action,
this.appLocalizations,
this.imagePaths,
);
@override
String get actionIcon => action.getContextMenuIcon(imagePaths);
@override
String get actionName => action.getContextMenuTitle(appLocalizations);
}
@@ -1,20 +1,14 @@
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/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:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/view/mobile/mobile_edit_recipients_view.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:tmail_ui_user/features/composer/presentation/view/web/desktop_edit_recipients_view.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 { class EditRecipientsView extends StatelessWidget {
final EmailAddress emailAddress; final EmailAddress emailAddress;
final ImagePaths imagePaths; final ImagePaths imagePaths;
final bool isMobile;
final double width;
final VoidCallback onCopyAction; final VoidCallback onCopyAction;
final VoidCallback onEditAction; final VoidCallback onEditAction;
final VoidCallback onCreateRuleAction; final VoidCallback onCreateRuleAction;
@@ -24,6 +18,8 @@ class EditRecipientsView extends StatelessWidget {
super.key, super.key,
required this.emailAddress, required this.emailAddress,
required this.imagePaths, required this.imagePaths,
required this.isMobile,
required this.width,
required this.onCopyAction, required this.onCopyAction,
required this.onEditAction, required this.onEditAction,
required this.onCreateRuleAction, required this.onCreateRuleAction,
@@ -32,135 +28,25 @@ class EditRecipientsView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PointerInterceptor( if (isMobile) {
child: Container( return MobileEditRecipientsView(
width: 361, emailAddress: emailAddress,
decoration: BoxDecoration( imagePaths: imagePaths,
borderRadius: const BorderRadius.all(Radius.circular(16)), width: width,
color: Colors.white, onCopyAction: onCopyAction,
boxShadow: [ onEditAction: onEditAction,
BoxShadow( onCreateRuleAction: onCreateRuleAction,
color: Colors.black.withOpacity(0.15), );
blurRadius: 8, } else {
spreadRadius: 3, return DesktopEditRecipientsView(
offset: const Offset(0, 4), emailAddress: emailAddress,
), imagePaths: imagePaths,
BoxShadow( width: width,
color: Colors.black.withOpacity(0.3), onCopyAction: onCopyAction,
blurRadius: 3, onEditAction: onEditAction,
offset: const Offset(0, 1), onCreateRuleAction: onCreateRuleAction,
), onCloseAction: onCloseAction,
], );
), }
child: Stack(
children: [
Padding(
padding: const EdgeInsetsDirectional.only(
start: 16,
end: 16,
top: 21,
bottom: 21,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
UserAvatarBuilder(
username: emailAddress.asString().firstLetterToUpperCase,
size: 42,
textStyle: ThemeUtils.textStyleInter600().copyWith(
fontSize: 16,
height: 22 / 16,
letterSpacing: -0.41,
color: Colors.white,
),
padding: const EdgeInsetsDirectional.only(end: 16),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (emailAddress.displayName.isNotEmpty)
Padding(
padding: const EdgeInsetsDirectional.only(end: 24),
child: Text(
emailAddress.displayName,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: AppColor.textPrimary,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
EmailAddressWithCopyWidget(
label: emailAddress.emailAddress,
copyLabelIcon: imagePaths.icCopy,
textStyle: ThemeUtils.textStyleBodyBody2(
color: AppColor.steelGray400,
),
copyIconMargin: const EdgeInsetsDirectional.only(
start: 7,
),
copyIconColor: AppColor.steelGray400,
onCopyButtonAction: onCopyAction,
),
],
),
),
],
),
const SizedBox(height: 12),
Row(
children: [
Flexible(
child: Container(
constraints: const BoxConstraints(minWidth: 127),
margin: const EdgeInsetsDirectional.only(end: 8),
height: 36,
child: ConfirmDialogButton(
label: AppLocalizations.of(context).editEmail,
backgroundColor: AppColor.primaryMain,
textColor: Colors.white,
onTapAction: onEditAction,
),
),
),
Flexible(
child: Container(
constraints: const BoxConstraints(minWidth: 134),
height: 36,
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,
),
),
],
),
),
);
} }
} }
@@ -0,0 +1,153 @@
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: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/user_avatar_builder.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/email_address_action_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class MobileEditRecipientsView extends StatelessWidget {
final EmailAddress emailAddress;
final ImagePaths imagePaths;
final double width;
final VoidCallback onCopyAction;
final VoidCallback onEditAction;
final VoidCallback onCreateRuleAction;
const MobileEditRecipientsView({
super.key,
required this.emailAddress,
required this.imagePaths,
required this.width,
required this.onCopyAction,
required this.onEditAction,
required this.onCreateRuleAction,
});
@override
Widget build(BuildContext context) {
return PointerInterceptor(
child: Container(
width: width,
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),
),
],
),
padding: const EdgeInsetsDirectional.only(bottom: 6),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsetsDirectional.symmetric(
horizontal: 14,
vertical: 12,
),
child: Row(
children: [
UserAvatarBuilder(
username: emailAddress.asString().firstLetterToUpperCase,
size: 28,
textStyle: ThemeUtils.textStyleInter600().copyWith(
fontSize: 11,
height: 22 / 11,
letterSpacing: -0.41,
color: Colors.white,
),
padding: const EdgeInsetsDirectional.only(end: 16),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (emailAddress.displayName.isNotEmpty)
Padding(
padding: const EdgeInsetsDirectional.only(end: 24),
child: Text(
emailAddress.displayName,
style: Theme.of(context)
.textTheme
.titleSmall
?.copyWith(
color: AppColor.textPrimary,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Text(
emailAddress.emailAddress,
style: ThemeUtils.textStyleInter400.copyWith(
color: AppColor.steelGray400,
fontSize: 11,
height: 14 / 11,
letterSpacing: 0.0,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
],
),
),
],
),
),
..._buildActions(AppLocalizations.of(context)),
],
),
),
);
}
List<Widget> _buildActions(AppLocalizations appLocalizations) {
return EmailAddressActionType.values.map((type) {
return Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: AppColor.gray424244.withOpacity(0.12),
width: 1,
),
),
),
child: EmailAddressActionWidget(
imagePaths: imagePaths,
actionType: type,
onClick: _handleEmailAddressActionTypeClick,
),
);
}).toList();
}
void _handleEmailAddressActionTypeClick(EmailAddressActionType actionType) {
switch (actionType) {
case EmailAddressActionType.copy:
onCopyAction();
break;
case EmailAddressActionType.edit:
onEditAction();
break;
case EmailAddressActionType.createRule:
onCreateRuleAction();
break;
}
}
}
@@ -0,0 +1,168 @@
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 DesktopEditRecipientsView extends StatelessWidget {
final EmailAddress emailAddress;
final ImagePaths imagePaths;
final double width;
final VoidCallback onCopyAction;
final VoidCallback onEditAction;
final VoidCallback onCreateRuleAction;
final VoidCallback onCloseAction;
const DesktopEditRecipientsView({
super.key,
required this.emailAddress,
required this.imagePaths,
required this.width,
required this.onCopyAction,
required this.onEditAction,
required this.onCreateRuleAction,
required this.onCloseAction,
});
@override
Widget build(BuildContext context) {
return PointerInterceptor(
child: Container(
width: width,
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: 16,
top: 21,
bottom: 21,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
UserAvatarBuilder(
username: emailAddress.asString().firstLetterToUpperCase,
size: 42,
textStyle: ThemeUtils.textStyleInter600().copyWith(
fontSize: 16,
height: 22 / 16,
letterSpacing: -0.41,
color: Colors.white,
),
padding: const EdgeInsetsDirectional.only(end: 16),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (emailAddress.displayName.isNotEmpty)
Padding(
padding: const EdgeInsetsDirectional.only(end: 24),
child: Text(
emailAddress.displayName,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: AppColor.textPrimary,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
EmailAddressWithCopyWidget(
label: emailAddress.emailAddress,
copyLabelIcon: imagePaths.icCopy,
textStyle: ThemeUtils.textStyleBodyBody2(
color: AppColor.steelGray400,
),
copyIconMargin: const EdgeInsetsDirectional.only(
start: 7,
),
copyIconColor: AppColor.steelGray400,
onCopyButtonAction: onCopyAction,
),
],
),
),
],
),
const SizedBox(height: 12),
Row(
children: [
Flexible(
child: Container(
constraints: const BoxConstraints(minWidth: 127),
margin: const EdgeInsetsDirectional.only(end: 8),
height: 36,
child: ConfirmDialogButton(
label: AppLocalizations.of(context).editEmail,
backgroundColor: AppColor.primaryMain,
textColor: Colors.white,
onTapAction: onEditAction,
),
),
),
Flexible(
child: Container(
constraints: const BoxConstraints(minWidth: 134),
height: 36,
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,
),
),
],
),
),
);
}
}
@@ -0,0 +1,63 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnClickEmailAddressAction = void Function(EmailAddressActionType actionType);
class EmailAddressActionWidget extends StatelessWidget {
final ImagePaths imagePaths;
final EmailAddressActionType actionType;
final OnClickEmailAddressAction onClick;
const EmailAddressActionWidget({
super.key,
required this.imagePaths,
required this.actionType,
required this.onClick,
});
@override
Widget build(BuildContext context) {
return Material(
type: MaterialType.transparency,
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () => onClick(actionType),
child: Container(
width: double.infinity,
height: 36,
padding: const EdgeInsets.symmetric(horizontal: 14),
child: Row(
children: [
SvgPicture.asset(
actionType.getContextMenuIcon(imagePaths),
width: 20,
height: 20,
colorFilter: AppColor.steelGrayA540.asFilter(),
fit: BoxFit.fill,
),
const SizedBox(width: 22),
Expanded(
child: Text(
actionType.getContextMenuTitle(AppLocalizations.of(context)),
style: ThemeUtils.textStyleInter400.copyWith(
fontSize: 14,
height: 21.01 / 14,
letterSpacing: -0.15,
color: AppColor.gray424244.withOpacity(0.9),
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
),
);
}
}
@@ -12,6 +12,7 @@ import 'package:core/utils/platform_info.dart';
import 'package:core/utils/string_convert.dart'; import 'package:core/utils/string_convert.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/email/prefix_email_address.dart'; import 'package:model/email/prefix_email_address.dart';
import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/email_address_extension.dart';
@@ -77,6 +78,7 @@ class RecipientComposerWidget extends StatefulWidget {
final bool isTestingForWeb; final bool isTestingForWeb;
final int minInputLengthAutocomplete; final int minInputLengthAutocomplete;
final String? composerId; final String? composerId;
final VoidCallback? onClearFocusAction;
const RecipientComposerWidget({ const RecipientComposerWidget({
super.key, super.key,
@@ -110,6 +112,7 @@ class RecipientComposerWidget extends StatefulWidget {
this.onEnableAllRecipientsInputAction, this.onEnableAllRecipientsInputAction,
this.focusNodeKeyboard, this.focusNodeKeyboard,
this.onEditRecipientAction, this.onEditRecipientAction,
this.onClearFocusAction,
}); });
@override @override
@@ -118,6 +121,8 @@ class RecipientComposerWidget extends StatefulWidget {
class _RecipientComposerWidgetState extends State<RecipientComposerWidget> { class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
final _responsiveUtils = Get.find<ResponsiveUtils>();
Timer? _gapBetweenTagChangedAndFindSuggestion; Timer? _gapBetweenTagChangedAndFindSuggestion;
bool _lastTagFocused = false; bool _lastTagFocused = false;
bool _isDragging = false; bool _isDragging = false;
@@ -224,9 +229,11 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
isCollapsed: _isCollapse, isCollapsed: _isCollapse,
isLatestTagFocused: _lastTagFocused, isLatestTagFocused: _lastTagFocused,
maxWidth: widget.maxWidth, maxWidth: widget.maxWidth,
isMobile: _responsiveUtils.isMobile(context),
onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter), onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter),
onShowFullAction: widget.onShowFullListEmailAddressAction, onShowFullAction: widget.onShowFullListEmailAddressAction,
onEditRecipientAction: widget.onEditRecipientAction, onEditRecipientAction: widget.onEditRecipientAction,
onClearFocusAction: widget.onClearFocusAction,
); );
}, },
onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter),
@@ -317,9 +324,11 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
isCollapsed: _isCollapse, isCollapsed: _isCollapse,
isLatestTagFocused: _lastTagFocused, isLatestTagFocused: _lastTagFocused,
maxWidth: widget.maxWidth, maxWidth: widget.maxWidth,
isMobile: _responsiveUtils.isMobile(context),
onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter), onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter),
onShowFullAction: widget.onShowFullListEmailAddressAction, onShowFullAction: widget.onShowFullListEmailAddressAction,
onEditRecipientAction: widget.onEditRecipientAction, onEditRecipientAction: widget.onEditRecipientAction,
onClearFocusAction: widget.onClearFocusAction,
); );
}, },
onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter),
@@ -1,7 +1,6 @@
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/text/rich_text_builder.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
@@ -50,7 +49,6 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
child: Padding( child: Padding(
padding: RecipientSuggestionItemWidgetStyle.labelPadding, padding: RecipientSuggestionItemWidgetStyle.labelPadding,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
AvatarSuggestionItemWidget(emailAddress: emailAddress), AvatarSuggestionItemWidget(emailAddress: emailAddress),
const SizedBox(width: 8), const SizedBox(width: 8),
@@ -58,18 +56,22 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [ children: [
RichTextWidget( RichTextWidget(
textOrigin: emailAddress.asString(), textOrigin: emailAddress.asString(),
wordSearched: suggestionValid ?? '', wordSearched: suggestionValid ?? '',
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1,
), ),
if (emailAddress.displayName.isNotEmpty) if (emailAddress.displayName.isNotEmpty)
RichTextBuilder( RichTextWidget(
textOrigin: emailAddress.emailAddress, textOrigin: emailAddress.emailAddress,
wordToStyle: suggestionValid ?? '', wordSearched: suggestionValid ?? '',
styleOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle, overflow: TextOverflow.ellipsis,
styleWord: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle, maxLines: 1,
styleTextOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle,
styleWordSearched: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle,
), ),
], ],
), ),
@@ -98,7 +100,6 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
child: Padding( child: Padding(
padding: RecipientSuggestionItemWidgetStyle.labelPadding, padding: RecipientSuggestionItemWidgetStyle.labelPadding,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
AvatarSuggestionItemWidget(emailAddress: emailAddress), AvatarSuggestionItemWidget(emailAddress: emailAddress),
const SizedBox(width: 8), const SizedBox(width: 8),
@@ -106,18 +107,22 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [ children: [
RichTextWidget( RichTextWidget(
textOrigin: emailAddress.asString(), textOrigin: emailAddress.asString(),
wordSearched: suggestionValid ?? '', wordSearched: suggestionValid ?? '',
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1,
), ),
if (emailAddress.displayName.isNotEmpty) if (emailAddress.displayName.isNotEmpty)
RichTextBuilder( RichTextWidget(
textOrigin: emailAddress.emailAddress, textOrigin: emailAddress.emailAddress,
wordToStyle: suggestionValid ?? '', wordSearched: suggestionValid ?? '',
styleOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle, overflow: TextOverflow.ellipsis,
styleWord: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle, maxLines: 1,
styleTextOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle,
styleWordSearched: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle,
), ),
], ],
), ),
@@ -36,6 +36,8 @@ class RecipientTagItemWidget extends StatelessWidget {
final OnEditRecipientAction? onEditRecipientAction; final OnEditRecipientAction? onEditRecipientAction;
final bool isTestingForWeb; final bool isTestingForWeb;
final String? composerId; final String? composerId;
final bool isMobile;
final VoidCallback? onClearFocusAction;
const RecipientTagItemWidget({ const RecipientTagItemWidget({
super.key, super.key,
@@ -49,28 +51,39 @@ class RecipientTagItemWidget extends StatelessWidget {
this.isCollapsed = false, this.isCollapsed = false,
this.isLatestTagFocused = false, this.isLatestTagFocused = false,
this.isLatestEmail = false, this.isLatestEmail = false,
this.isMobile = false,
this.onShowFullAction, this.onShowFullAction,
this.onDeleteTagAction, this.onDeleteTagAction,
this.onEditRecipientAction, this.onEditRecipientAction,
this.maxWidth, this.maxWidth,
this.composerId, this.composerId,
this.onClearFocusAction,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final overlayWidth = isMobile ? 227.0 : 361.0;
Widget tagWidget = CardWithSmartInteractionOverlayView( Widget tagWidget = CardWithSmartInteractionOverlayView(
overlayWidth: overlayWidth,
menuBuilder: (onClose) => EditRecipientsView( menuBuilder: (onClose) => EditRecipientsView(
emailAddress: currentEmailAddress, emailAddress: currentEmailAddress,
imagePaths: imagePaths, imagePaths: imagePaths,
onCopyAction: () => _onEditRecipientAction( isMobile: isMobile,
context, width: overlayWidth,
EmailAddressActionType.copy, onCopyAction: () {
), if (isMobile) {
onClose();
}
_onEditRecipientAction(
context,
EmailAddressActionType.copy,
);
},
onEditAction: () { onEditAction: () {
onClose(); onClose();
_onEditRecipientAction( _onEditRecipientAction(
context, context,
EmailAddressActionType.modify, EmailAddressActionType.edit,
); );
}, },
onCreateRuleAction: () { onCreateRuleAction: () {
@@ -82,6 +95,7 @@ class RecipientTagItemWidget extends StatelessWidget {
}, },
onCloseAction: onClose, onCloseAction: onClose,
), ),
onClearFocusAction: onClearFocusAction,
child: Chip( child: Chip(
labelPadding: EdgeInsetsDirectional.symmetric( labelPadding: EdgeInsetsDirectional.symmetric(
horizontal: 4, horizontal: 4,
+1 -7
View File
@@ -1,5 +1,5 @@
{ {
"@@last_modified": "2025-07-24T16:57:08.573149", "@@last_modified": "2025-07-25T12:21:42.514040",
"initializing_data": "Initializing data...", "initializing_data": "Initializing data...",
"@initializing_data": { "@initializing_data": {
"type": "text", "type": "text",
@@ -4608,12 +4608,6 @@
"placeholders_order": [], "placeholders_order": [],
"placeholders": {} "placeholders": {}
}, },
"modifyEmailAddress": "Modify email address",
"@modifyEmailAddress": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"editEmail": "Edit email", "editEmail": "Edit email",
"@editEmail": { "@editEmail": {
"type": "text", "type": "text",
@@ -4856,13 +4856,6 @@ class AppLocalizations {
); );
} }
String get modifyEmailAddress {
return Intl.message(
'Modify email address',
name: 'modifyEmailAddress',
);
}
String get editEmail { String get editEmail {
return Intl.message( return Intl.message(
'Edit email', 'Edit email',