TF-524 Apply quick search for mobile and tablet
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:model/email/email_action_type.dart';
|
||||
import 'package:model/email/filter_message_option.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/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
|
||||
|
||||
class DashBoardAction extends UIAction {
|
||||
@@ -97,4 +97,12 @@ class OpenEmailDetailedAction extends DashBoardAction {
|
||||
|
||||
@override
|
||||
List<Object?> get props => [presentationEmail];
|
||||
}
|
||||
|
||||
class DisableSearchEmailAction extends DashBoardAction {
|
||||
|
||||
DisableSearchEmailAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
extension FilterMessageOptionExtension on FilterMessageOption {
|
||||
|
||||
String getName(BuildContext context) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return AppLocalizations.of(context).unread;
|
||||
case FilterMessageOption.attachments:
|
||||
return AppLocalizations.of(context).with_attachments;
|
||||
case FilterMessageOption.starred:
|
||||
return AppLocalizations.of(context).starred;
|
||||
}
|
||||
}
|
||||
|
||||
String getIcon(ImagePaths imagePaths) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return imagePaths.icUnread;
|
||||
case FilterMessageOption.attachments:
|
||||
return imagePaths.icAttachment;
|
||||
case FilterMessageOption.starred:
|
||||
return imagePaths.icStar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/emai
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/quick_search_filter.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/filter_message_option.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';
|
||||
@@ -82,7 +83,6 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
final accountId = Rxn<AccountId>();
|
||||
final userProfile = Rxn<UserProfile>();
|
||||
final searchState = SearchState.initial().obs;
|
||||
final suggestionSearch = <String>[].obs;
|
||||
final dashBoardAction = Rxn<UIAction>();
|
||||
final routePath = AppRoutes.MAILBOX_DASHBOARD.obs;
|
||||
final appInformation = Rxn<PackageInfo>();
|
||||
@@ -286,35 +286,40 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
void disableSearch() {
|
||||
searchState.value = searchState.value.disableSearchState();
|
||||
searchQuery = SearchQuery.initial();
|
||||
clearSuggestionSearch();
|
||||
searchInputController.clear();
|
||||
listFilterQuickSearch.clear();
|
||||
emailReceiveTimeType.value = null;
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
|
||||
void clearSearchText() {
|
||||
void clearTextSearch() {
|
||||
searchQuery = SearchQuery.initial();
|
||||
clearSuggestionSearch();
|
||||
searchInputController.clear();
|
||||
searchFocus.requestFocus();
|
||||
}
|
||||
|
||||
void clearSuggestionSearch() {
|
||||
suggestionSearch.clear();
|
||||
}
|
||||
|
||||
void addSuggestionSearch(String query) {
|
||||
if (query.trim().isNotEmpty) {
|
||||
suggestionSearch.value = [query];
|
||||
} else {
|
||||
clearSearchText();
|
||||
}
|
||||
void updateTextSearch(String value) {
|
||||
searchInputController.text = value;
|
||||
}
|
||||
|
||||
void searchEmail(BuildContext context, String value) {
|
||||
searchQuery = SearchQuery(value);
|
||||
dispatchState(Right(SearchEmailNewQuery(searchQuery ?? SearchQuery.initial())));
|
||||
clearSuggestionSearch();
|
||||
FocusScope.of(context).unfocus();
|
||||
if (searchInsideEmailDetailedViewIsActive(context)) {
|
||||
closeEmailDetailedView();
|
||||
}
|
||||
}
|
||||
|
||||
bool searchInsideEmailDetailedViewIsActive(BuildContext context) {
|
||||
return BuildUtils.isWeb
|
||||
&& _responsiveUtils.isDesktop(context)
|
||||
&& routePath.value == AppRoutes.EMAIL;
|
||||
}
|
||||
|
||||
void closeEmailDetailedView() {
|
||||
dispatchRoute(AppRoutes.THREAD);
|
||||
clearSelectedEmail();
|
||||
}
|
||||
|
||||
void _saveEmailAsDraftsSuccess(SaveEmailAsDraftsSuccess success) {
|
||||
@@ -472,6 +477,36 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
emailReceiveTimeType.value = receiveTimeType;
|
||||
}
|
||||
|
||||
bool quickSearchFilterForLast7DaysIsActive () {
|
||||
return listFilterQuickSearch.contains(QuickSearchFilter.last7Days)
|
||||
&& emailReceiveTimeType.value != null;
|
||||
}
|
||||
|
||||
bool quickSearchFilterForHasAttachmentIsActive () {
|
||||
return listFilterQuickSearch.contains(QuickSearchFilter.hasAttachment)
|
||||
|| filterMessageOption.value == FilterMessageOption.attachments;
|
||||
}
|
||||
|
||||
bool quickSearchFilterForFromMeIsActive () {
|
||||
return listFilterQuickSearch.contains(QuickSearchFilter.fromMe);
|
||||
}
|
||||
|
||||
bool filterForHasAttachmentIsActive () {
|
||||
return quickSearchFilterForHasAttachmentIsActive() || filterMessageWithAttachmentIsActive();
|
||||
}
|
||||
|
||||
bool filterMessageWithAttachmentIsActive () {
|
||||
return filterMessageOption.value == FilterMessageOption.attachments;
|
||||
}
|
||||
|
||||
bool filterMessageUnreadIsActive () {
|
||||
return filterMessageOption.value == FilterMessageOption.unread;
|
||||
}
|
||||
|
||||
bool filterMessageStarredIsActive () {
|
||||
return filterMessageOption.value == FilterMessageOption.starred;
|
||||
}
|
||||
|
||||
void composeEmailAction() {
|
||||
if (kIsWeb) {
|
||||
if (dashBoardAction.value is! ComposeEmailAction) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
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/composer/presentation/composer_view_web.dart';
|
||||
@@ -15,7 +14,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/em
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
@@ -396,17 +395,17 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
return Row(
|
||||
children: [
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icBack, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
controller.disableSearch();
|
||||
controller.dispatchAction(CancelSelectionAllEmailAction());
|
||||
}),
|
||||
icon: SvgPicture.asset(
|
||||
imagePaths.icBack,
|
||||
color: AppColor.colorTextButton,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () => controller.dispatchAction(DisableSearchEmailAction())),
|
||||
Expanded(child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
color: AppColor.colorBgSearchBar),
|
||||
height: 45,
|
||||
child: TypeAheadFormFieldQuickSearch<PresentationEmail, RecentSearch>(
|
||||
child: QuickSearchInputForm<PresentationEmail, RecentSearch>(
|
||||
textFieldConfiguration: QuickSearchTextFieldConfiguration(
|
||||
controller: controller.searchInputController,
|
||||
autofocus: true,
|
||||
@@ -414,7 +413,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
textInputAction: TextInputAction.done,
|
||||
onSubmitted: (keyword) {
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
},
|
||||
@@ -424,30 +423,43 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
enabledBorder: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
hintText: AppLocalizations.of(context).search_mail,
|
||||
hintStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0),
|
||||
labelStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0)
|
||||
hintStyle: const TextStyle(
|
||||
color: AppColor.colorHintSearchBar,
|
||||
fontSize: 17.0),
|
||||
labelStyle: const TextStyle(
|
||||
color: AppColor.colorHintSearchBar,
|
||||
fontSize: 17.0)
|
||||
),
|
||||
leftButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icSearchBar, width: 16, height: 16, fit: BoxFit.fill),
|
||||
icon: SvgPicture.asset(
|
||||
imagePaths.icSearchBar,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
final keyword = controller.searchInputController.text;
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
}),
|
||||
clearTextButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icClearTextSearch, width: 16, height: 16, fit: BoxFit.fill),
|
||||
icon: SvgPicture.asset(
|
||||
imagePaths.icClearTextSearch,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
controller.searchInputController.clear();
|
||||
controller.clearSearchText();
|
||||
controller.clearTextSearch();
|
||||
})
|
||||
),
|
||||
suggestionsBoxDecoration: QuickSearchSuggestionsBoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: responsiveUtils.isDesktop(context) ? 556 : double.infinity),
|
||||
maxWidth: responsiveUtils.isDesktop(context)
|
||||
? 556
|
||||
: double.infinity),
|
||||
),
|
||||
debounceDuration: const Duration(milliseconds: 500),
|
||||
listActionButton: const [
|
||||
@@ -463,12 +475,18 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
},
|
||||
buttonActionCallback: (filterAction) {
|
||||
if (filterAction is QuickSearchFilter) {
|
||||
controller.selectQuickSearchFilter(filterAction, fromSuggestionBox: true);
|
||||
controller.selectQuickSearchFilter(
|
||||
filterAction,
|
||||
fromSuggestionBox: true);
|
||||
}
|
||||
},
|
||||
listActionPadding: const EdgeInsets.only(left: 24, top: 24, right: 24, bottom: 16),
|
||||
listActionPadding: const EdgeInsets.only(
|
||||
left: 24,
|
||||
top: 24,
|
||||
right: 24,
|
||||
bottom: 16),
|
||||
titleHeaderRecent: Padding(
|
||||
padding: const EdgeInsets.only(left: 24, right: 24, bottom: 8, top: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
child: Text(AppLocalizations.of(context).recent,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
color: AppColor.colorTextButtonHeaderThread,
|
||||
@@ -480,12 +498,14 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 24, right: 24, top: 14, bottom: 14),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
vertical: 14),
|
||||
child: Row(children: [
|
||||
Text(AppLocalizations.of(context).showingResultsFor,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
@@ -523,10 +543,12 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
return controller.quickSearchEmailsAction(pattern);
|
||||
},
|
||||
itemBuilder: (context, email) {
|
||||
return EmailQuickSearchItemTileWidget(email, controller.selectedMailbox.value);
|
||||
return EmailQuickSearchItemTileWidget(
|
||||
email, controller.selectedMailbox.value);
|
||||
},
|
||||
onSuggestionSelected: (presentationEmail) async {
|
||||
controller.dispatchAction(OpenEmailDetailedAction(context, presentationEmail));
|
||||
controller.dispatchAction(
|
||||
OpenEmailDetailedAction(context, presentationEmail));
|
||||
}),
|
||||
)),
|
||||
const SizedBox(width: 16),
|
||||
|
||||
+15
-7
@@ -3,8 +3,7 @@ import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
mixin FilterEmailPopupMenuMixin {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
@@ -38,15 +37,24 @@ mixin FilterEmailPopupMenuMixin {
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill,
|
||||
color: option != FilterMessageOption.starred ? AppColor.colorTextButton : null),
|
||||
color: option != FilterMessageOption.starred
|
||||
? AppColor.colorTextButton
|
||||
: null),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: Text(
|
||||
option.getName(context),
|
||||
style: const TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.w500))),
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500))),
|
||||
if (optionSelected == option)
|
||||
const SizedBox(width: 12),
|
||||
if (optionSelected == option)
|
||||
SvgPicture.asset(_imagePaths.icFilterSelected, width: 16, height: 16, fit: BoxFit.fill),
|
||||
... [
|
||||
const SizedBox(width: 12),
|
||||
SvgPicture.asset(_imagePaths.icFilterSelected,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
]
|
||||
])
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user