TF-3480 Support drag email address from To/Cc/Bcc/ReplyTo of composer to To/Cc/Bcc/ReplyTo of other

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-03-12 21:04:29 +07:00
committed by Dat H. Pham
parent 9789458055
commit e6b2868044
6 changed files with 104 additions and 34 deletions
@@ -68,7 +68,6 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/list_sha
import 'package:tmail_ui_user/features/composer/presentation/extensions/update_screen_display_mode_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/mixin/drag_drog_file_mixin.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/create_email_request.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/draggable_email_address.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/saved_email_draft.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/signature_status.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/inline_image.dart';
@@ -2130,33 +2129,7 @@ class ComposerController extends BaseController
void setSubjectEmail(String subject) => subjectEmail.value = subject;
void removeDraggableEmailAddress(DraggableEmailAddress draggableEmailAddress) {
log('ComposerController::removeDraggableEmailAddress: $draggableEmailAddress');
switch(draggableEmailAddress.prefix) {
case PrefixEmailAddress.to:
listToEmailAddress.remove(draggableEmailAddress.emailAddress);
toAddressExpandMode.value = ExpandMode.EXPAND;
break;
case PrefixEmailAddress.cc:
listCcEmailAddress.remove(draggableEmailAddress.emailAddress);
ccAddressExpandMode.value = ExpandMode.EXPAND;
break;
case PrefixEmailAddress.bcc:
listBccEmailAddress.remove(draggableEmailAddress.emailAddress);
bccAddressExpandMode.value = ExpandMode.EXPAND;
break;
case PrefixEmailAddress.replyTo:
listReplyToEmailAddress.remove(draggableEmailAddress.emailAddress);
replyToAddressExpandMode.value = ExpandMode.EXPAND;
break;
default:
break;
}
isInitialRecipient.value = true;
isInitialRecipient.refresh();
updateStatusEmailSendButton();
}
void onAttachmentDropZoneListener(Attachment attachment) {
log('ComposerController::onAttachmentDropZoneListener: attachment = $attachment');
@@ -7,6 +7,7 @@ import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/composer_print_draft_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/view/web/desktop_responsive_container_view.dart';
@@ -92,6 +93,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
),
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.to,
listEmailAddress: controller.listToEmailAddress,
imagePaths: controller.imagePaths,
@@ -122,6 +124,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.cc,
listEmailAddress: controller.listCcEmailAddress,
imagePaths: controller.imagePaths,
@@ -148,6 +151,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.bcc,
listEmailAddress: controller.listBccEmailAddress,
imagePaths: controller.imagePaths,
@@ -174,6 +178,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.replyTo,
listEmailAddress: controller.listReplyToEmailAddress,
imagePaths: controller.imagePaths,
@@ -365,6 +370,7 @@ class ComposerView extends GetWidget<ComposerController> {
onChangeIdentity: controller.onChangeIdentity,
),
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.to,
listEmailAddress: controller.listToEmailAddress,
imagePaths: controller.imagePaths,
@@ -395,6 +401,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.cc,
listEmailAddress: controller.listCcEmailAddress,
imagePaths: controller.imagePaths,
@@ -421,6 +428,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.bcc,
listEmailAddress: controller.listBccEmailAddress,
imagePaths: controller.imagePaths,
@@ -447,6 +455,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.replyTo,
listEmailAddress: controller.listReplyToEmailAddress,
imagePaths: controller.imagePaths,
@@ -680,6 +689,7 @@ class ComposerView extends GetWidget<ComposerController> {
onChangeIdentity: controller.onChangeIdentity,
),
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.to,
listEmailAddress: controller.listToEmailAddress,
imagePaths: controller.imagePaths,
@@ -710,6 +720,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.ccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.cc,
listEmailAddress: controller.listCcEmailAddress,
imagePaths: controller.imagePaths,
@@ -736,6 +747,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.bccRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.bcc,
listEmailAddress: controller.listBccEmailAddress,
imagePaths: controller.imagePaths,
@@ -762,6 +774,7 @@ class ComposerView extends GetWidget<ComposerController> {
),
if (controller.replyToRecipientState.value == PrefixRecipientState.enabled)
RecipientComposerWidget(
composerId: composerId,
prefix: PrefixEmailAddress.replyTo,
listEmailAddress: controller.listReplyToEmailAddress,
imagePaths: controller.imagePaths,
@@ -0,0 +1,57 @@
import 'package:model/email/prefix_email_address.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/model/draggable_email_address.dart';
extension RemoveDraggableEmailAddressBetweenRecipientFieldsExtension on ComposerController {
void removeDraggableEmailAddress(DraggableEmailAddress draggableEmailAddress) {
if (composerId == null || composerId == draggableEmailAddress.composerId) {
removeDraggableEmailAddressByComposerController(
controller: this,
draggableEmailAddress: draggableEmailAddress,
);
} else if (draggableEmailAddress.composerId != null) {
final composerManager = mailboxDashBoardController.composerManager;
if (!composerManager.composers.containsKey(composerId)) return;
final draggableComposerController = composerManager
.getComposerView(draggableEmailAddress.composerId!)
.controller;
removeDraggableEmailAddressByComposerController(
controller: draggableComposerController,
draggableEmailAddress: draggableEmailAddress,
);
}
}
void removeDraggableEmailAddressByComposerController({
required ComposerController controller,
required DraggableEmailAddress draggableEmailAddress,
}) {
switch(draggableEmailAddress.prefix) {
case PrefixEmailAddress.to:
controller.listToEmailAddress.remove(draggableEmailAddress.emailAddress);
controller.toAddressExpandMode.value = ExpandMode.EXPAND;
break;
case PrefixEmailAddress.cc:
controller.listCcEmailAddress.remove(draggableEmailAddress.emailAddress);
controller.ccAddressExpandMode.value = ExpandMode.EXPAND;
break;
case PrefixEmailAddress.bcc:
controller.listBccEmailAddress.remove(draggableEmailAddress.emailAddress);
controller.bccAddressExpandMode.value = ExpandMode.EXPAND;
break;
case PrefixEmailAddress.replyTo:
controller.listReplyToEmailAddress.remove(draggableEmailAddress.emailAddress);
controller.replyToAddressExpandMode.value = ExpandMode.EXPAND;
break;
default:
break;
}
controller.isInitialRecipient.value = true;
controller.isInitialRecipient.refresh();
controller.updateStatusEmailSendButton();
}
}
@@ -5,12 +5,14 @@ import 'package:model/email/prefix_email_address.dart';
class DraggableEmailAddress with EquatableMixin {
final EmailAddress emailAddress;
final PrefixEmailAddress prefix;
final String? composerId;
DraggableEmailAddress({
required this.emailAddress,
required this.prefix,
this.composerId,
});
@override
List<Object?> get props => [emailAddress, prefix];
List<Object?> get props => [emailAddress, prefix, composerId];
}
@@ -68,6 +68,7 @@ class RecipientComposerWidget extends StatefulWidget {
final OnEnableAllRecipientsInputAction? onEnableAllRecipientsInputAction;
final bool isTestingForWeb;
final int minInputLengthAutocomplete;
final String? composerId;
const RecipientComposerWidget({
super.key,
@@ -89,6 +90,7 @@ class RecipientComposerWidget extends StatefulWidget {
this.nextFocusNode,
this.padding,
this.margin,
this.composerId,
this.onUpdateListEmailAddressAction,
this.onSuggestionEmailAddress,
this.onAddEmailAddressTypeAction,
@@ -205,6 +207,7 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
index: index,
imagePaths: widget.imagePaths,
prefix: widget.prefix,
composerId: widget.composerId,
currentEmailAddress: currentEmailAddress,
currentListEmailAddress: _currentListEmailAddress,
collapsedListEmailAddress: _collapsedListEmailAddress,
@@ -296,6 +299,7 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
index: index,
imagePaths: widget.imagePaths,
prefix: widget.prefix,
composerId: widget.composerId,
currentEmailAddress: currentEmailAddress,
currentListEmailAddress: _currentListEmailAddress,
collapsedListEmailAddress: _collapsedListEmailAddress,
@@ -567,7 +571,26 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
StateSetter stateSetter
) {
log('_RecipientComposerWidgetState::_handleAcceptDraggableEmailAddressAction: $draggableEmailAddress');
if (draggableEmailAddress.prefix != widget.prefix) {
if (draggableEmailAddress.composerId == widget.composerId) {
if (draggableEmailAddress.prefix != widget.prefix) {
if (!_currentListEmailAddress.contains(draggableEmailAddress.emailAddress)) {
stateSetter(() {
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
_isDragging = false;
});
_updateListEmailAddressAction();
} else {
if (_isDragging) {
stateSetter(() => _isDragging = false);
}
}
widget.onRemoveDraggableEmailAddressAction?.call(draggableEmailAddress);
} else {
if (_isDragging) {
stateSetter(() => _isDragging = false);
}
}
} else {
if (!_currentListEmailAddress.contains(draggableEmailAddress.emailAddress)) {
stateSetter(() {
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
@@ -580,10 +603,6 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
}
}
widget.onRemoveDraggableEmailAddressAction?.call(draggableEmailAddress);
} else {
if (_isDragging) {
stateSetter(() => _isDragging = false);
}
}
}
@@ -31,6 +31,7 @@ class RecipientTagItemWidget extends StatelessWidget {
final OnShowFullListEmailAddressAction? onShowFullAction;
final OnDeleteTagAction? onDeleteTagAction;
final bool isTestingForWeb;
final String? composerId;
const RecipientTagItemWidget({
super.key,
@@ -47,6 +48,7 @@ class RecipientTagItemWidget extends StatelessWidget {
this.onShowFullAction,
this.onDeleteTagAction,
this.maxWidth,
this.composerId,
});
@override
@@ -89,7 +91,11 @@ class RecipientTagItemWidget extends StatelessWidget {
if (PlatformInfo.isWeb || isTestingForWeb) {
tagWidget = Draggable<DraggableEmailAddress>(
data: DraggableEmailAddress(emailAddress: currentEmailAddress, prefix: prefix),
data: DraggableEmailAddress(
emailAddress: currentEmailAddress,
prefix: prefix,
composerId: composerId,
),
feedback: DraggableRecipientTagWidget(emailAddress: currentEmailAddress),
childWhenDragging: DraggableRecipientTagWidget(emailAddress: currentEmailAddress),
child: MouseRegion(