TF-2198 Implement get autocomplete contact in quick search
(cherry picked from commit 060056aa5d091d92b17faf308c9a1e055c3b0e0e)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
import 'package:model/email/email_action_type.dart';
|
import 'package:model/email/email_action_type.dart';
|
||||||
import 'package:model/email/presentation_email.dart';
|
import 'package:model/email/presentation_email.dart';
|
||||||
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
||||||
@@ -120,3 +121,13 @@ class ClearDateRangeToAdvancedSearch extends DashBoardAction {
|
|||||||
@override
|
@override
|
||||||
List<Object?> get props => [receiveTime];
|
List<Object?> get props => [receiveTime];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SearchEmailByFromFieldsAction extends DashBoardAction {
|
||||||
|
|
||||||
|
final EmailAddress emailAddress;
|
||||||
|
|
||||||
|
SearchEmailByFromFieldsAction(this.emailAddress);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [emailAddress];
|
||||||
|
}
|
||||||
|
|||||||
+15
-4
@@ -447,10 +447,21 @@ class AdvancedFilterController extends BaseController {
|
|||||||
);
|
);
|
||||||
} else if (action is ClearDateRangeToAdvancedSearch) {
|
} else if (action is ClearDateRangeToAdvancedSearch) {
|
||||||
_updateDateRangeTime(action.receiveTime);
|
_updateDateRangeTime(action.receiveTime);
|
||||||
} else if (action is StartSearchEmailAction) {
|
} else if (action is StartSearchEmailAction && action.filter == QuickSearchFilter.fromMe) {
|
||||||
if (action.filter == QuickSearchFilter.fromMe) {
|
_updateFromField();
|
||||||
_updateFromField();
|
} else if (action is SearchEmailByFromFieldsAction) {
|
||||||
}
|
searchController.clearSearchFilter();
|
||||||
|
_resetAllToOriginalValue();
|
||||||
|
_clearAllTextFieldInput();
|
||||||
|
searchController.searchInputController.clear();
|
||||||
|
searchController.deactivateAdvancedSearch();
|
||||||
|
searchController.isAdvancedSearchViewOpen.value = false;
|
||||||
|
|
||||||
|
listFromEmailAddress = List.from({action.emailAddress});
|
||||||
|
final listAddress = listFromEmailAddress.map((emailAddress) => emailAddress.emailAddress).toSet();
|
||||||
|
searchController.updateFilterEmail(fromOption: Some(listAddress));
|
||||||
|
|
||||||
|
_mailboxDashBoardController.dispatchAction(StartSearchEmailAction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
+32
@@ -15,6 +15,7 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
|||||||
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
||||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
|
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
@@ -26,9 +27,11 @@ import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dar
|
|||||||
import 'package:tmail_ui_user/features/composer/domain/exceptions/set_email_method_exception.dart';
|
import 'package:tmail_ui_user/features/composer/domain/exceptions/set_email_method_exception.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/extensions/email_request_extension.dart';
|
import 'package:tmail_ui_user/features/composer/domain/extensions/email_request_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
|
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
|
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_as_drafts_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_as_drafts_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/update_email_drafts_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/update_email_drafts_interactor.dart';
|
||||||
@@ -184,6 +187,7 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
DeleteEmailStateToRefreshInteractor? _deleteEmailStateToRefreshInteractor;
|
DeleteEmailStateToRefreshInteractor? _deleteEmailStateToRefreshInteractor;
|
||||||
GetMailboxStateToRefreshInteractor? _getMailboxStateToRefreshInteractor;
|
GetMailboxStateToRefreshInteractor? _getMailboxStateToRefreshInteractor;
|
||||||
DeleteMailboxStateToRefreshInteractor? _deleteMailboxStateToRefreshInteractor;
|
DeleteMailboxStateToRefreshInteractor? _deleteMailboxStateToRefreshInteractor;
|
||||||
|
GetAutoCompleteInteractor? _getAutoCompleteInteractor;
|
||||||
|
|
||||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
final selectedMailbox = Rxn<PresentationMailbox>();
|
final selectedMailbox = Rxn<PresentationMailbox>();
|
||||||
@@ -2174,6 +2178,34 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<EmailAddress>> getContactSuggestion(String query) async {
|
||||||
|
_getAutoCompleteInteractor = getBinding<GetAutoCompleteInteractor>();
|
||||||
|
|
||||||
|
if (_getAutoCompleteInteractor == null || accountId.value == null) {
|
||||||
|
return <EmailAddress>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
final listEmailAddress = await _getAutoCompleteInteractor!
|
||||||
|
.execute(AutoCompletePattern(word: query, accountId: accountId.value!, limit: 2))
|
||||||
|
.then((value) => value.fold(
|
||||||
|
(failure) => <EmailAddress>[],
|
||||||
|
(success) => success is GetAutoCompleteSuccess ? success.listEmailAddress : <EmailAddress>[]
|
||||||
|
));
|
||||||
|
log('MailboxDashBoardController::getAutoCompleteSuggestion:listEmailAddress: $listEmailAddress');
|
||||||
|
return listEmailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void searchEmailByFromFields(BuildContext context, EmailAddress emailAddress) {
|
||||||
|
KeyboardUtils.hideKeyboard(context);
|
||||||
|
clearFilterMessageOption();
|
||||||
|
searchController.clearFilterSuggestion();
|
||||||
|
if (_searchInsideEmailDetailedViewIsActive(context)) {
|
||||||
|
_closeEmailDetailedView();
|
||||||
|
}
|
||||||
|
_unSelectedMailbox();
|
||||||
|
dispatchAction(SearchEmailByFromFieldsAction(emailAddress));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
_emailReceiveManager.closeEmailReceiveManagerStream();
|
_emailReceiveManager.closeEmailReceiveManagerStream();
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/utils/style_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
|
import 'package:model/extensions/email_address_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/avatar_suggestion_item_widget.dart';
|
||||||
|
|
||||||
|
class ContactQuickSearchItem extends StatelessWidget {
|
||||||
|
final EmailAddress emailAddress;
|
||||||
|
|
||||||
|
const ContactQuickSearchItem({
|
||||||
|
super.key,
|
||||||
|
required this.emailAddress,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
AvatarSuggestionItemWidget(emailAddress: emailAddress),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
emailAddress.asString(),
|
||||||
|
maxLines: 1,
|
||||||
|
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||||
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal
|
||||||
|
)
|
||||||
|
),
|
||||||
|
if (emailAddress.displayName.isNotEmpty)
|
||||||
|
Text(
|
||||||
|
emailAddress.emailAddress,
|
||||||
|
maxLines: 1,
|
||||||
|
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||||
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: AppColor.colorHintSearchBar,
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.normal
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_portal/flutter_portal.dart';
|
import 'package:flutter_portal/flutter_portal.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
import 'package:model/email/presentation_email.dart';
|
import 'package:model/email/presentation_email.dart';
|
||||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||||
@@ -18,8 +19,9 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller
|
|||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/advanced_search_filter_overlay.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/advanced_search_filter_overlay.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/icon_open_advanced_search_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/icon_open_advanced_search_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/contact_quick_search_item.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/email_quick_search_item_tile_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/recent_search_item_tile_widget.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart' as search;
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart' as search;
|
||||||
@@ -55,7 +57,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
portalFollower: const AdvancedSearchFilterOverlay(),
|
portalFollower: const AdvancedSearchFilterOverlay(),
|
||||||
child: QuickSearchInputForm<PresentationEmail, RecentSearch>(
|
child: QuickSearchInputForm<PresentationEmail, EmailAddress, RecentSearch>(
|
||||||
maxHeight: 52,
|
maxHeight: 52,
|
||||||
suggestionsBoxVerticalOffset: 0.0,
|
suggestionsBoxVerticalOffset: 0.0,
|
||||||
textFieldConfiguration: _createConfiguration(context),
|
textFieldConfiguration: _createConfiguration(context),
|
||||||
@@ -105,7 +107,11 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
onRecentSelected: (recent) => _invokeSelectRecentItem(context, recent),
|
onRecentSelected: (recent) => _invokeSelectRecentItem(context, recent),
|
||||||
suggestionsCallback: _dashBoardController.quickSearchEmails,
|
suggestionsCallback: _dashBoardController.quickSearchEmails,
|
||||||
itemBuilder: (context, email) => EmailQuickSearchItemTileWidget(email, _dashBoardController.selectedMailbox.value),
|
itemBuilder: (context, email) => EmailQuickSearchItemTileWidget(email, _dashBoardController.selectedMailbox.value),
|
||||||
onSuggestionSelected: (presentationEmail) => _invokeSelectSuggestionItem(context, presentationEmail))
|
onSuggestionSelected: (presentationEmail) => _invokeSelectSuggestionItem(context, presentationEmail),
|
||||||
|
contactItemBuilder: (context, emailAddress) => ContactQuickSearchItem(emailAddress: emailAddress),
|
||||||
|
contactSuggestionsCallback: _dashBoardController.getContactSuggestion,
|
||||||
|
onContactSuggestionSelected: (emailAddress) => _invokeSelectContactSuggestion(context, emailAddress),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -246,4 +252,11 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _invokeSelectContactSuggestion(BuildContext context, EmailAddress emailAddress) {
|
||||||
|
_searchController.searchInputController.clear();
|
||||||
|
_searchController.searchFocus.unfocus();
|
||||||
|
_searchController.enableSearch();
|
||||||
|
_dashBoardController.searchEmailByFromFields(context, emailAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,8 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_c
|
|||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/email_quick_search_item_tile_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/recent_search_item_tile_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/search/email/presentation/model/search_more_state.dart';
|
import 'package:tmail_ui_user/features/search/email/presentation/model/search_more_state.dart';
|
||||||
import 'package:tmail_ui_user/features/search/email/presentation/model/simple_search_filter.dart';
|
import 'package:tmail_ui_user/features/search/email/presentation/model/simple_search_filter.dart';
|
||||||
import 'package:tmail_ui_user/features/search/email/presentation/search_email_controller.dart';
|
import 'package:tmail_ui_user/features/search/email/presentation/search_email_controller.dart';
|
||||||
|
|||||||
Reference in New Issue
Block a user