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 index d6f1e95cc0..758ceaf8d4 100644 --- a/lib/features/base/widget/card_with_smart_interaction_overlay_view.dart +++ b/lib/features/base/widget/card_with_smart_interaction_overlay_view.dart @@ -111,7 +111,6 @@ class _CardWithSmartInteractionOverlayViewState child: SmartInteractionWidget( onRightMouseClickAction: ({RelativeRect? position}) => _togglePopup(), onDoubleClickAction: ({RelativeRect? position}) => _togglePopup(), - onLongPressAction: _togglePopup, onTapAction: _togglePopup, child: widget.child, ), diff --git a/lib/features/base/widget/default_field/default_autocomplete_input_field_widget.dart b/lib/features/base/widget/default_field/default_autocomplete_input_field_widget.dart index ce094b352a..e9862110b0 100644 --- a/lib/features/base/widget/default_field/default_autocomplete_input_field_widget.dart +++ b/lib/features/base/widget/default_field/default_autocomplete_input_field_widget.dart @@ -159,6 +159,7 @@ class _DefaultAutocompleteInputFieldWidgetState final currentEmailAddress = _currentListEmailAddress.elementAt(index); return DefaultAutocompleteTagItemWidget( field: widget.field, + imagePaths: _imagePaths, currentEmailAddress: currentEmailAddress, currentListEmailAddress: _currentListEmailAddress, collapsedListEmailAddress: _collapsedListEmailAddress, diff --git a/lib/features/base/widget/default_field/default_autocomplete_tag_item_widget.dart b/lib/features/base/widget/default_field/default_autocomplete_tag_item_widget.dart index 2e5b6ce7cc..e35bd189eb 100644 --- a/lib/features/base/widget/default_field/default_autocomplete_tag_item_widget.dart +++ b/lib/features/base/widget/default_field/default_autocomplete_tag_item_widget.dart @@ -1,4 +1,5 @@ import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:core/utils/direction_utils.dart'; import 'package:core/utils/platform_info.dart'; @@ -15,6 +16,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad class DefaultAutocompleteTagItemWidget extends StatelessWidget { + final ImagePaths imagePaths; final bool isCollapsed; final bool isTagFocused; final FilterField field; @@ -27,6 +29,7 @@ class DefaultAutocompleteTagItemWidget extends StatelessWidget { const DefaultAutocompleteTagItemWidget({ Key? key, + required this.imagePaths, required this.field, required this.currentEmailAddress, required this.currentListEmailAddress, @@ -73,10 +76,12 @@ class DefaultAutocompleteTagItemWidget extends StatelessWidget { ), feedback: DraggableRecipientTagWidget( emailAddress: currentEmailAddress, + imagePaths: imagePaths, padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), ), childWhenDragging: DraggableRecipientTagWidget( emailAddress: currentEmailAddress, + imagePaths: imagePaths, padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), ), child: TextFieldTapRegion( diff --git a/lib/features/base/widget/smart_interaction_widget.dart b/lib/features/base/widget/smart_interaction_widget.dart index 707d1b5399..2bf4024517 100644 --- a/lib/features/base/widget/smart_interaction_widget.dart +++ b/lib/features/base/widget/smart_interaction_widget.dart @@ -7,7 +7,6 @@ import 'package:universal_html/html.dart' as html; typedef OnRightMouseClickAction = void Function({RelativeRect? position}); typedef OnDoubleClickAction = void Function({RelativeRect? position}); -typedef OnLongPressAction = void Function(); typedef OnTapAction = void Function(); class SmartInteractionWidget extends StatefulWidget { @@ -15,7 +14,6 @@ class SmartInteractionWidget extends StatefulWidget { final bool usePosition; final OnRightMouseClickAction onRightMouseClickAction; final OnDoubleClickAction onDoubleClickAction; - final OnLongPressAction onLongPressAction; final OnTapAction onTapAction; const SmartInteractionWidget({ @@ -23,7 +21,6 @@ class SmartInteractionWidget extends StatefulWidget { required this.child, required this.onRightMouseClickAction, required this.onDoubleClickAction, - required this.onLongPressAction, required this.onTapAction, this.usePosition = false, }); @@ -133,8 +130,6 @@ class _SmartInteractionWidgetState extends State { } } - void _handleLongPress() => widget.onLongPressAction(); - void _handleOnTapAction() => widget.onTapAction(); @override @@ -166,7 +161,6 @@ class _SmartInteractionWidgetState extends State { } } else { return GestureDetector( - onLongPress: _handleLongPress, onTap: _handleOnTapAction, child: widget.child, ); diff --git a/lib/features/composer/presentation/composer_view.dart b/lib/features/composer/presentation/composer_view.dart index abb7655cc1..c0cf6e6790 100644 --- a/lib/features/composer/presentation/composer_view.dart +++ b/lib/features/composer/presentation/composer_view.dart @@ -12,6 +12,7 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_c 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/mark_as_important_extension.dart'; +import 'package:tmail_ui_user/features/composer/presentation/extensions/remove_draggable_email_address_between_recipient_fields_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/prefix_recipient_state.dart'; import 'package:tmail_ui_user/features/composer/presentation/styles/composer_style.dart'; import 'package:tmail_ui_user/features/composer/presentation/styles/mobile_app_bar_composer_widget_style.dart'; @@ -146,6 +147,7 @@ class ComposerView extends GetWidget { onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, )), @@ -171,6 +173,7 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, ); @@ -200,6 +203,7 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, ); @@ -229,6 +233,7 @@ class ComposerView extends GetWidget { onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, ); @@ -357,6 +362,7 @@ class ComposerView extends GetWidget { onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, onEnableAllRecipientsInputAction: controller.handleEnableRecipientsInputAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, ), @@ -381,6 +387,7 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, ), @@ -405,6 +412,7 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, ), @@ -428,6 +436,7 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, onEditRecipientAction: controller.onEditRecipient, onClearFocusAction: controller.onClearFocusAction, ), diff --git a/lib/features/composer/presentation/widgets/draggable_recipient_tag_widget.dart b/lib/features/composer/presentation/widgets/draggable_recipient_tag_widget.dart index a4573699e7..b30b151f49 100644 --- a/lib/features/composer/presentation/widgets/draggable_recipient_tag_widget.dart +++ b/lib/features/composer/presentation/widgets/draggable_recipient_tag_widget.dart @@ -4,21 +4,20 @@ import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/views/avatar/gradient_circle_avatar_icon.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:get/get.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/styles/draggable_recipient_tag_widget_style.dart'; class DraggableRecipientTagWidget extends StatelessWidget { + final ImagePaths imagePaths; final EmailAddress emailAddress; final EdgeInsetsGeometry? padding; - final _imagePaths = Get.find(); - - DraggableRecipientTagWidget({ + const DraggableRecipientTagWidget({ super.key, required this.emailAddress, + required this.imagePaths, this.padding, }); @@ -44,15 +43,19 @@ class DraggableRecipientTagWidget extends StatelessWidget { labelFontSize: DraggableRecipientTagWidgetStyle.avatarLabelFontSize, iconSize: DraggableRecipientTagWidgetStyle.avatarIconSize, ), - Padding( - padding: DraggableRecipientTagWidgetStyle.labelPadding, - child: DefaultTextStyle( - style: DraggableRecipientTagWidgetStyle.labelTextStyle, - child: Text(emailAddress.asString()), + Flexible( + child: Padding( + padding: DraggableRecipientTagWidgetStyle.labelPadding, + child: DefaultTextStyle( + style: DraggableRecipientTagWidgetStyle.labelTextStyle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + child: Text(emailAddress.asString()), + ), ), ), SvgPicture.asset( - _imagePaths.icClose, + imagePaths.icClose, colorFilter: DraggableRecipientTagWidgetStyle.deleteIconColor.asFilter(), fit: BoxFit.fill ) diff --git a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart index 8c422a1673..2717ab64d4 100644 --- a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart @@ -175,7 +175,6 @@ class _RecipientComposerWidgetState extends State { onKeyEvent: PlatformInfo.isWeb ? _recipientInputOnKeyListener : null, child: StatefulBuilder( builder: (context, stateSetter) { - if (PlatformInfo.isWeb || widget.isTestingForWeb) { return DragTarget( builder: (context, candidateData, rejectedData) { return TagEditor( @@ -187,6 +186,9 @@ class _RecipientComposerWidgetState extends State { focusNodeKeyboard: widget.focusNodeKeyboard, borderRadius: RecipientComposerWidgetStyle.enableBorderRadius, enableBorderColor: RecipientComposerWidgetStyle.enableBorderColor, + focusedBorderColor: _isDragging + ? RecipientComposerWidgetStyle.enableBorderColor + : null, keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.done, debounceDuration: RecipientComposerWidgetStyle.suggestionDebounceDuration, @@ -274,87 +276,6 @@ class _RecipientComposerWidgetState extends State { } }, ); - } else { - return TagEditor( - key: widget.keyTagEditor, - length: _collapsedListEmailAddress.length, - controller: widget.controller, - focusNode: widget.focusNode, - focusNodeKeyboard: widget.focusNodeKeyboard, - keyboardType: TextInputType.emailAddress, - textInputAction: TextInputAction.done, - debounceDuration: RecipientComposerWidgetStyle.suggestionDebounceDuration, - tagSpacing: RecipientComposerWidgetStyle.tagSpacing, - minTextFieldWidth: RecipientComposerWidgetStyle.minTextFieldWidth, - resetTextOnSubmitted: true, - autoScrollToInput: false, - autoHideTextInputField: true, - cursorColor: RecipientComposerWidgetStyle.cursorColor, - suggestionsBoxElevation: RecipientComposerWidgetStyle.suggestionsBoxElevation, - suggestionsBoxBackgroundColor: RecipientComposerWidgetStyle.suggestionsBoxBackgroundColor, - suggestionsBoxRadius: RecipientComposerWidgetStyle.suggestionsBoxRadius, - suggestionsBoxMaxHeight: RecipientComposerWidgetStyle.suggestionsBoxMaxHeight, - suggestionItemHeight: RecipientComposerWidgetStyle.suggestionBoxItemHeight, - suggestionBoxWidth: _getSuggestionBoxWidth(widget.maxWidth), - textStyle: RecipientComposerWidgetStyle.inputTextStyle, - onFocusTagAction: (index) => _handleFocusTagAction.call(index, stateSetter), - onDeleteTagAction: (index) => _handleDeleteLatestTagAction.call(index, stateSetter), - onSelectOptionAction: (item) => _handleSelectOptionAction.call(item, stateSetter), - onSubmitted: (value) => _handleSubmitTagAction.call(value, stateSetter), - onTapOutside: (_) {}, - onFocusTextInput: () { - if (_isCollapse) { - widget.onShowFullListEmailAddressAction?.call(widget.prefix); - } - }, - inputDecoration: const InputDecoration(border: InputBorder.none), - tagBuilder: (context, index) { - final currentEmailAddress = _currentListEmailAddress[index]; - - return RecipientTagItemWidget( - index: index, - imagePaths: widget.imagePaths, - prefix: widget.prefix, - composerId: widget.composerId, - currentEmailAddress: currentEmailAddress, - currentListEmailAddress: _currentListEmailAddress, - collapsedListEmailAddress: _collapsedListEmailAddress, - isCollapsed: _isCollapse, - isTagFocused: _tagIndexFocused == index, - maxWidth: widget.maxWidth, - isMobile: _responsiveUtils.isMobile(context), - onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter), - onShowFullAction: widget.onShowFullListEmailAddressAction, - onEditRecipientAction: widget.onEditRecipientAction, - onClearFocusAction: widget.onClearFocusAction, - ); - }, - onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), - findSuggestions: (queryString) => _findSuggestions( - queryString, - limit: AppConfig.defaultLimitAutocomplete, - ), - isLoadMoreOnlyOnce: true, - isLoadMoreReplaceAllOld: false, - loadMoreSuggestions: _findSuggestions, - useDefaultHighlight: false, - suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) { - return RecipientSuggestionItemWidget( - imagePaths: widget.imagePaths, - suggestionState: suggestionEmailAddress.state, - emailAddress: _subAddressingValidatedEmailAddress(suggestionEmailAddress.emailAddress), - suggestionValid: suggestionValid, - highlight: highlight, - onSelectedAction: (emailAddress) { - stateSetter(() => _currentListEmailAddress.add(emailAddress)); - _updateListEmailAddressAction(); - tagEditorState.resetTextField(); - tagEditorState.closeSuggestionBox(); - }, - ); - }, - ); - } }, ) ) 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 71cb35853d..0f15a73a23 100644 --- a/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart @@ -133,21 +133,37 @@ class RecipientTagItemWidget extends StatelessWidget { ); if (PlatformInfo.isWeb || isTestingForWeb) { - tagWidget = Draggable( - data: DraggableEmailAddress( - emailAddress: currentEmailAddress, - filterField: prefix.filterField, - composerId: composerId, - ), - feedback: DraggableRecipientTagWidget(emailAddress: currentEmailAddress), - childWhenDragging: DraggableRecipientTagWidget(emailAddress: currentEmailAddress), - child: MouseRegion( - cursor: SystemMouseCursors.grab, - child: tagWidget, - ), + tagWidget = MouseRegion( + cursor: SystemMouseCursors.grab, + child: tagWidget, ); } + tagWidget = Draggable( + data: DraggableEmailAddress( + emailAddress: currentEmailAddress, + filterField: prefix.filterField, + composerId: composerId, + ), + feedback: DraggableRecipientTagWidget( + imagePaths: imagePaths, + emailAddress: currentEmailAddress, + ), + childWhenDragging: PlatformInfo.isMobile + ? Padding( + padding: const EdgeInsets.only(top: 10), + child: DraggableRecipientTagWidget( + imagePaths: imagePaths, + emailAddress: currentEmailAddress, + ), + ) + : DraggableRecipientTagWidget( + imagePaths: imagePaths, + emailAddress: currentEmailAddress, + ), + child: tagWidget, + ); + if ((PlatformInfo.isWeb || isTestingForWeb) && PlatformInfo.isCanvasKit) { tagWidget = Padding( padding: const EdgeInsetsDirectional.only(top: 8),