fix: Avoid duplicated recipients in autocomplete
(cherry picked from commit a4f877d3af39fddfeb1ad029fc8c1df76f0daf32)
This commit is contained in:
+13
-36
@@ -1,5 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math' as math;
|
||||||
|
|
||||||
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';
|
||||||
@@ -11,6 +11,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:get/get.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/extensions/email_address_extension.dart';
|
import 'package:model/extensions/email_address_extension.dart';
|
||||||
|
import 'package:model/extensions/list_email_address_extension.dart';
|
||||||
import 'package:model/mailbox/expand_mode.dart';
|
import 'package:model/mailbox/expand_mode.dart';
|
||||||
import 'package:super_tag_editor/tag_editor.dart';
|
import 'package:super_tag_editor/tag_editor.dart';
|
||||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_autocomplete_tag_item_widget.dart';
|
import 'package:tmail_ui_user/features/base/widget/default_field/default_autocomplete_tag_item_widget.dart';
|
||||||
@@ -193,7 +194,9 @@ class _DefaultAutocompleteInputFieldWidgetState
|
|||||||
suggestionValid: suggestionValid,
|
suggestionValid: suggestionValid,
|
||||||
highlight: highlight,
|
highlight: highlight,
|
||||||
onSelectedAction: (emailAddress) {
|
onSelectedAction: (emailAddress) {
|
||||||
_setStateSafety(() => _currentListEmailAddress.add(emailAddress));
|
if (!_isDuplicated(emailAddress.emailAddress)) {
|
||||||
|
_setStateSafety(() => _currentListEmailAddress.add(emailAddress));
|
||||||
|
}
|
||||||
_updateListEmailAddressAction();
|
_updateListEmailAddressAction();
|
||||||
tagEditorState.resetTextField();
|
tagEditorState.resetTextField();
|
||||||
tagEditorState.closeSuggestionBox();
|
tagEditorState.closeSuggestionBox();
|
||||||
@@ -268,19 +271,12 @@ class _DefaultAutocompleteInputFieldWidgetState
|
|||||||
processedQuery,
|
processedQuery,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
);
|
);
|
||||||
final listSuggestionEmailAddress =
|
final listSuggestionEmailAddress = listEmailAddress
|
||||||
listEmailAddress.map((emailAddress) => _toSuggestionEmailAddress(
|
.map(_toSuggestionEmailAddress);
|
||||||
emailAddress,
|
|
||||||
_currentListEmailAddress,
|
|
||||||
));
|
|
||||||
displayedSuggestion.addAll(listSuggestionEmailAddress);
|
displayedSuggestion.addAll(listSuggestionEmailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayedSuggestion.addAll(_matchedSuggestionEmailAddress(
|
|
||||||
processedQuery,
|
|
||||||
_currentListEmailAddress,
|
|
||||||
));
|
|
||||||
|
|
||||||
final currentTextOnTextField = widget.controller?.text ?? '';
|
final currentTextOnTextField = widget.controller?.text ?? '';
|
||||||
if (currentTextOnTextField.isEmpty) {
|
if (currentTextOnTextField.isEmpty) {
|
||||||
return [];
|
return [];
|
||||||
@@ -293,17 +289,11 @@ class _DefaultAutocompleteInputFieldWidgetState
|
|||||||
if (inputEmail.isEmpty) {
|
if (inputEmail.isEmpty) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return _currentListEmailAddress
|
return _currentListEmailAddress.isDuplicatedEmail(inputEmail.trim());
|
||||||
.map((emailAddress) => emailAddress.email)
|
|
||||||
.nonNulls
|
|
||||||
.contains(inputEmail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SuggestionEmailAddress _toSuggestionEmailAddress(
|
SuggestionEmailAddress _toSuggestionEmailAddress(EmailAddress item) {
|
||||||
EmailAddress item,
|
if (_currentListEmailAddress.isDuplicatedEmail(item.emailAddress)) {
|
||||||
List<EmailAddress> addedEmailAddresses,
|
|
||||||
) {
|
|
||||||
if (addedEmailAddresses.contains(item)) {
|
|
||||||
return SuggestionEmailAddress(
|
return SuggestionEmailAddress(
|
||||||
item,
|
item,
|
||||||
state: SuggestionEmailState.duplicated,
|
state: SuggestionEmailState.duplicated,
|
||||||
@@ -313,18 +303,6 @@ class _DefaultAutocompleteInputFieldWidgetState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<SuggestionEmailAddress> _matchedSuggestionEmailAddress(
|
|
||||||
String query,
|
|
||||||
List<EmailAddress> addedEmailAddress,
|
|
||||||
) {
|
|
||||||
return addedEmailAddress
|
|
||||||
.where((addedMail) => addedMail.emailAddress.contains(query))
|
|
||||||
.map((emailAddress) => SuggestionEmailAddress(
|
|
||||||
emailAddress,
|
|
||||||
state: SuggestionEmailState.duplicated,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateListEmailAddressAction() {
|
void _updateListEmailAddressAction() {
|
||||||
widget.onUpdateListEmailAddressAction?.call(
|
widget.onUpdateListEmailAddressAction?.call(
|
||||||
widget.field,
|
widget.field,
|
||||||
@@ -396,7 +374,7 @@ class _DefaultAutocompleteInputFieldWidgetState
|
|||||||
|
|
||||||
double? _getSuggestionBoxWidth(double maxWidth) {
|
double? _getSuggestionBoxWidth(double maxWidth) {
|
||||||
if (maxWidth < ResponsiveUtils.minTabletWidth) {
|
if (maxWidth < ResponsiveUtils.minTabletWidth) {
|
||||||
final newWidth = min(maxWidth, 300.0);
|
final newWidth = math.min(maxWidth, 300.0);
|
||||||
return newWidth;
|
return newWidth;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -405,8 +383,7 @@ class _DefaultAutocompleteInputFieldWidgetState
|
|||||||
|
|
||||||
void _onAcceptWithDetails(DraggableEmailAddress draggableEmailAddress) {
|
void _onAcceptWithDetails(DraggableEmailAddress draggableEmailAddress) {
|
||||||
if (draggableEmailAddress.filterField != widget.field) {
|
if (draggableEmailAddress.filterField != widget.field) {
|
||||||
if (!_currentListEmailAddress
|
if (!_isDuplicated(draggableEmailAddress.emailAddress.emailAddress)) {
|
||||||
.contains(draggableEmailAddress.emailAddress)) {
|
|
||||||
_setStateSafety(() {
|
_setStateSafety(() {
|
||||||
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
|
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
|
||||||
_isDragging = false;
|
_isDragging = false;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ 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/extensions/list_email_address_extension.dart';
|
||||||
import 'package:super_tag_editor/tag_editor.dart';
|
import 'package:super_tag_editor/tag_editor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/list_address_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/list_address_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/list_named_address_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/list_named_address_extension.dart';
|
||||||
@@ -270,7 +271,9 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
|||||||
suggestionValid: suggestionValid,
|
suggestionValid: suggestionValid,
|
||||||
highlight: highlight,
|
highlight: highlight,
|
||||||
onSelectedAction: (emailAddress) {
|
onSelectedAction: (emailAddress) {
|
||||||
stateSetter(() => _currentListEmailAddress.add(emailAddress));
|
if (!_isDuplicatedRecipient(emailAddress.emailAddress)) {
|
||||||
|
stateSetter(() => _currentListEmailAddress.add(emailAddress));
|
||||||
|
}
|
||||||
_updateListEmailAddressAction();
|
_updateListEmailAddressAction();
|
||||||
tagEditorState.resetTextField();
|
tagEditorState.resetTextField();
|
||||||
tagEditorState.closeSuggestionBox();
|
tagEditorState.closeSuggestionBox();
|
||||||
@@ -434,14 +437,11 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
|||||||
limit: limit,
|
limit: limit,
|
||||||
);
|
);
|
||||||
final listSuggestionEmailAddress = listEmailAddress
|
final listSuggestionEmailAddress = listEmailAddress
|
||||||
.map((emailAddress) => _toSuggestionEmailAddress(
|
.map(_toSuggestionEmailAddress);
|
||||||
emailAddress,
|
|
||||||
_currentListEmailAddress));
|
|
||||||
tmailSuggestion.addAll(listSuggestionEmailAddress);
|
tmailSuggestion.addAll(listSuggestionEmailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmailSuggestion.addAll(_matchedSuggestionEmailAddress(processedQuery, _currentListEmailAddress));
|
|
||||||
|
|
||||||
final currentTextOnTextField = widget.controller?.text ?? '';
|
final currentTextOnTextField = widget.controller?.text ?? '';
|
||||||
if (currentTextOnTextField.isEmpty) {
|
if (currentTextOnTextField.isEmpty) {
|
||||||
return [];
|
return [];
|
||||||
@@ -453,27 +453,17 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
|||||||
bool _isDuplicatedRecipient(String inputEmail) {
|
bool _isDuplicatedRecipient(String inputEmail) {
|
||||||
if (inputEmail.trim().isEmpty) return false;
|
if (inputEmail.trim().isEmpty) return false;
|
||||||
|
|
||||||
return _currentListEmailAddress
|
return _currentListEmailAddress.isDuplicatedEmail(inputEmail.trim());
|
||||||
.any((emailAddress) => emailAddress.email?.trim() == inputEmail.trim());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SuggestionEmailAddress _toSuggestionEmailAddress(EmailAddress item, List<EmailAddress> addedEmailAddresses) {
|
SuggestionEmailAddress _toSuggestionEmailAddress(EmailAddress item) {
|
||||||
if (addedEmailAddresses.contains(item)) {
|
if (_currentListEmailAddress.isDuplicatedEmail(item.emailAddress)) {
|
||||||
return SuggestionEmailAddress(item, state: SuggestionEmailState.duplicated);
|
return SuggestionEmailAddress(item, state: SuggestionEmailState.duplicated);
|
||||||
} else {
|
} else {
|
||||||
return SuggestionEmailAddress(item);
|
return SuggestionEmailAddress(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<SuggestionEmailAddress> _matchedSuggestionEmailAddress(String query, List<EmailAddress> addedEmailAddress) {
|
|
||||||
return addedEmailAddress
|
|
||||||
.where((addedMail) => addedMail.emailAddress.contains(query))
|
|
||||||
.map((emailAddress) => SuggestionEmailAddress(
|
|
||||||
emailAddress,
|
|
||||||
state: SuggestionEmailState.duplicated
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleGapBetweenTagChangedAndFindSuggestion() {
|
void _handleGapBetweenTagChangedAndFindSuggestion() {
|
||||||
log('_RecipientComposerWidgetState::_handleGapBetweenTagChangedAndFindSuggestion:Timeout');
|
log('_RecipientComposerWidgetState::_handleGapBetweenTagChangedAndFindSuggestion:Timeout');
|
||||||
}
|
}
|
||||||
@@ -571,7 +561,7 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
|||||||
log('_RecipientComposerWidgetState::_handleAcceptDraggableEmailAddressAction: $draggableEmailAddress');
|
log('_RecipientComposerWidgetState::_handleAcceptDraggableEmailAddressAction: $draggableEmailAddress');
|
||||||
if (draggableEmailAddress.composerId == widget.composerId) {
|
if (draggableEmailAddress.composerId == widget.composerId) {
|
||||||
if (draggableEmailAddress.filterField != widget.prefix.filterField) {
|
if (draggableEmailAddress.filterField != widget.prefix.filterField) {
|
||||||
if (!_currentListEmailAddress.contains(draggableEmailAddress.emailAddress)) {
|
if (!_isDuplicatedRecipient(draggableEmailAddress.emailAddress.emailAddress)) {
|
||||||
stateSetter(() {
|
stateSetter(() {
|
||||||
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
|
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
|
||||||
_isDragging = false;
|
_isDragging = false;
|
||||||
@@ -589,7 +579,7 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_currentListEmailAddress.contains(draggableEmailAddress.emailAddress)) {
|
if (!_isDuplicatedRecipient(draggableEmailAddress.emailAddress.emailAddress)) {
|
||||||
stateSetter(() {
|
stateSetter(() {
|
||||||
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
|
_currentListEmailAddress.add(draggableEmailAddress.emailAddress);
|
||||||
_isDragging = false;
|
_isDragging = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user