From b73784742ae5eaa966aa00c771a17773e6bedb55 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 15 Jan 2025 04:27:49 +0700 Subject: [PATCH] TF-3408 Remove limit result in autocomplete --- contact/lib/data/network/contact_api.dart | 4 ++- .../presentation/composer_controller.dart | 5 ++-- .../recipient_composer_widget_style.dart | 2 +- .../widgets/recipient_composer_widget.dart | 25 +++++++++++++++---- .../email_recovery_controller.dart | 14 ++++++++--- .../text_input_field_suggestion_widget.dart | 17 ++++++++++--- .../advanced_filter_controller.dart | 7 +++--- ..._field_autocomplete_email_address_web.dart | 17 ++++++++++--- .../forward_recipient_controller.dart | 15 +++++++---- ...complete_contact_text_field_with_tags.dart | 17 ++++++++++--- lib/main/utils/app_config.dart | 1 + pubspec.lock | 9 ++++--- pubspec.yaml | 6 +++-- 13 files changed, 100 insertions(+), 39 deletions(-) diff --git a/contact/lib/data/network/contact_api.dart b/contact/lib/data/network/contact_api.dart index 20ae20231..496b6066e 100644 --- a/contact/lib/data/network/contact_api.dart +++ b/contact/lib/data/network/contact_api.dart @@ -22,7 +22,9 @@ class ContactAPI { autoCompletePattern.accountId!, ContactFilter(autoCompletePattern.word)); - autoCompleteMethod.addLimit(UnsignedInt(autoCompletePattern.limit ?? 5)); + if (autoCompletePattern.limit != null) { + autoCompleteMethod.addLimit(UnsignedInt(autoCompletePattern.limit!)); + } final autoCompleteInvocation = requestBuilder.invocation(autoCompleteMethod); final response = await (requestBuilder diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 3978f4e83..61501fa14 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -1110,14 +1110,15 @@ class ComposerController extends BaseController } } - Future> getAutoCompleteSuggestion(String queryString) async { - log('ComposerController::getAutoCompleteSuggestion(): $queryString | $_contactSuggestionSource'); + Future> getAutoCompleteSuggestion(String queryString, {int? limit}) async { + log('ComposerController::getAutoCompleteSuggestion():queryString = $queryString | limit = $limit | $_contactSuggestionSource'); _getAllAutoCompleteInteractor = getBinding(); _getAutoCompleteInteractor = getBinding(); _getDeviceContactSuggestionsInteractor = getBinding(); final autoCompletePattern = AutoCompletePattern( word: queryString, + limit: limit, accountId: mailboxDashBoardController.accountId.value); if (_contactSuggestionSource == ContactSuggestionSource.all) { diff --git a/lib/features/composer/presentation/styles/recipient_composer_widget_style.dart b/lib/features/composer/presentation/styles/recipient_composer_widget_style.dart index 359c864ce..52de37d4a 100644 --- a/lib/features/composer/presentation/styles/recipient_composer_widget_style.dart +++ b/lib/features/composer/presentation/styles/recipient_composer_widget_style.dart @@ -8,7 +8,7 @@ class RecipientComposerWidgetStyle { static const double enableBorderRadius = 10; static const double suggestionsBoxElevation = 20.0; static const double suggestionsBoxRadius = 20; - static const double suggestionsBoxMaxHeight = 350; + static const double suggestionsBoxMaxHeight = 300; static const double suggestionBoxWidth = 300; static const double minTextFieldWidth = 20; static const double tagSpacing = 8; diff --git a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart index e9fdb7073..104d14b45 100644 --- a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart @@ -27,7 +27,7 @@ import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_t import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; -typedef OnSuggestionEmailAddress = Future> Function(String word); +typedef OnSuggestionEmailAddress = Future> Function(String word, {int? limit}); typedef OnUpdateListEmailAddressAction = void Function(PrefixEmailAddress prefix, List newData); typedef OnAddEmailAddressTypeAction = void Function(PrefixEmailAddress prefix); typedef OnDeleteEmailAddressTypeAction = void Function(PrefixEmailAddress prefix); @@ -213,7 +213,13 @@ class _RecipientComposerWidgetState extends State { ); }, onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), - findSuggestions: _findSuggestions, + 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( @@ -297,7 +303,13 @@ class _RecipientComposerWidgetState extends State { ); }, onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter), - findSuggestions: _findSuggestions, + 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( @@ -402,7 +414,7 @@ class _RecipientComposerWidgetState extends State { ? _currentListEmailAddress.sublist(0, 1) : _currentListEmailAddress; - FutureOr> _findSuggestions(String query) async { + FutureOr> _findSuggestions(String query, {int? limit}) async { if (_gapBetweenTagChangedAndFindSuggestion?.isActive ?? false) { return []; } @@ -415,7 +427,10 @@ class _RecipientComposerWidgetState extends State { final tmailSuggestion = List.empty(growable: true); if (processedQuery.length >= widget.minInputLengthAutocomplete && widget.onSuggestionEmailAddress != null) { - final listEmailAddress = await widget.onSuggestionEmailAddress!(processedQuery); + final listEmailAddress = await widget.onSuggestionEmailAddress!( + processedQuery, + limit: limit, + ); final listSuggestionEmailAddress = listEmailAddress .map((emailAddress) => _toSuggestionEmailAddress( emailAddress, diff --git a/lib/features/email_recovery/presentation/email_recovery_controller.dart b/lib/features/email_recovery/presentation/email_recovery_controller.dart index d48991ddb..61da363e4 100644 --- a/lib/features/email_recovery/presentation/email_recovery_controller.dart +++ b/lib/features/email_recovery/presentation/email_recovery_controller.dart @@ -229,16 +229,22 @@ class EmailRecoveryController extends BaseController with DateRangePickerMixin { hasAttachment.value = value ?? false; } - Future> getAutoCompleteSuggestion(String word) async { + Future> getAutoCompleteSuggestion(String word, {int? limit}) async { log('EmailRecoveryController::getAutoCompleteSuggestion(): $word | $_contactSuggestionSource'); _getAllAutoCompleteInteractor = getBinding(); _getAutoCompleteInteractor = getBinding(); _getDeviceContactSuggestionsInteractor = getBinding(); + final autoCompletePattern = AutoCompletePattern( + word: word, + limit: limit, + accountId: _accountId + ); + if (_contactSuggestionSource == ContactSuggestionSource.all) { if (_getAllAutoCompleteInteractor != null) { return await _getAllAutoCompleteInteractor! - .execute(AutoCompletePattern(word: word, accountId: _accountId)) + .execute(autoCompletePattern) .then((value) => value.fold( (failure) => [], (success) => success is GetAutoCompleteSuccess @@ -247,7 +253,7 @@ class EmailRecoveryController extends BaseController with DateRangePickerMixin { )); } else if (_getDeviceContactSuggestionsInteractor != null) { return await _getDeviceContactSuggestionsInteractor! - .execute(AutoCompletePattern(word: word, accountId: _accountId)) + .execute(autoCompletePattern) .then((value) => value.fold( (failure) => [], (success) => success is GetDeviceContactSuggestionsSuccess @@ -262,7 +268,7 @@ class EmailRecoveryController extends BaseController with DateRangePickerMixin { return []; } else { return await _getAutoCompleteInteractor! - .execute(AutoCompletePattern(word: word, accountId: _accountId)) + .execute(autoCompletePattern) .then((value) => value.fold( (failure) => [], (success) => success is GetAutoCompleteSuccess diff --git a/lib/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart b/lib/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart index 60e4fd33a..f8829604d 100644 --- a/lib/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart +++ b/lib/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart @@ -17,7 +17,7 @@ import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/suggesstion_email_address.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; -typedef OnSuggestionEmailAddress = Future> Function(String word); +typedef OnSuggestionEmailAddress = Future> Function(String word, {int? limit}); typedef OnUpdateListEmailAddressAction = void Function(EmailRecoveryField field, List newDate); typedef OnDeleteEmailAddressTypeAction = void Function(EmailRecoveryField field, EmailAddress emailAddress); typedef OnShowFullListEmailAddressAction = void Function(EmailRecoveryField field); @@ -160,7 +160,13 @@ class _TextInputFieldSuggestionWidgetState extends State _handleOnTagChangeAction.call(tag, setState), - findSuggestions: _findSuggestions, + findSuggestions: (queryString) => _findSuggestions( + queryString, + limit: AppConfig.defaultLimitAutocomplete, + ), + isLoadMoreOnlyOnce: true, + isLoadMoreReplaceAllOld: false, + loadMoreSuggestions: _findSuggestions, suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) { return SuggestionItemWidget( suggestionState: suggestionEmailAddress.state, @@ -315,7 +321,7 @@ class _TextInputFieldSuggestionWidgetState extends State> _findSuggestions(String query) async { + FutureOr> _findSuggestions(String query, {int? limit}) async { if (_gapBetweenTagChangedAndFindSuggestion?.isActive ?? false) { return []; } @@ -330,7 +336,10 @@ class _TextInputFieldSuggestionWidgetState extends State= widget.minInputLengthAutocomplete && widget.onSuggestionEmailAddress != null ) { - final listEmailAddress = await widget.onSuggestionEmailAddress!(processedQuery); + final listEmailAddress = await widget.onSuggestionEmailAddress!( + processedQuery, + limit: limit, + ); log('_TextFieldAutocompleteEmailAddressWebState::_findSuggestions: listEmailAddress: $listEmailAddress'); final listSuggestionEmailAddress = listEmailAddress.map((emailAddress) => _toSuggestionEmailAddress(emailAddress, _currentListEmailAddress)); tmailSuggestion.addAll(listSuggestionEmailAddress); diff --git a/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart index 583fed6a3..7ac8907f5 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart @@ -222,14 +222,15 @@ class AdvancedFilterController extends BaseController { _mailboxDashBoardController.handleAdvancedSearchEmail(); } - Future> getAutoCompleteSuggestion(String word) async { - log('AdvancedFilterController::getAutoCompleteSuggestion(): word = $word'); + Future> getAutoCompleteSuggestion(String word, {int? limit}) async { + log('AdvancedFilterController::getAutoCompleteSuggestion():word = $word | limit = $limit'); _getAutoCompleteInteractor = getBinding(); return await _getAutoCompleteInteractor ?.execute(AutoCompletePattern( word: word, - accountId: _mailboxDashBoardController.accountId.value + limit: limit, + accountId: _mailboxDashBoardController.accountId.value, )).then((value) => value.fold( (failure) => [], (success) => success is GetAutoCompleteSuccess diff --git a/lib/features/mailbox_dashboard/presentation/widgets/advanced_search/text_field_autocomplete_email_address_web.dart b/lib/features/mailbox_dashboard/presentation/widgets/advanced_search/text_field_autocomplete_email_address_web.dart index 1eeb8a717..3d0c5228f 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/advanced_search/text_field_autocomplete_email_address_web.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/advanced_search/text_field_autocomplete_email_address_web.dart @@ -21,7 +21,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/autocomplete_tag_item_widget_web.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; -typedef OnSuggestionEmailAddress = Future> Function(String word); +typedef OnSuggestionEmailAddress = Future> Function(String word, {int? limit}); typedef OnUpdateListEmailAddressAction = void Function(AdvancedSearchFilterField field, List newData); typedef OnDeleteEmailAddressTypeAction = void Function(AdvancedSearchFilterField field); typedef OnShowFullListEmailAddressAction = void Function(AdvancedSearchFilterField field); @@ -188,7 +188,13 @@ class _TextFieldAutocompleteEmailAddressWebState extends State _handleOnTagChangeAction.call(tag, setState), - findSuggestions: _findSuggestions, + findSuggestions: (queryString) => _findSuggestions( + queryString, + limit: AppConfig.defaultLimitAutocomplete, + ), + isLoadMoreOnlyOnce: true, + isLoadMoreReplaceAllOld: false, + loadMoreSuggestions: _findSuggestions, suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) { return AutoCompleteSuggestionItemWidgetWeb( suggestionState: suggestionEmailAddress.state, @@ -233,7 +239,7 @@ class _TextFieldAutocompleteEmailAddressWebState extends State> _findSuggestions(String query) async { + FutureOr> _findSuggestions(String query, {int? limit}) async { if (_gapBetweenTagChangedAndFindSuggestion?.isActive ?? false) { return []; } @@ -246,7 +252,10 @@ class _TextFieldAutocompleteEmailAddressWebState extends State.empty(growable: true); if (processedQuery.length >= widget.minInputLengthAutocomplete && widget.onSuggestionEmailAddress != null) { - final listEmailAddress = await widget.onSuggestionEmailAddress!(processedQuery); + final listEmailAddress = await widget.onSuggestionEmailAddress!( + processedQuery, + limit: limit, + ); final listSuggestionEmailAddress = listEmailAddress.map((emailAddress) => _toSuggestionEmailAddress(emailAddress, _currentListEmailAddress)); tmailSuggestion.addAll(listSuggestionEmailAddress); } diff --git a/lib/features/manage_account/presentation/forward/controller/forward_recipient_controller.dart b/lib/features/manage_account/presentation/forward/controller/forward_recipient_controller.dart index 9def28097..cb60d6b28 100644 --- a/lib/features/manage_account/presentation/forward/controller/forward_recipient_controller.dart +++ b/lib/features/manage_account/presentation/forward/controller/forward_recipient_controller.dart @@ -52,16 +52,21 @@ class ForwardRecipientController { } } - Future> getAutoCompleteSuggestion(String word) async { - log('ForwardRecipientController::getAutoCompleteSuggestion(): $word'); + Future> getAutoCompleteSuggestion(String word, {int? limit}) async { + log('ForwardRecipientController::getAutoCompleteSuggestion():word = $word | limit = $limit'); _getAllAutoCompleteInteractor = getBinding(); _getAutoCompleteInteractor = getBinding(); _getDeviceContactSuggestionsInteractor = getBinding(); + final autoCompletePattern = AutoCompletePattern( + word: word, + limit: limit, + accountId: _accountId, + ); if (_contactSuggestionSource == ContactSuggestionSource.all) { if (_getAllAutoCompleteInteractor != null) { return await _getAllAutoCompleteInteractor! - .execute(AutoCompletePattern(word: word, accountId: _accountId)) + .execute(autoCompletePattern) .then((value) => value.fold( (failure) => [], (success) => success is GetAutoCompleteSuccess @@ -70,7 +75,7 @@ class ForwardRecipientController { )); } else if (_getDeviceContactSuggestionsInteractor != null) { return await _getDeviceContactSuggestionsInteractor! - .execute(AutoCompletePattern(word: word, accountId: _accountId)) + .execute(autoCompletePattern) .then((value) => value.fold( (failure) => [], (success) => success is GetDeviceContactSuggestionsSuccess @@ -85,7 +90,7 @@ class ForwardRecipientController { return []; } else { return await _getAutoCompleteInteractor! - .execute(AutoCompletePattern(word: word, accountId: _accountId)) + .execute(autoCompletePattern) .then((value) => value.fold( (failure) => [], (success) => success is GetAutoCompleteSuccess diff --git a/lib/features/manage_account/presentation/forward/widgets/autocomplete_contact_text_field_with_tags.dart b/lib/features/manage_account/presentation/forward/widgets/autocomplete_contact_text_field_with_tags.dart index 0b25f2c54..b24652e08 100644 --- a/lib/features/manage_account/presentation/forward/widgets/autocomplete_contact_text_field_with_tags.dart +++ b/lib/features/manage_account/presentation/forward/widgets/autocomplete_contact_text_field_with_tags.dart @@ -26,7 +26,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; import 'package:tmail_ui_user/main/utils/app_utils.dart'; -typedef OnSuggestionContactCallbackAction = Future> Function(String query); +typedef OnSuggestionContactCallbackAction = Future> Function(String query, {int? limit}); typedef OnAddListContactCallbackAction = Function(List listEmailAddress); typedef OnExceptionAddListContactCallbackAction = Function(Exception exception); @@ -140,7 +140,13 @@ class _AutocompleteContactTextFieldWithTagsState extends State _findSuggestions( + queryString, + limit: AppConfig.defaultLimitAutocomplete, + ), + isLoadMoreOnlyOnce: true, + isLoadMoreReplaceAllOld: false, + loadMoreSuggestions: _findSuggestions, suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) { return Container( padding: const EdgeInsets.symmetric(horizontal: 12), @@ -200,7 +206,7 @@ class _AutocompleteContactTextFieldWithTagsState extends State> _findSuggestions(String query) async { + FutureOr> _findSuggestions(String query, {int? limit}) async { final processedQuery = query.trim(); if (processedQuery.isEmpty) { @@ -212,7 +218,10 @@ class _AutocompleteContactTextFieldWithTagsState extends State= widget.minInputLengthAutocomplete && widget.onSuggestionCallback != null ) { - final addedEmailAddresses = await widget.onSuggestionCallback!(processedQuery); + final addedEmailAddresses = await widget.onSuggestionCallback!( + processedQuery, + limit: limit, + ); final listSuggestionEmailAddress = addedEmailAddresses .map((emailAddress) => _toSuggestionEmailAddress(emailAddress, listEmailAddress)) .toList(); diff --git a/lib/main/utils/app_config.dart b/lib/main/utils/app_config.dart index 9f165e945..6c3bcc069 100644 --- a/lib/main/utils/app_config.dart +++ b/lib/main/utils/app_config.dart @@ -9,6 +9,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class AppConfig { static const int defaultMinInputLengthAutocomplete = 3; static const int warningAttachmentFileSizeInMegabytes = 10; + static const int defaultLimitAutocomplete = 8; static const String appDashboardConfigurationPath = "configurations/app_dashboard.json"; static const String appFCMConfigurationPath = "configurations/env.fcm"; diff --git a/pubspec.lock b/pubspec.lock index ec4cec04d..b328456e4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1954,10 +1954,11 @@ packages: super_tag_editor: dependency: "direct main" description: - name: super_tag_editor - sha256: "8e6e978c546f665be421bfdf76db3e7f31aaf10a0cf7ff4f69b71d04124e16c6" - url: "https://pub.dev" - source: hosted + path: "." + ref: fix-some-issue-with-suggestion-box + resolved-ref: "2d6bc8b1481f555e4aa29f744d1a7168641aed8b" + url: "https://github.com/dab246/super_tag_editor.git" + source: git version: "0.3.0" syncfusion_flutter_core: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index 6ab8dc03c..536258d22 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,9 +86,11 @@ dependencies: git: url: https://github.com/linagora/flutter-date-range-picker.git ref: main - # TODO: Move back to master after sprint 25 released - super_tag_editor: 0.3.0 + super_tag_editor: + git: + url: https://github.com/dab246/super_tag_editor.git + ref: fix-some-issue-with-suggestion-box # TODO: We will change it when the PR in upstream repository will be merged # https://github.com/dietfriends/dns_client/pull/9