From 3392bf16bc40cc54740f95c64a034f1322c1a35d Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 17 Sep 2024 13:13:28 +0700 Subject: [PATCH] TF-3006 [WEB] Handle mail address in quick search bar --- .../presentation/action/dashboard_action.dart | 14 +-- .../advanced_filter_controller.dart | 37 ++++---- .../mailbox_dashboard_controller.dart | 87 +++++++++++-------- .../controller/search_controller.dart | 11 ++- .../model/search/search_email_filter.dart | 10 +-- .../widgets/search_input_form_widget.dart | 19 ++-- .../presentation/search_email_controller.dart | 5 -- .../presentation/thread_controller.dart | 20 ++--- .../mailbox_dashboard_controller_test.dart | 7 +- 9 files changed, 111 insertions(+), 99 deletions(-) diff --git a/lib/features/mailbox_dashboard/presentation/action/dashboard_action.dart b/lib/features/mailbox_dashboard/presentation/action/dashboard_action.dart index 787fa6bd6..b1686a61f 100644 --- a/lib/features/mailbox_dashboard/presentation/action/dashboard_action.dart +++ b/lib/features/mailbox_dashboard/presentation/action/dashboard_action.dart @@ -54,13 +54,15 @@ class OpenEmailDetailedFromSuggestionQuickSearchAction extends DashBoardAction { List get props => [presentationEmail]; } -class StartSearchEmailAction extends DashBoardAction { - final QuickSearchFilter? filter; +class StartSearchEmailAction extends DashBoardAction {} - StartSearchEmailAction({this.filter}); +class StartSearchEmailBySearchFilterAction extends DashBoardAction { + final QuickSearchFilter searchFilter; + + StartSearchEmailBySearchFilterAction(this.searchFilter); @override - List get props => [filter]; + List get props => [searchFilter]; } class EmptyTrashAction extends DashBoardAction {} @@ -153,4 +155,6 @@ class CancelSelectionSearchEmailAction extends DashBoardAction {} class OpenAdvancedSearchViewAction extends DashBoardAction {} -class ClearSearchFilterAppliedAction extends DashBoardAction {} \ No newline at end of file +class ClearSearchFilterAppliedAction extends DashBoardAction {} + +class ClearAdvancedSearchFilterEmailAction extends DashBoardAction {} \ No newline at end of file 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 da3a463b4..66c4c830c 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart @@ -79,14 +79,9 @@ class AdvancedFilterController extends BaseController { } void clearSearchFilter() { - searchController.clearSearchFilter(); _resetAllToOriginalValue(); _clearAllTextFieldInput(); - searchController.searchInputController.clear(); - searchController.clearSortOrder(); - searchController.deactivateAdvancedSearch(); - searchController.isAdvancedSearchViewOpen.value = false; - _mailboxDashBoardController.searchEmail(); + _mailboxDashBoardController.handleClearAdvancedSearchFilterEmail(); } void _updateFilterEmailFromAdvancedSearchView() { @@ -119,8 +114,6 @@ class AdvancedFilterController extends BaseController { searchController.updateFilterEmail(toOption: const None()); } - searchController.updateFilterEmail(sortOrderOption: searchController.sortOrderFiltered.value.getSortOrder()); - searchController.updateFilterEmail( mailboxOption: optionOf(_destinationMailboxSelected), subjectOption: optionOf(subjectFilterInputController.text), @@ -170,7 +163,7 @@ class AdvancedFilterController extends BaseController { searchController.updateFilterEmail(beforeOption: const None()); } searchController.isAdvancedSearchViewOpen.value = false; - _mailboxDashBoardController.searchEmail(); + _mailboxDashBoardController.handleAdvancedSearchEmail(); } Future> getAutoCompleteSuggestion(String word) async { @@ -405,17 +398,8 @@ class AdvancedFilterController extends BaseController { ); } else if (action is ClearDateRangeToAdvancedSearch) { _updateDateRangeTime(action.receiveTime); - } else if (action is StartSearchEmailAction) { - switch(action.filter) { - case QuickSearchFilter.from: - _updateFromField(); - break; - case QuickSearchFilter.to: - _updateToField(); - break; - default: - break; - } + } else if (action is StartSearchEmailBySearchFilterAction) { + _handleSearchEmailBySearchFilterAction(action.searchFilter); } else if (action is SearchEmailByFromFieldsAction) { searchController.clearSearchFilter(); _resetAllToOriginalValue(); @@ -480,6 +464,19 @@ class AdvancedFilterController extends BaseController { applyAdvancedSearchFilter(); } + void _handleSearchEmailBySearchFilterAction(QuickSearchFilter searchFilter) { + switch(searchFilter) { + case QuickSearchFilter.from: + _updateFromField(); + break; + case QuickSearchFilter.to: + _updateToField(); + break; + default: + break; + } + } + @override void onClose() { _removeFocusListener(); diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index eadf7f6f6..5f88cd3b0 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -667,20 +667,55 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo bool isSelectionEnabled() => currentSelectMode.value == SelectMode.ACTIVE; - void searchEmail({String? queryString}) { - log('MailboxDashBoardController::searchEmail():'); + void handleAdvancedSearchEmail() { + log('MailboxDashBoardController::handleAdvancedSearchEmail:'); clearFilterMessageOption(); - searchController.clearFilterSuggestion(); - if (queryString?.isNotEmpty == true) { - searchController.updateFilterEmail(textOption: Some(SearchQuery(queryString!))); - } - searchController.updateFilterEmail(sortOrderOption: searchController.sortOrderFiltered.value.getSortOrder()); - dispatchAction(StartSearchEmailAction()); - FocusManager.instance.primaryFocus?.unfocus(); if (_searchInsideEmailDetailedViewIsActive()) { _closeEmailDetailedView(); } _unSelectedMailbox(); + searchController.clearFilterSuggestion(); + FocusManager.instance.primaryFocus?.unfocus(); + dispatchAction(StartSearchEmailAction()); + } + + void handleClearAdvancedSearchFilterEmail() { + log('MailboxDashBoardController::handleClearAdvancedSearchFilterEmail:'); + clearFilterMessageOption(); + if (_searchInsideEmailDetailedViewIsActive()) { + _closeEmailDetailedView(); + } + _unSelectedMailbox(); + searchController.clearAllFilterSearch(); + FocusManager.instance.primaryFocus?.unfocus(); + dispatchAction(ClearAdvancedSearchFilterEmailAction()); + } + + void searchEmailByQueryString(String queryString) { + final isMailAddress = EmailUtils.isEmailAddressValid(queryString); + log('MailboxDashBoardController::searchEmailByQueryString():QueryString = $queryString | isMailAddress = $isMailAddress'); + clearFilterMessageOption(); + if (_searchInsideEmailDetailedViewIsActive()) { + _closeEmailDetailedView(); + } + _unSelectedMailbox(); + searchController.clearFilterSuggestion(); + + searchController.updateFilterEmail( + textOption: !isMailAddress + ? Some(SearchQuery(queryString)) + : null, + fromOption: isMailAddress + ? Some({queryString}) + : null); + + FocusManager.instance.primaryFocus?.unfocus(); + + if (isMailAddress) { + dispatchAction(StartSearchEmailBySearchFilterAction(QuickSearchFilter.from)); + } else { + dispatchAction(StartSearchEmailAction()); + } } bool _searchInsideEmailDetailedViewIsActive() { @@ -1675,7 +1710,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo if (newContact is EmailAddress) { searchController.updateFilterEmail(fromOption: Some({newContact.emailAddress})); - dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.from)); + dispatchAction(StartSearchEmailBySearchFilterAction(QuickSearchFilter.from)); } } @@ -1693,7 +1728,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo if (newContact is EmailAddress) { searchController.updateFilterEmail(toOption: Some({newContact.emailAddress})); - dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.to)); + dispatchAction(StartSearchEmailBySearchFilterAction(QuickSearchFilter.to)); } } @@ -1721,11 +1756,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo searchController.updateFilterEmail( mailboxOption: destinationMailbox.id == PresentationMailbox.unifiedMailbox.id ? const None() - : Some(destinationMailbox), - beforeOption: const None(), - positionOption: searchController.sortOrderFiltered.value.isScrollByPosition() - ? const Some(0) - : const None() + : Some(destinationMailbox) ); dispatchAction(StartSearchEmailAction()); @@ -1745,8 +1776,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo searchController.updateFilterEmail( emailReceiveTimeTypeOption: Some(receiveTime), startDateOption: optionOf(startDate?.toUTCDate()), - endDateOption: optionOf(endDate?.toUTCDate()), - beforeOption: const None() + endDateOption: optionOf(endDate?.toUTCDate()) ); dispatchAction(StartSearchEmailAction()); } @@ -1756,8 +1786,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo searchController.updateFilterEmail( emailReceiveTimeTypeOption: Some(receiveTime), startDateOption: const None(), - endDateOption: const None(), - beforeOption: const None() + endDateOption: const None() ); dispatchAction(StartSearchEmailAction()); } @@ -1767,7 +1796,6 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo log('MailboxDashBoardController::selectSortOrderQuickSearchFilter():sortOrder: $sortOrder'); popBack(); searchController.sortOrderFiltered.value = sortOrder; - searchController.updateFilterEmail(sortOrderOption: sortOrder.getSortOrder()); dispatchAction(StartSearchEmailAction()); } @@ -1776,27 +1804,24 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo searchController.updateFilterEmail( emailReceiveTimeTypeOption: const Some(EmailReceiveTimeType.allTime), startDateOption: const None(), - endDateOption: const None(), - beforeOption: const None() + endDateOption: const None() ); dispatchAction(StartSearchEmailAction()); } void _deleteSortOrderSearchFilter() { searchController.sortOrderFiltered.value = EmailSortOrderType.mostRecent; - searchController.updateFilterEmail( - sortOrderOption: EmailSortOrderType.mostRecent.getSortOrder()); dispatchAction(StartSearchEmailAction()); } void _deleteFromSearchFilter() { searchController.updateFilterEmail(fromOption: const None()); - dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.from)); + dispatchAction(StartSearchEmailBySearchFilterAction(QuickSearchFilter.from)); } void _deleteToSearchFilter() { searchController.updateFilterEmail(toOption: const None()); - dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.to)); + dispatchAction(StartSearchEmailBySearchFilterAction(QuickSearchFilter.to)); } void _deleteHasAttachmentSearchFilter() { @@ -1805,13 +1830,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo } void _deleteFolderSearchFilter() { - searchController.updateFilterEmail( - mailboxOption: const None(), - beforeOption: const None(), - positionOption: searchController.sortOrderFiltered.value.isScrollByPosition() - ? const Some(0) - : const None() - ); + searchController.updateFilterEmail(mailboxOption: const None()); dispatchAction(StartSearchEmailAction()); } diff --git a/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart index 5f7490426..2cccca644 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart @@ -170,7 +170,6 @@ class SearchController extends BaseController with DateRangePickerMixin { Option? beforeOption, Option? startDateOption, Option? endDateOption, - Option>? sortOrderOption, Option? positionOption, }) { searchEmailFilter.value = searchEmailFilter.value.copyWith( @@ -185,7 +184,6 @@ class SearchController extends BaseController with DateRangePickerMixin { beforeOption: beforeOption, startDateOption: startDateOption, endDateOption: endDateOption, - sortOrderOption: sortOrderOption, positionOption: positionOption, ); searchEmailFilter.refresh(); @@ -284,6 +282,15 @@ class SearchController extends BaseController with DateRangePickerMixin { sortOrderFiltered.value = EmailSortOrderType.mostRecent; } + void clearAllFilterSearch() { + _clearAllTextInputSimpleSearch(); + clearSortOrder(); + clearFilterSuggestion(); + clearSearchFilter(); + deactivateAdvancedSearch(); + hideAdvancedSearchFormView(); + } + void disableAllSearchEmail() { _clearAllTextInputSimpleSearch(); deactivateSimpleSearch(); diff --git a/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart b/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart index 526430daa..19b428a71 100644 --- a/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart +++ b/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart @@ -4,7 +4,6 @@ import 'package:equatable/equatable.dart'; import 'package:jmap_dart_client/jmap/core/filter/filter.dart'; import 'package:jmap_dart_client/jmap/core/filter/filter_operator.dart'; import 'package:jmap_dart_client/jmap/core/filter/operator/logic_filter_operator.dart'; -import 'package:jmap_dart_client/jmap/core/sort/comparator.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart'; import 'package:model/email/prefix_email_address.dart'; @@ -28,12 +27,9 @@ class SearchEmailFilter with EquatableMixin, OptionParamMixin { final UTCDate? before; final UTCDate? startDate; final UTCDate? endDate; - final Set? sortOrder; final int? position; - factory SearchEmailFilter.initial() => SearchEmailFilter( - sortOrder: EmailSortOrderType.mostRecent.getSortOrder().toNullable() - ); + factory SearchEmailFilter.initial() => SearchEmailFilter(); SearchEmailFilter({ Set? from, @@ -48,7 +44,6 @@ class SearchEmailFilter with EquatableMixin, OptionParamMixin { this.before, this.startDate, this.endDate, - this.sortOrder, this.position, }) : from = from ?? {}, to = to ?? {}, @@ -71,7 +66,6 @@ class SearchEmailFilter with EquatableMixin, OptionParamMixin { Option? beforeOption, Option? startDateOption, Option? endDateOption, - Option>? sortOrderOption, Option? positionOption, }) { return SearchEmailFilter( @@ -87,7 +81,6 @@ class SearchEmailFilter with EquatableMixin, OptionParamMixin { before: getOptionParam(beforeOption, before), startDate: getOptionParam(startDateOption, startDate), endDate: getOptionParam(endDateOption, endDate), - sortOrder: getOptionParam(sortOrderOption, sortOrder), position: getOptionParam(positionOption, position), ); } @@ -166,7 +159,6 @@ class SearchEmailFilter with EquatableMixin, OptionParamMixin { before, startDate, endDate, - sortOrder, position, ]; } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/widgets/search_input_form_widget.dart b/lib/features/mailbox_dashboard/presentation/widgets/search_input_form_widget.dart index 6f1d11b89..848711df8 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/search_input_form_widget.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/search_input_form_widget.dart @@ -4,6 +4,7 @@ import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/views/button/icon_button_web.dart'; import 'package:core/presentation/views/quick_search/quick_search_input_form.dart'; +import 'package:core/utils/app_logger.dart'; import 'package:core/utils/direction_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; @@ -126,17 +127,20 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin { }); } - void _invokeSearchEmailAction(String query) { + void _invokeSearchEmailAction(String queryString) { + log('SearchInputFormWidget::_invokeSearchEmailAction:QueryString = $queryString'); _searchController.searchFocus.unfocus(); _searchController.enableSearch(); - if (query.isNotEmpty) { - _searchController.saveRecentSearch(RecentSearch.now(query)); + if (queryString.isNotEmpty) { + _searchController.saveRecentSearch(RecentSearch.now(queryString)); } - if (query.isNotEmpty || _searchController.listFilterOnSuggestionForm.isNotEmpty) { + if (queryString.isNotEmpty || _searchController.listFilterOnSuggestionForm.isNotEmpty) { + _searchController.clearSortOrder(); + _searchController.clearSearchFilter(); _searchController.applyFilterSuggestionToSearchFilter(_dashBoardController.sessionCurrent?.username); - _dashBoardController.searchEmail(queryString: query); + _dashBoardController.searchEmailByQueryString(queryString); } else { _dashBoardController.clearSearchEmail(); } @@ -154,9 +158,10 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin { _searchController.searchInputController.text = recent.value; _searchController.searchFocus.unfocus(); _searchController.enableSearch(); - + _searchController.clearSortOrder(); + _searchController.clearSearchFilter(); _searchController.applyFilterSuggestionToSearchFilter(_dashBoardController.sessionCurrent?.username); - _dashBoardController.searchEmail(queryString: recent.value); + _dashBoardController.searchEmailByQueryString(recent.value); } Widget _buildShowAllResultButton(BuildContext context, String keyword) { diff --git a/lib/features/search/email/presentation/search_email_controller.dart b/lib/features/search/email/presentation/search_email_controller.dart index dd566c167..0d24e6a11 100644 --- a/lib/features/search/email/presentation/search_email_controller.dart +++ b/lib/features/search/email/presentation/search_email_controller.dart @@ -10,7 +10,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; -import 'package:jmap_dart_client/jmap/core/sort/comparator.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; @@ -616,7 +615,6 @@ class SearchEmailController extends BaseController void selectSortOrderQuickSearchFilter(BuildContext context, EmailSortOrderType sortOrderType) { popBack(); _updateSimpleSearchFilter( - sortOrderOption: sortOrderType.getSortOrder(), beforeOption: const None(), positionOption: emailSortOrderType.value.isScrollByPosition() ? const Some(0) : const None() ); @@ -744,7 +742,6 @@ class SearchEmailController extends BaseController Option? beforeOption, Option? startDateOption, Option? endDateOption, - Option>? sortOrderOption, Option? positionOption, Option>? hasKeywordOption, }) { @@ -758,7 +755,6 @@ class SearchEmailController extends BaseController beforeOption: beforeOption, startDateOption: startDateOption, endDateOption: endDateOption, - sortOrderOption: sortOrderOption, positionOption: positionOption, hasKeywordOption: hasKeywordOption, ); @@ -1008,7 +1004,6 @@ class SearchEmailController extends BaseController void _deleteSortOrderSearchFilter(BuildContext context) { _updateSimpleSearchFilter( - sortOrderOption: EmailSortOrderType.mostRecent.getSortOrder(), beforeOption: const None(), positionOption: emailSortOrderType.value.isScrollByPosition() ? const Some(0) diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index f3bb28c51..5eff361d4 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -301,7 +301,9 @@ class ThreadController extends BaseController with EmailActionController { mailboxContain: mailboxContain, ); mailboxDashBoardController.clearDashBoardAction(); - } else if (action is StartSearchEmailAction) { + } else if (action is StartSearchEmailAction + || action is ClearAdvancedSearchFilterEmailAction + || action is StartSearchEmailBySearchFilterAction) { cancelSelectEmail(); _replaceBrowserHistory(); _searchEmail(); @@ -816,17 +818,11 @@ class ThreadController extends BaseController with EmailActionController { mailboxDashBoardController.emailsInCurrentMailbox.clear(); canSearchMore = false; - if (searchController.sortOrderFiltered.value.isScrollByPosition()) { - searchController.updateFilterEmail( - positionOption: const Some(0), - beforeOption: const None(), - ); - } else { - searchController.updateFilterEmail( - positionOption: const None(), - beforeOption: const None(), - ); - } + searchController.updateFilterEmail( + positionOption: searchController.sortOrderFiltered.value.isScrollByPosition() + ? const Some(0) + : const None(), + beforeOption: const None()); searchController.activateSimpleSearch(); diff --git a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart index 469ff10ef..e36ff127d 100644 --- a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart +++ b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart @@ -394,7 +394,7 @@ void main() { when(context.owner).thenReturn(BuildOwner(focusManager: FocusManager())); // expect query in search controller update as expected - mailboxDashboardController.searchEmail(queryString: queryString); + mailboxDashboardController.searchEmailByQueryString(queryString); expect(searchController.searchEmailFilter.value.text, SearchQuery(queryString)); // expect sort in search controller update as expected @@ -463,7 +463,6 @@ void main() { text: SearchQuery(emailContainsWord), notKeyword: {emailNotContainsWord}, emailReceiveTimeType: EmailReceiveTimeType.last30Days, - sortOrder: EmailSortOrderType.relevance.getSortOrder().toNullable(), position: 0)); // expect mailbox dashboard controller calls GetEmailsInMailboxInteractor @@ -500,8 +499,7 @@ void main() { when(context.owner).thenReturn(BuildOwner(focusManager: FocusManager())); // act - mailboxDashboardController.searchEmail(queryString: queryString); - mailboxDashboardController.selectSortOrderQuickSearchFilter(context, EmailSortOrderType.oldest); + mailboxDashboardController.searchEmailByQueryString(queryString); mailboxDashboardController.selectHasAttachmentSearchFilter(); mailboxDashboardController.selectReceiveTimeQuickSearchFilter(context, EmailReceiveTimeType.last30Days); @@ -521,7 +519,6 @@ void main() { text: SearchQuery(queryString), emailReceiveTimeType: EmailReceiveTimeType.last30Days, hasAttachment: true, - sortOrder: EmailSortOrderType.oldest.getSortOrder().toNullable() ) ); });