From c3a6d0f4d817f1e687b5f4d431b699f3165edc28 Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 15 Sep 2023 00:46:35 +0700 Subject: [PATCH] TF-2119 Disable drag and drop recipients on mobile (cherry picked from commit d1760dbdbac30a3af13fd6a7dca97236484dbd9a) --- .../composer/presentation/composer_view.dart | 6 - .../widgets/recipient_composer_widget.dart | 212 +++++++++++------- .../widgets/recipient_tag_item_widget.dart | 124 ++++++---- 3 files changed, 218 insertions(+), 124 deletions(-) diff --git a/lib/features/composer/presentation/composer_view.dart b/lib/features/composer/presentation/composer_view.dart index 77f5231c7..82bd999d2 100644 --- a/lib/features/composer/presentation/composer_view.dart +++ b/lib/features/composer/presentation/composer_view.dart @@ -118,7 +118,6 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, ), if (controller.ccRecipientState.value == PrefixRecipientState.enabled) RecipientComposerWidget( @@ -139,7 +138,6 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, ), if (controller.bccRecipientState.value == PrefixRecipientState.enabled) RecipientComposerWidget( @@ -160,7 +158,6 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, ), ], )), @@ -262,7 +259,6 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, ), if (controller.ccRecipientState.value == PrefixRecipientState.enabled) RecipientComposerWidget( @@ -283,7 +279,6 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, ), if (controller.bccRecipientState.value == PrefixRecipientState.enabled) RecipientComposerWidget( @@ -304,7 +299,6 @@ class ComposerView extends GetWidget { onUpdateListEmailAddressAction: controller.updateListEmailAddress, onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, ), ], )), diff --git a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart index 8c7257536..91f347bad 100644 --- a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart @@ -5,6 +5,7 @@ import 'package:collection/collection.dart'; import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:core/utils/app_logger.dart'; +import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; @@ -146,82 +147,143 @@ class _RecipientComposerWidgetState extends State { }, child: StatefulBuilder( builder: (context, stateSetter) { - return DragTarget( - builder: (context, candidateData, rejectedData) { - return TagEditor( - key: widget.keyTagEditor, - length: _collapsedListEmailAddress.length, - controller: widget.controller, - focusNode: widget.focusNode, - enableBorder: _isDragging, - borderRadius: RecipientComposerWidgetStyle.enableBorderRadius, - enableBorderColor: RecipientComposerWidgetStyle.enableBorderColor, - autoDisposeFocusNode: widget.autoDisposeFocusNode, - keyboardType: TextInputType.emailAddress, - textInputAction: TextInputAction.done, - debounceDuration: const Duration(milliseconds: 150), - hasAddButton: false, - tagSpacing: 8, - autofocus: widget.prefix != PrefixEmailAddress.to && _currentListEmailAddress.isEmpty, - minTextFieldWidth: 20, - resetTextOnSubmitted: true, - suggestionsBoxElevation: 20.0, - suggestionsBoxBackgroundColor: Colors.white, - suggestionsBoxRadius: 20, - suggestionsBoxMaxHeight: 350, - textStyle: RecipientComposerWidgetStyle.inputTextStyle, - onFocusTagAction: (focused) => _handleFocusTagAction.call(focused, stateSetter), - onDeleteTagAction: () => _handleDeleteLatestTagAction.call(stateSetter), - onSelectOptionAction: (item) => _handleSelectOptionAction.call(item, stateSetter), - onSubmitted: (value) => _handleSubmitTagAction.call(value, stateSetter), - inputDecoration: const InputDecoration(border: InputBorder.none), - tagBuilder: (context, index) { - final currentEmailAddress = _currentListEmailAddress[index]; - final isLatestEmail = currentEmailAddress == _currentListEmailAddress.last; + if (PlatformInfo.isWeb) { + return DragTarget( + builder: (context, candidateData, rejectedData) { + return TagEditor( + key: widget.keyTagEditor, + length: _collapsedListEmailAddress.length, + controller: widget.controller, + focusNode: widget.focusNode, + enableBorder: _isDragging, + borderRadius: RecipientComposerWidgetStyle.enableBorderRadius, + enableBorderColor: RecipientComposerWidgetStyle.enableBorderColor, + autoDisposeFocusNode: widget.autoDisposeFocusNode, + keyboardType: TextInputType.emailAddress, + textInputAction: TextInputAction.done, + debounceDuration: const Duration(milliseconds: 150), + hasAddButton: false, + tagSpacing: 8, + autofocus: widget.prefix != PrefixEmailAddress.to && _currentListEmailAddress.isEmpty, + minTextFieldWidth: 20, + resetTextOnSubmitted: true, + suggestionsBoxElevation: 20.0, + suggestionsBoxBackgroundColor: Colors.white, + suggestionsBoxRadius: 20, + suggestionsBoxMaxHeight: 350, + textStyle: RecipientComposerWidgetStyle.inputTextStyle, + onFocusTagAction: (focused) => _handleFocusTagAction.call(focused, stateSetter), + onDeleteTagAction: () => _handleDeleteLatestTagAction.call(stateSetter), + onSelectOptionAction: (item) => _handleSelectOptionAction.call(item, stateSetter), + onSubmitted: (value) => _handleSubmitTagAction.call(value, stateSetter), + inputDecoration: const InputDecoration(border: InputBorder.none), + tagBuilder: (context, index) { + final currentEmailAddress = _currentListEmailAddress[index]; + final isLatestEmail = currentEmailAddress == _currentListEmailAddress.last; - return RecipientTagItemWidget( - prefix: widget.prefix, - currentEmailAddress: currentEmailAddress, - currentListEmailAddress: _currentListEmailAddress, - collapsedListEmailAddress: _collapsedListEmailAddress, - isLatestEmail: isLatestEmail, - isCollapsed: _isCollapse, - isLatestTagFocused: _lastTagFocused, - onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter), - onShowFullAction: widget.onShowFullListEmailAddressAction, - ); - }, - onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), - findSuggestions: _findSuggestions, - useDefaultHighlight: false, - suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) { - return RecipientSuggestionItemWidget( - suggestionState: suggestionEmailAddress.state, - emailAddress: suggestionEmailAddress.emailAddress, - suggestionValid: suggestionValid, - highlight: highlight, - onSelectedAction: (emailAddress) { - stateSetter(() => _currentListEmailAddress.add(emailAddress)); - _updateListEmailAddressAction(); - tagEditorState.resetTextField(); - tagEditorState.closeSuggestionBox(); - }, - ); - }, - ); - }, - onAccept: (draggableEmailAddress) => _handleAcceptDraggableEmailAddressAction(draggableEmailAddress, stateSetter), - onLeave: (draggableEmailAddress) { - if (_isDragging) { - stateSetter(() => _isDragging = false); - } - }, - onMove: (details) { - if (!_isDragging) { - stateSetter(() => _isDragging = true); - } - }, - ); + return RecipientTagItemWidget( + prefix: widget.prefix, + currentEmailAddress: currentEmailAddress, + currentListEmailAddress: _currentListEmailAddress, + collapsedListEmailAddress: _collapsedListEmailAddress, + isLatestEmail: isLatestEmail, + isCollapsed: _isCollapse, + isLatestTagFocused: _lastTagFocused, + onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter), + onShowFullAction: widget.onShowFullListEmailAddressAction, + ); + }, + onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), + findSuggestions: _findSuggestions, + useDefaultHighlight: false, + suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) { + return RecipientSuggestionItemWidget( + suggestionState: suggestionEmailAddress.state, + emailAddress: suggestionEmailAddress.emailAddress, + suggestionValid: suggestionValid, + highlight: highlight, + onSelectedAction: (emailAddress) { + stateSetter(() => _currentListEmailAddress.add(emailAddress)); + _updateListEmailAddressAction(); + tagEditorState.resetTextField(); + tagEditorState.closeSuggestionBox(); + }, + ); + }, + ); + }, + onAccept: (draggableEmailAddress) => _handleAcceptDraggableEmailAddressAction(draggableEmailAddress, stateSetter), + onLeave: (draggableEmailAddress) { + if (_isDragging) { + stateSetter(() => _isDragging = false); + } + }, + onMove: (details) { + if (!_isDragging) { + stateSetter(() => _isDragging = true); + } + }, + ); + } else { + return TagEditor( + key: widget.keyTagEditor, + length: _collapsedListEmailAddress.length, + controller: widget.controller, + focusNode: widget.focusNode, + autoDisposeFocusNode: widget.autoDisposeFocusNode, + keyboardType: TextInputType.emailAddress, + textInputAction: TextInputAction.done, + debounceDuration: const Duration(milliseconds: 150), + hasAddButton: false, + tagSpacing: 8, + autofocus: widget.prefix != PrefixEmailAddress.to && _currentListEmailAddress.isEmpty, + minTextFieldWidth: 20, + resetTextOnSubmitted: true, + suggestionsBoxElevation: 20.0, + suggestionsBoxBackgroundColor: Colors.white, + suggestionsBoxRadius: 20, + suggestionsBoxMaxHeight: 350, + textStyle: RecipientComposerWidgetStyle.inputTextStyle, + onFocusTagAction: (focused) => _handleFocusTagAction.call(focused, stateSetter), + onDeleteTagAction: () => _handleDeleteLatestTagAction.call(stateSetter), + onSelectOptionAction: (item) => _handleSelectOptionAction.call(item, stateSetter), + onSubmitted: (value) => _handleSubmitTagAction.call(value, stateSetter), + inputDecoration: const InputDecoration(border: InputBorder.none), + tagBuilder: (context, index) { + final currentEmailAddress = _currentListEmailAddress[index]; + final isLatestEmail = currentEmailAddress == _currentListEmailAddress.last; + + return RecipientTagItemWidget( + prefix: widget.prefix, + currentEmailAddress: currentEmailAddress, + currentListEmailAddress: _currentListEmailAddress, + collapsedListEmailAddress: _collapsedListEmailAddress, + isLatestEmail: isLatestEmail, + isCollapsed: _isCollapse, + isLatestTagFocused: _lastTagFocused, + onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter), + onShowFullAction: widget.onShowFullListEmailAddressAction, + ); + }, + onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), + findSuggestions: _findSuggestions, + useDefaultHighlight: false, + suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) { + return RecipientSuggestionItemWidget( + suggestionState: suggestionEmailAddress.state, + emailAddress: 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 a36190ebf..5734c96a1 100644 --- a/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_tag_item_widget.dart @@ -49,52 +49,90 @@ class RecipientTagItemWidget extends StatelessWidget { return Stack( alignment: AlignmentDirectional.centerEnd, children: [ - Padding( - padding: EdgeInsetsDirectional.only( - top: PlatformInfo.isWeb ? 8 : 0, - end: isCollapsed ? 40 : 0), - child: InkWell( - onTap: () => isCollapsed - ? onShowFullAction?.call(prefix) - : null, - child: Draggable( - data: DraggableEmailAddress(emailAddress: currentEmailAddress, prefix: prefix), - feedback: DraggableRecipientTagWidget(emailAddress: currentEmailAddress), - childWhenDragging: DraggableRecipientTagWidget(emailAddress: currentEmailAddress), - child: MouseRegion( - cursor: SystemMouseCursors.grab, - child: Chip( - labelPadding: EdgeInsetsDirectional.symmetric( - horizontal: 4, - vertical: DirectionUtils.isDirectionRTLByHasAnyRtl(currentEmailAddress.asString()) ? 0 : 2 + if (PlatformInfo.isWeb) + Padding( + padding: EdgeInsetsDirectional.only( + top: 8, + end: isCollapsed ? 40 : 0), + child: InkWell( + onTap: () => isCollapsed + ? onShowFullAction?.call(prefix) + : null, + child: Draggable( + data: DraggableEmailAddress(emailAddress: currentEmailAddress, prefix: prefix), + feedback: DraggableRecipientTagWidget(emailAddress: currentEmailAddress), + childWhenDragging: DraggableRecipientTagWidget(emailAddress: currentEmailAddress), + child: MouseRegion( + cursor: SystemMouseCursors.grab, + child: Chip( + labelPadding: EdgeInsetsDirectional.symmetric( + horizontal: 4, + vertical: DirectionUtils.isDirectionRTLByHasAnyRtl(currentEmailAddress.asString()) ? 0 : 2 + ), + label: Text( + currentEmailAddress.asString(), + maxLines: 1, + overflow: CommonTextStyle.defaultTextOverFlow, + softWrap: CommonTextStyle.defaultSoftWrap, + ), + deleteIcon: SvgPicture.asset(_imagePaths.icClose, fit: BoxFit.fill), + labelStyle: RecipientTagItemWidgetStyle.labelTextStyle, + backgroundColor: _getTagBackgroundColor(), + shape: RoundedRectangleBorder( + borderRadius: const BorderRadius.all(Radius.circular(RecipientTagItemWidgetStyle.radius)), + side: _getTagBorderSide(), + ), + avatar: currentEmailAddress.displayName.isNotEmpty + ? GradientCircleAvatarIcon( + colors: currentEmailAddress.avatarColors, + label: currentEmailAddress.displayName.firstLetterToUpperCase, + labelFontSize: RecipientTagItemWidgetStyle.avatarLabelFontSize, + iconSize: RecipientTagItemWidgetStyle.avatarIconSize, + ) + : null, + onDeleted: () => onDeleteTagAction?.call(currentEmailAddress), ), - label: Text( - currentEmailAddress.asString(), - maxLines: 1, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - ), - deleteIcon: SvgPicture.asset(_imagePaths.icClose, fit: BoxFit.fill), - labelStyle: RecipientTagItemWidgetStyle.labelTextStyle, - backgroundColor: _getTagBackgroundColor(), - shape: RoundedRectangleBorder( - borderRadius: const BorderRadius.all(Radius.circular(RecipientTagItemWidgetStyle.radius)), - side: _getTagBorderSide(), - ), - avatar: currentEmailAddress.displayName.isNotEmpty - ? GradientCircleAvatarIcon( - colors: currentEmailAddress.avatarColors, - label: currentEmailAddress.displayName.firstLetterToUpperCase, - labelFontSize: RecipientTagItemWidgetStyle.avatarLabelFontSize, - iconSize: RecipientTagItemWidgetStyle.avatarIconSize, - ) - : null, - onDeleted: () => onDeleteTagAction?.call(currentEmailAddress), ), - ), - ) + ) + ), + ) + else + Padding( + padding: EdgeInsetsDirectional.only(end: isCollapsed ? 40 : 0), + child: InkWell( + onTap: () => isCollapsed + ? onShowFullAction?.call(prefix) + : null, + child: Chip( + labelPadding: EdgeInsetsDirectional.symmetric( + horizontal: 4, + vertical: DirectionUtils.isDirectionRTLByHasAnyRtl(currentEmailAddress.asString()) ? 0 : 2 + ), + label: Text( + currentEmailAddress.asString(), + maxLines: 1, + overflow: CommonTextStyle.defaultTextOverFlow, + softWrap: CommonTextStyle.defaultSoftWrap, + ), + deleteIcon: SvgPicture.asset(_imagePaths.icClose, fit: BoxFit.fill), + labelStyle: RecipientTagItemWidgetStyle.labelTextStyle, + backgroundColor: _getTagBackgroundColor(), + shape: RoundedRectangleBorder( + borderRadius: const BorderRadius.all(Radius.circular(RecipientTagItemWidgetStyle.radius)), + side: _getTagBorderSide(), + ), + avatar: currentEmailAddress.displayName.isNotEmpty + ? GradientCircleAvatarIcon( + colors: currentEmailAddress.avatarColors, + label: currentEmailAddress.displayName.firstLetterToUpperCase, + labelFontSize: RecipientTagItemWidgetStyle.avatarLabelFontSize, + iconSize: RecipientTagItemWidgetStyle.avatarIconSize, + ) + : null, + onDeleted: () => onDeleteTagAction?.call(currentEmailAddress), + ) + ), ), - ), if (isCollapsed) TMailButtonWidget.fromText( margin: RecipientTagItemWidgetStyle.counterMargin,