TF-524 Implement quick search emails in selected mailbox by word
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
|
||||
class QuickSearchEmailSuccess extends UIState {
|
||||
final List<PresentationEmail> emailList;
|
||||
|
||||
QuickSearchEmailSuccess(this.emailList);
|
||||
|
||||
@override
|
||||
List<Object> get props => [emailList];
|
||||
}
|
||||
|
||||
class QuickSearchEmailFailure extends FeatureFailure {
|
||||
final dynamic exception;
|
||||
|
||||
QuickSearchEmailFailure(this.exception);
|
||||
|
||||
@override
|
||||
List<Object> get props => [exception];
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/quick_search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||
|
||||
class QuickSearchEmailInteractor {
|
||||
|
||||
final ThreadRepository threadRepository;
|
||||
|
||||
QuickSearchEmailInteractor(this.threadRepository);
|
||||
|
||||
Future<Either<Failure, Success>> execute(
|
||||
AccountId accountId,
|
||||
{
|
||||
UnsignedInt? limit,
|
||||
Set<Comparator>? sort,
|
||||
Filter? filter,
|
||||
Properties? properties,
|
||||
}
|
||||
) async {
|
||||
try {
|
||||
final emailList = await threadRepository.searchEmails(
|
||||
accountId,
|
||||
limit: limit,
|
||||
sort: sort,
|
||||
filter: filter,
|
||||
properties: properties);
|
||||
|
||||
final presentationEmailList = emailList
|
||||
.map((email) => email.toPresentationEmail())
|
||||
.toList();
|
||||
|
||||
return Right(QuickSearchEmailSuccess(presentationEmailList));
|
||||
} catch (e) {
|
||||
return Left(QuickSearchEmailFailure(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import 'package:core/core.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/caching/recent_search_cache_client.dart';
|
||||
import 'package:tmail_ui_user/features/caching/state_cache_client.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart';
|
||||
@@ -14,6 +15,8 @@ import 'package:tmail_ui_user/features/email/domain/usecases/delete_email_perman
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/email_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/state_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/search_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart';
|
||||
@@ -21,9 +24,17 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/search_
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/search_repository.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_user_profile_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/quick_search_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource_impl/local_thread_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource_impl/thread_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/repository/thread_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_bindings.dart';
|
||||
|
||||
class MailboxDashBoardBindings extends BaseBindings {
|
||||
@@ -43,6 +54,7 @@ class MailboxDashBoardBindings extends BaseBindings {
|
||||
Get.find<DeleteEmailPermanentlyInteractor>(),
|
||||
Get.find<SaveRecentSearchInteractor>(),
|
||||
Get.find<GetAllRecentSearchLatestInteractor>(),
|
||||
Get.find<QuickSearchEmailInteractor>(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -51,6 +63,8 @@ class MailboxDashBoardBindings extends BaseBindings {
|
||||
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
|
||||
Get.lazyPut<HtmlDataSource>(() => Get.find<HtmlDataSourceImpl>());
|
||||
Get.lazyPut<SearchDataSource>(() => Get.find<SearchDataSourceImpl>());
|
||||
Get.lazyPut<ThreadDataSource>(() => Get.find<ThreadDataSourceImpl>());
|
||||
Get.lazyPut<StateDataSource>(() => Get.find<StateDataSourceImpl>());
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -61,6 +75,9 @@ class MailboxDashBoardBindings extends BaseBindings {
|
||||
Get.find<DioClient>()
|
||||
));
|
||||
Get.lazyPut(() => SearchDataSourceImpl(Get.find<RecentSearchCacheClient>()));
|
||||
Get.lazyPut(() => ThreadDataSourceImpl(Get.find<ThreadAPI>()));
|
||||
Get.lazyPut(() => LocalThreadDataSourceImpl(Get.find<EmailCacheManager>()));
|
||||
Get.lazyPut(() => StateDataSourceImpl(Get.find<StateCacheClient>()));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -71,12 +88,14 @@ class MailboxDashBoardBindings extends BaseBindings {
|
||||
Get.lazyPut(() => DeleteEmailPermanentlyInteractor(Get.find<EmailRepository>()));
|
||||
Get.lazyPut(() => SaveRecentSearchInteractor(Get.find<SearchRepository>()));
|
||||
Get.lazyPut(() => GetAllRecentSearchLatestInteractor(Get.find<SearchRepository>()));
|
||||
Get.lazyPut(() => QuickSearchEmailInteractor(Get.find<ThreadRepository>()));
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsRepository() {
|
||||
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
|
||||
Get.lazyPut<SearchRepository>(() => Get.find<SearchRepositoryImpl>());
|
||||
Get.lazyPut<ThreadRepository>(() => Get.find<ThreadRepositoryImpl>());
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -86,5 +105,13 @@ class MailboxDashBoardBindings extends BaseBindings {
|
||||
Get.find<HtmlDataSource>()
|
||||
));
|
||||
Get.lazyPut(() => SearchRepositoryImpl(Get.find<SearchDataSource>()));
|
||||
Get.lazyPut(() => ThreadRepositoryImpl(
|
||||
{
|
||||
DataSourceType.network: Get.find<ThreadDataSource>(),
|
||||
DataSourceType.local: Get.find<LocalThreadDataSourceImpl>()
|
||||
},
|
||||
Get.find<StateDataSource>(),
|
||||
Get.find<EmailDataSource>(),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,10 @@ import 'package:jmap_dart_client/jmap/core/capability/mail_capability.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.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_comparator.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
@@ -33,13 +37,16 @@ import 'package:tmail_ui_user/features/email/presentation/model/composer_argumen
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/quick_search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_user_profile_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/quick_search_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart';
|
||||
@@ -64,6 +71,7 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor;
|
||||
final SaveRecentSearchInteractor _saveRecentSearchInteractor;
|
||||
final GetAllRecentSearchLatestInteractor _getAllRecentSearchLatestInteractor;
|
||||
final QuickSearchEmailInteractor _quickSearchEmailInteractor;
|
||||
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final selectedMailbox = Rxn<PresentationMailbox>();
|
||||
@@ -94,6 +102,7 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
this._deleteEmailPermanentlyInteractor,
|
||||
this._saveRecentSearchInteractor,
|
||||
this._getAllRecentSearchLatestInteractor,
|
||||
this._quickSearchEmailInteractor,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -415,6 +424,25 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
: <RecentSearch>[]));
|
||||
}
|
||||
|
||||
Future<List<PresentationEmail>> quickSearchEmailsAction(String pattern) async {
|
||||
if (accountId.value != null && selectedMailbox.value != null) {
|
||||
return await _quickSearchEmailInteractor.execute(
|
||||
accountId.value!,
|
||||
limit: UnsignedInt(5),
|
||||
sort: <Comparator>{}
|
||||
..add(EmailComparator(EmailComparatorProperty.receivedAt)
|
||||
..setIsAscending(false)),
|
||||
filter: EmailFilterCondition(
|
||||
text: pattern,
|
||||
inMailbox: selectedMailbox.value!.id),
|
||||
properties: ThreadConstants.propertiesQuickSearch
|
||||
).then((result) => result.fold(
|
||||
(failure) => <PresentationEmail>[],
|
||||
(success) => success is QuickSearchEmailSuccess ? success.emailList : <PresentationEmail>[]));
|
||||
}
|
||||
return <PresentationEmail>[];
|
||||
}
|
||||
|
||||
void composeEmailAction() {
|
||||
if (kIsWeb) {
|
||||
if (dashBoardAction.value is! ComposeEmailAction) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/network_connection_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
|
||||
@@ -24,7 +25,7 @@ import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with NetworkConnectionMixin,
|
||||
UserSettingPopupMenuMixin, FilterEmailPopupMenuMixin {
|
||||
UserSettingPopupMenuMixin, FilterEmailPopupMenuMixin, AppLoaderMixin {
|
||||
|
||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
@@ -425,6 +426,7 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
@@ -443,6 +445,7 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
}),
|
||||
rightButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icComposerClose, width: 18, height: 18, fit: BoxFit.fill),
|
||||
@@ -508,20 +511,31 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
child: Text(AppLocalizations.of(context).recent,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
color: AppColor.colorTextButtonHeaderThread,
|
||||
fontWeight: FontWeight.w500))),
|
||||
fontWeight: FontWeight.w500)
|
||||
)
|
||||
),
|
||||
loadingBuilder: (context) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: loadingWidget,
|
||||
),
|
||||
getRecentCallback: (pattern) async {
|
||||
return controller.getAllRecentSearchAction(pattern);
|
||||
},
|
||||
itemRecentBuilder: (context, recent) {
|
||||
return RecentSearchItemTileWidget(recent);
|
||||
},
|
||||
onRecentSelected: (recent) {
|
||||
controller.searchInputController.text = recent.value;
|
||||
controller.searchEmail(context, recent.value);
|
||||
},
|
||||
suggestionsCallback: (pattern) async {
|
||||
return [];
|
||||
return controller.quickSearchEmailsAction(pattern);
|
||||
},
|
||||
itemBuilder: (context, email) {
|
||||
return EmailQuickSearchItemTileWidget(email, controller.selectedMailbox.value);
|
||||
},
|
||||
onSuggestionSelected: (autoCompleteResult) async {
|
||||
|
||||
}),
|
||||
)),
|
||||
const SizedBox(width: 16),
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ class EmailQuickSearchItemTileWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
@@ -24,4 +24,16 @@ class ThreadConstants {
|
||||
EmailProperty.keywords,
|
||||
EmailProperty.mailboxIds,
|
||||
});
|
||||
|
||||
static final propertiesQuickSearch = Properties({
|
||||
EmailProperty.id,
|
||||
EmailProperty.subject,
|
||||
EmailProperty.from,
|
||||
EmailProperty.to,
|
||||
EmailProperty.keywords,
|
||||
EmailProperty.receivedAt,
|
||||
EmailProperty.sentAt,
|
||||
EmailProperty.preview,
|
||||
EmailProperty.hasAttachment,
|
||||
});
|
||||
}
|
||||
@@ -396,7 +396,9 @@ class ThreadController extends BaseController {
|
||||
_accountId!,
|
||||
limit: limit,
|
||||
sort: _sortOrder,
|
||||
filter: EmailFilterCondition(text: searchQuery!.value),
|
||||
filter: EmailFilterCondition(
|
||||
text: searchQuery!.value,
|
||||
inMailbox: _currentMailboxId),
|
||||
properties: ThreadConstants.propertiesDefault,
|
||||
));
|
||||
}
|
||||
@@ -844,7 +846,9 @@ class ThreadController extends BaseController {
|
||||
_accountId!,
|
||||
limit: ThreadConstants.defaultLimit,
|
||||
sort: _sortOrder,
|
||||
filter: EmailFilterCondition(text: searchQuery!.value),
|
||||
filter: EmailFilterCondition(
|
||||
text: searchQuery!.value,
|
||||
inMailbox: _currentMailboxId),
|
||||
properties: ThreadConstants.propertiesDefault,
|
||||
));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user