TF-2666 Edit one recipient in To/Cc/Bcc on mobile
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -7,17 +7,20 @@ import 'package:universal_html/html.dart' as html;
|
|||||||
|
|
||||||
typedef OnRightMouseClickAction = void Function(RelativeRect position);
|
typedef OnRightMouseClickAction = void Function(RelativeRect position);
|
||||||
typedef OnDoubleClickAction = void Function(RelativeRect position);
|
typedef OnDoubleClickAction = void Function(RelativeRect position);
|
||||||
|
typedef OnLongPressAction = void Function();
|
||||||
|
|
||||||
class SmartInteractionWidget extends StatefulWidget {
|
class SmartInteractionWidget extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final OnRightMouseClickAction onRightMouseClickAction;
|
final OnRightMouseClickAction onRightMouseClickAction;
|
||||||
final OnDoubleClickAction onDoubleClickAction;
|
final OnDoubleClickAction onDoubleClickAction;
|
||||||
|
final OnLongPressAction onLongPressAction;
|
||||||
|
|
||||||
const SmartInteractionWidget({
|
const SmartInteractionWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.child,
|
required this.child,
|
||||||
required this.onRightMouseClickAction,
|
required this.onRightMouseClickAction,
|
||||||
required this.onDoubleClickAction,
|
required this.onDoubleClickAction,
|
||||||
|
required this.onLongPressAction,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -25,8 +28,8 @@ class SmartInteractionWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SmartInteractionWidgetState extends State<SmartInteractionWidget> {
|
class _SmartInteractionWidgetState extends State<SmartInteractionWidget> {
|
||||||
final GlobalKey _childKey = GlobalKey();
|
|
||||||
|
|
||||||
|
GlobalKey? _childKey;
|
||||||
Offset? _lastPointerEventOffset;
|
Offset? _lastPointerEventOffset;
|
||||||
StreamSubscription<html.MouseEvent>? _contextMenuSubscription;
|
StreamSubscription<html.MouseEvent>? _contextMenuSubscription;
|
||||||
|
|
||||||
@@ -34,6 +37,7 @@ class _SmartInteractionWidgetState extends State<SmartInteractionWidget> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
if (PlatformInfo.isWeb) {
|
if (PlatformInfo.isWeb) {
|
||||||
|
_childKey = GlobalKey();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_addWebContextMenuListener();
|
_addWebContextMenuListener();
|
||||||
});
|
});
|
||||||
@@ -47,7 +51,7 @@ class _SmartInteractionWidgetState extends State<SmartInteractionWidget> {
|
|||||||
|
|
||||||
void _onContextMenuListener(html.MouseEvent event) {
|
void _onContextMenuListener(html.MouseEvent event) {
|
||||||
final renderBox =
|
final renderBox =
|
||||||
_childKey.currentContext?.findRenderObject() as RenderBox?;
|
_childKey?.currentContext?.findRenderObject() as RenderBox?;
|
||||||
if (renderBox == null) return;
|
if (renderBox == null) return;
|
||||||
|
|
||||||
final localPosition = Offset(
|
final localPosition = Offset(
|
||||||
@@ -79,7 +83,7 @@ class _SmartInteractionWidgetState extends State<SmartInteractionWidget> {
|
|||||||
Offset offset,
|
Offset offset,
|
||||||
) {
|
) {
|
||||||
final widgetBox =
|
final widgetBox =
|
||||||
_childKey.currentContext?.findRenderObject() as RenderBox?;
|
_childKey?.currentContext?.findRenderObject() as RenderBox?;
|
||||||
final overlayBox =
|
final overlayBox =
|
||||||
Overlay.maybeOf(context)?.context.findRenderObject() as RenderBox?;
|
Overlay.maybeOf(context)?.context.findRenderObject() as RenderBox?;
|
||||||
|
|
||||||
@@ -118,6 +122,8 @@ class _SmartInteractionWidgetState extends State<SmartInteractionWidget> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleLongPress() => widget.onLongPressAction();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (PlatformInfo.isWeb) {
|
if (PlatformInfo.isWeb) {
|
||||||
@@ -135,14 +141,17 @@ class _SmartInteractionWidgetState extends State<SmartInteractionWidget> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return widget.child;
|
return GestureDetector(
|
||||||
|
onLongPress: _handleLongPress,
|
||||||
|
child: widget.child,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_lastPointerEventOffset = null;
|
|
||||||
if (PlatformInfo.isWeb) {
|
if (PlatformInfo.isWeb) {
|
||||||
|
_lastPointerEventOffset = null;
|
||||||
_contextMenuSubscription?.cancel();
|
_contextMenuSubscription?.cancel();
|
||||||
}
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|||||||
@@ -1497,28 +1497,36 @@ class ComposerController extends BaseController
|
|||||||
} else {
|
} else {
|
||||||
switch(prefixEmailAddress) {
|
switch(prefixEmailAddress) {
|
||||||
case PrefixEmailAddress.to:
|
case PrefixEmailAddress.to:
|
||||||
toAddressExpandMode.value = ExpandMode.COLLAPSE;
|
if (mailboxDashBoardController.isPopupMenuOpened.isFalse) {
|
||||||
|
toAddressExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
}
|
||||||
final inputToEmail = toEmailAddressController.text;
|
final inputToEmail = toEmailAddressController.text;
|
||||||
if (inputToEmail.trim().isNotEmpty) {
|
if (inputToEmail.trim().isNotEmpty) {
|
||||||
autoCreateEmailTagForType(PrefixEmailAddress.to, inputToEmail);
|
autoCreateEmailTagForType(PrefixEmailAddress.to, inputToEmail);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PrefixEmailAddress.cc:
|
case PrefixEmailAddress.cc:
|
||||||
ccAddressExpandMode.value = ExpandMode.COLLAPSE;
|
if (mailboxDashBoardController.isPopupMenuOpened.isFalse) {
|
||||||
|
ccAddressExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
}
|
||||||
final inputCcEmail = ccEmailAddressController.text;
|
final inputCcEmail = ccEmailAddressController.text;
|
||||||
if (inputCcEmail.trim().isNotEmpty) {
|
if (inputCcEmail.trim().isNotEmpty) {
|
||||||
autoCreateEmailTagForType(PrefixEmailAddress.cc, inputCcEmail);
|
autoCreateEmailTagForType(PrefixEmailAddress.cc, inputCcEmail);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PrefixEmailAddress.bcc:
|
case PrefixEmailAddress.bcc:
|
||||||
bccAddressExpandMode.value = ExpandMode.COLLAPSE;
|
if (mailboxDashBoardController.isPopupMenuOpened.isFalse) {
|
||||||
|
bccAddressExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
}
|
||||||
final inputBccEmail = bccEmailAddressController.text;
|
final inputBccEmail = bccEmailAddressController.text;
|
||||||
if (inputBccEmail.trim().isNotEmpty) {
|
if (inputBccEmail.trim().isNotEmpty) {
|
||||||
autoCreateEmailTagForType(PrefixEmailAddress.bcc, inputBccEmail);
|
autoCreateEmailTagForType(PrefixEmailAddress.bcc, inputBccEmail);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PrefixEmailAddress.replyTo:
|
case PrefixEmailAddress.replyTo:
|
||||||
replyToAddressExpandMode.value = ExpandMode.COLLAPSE;
|
if (mailboxDashBoardController.isPopupMenuOpened.isFalse) {
|
||||||
|
replyToAddressExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
}
|
||||||
final inputReplyToEmail = replyToEmailAddressController.text;
|
final inputReplyToEmail = replyToEmailAddressController.text;
|
||||||
if (inputReplyToEmail.trim().isNotEmpty) {
|
if (inputReplyToEmail.trim().isNotEmpty) {
|
||||||
autoCreateEmailTagForType(PrefixEmailAddress.replyTo, inputReplyToEmail);
|
autoCreateEmailTagForType(PrefixEmailAddress.replyTo, inputReplyToEmail);
|
||||||
@@ -1783,6 +1791,9 @@ class ComposerController extends BaseController
|
|||||||
if (menuMoreOptionController?.menuIsShowing == true) {
|
if (menuMoreOptionController?.menuIsShowing == true) {
|
||||||
menuMoreOptionController?.hideMenu();
|
menuMoreOptionController?.hideMenu();
|
||||||
}
|
}
|
||||||
|
if (mailboxDashBoardController.isPopupMenuOpened.isTrue) {
|
||||||
|
popBack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleOnMouseDownHtmlEditorWeb() {
|
void handleOnMouseDownHtmlEditorWeb() {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:model/email/prefix_email_address.dart';
|
import 'package:model/email/prefix_email_address.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/extensions/handle_content_height_exceeded_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_content_height_exceeded_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_edit_recipient_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_open_context_menu_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_open_context_menu_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/mark_as_important_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/mark_as_important_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/model/prefix_recipient_state.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/model/prefix_recipient_state.dart';
|
||||||
@@ -140,6 +141,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
|
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
)),
|
)),
|
||||||
Obx(() {
|
Obx(() {
|
||||||
if (controller.ccRecipientState.value == PrefixRecipientState.enabled) {
|
if (controller.ccRecipientState.value == PrefixRecipientState.enabled) {
|
||||||
@@ -163,6 +165,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
@@ -190,6 +193,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
@@ -217,6 +221,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
|
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
@@ -340,6 +345,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
|
onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
),
|
),
|
||||||
if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
|
if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
|
||||||
RecipientComposerWidget(
|
RecipientComposerWidget(
|
||||||
@@ -362,6 +368,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
),
|
),
|
||||||
if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
|
if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
|
||||||
RecipientComposerWidget(
|
RecipientComposerWidget(
|
||||||
@@ -384,6 +391,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
),
|
),
|
||||||
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
|
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
|
||||||
RecipientComposerWidget(
|
RecipientComposerWidget(
|
||||||
@@ -405,6 +413,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||||
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
|
||||||
|
onEditRecipientAction: controller.onEditRecipient,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
|
|||||||
+74
-23
@@ -1,14 +1,17 @@
|
|||||||
|
|
||||||
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';
|
||||||
import 'package:model/mailbox/expand_mode.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/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/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/composer/presentation/model/popup_menu_item_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/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';
|
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||||
|
|
||||||
@@ -17,31 +20,63 @@ extension HandleEditRecipientExtension on ComposerController {
|
|||||||
BuildContext context,
|
BuildContext context,
|
||||||
PrefixEmailAddress prefix,
|
PrefixEmailAddress prefix,
|
||||||
EmailAddress emailAddress,
|
EmailAddress emailAddress,
|
||||||
RelativeRect position,
|
RelativeRect? position,
|
||||||
) {
|
) {
|
||||||
final popupMenuItems = EmailAddressActionType.values.map((type) {
|
if (position == null) {
|
||||||
return PopupMenuItem(
|
clearFocus(context);
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
child: PopupMenuItemActionWidget(
|
|
||||||
menuAction: PopupMenuItemEmailAddressActionType(
|
|
||||||
type,
|
|
||||||
AppLocalizations.of(context),
|
|
||||||
imagePaths,
|
|
||||||
),
|
|
||||||
menuActionClick: (menuAction) {
|
|
||||||
popBack();
|
|
||||||
_handleEmailAddressActionTypeClick(
|
|
||||||
context,
|
|
||||||
menuAction.action,
|
|
||||||
prefix,
|
|
||||||
emailAddress,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
openPopupMenuAction(context, position, popupMenuItems);
|
final contextMenuActions = EmailAddressActionType.values
|
||||||
|
.map((action) => ContextItemEmailAddressActionType(
|
||||||
|
action,
|
||||||
|
AppLocalizations.of(context),
|
||||||
|
imagePaths
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
openBottomSheetContextMenuAction(
|
||||||
|
context: context,
|
||||||
|
itemActions: contextMenuActions,
|
||||||
|
onContextMenuActionClick: (menuAction) {
|
||||||
|
popBack();
|
||||||
|
_handleEmailAddressActionTypeClick(
|
||||||
|
context,
|
||||||
|
menuAction.action,
|
||||||
|
prefix,
|
||||||
|
emailAddress,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} 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(
|
||||||
|
context,
|
||||||
|
position,
|
||||||
|
popupMenuItems,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleEmailAddressActionTypeClick(
|
void _handleEmailAddressActionTypeClick(
|
||||||
@@ -121,6 +156,22 @@ extension HandleEditRecipientExtension on ComposerController {
|
|||||||
);
|
);
|
||||||
bccAddressFocusNode?.requestFocus();
|
bccAddressFocusNode?.requestFocus();
|
||||||
break;
|
break;
|
||||||
|
case PrefixEmailAddress.replyTo:
|
||||||
|
listReplyToEmailAddress.remove(emailAddress);
|
||||||
|
replyToAddressExpandMode.value = ExpandMode.EXPAND;
|
||||||
|
replyToAddressExpandMode.refresh();
|
||||||
|
|
||||||
|
replyToEmailAddressController.text = emailAddress.emailAddress;
|
||||||
|
replyToEmailAddressController.value = replyToEmailAddressController.value.copyWith(
|
||||||
|
text: emailAddress.emailAddress,
|
||||||
|
selection: TextSelection(
|
||||||
|
baseOffset: emailAddress.emailAddress.length,
|
||||||
|
extentOffset: emailAddress.emailAddress.length,
|
||||||
|
),
|
||||||
|
composing: TextRange.empty,
|
||||||
|
);
|
||||||
|
replyToAddressFocusNode?.requestFocus();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ typedef OnEditRecipientAction = void Function(
|
|||||||
BuildContext context,
|
BuildContext context,
|
||||||
PrefixEmailAddress prefix,
|
PrefixEmailAddress prefix,
|
||||||
EmailAddress emailAddress,
|
EmailAddress emailAddress,
|
||||||
RelativeRect position,
|
RelativeRect? position,
|
||||||
);
|
);
|
||||||
|
|
||||||
class RecipientComposerWidget extends StatefulWidget {
|
class RecipientComposerWidget extends StatefulWidget {
|
||||||
|
|||||||
@@ -56,40 +56,51 @@ class RecipientTagItemWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Widget tagWidget = Chip(
|
Widget tagWidget = SmartInteractionWidget(
|
||||||
labelPadding: EdgeInsetsDirectional.symmetric(
|
onRightMouseClickAction: (position) => _onEditRecipientAction(
|
||||||
horizontal: 4,
|
context,
|
||||||
vertical: DirectionUtils.isDirectionRTLByHasAnyRtl(currentEmailAddress.asString()) ? 0 : 2
|
position: position,
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.zero,
|
onDoubleClickAction: (position) => _onEditRecipientAction(
|
||||||
label: Text(
|
context,
|
||||||
key: Key('label_recipient_tag_item_${prefix.name}_$index'),
|
position: position,
|
||||||
currentEmailAddress.asString(),
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
softWrap: true,
|
|
||||||
),
|
),
|
||||||
deleteIcon: SvgPicture.asset(
|
onLongPressAction: () => _onEditRecipientAction(context),
|
||||||
imagePaths.icClose,
|
child: Chip(
|
||||||
key: Key('delete_icon_recipient_tag_item_${prefix.name}_$index'),
|
labelPadding: EdgeInsetsDirectional.symmetric(
|
||||||
fit: BoxFit.fill
|
horizontal: 4,
|
||||||
|
vertical: DirectionUtils.isDirectionRTLByHasAnyRtl(currentEmailAddress.asString()) ? 0 : 2
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
label: Text(
|
||||||
|
key: Key('label_recipient_tag_item_${prefix.name}_$index'),
|
||||||
|
currentEmailAddress.asString(),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
softWrap: true,
|
||||||
|
),
|
||||||
|
deleteIcon: SvgPicture.asset(
|
||||||
|
imagePaths.icClose,
|
||||||
|
key: Key('delete_icon_recipient_tag_item_${prefix.name}_$index'),
|
||||||
|
fit: BoxFit.fill
|
||||||
|
),
|
||||||
|
labelStyle: RecipientTagItemWidgetStyle.labelTextStyle,
|
||||||
|
backgroundColor: _getTagBackgroundColor(),
|
||||||
|
side: _getTagBorderSide(),
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(RecipientTagItemWidgetStyle.radius)),
|
||||||
|
),
|
||||||
|
avatar: currentEmailAddress.displayName.isNotEmpty
|
||||||
|
? GradientCircleAvatarIcon(
|
||||||
|
key: Key('avatar_icon_recipient_tag_item_${prefix.name}_$index'),
|
||||||
|
colors: currentEmailAddress.avatarColors,
|
||||||
|
label: currentEmailAddress.displayName.firstLetterToUpperCase,
|
||||||
|
labelFontSize: RecipientTagItemWidgetStyle.avatarLabelFontSize,
|
||||||
|
iconSize: RecipientTagItemWidgetStyle.avatarIconSize,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
onDeleted: () => onDeleteTagAction?.call(currentEmailAddress),
|
||||||
),
|
),
|
||||||
labelStyle: RecipientTagItemWidgetStyle.labelTextStyle,
|
|
||||||
backgroundColor: _getTagBackgroundColor(),
|
|
||||||
side: _getTagBorderSide(),
|
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(RecipientTagItemWidgetStyle.radius)),
|
|
||||||
),
|
|
||||||
avatar: currentEmailAddress.displayName.isNotEmpty
|
|
||||||
? GradientCircleAvatarIcon(
|
|
||||||
key: Key('avatar_icon_recipient_tag_item_${prefix.name}_$index'),
|
|
||||||
colors: currentEmailAddress.avatarColors,
|
|
||||||
label: currentEmailAddress.displayName.firstLetterToUpperCase,
|
|
||||||
labelFontSize: RecipientTagItemWidgetStyle.avatarLabelFontSize,
|
|
||||||
iconSize: RecipientTagItemWidgetStyle.avatarIconSize,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
onDeleted: () => onDeleteTagAction?.call(currentEmailAddress),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (PlatformInfo.isWeb || isTestingForWeb) {
|
if (PlatformInfo.isWeb || isTestingForWeb) {
|
||||||
@@ -103,17 +114,7 @@ class RecipientTagItemWidget extends StatelessWidget {
|
|||||||
childWhenDragging: DraggableRecipientTagWidget(emailAddress: currentEmailAddress),
|
childWhenDragging: DraggableRecipientTagWidget(emailAddress: currentEmailAddress),
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
cursor: SystemMouseCursors.grab,
|
cursor: SystemMouseCursors.grab,
|
||||||
child: SmartInteractionWidget(
|
child: tagWidget,
|
||||||
onRightMouseClickAction: (position) => _onEditRecipientAction(
|
|
||||||
context,
|
|
||||||
position,
|
|
||||||
),
|
|
||||||
onDoubleClickAction: (position) => _onEditRecipientAction(
|
|
||||||
context,
|
|
||||||
position,
|
|
||||||
),
|
|
||||||
child: tagWidget,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -185,7 +186,7 @@ class RecipientTagItemWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onEditRecipientAction(BuildContext context, RelativeRect position) {
|
void _onEditRecipientAction(BuildContext context, {RelativeRect? position}) {
|
||||||
onEditRecipientAction?.call(
|
onEditRecipientAction?.call(
|
||||||
context,
|
context,
|
||||||
prefix,
|
prefix,
|
||||||
|
|||||||
Reference in New Issue
Block a user