diff --git a/assets/images/ic_delete_selection.svg b/assets/images/ic_delete_selection.svg
new file mode 100644
index 000000000..91fd7df66
--- /dev/null
+++ b/assets/images/ic_delete_selection.svg
@@ -0,0 +1,3 @@
+
diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart
index 85813ca8b..b4eb31a01 100644
--- a/core/lib/presentation/extensions/color_extension.dart
+++ b/core/lib/presentation/extensions/color_extension.dart
@@ -225,6 +225,8 @@ extension AppColor on Color {
static const loginViewShadowColor = Color(0x3DBCBCBC);
static const colorEmailTileCheckboxUnhover = Color(0xFFAEB7C2);
static const colorEmailTileHoverWeb = Color(0xFFDFEEFF);
+ static const colorSearchFilterButton = Color(0xFFECEEF1);
+ static const colorSuggestionSearchFilterButton = Color(0xFFEBEDF0);
static const mapGradientColor = [
[Color(0xFF21D4FD), Color(0xFFB721FF)],
diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart
index eca728238..075cc5b54 100644
--- a/core/lib/presentation/resources/image_paths.dart
+++ b/core/lib/presentation/resources/image_paths.dart
@@ -218,6 +218,7 @@ class ImagePaths {
String get icCheckboxSelected => _getImagePath('ic_checkbox_selected.svg');
String get icGoodSignature => _getImagePath('ic_good_signature.svg');
String get icBadSignature => _getImagePath('ic_bad_signature.svg');
+ String get icDeleteSelection => _getImagePath('ic_delete_selection.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
diff --git a/core/lib/presentation/views/quick_search/quick_search_input_form.dart b/core/lib/presentation/views/quick_search/quick_search_input_form.dart
index 1a159229d..b037a14f6 100644
--- a/core/lib/presentation/views/quick_search/quick_search_input_form.dart
+++ b/core/lib/presentation/views/quick_search/quick_search_input_form.dart
@@ -1286,13 +1286,16 @@ class _SuggestionsListState extends State<_SuggestionsList>
if (widget.buttonActionCallback != null) {
return Padding(
padding: const EdgeInsetsDirectional.only(end: 8, bottom: 8),
- child: InkWell(
- borderRadius: const BorderRadius.all(Radius.circular(10)),
- onTap: () {
- widget.buttonActionCallback?.call(action);
- invalidateSuggestions();
- },
- child: widget.actionButtonBuilder!(context, action),
+ child: Material(
+ type: MaterialType.transparency,
+ child: InkWell(
+ borderRadius: const BorderRadius.all(Radius.circular(10)),
+ onTap: () {
+ widget.buttonActionCallback?.call(action);
+ invalidateSuggestions();
+ },
+ child: widget.actionButtonBuilder!(context, action),
+ ),
),
);
} else {
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 616c4c786..25c9e8bc9 100644
--- a/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart
+++ b/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart
@@ -397,7 +397,7 @@ class AdvancedFilterController extends BaseController {
);
} else if (action is ClearDateRangeToAdvancedSearch) {
_updateDateRangeTime(action.receiveTime);
- } else if (action is StartSearchEmailAction && action.filter == QuickSearchFilter.fromMe) {
+ } else if (action is StartSearchEmailAction && action.filter == QuickSearchFilter.from) {
_updateFromField();
} else if (action is SearchEmailByFromFieldsAction) {
searchController.clearSearchFilter();
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 f13d24084..a7d1679df 100644
--- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
+++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
@@ -1575,17 +1575,6 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
_getAllIdentities();
}
- void selectQuickSearchFilter(QuickSearchFilter filter) {
- return searchController.selectQuickSearchFilter(filter);
- }
-
- void selectQuickSearchFilterFrom(EmailAddress fromEmailFilter) {
- return searchController.selectQuickSearchFilter(
- QuickSearchFilter.fromMe,
- fromEmailFilter: fromEmailFilter
- );
- }
-
void addFilterToSuggestionForm(QuickSearchFilter filter) {
searchController.addFilterToSuggestionForm(filter);
}
@@ -1667,24 +1656,26 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
}
}
- void selectQuickSearchFilterAction(QuickSearchFilter filter) async {
- log('MailboxDashBoardController::selectQuickSearchFilterAction(): filter: $filter');
- if (filter == QuickSearchFilter.fromMe) {
- if (accountId.value == null || sessionCurrent == null) {
- logError('MailboxDashBoardController::selectQuickSearchFilterAction(): accountId or sessionCurrent is null');
- }
- final listContactSelected = searchController.searchEmailFilter.value.from;
- final arguments = ContactArguments(accountId.value!, sessionCurrent!, listContactSelected);
+ void selectHasAttachmentSearchFilter() {
+ searchController.updateFilterEmail(hasAttachment: true);
+ dispatchAction(StartSearchEmailAction());
+ }
- final newContact = await DialogRouter.pushGeneralDialog(routeName: AppRoutes.contact, arguments: arguments);
+ Future selectFromSearchFilter() async {
+ if (accountId.value == null || sessionCurrent == null) return;
- if (newContact is EmailAddress) {
- selectQuickSearchFilterFrom(newContact);
- dispatchAction(StartSearchEmailAction(filter: filter));
- }
- } else {
- selectQuickSearchFilter(filter);
- dispatchAction(StartSearchEmailAction(filter: filter));
+ final contactArgument = ContactArguments(
+ accountId.value!,
+ sessionCurrent!,
+ searchController.searchEmailFilter.value.from);
+
+ final newContact = await DialogRouter.pushGeneralDialog(
+ routeName: AppRoutes.contact,
+ arguments: contactArgument);
+
+ if (newContact is EmailAddress) {
+ searchController.updateFilterEmail(fromOption: Some({newContact.emailAddress}));
+ dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.from));
}
}
diff --git a/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart
index c725cda47..8ee5a0aff 100644
--- a/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart
+++ b/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart
@@ -11,7 +11,6 @@ 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/user_name.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
-import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_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';
@@ -71,32 +70,6 @@ class SearchController extends BaseController with DateRangePickerMixin {
searchEmailFilter.value = SearchEmailFilter.initial();
}
- void selectQuickSearchFilter(
- QuickSearchFilter quickSearchFilter,
- {EmailAddress? fromEmailFilter}
- ) {
- final isFilterSelected = quickSearchFilter.isSelected(searchEmailFilter.value);
-
- switch (quickSearchFilter) {
- case QuickSearchFilter.hasAttachment:
- updateFilterEmail(hasAttachment: !isFilterSelected);
- return;
- case QuickSearchFilter.last7Days:
- updateFilterEmail(emailReceiveTimeType: EmailReceiveTimeType.allTime);
- return;
- case QuickSearchFilter.fromMe:
- if (fromEmailFilter != null) {
- final newListEmailAddress = (fromEmailFilter.email != null && fromEmailFilter.email!.isNotEmpty)
- ? {fromEmailFilter.email!}
- : {};
- updateFilterEmail(fromOption: Some(newListEmailAddress));
- }
- return;
- case QuickSearchFilter.sortBy:
- return;
- }
- }
-
void addFilterToSuggestionForm(QuickSearchFilter filter) {
if (listFilterOnSuggestionForm.contains(filter)) {
listFilterOnSuggestionForm.remove(filter);
diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart
index 0aa186da8..a9858dbf1 100644
--- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart
+++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart
@@ -21,6 +21,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/sear
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/download/download_task_item_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recover_deleted_message_loading_banner_widget.dart';
+import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/search_filters/search_filter_button.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/search_input_form_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
@@ -36,7 +37,6 @@ import 'package:tmail_ui_user/features/thread/presentation/widgets/banner_delete
import 'package:tmail_ui_user/features/thread/presentation/widgets/banner_empty_trash_widget.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/spam_banner/spam_report_banner_web_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
-import 'package:tmail_ui_user/main/utils/app_utils.dart';
class MailboxDashBoardView extends BaseMailboxDashBoardView {
@@ -460,24 +460,23 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
});
}
- bool supportListButtonQuickSearchFilter(BuildContext context) {
- return controller.searchController.isSearchEmailRunning
- && controller.dashboardRoute.value == DashboardRoutes.thread;
- }
-
Widget _buildListButtonQuickSearchFilter(BuildContext context) {
return Obx(() {
- if (supportListButtonQuickSearchFilter(context)) {
+ if (controller.searchController.isSearchEmailRunning &&
+ controller.dashboardRoute.value == DashboardRoutes.thread) {
return Padding(
padding: const EdgeInsetsDirectional.only(end: 16, top: 8),
child: Row(
children: [
- ...QuickSearchFilter.values
- .where((filter) => filter != QuickSearchFilter.sortBy)
- .map((filter) => _buildQuickSearchFilterButton(context, filter)),
- const Spacer(),
- _buildQuickSearchFilterButton(context, QuickSearchFilter.sortBy)
- ]
+ _buildQuickSearchFilterButton(context, QuickSearchFilter.from),
+ const SizedBox(width: 8),
+ _buildQuickSearchFilterButton(context, QuickSearchFilter.dateTime),
+ const SizedBox(width: 8),
+ _buildQuickSearchFilterButton(context, QuickSearchFilter.hasAttachment),
+ const Spacer(),
+ _buildQuickSearchFilterButton(context, QuickSearchFilter.sortBy),
+ const SizedBox(width: 8),
+ ]
),
);
} else {
@@ -488,87 +487,64 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
Widget _buildQuickSearchFilterButton(
BuildContext context,
- QuickSearchFilter filter
+ QuickSearchFilter searchFilter
) {
return Obx(() {
- final isFilterSelected = filter.isSelected(
- controller.searchController.searchEmailFilter.value,
- );
+ final searchEmailFilter = controller.searchController.searchEmailFilter.value;
+ final sortOrderType = controller.searchController.sortOrderFiltered.value;
+ final listAddressOfFrom = controller.searchController.searchEmailFilter.value.from;
+ final userName = controller.sessionCurrent?.username;
+ final startDate = controller.searchController.startDateFiltered;
+ final endDate = controller.searchController.endDateFiltered;
+ final receiveTimeType = controller.searchController.receiveTimeFiltered;
- return Padding(
- padding: EdgeInsets.only(
- right: AppUtils.isDirectionRTL(context) ? 0 : 8,
- left: AppUtils.isDirectionRTL(context) ? 8 : 0,
- ),
- child: InkWell(
- onTap: () {
- if (!filter.isTapOpenPopupMenu()) {
- controller.selectQuickSearchFilterAction(filter);
- }
- },
- onTapDown: (detail) {
- final screenSize = MediaQuery.of(context).size;
- final offset = detail.globalPosition;
- final position = RelativeRect.fromLTRB(
- offset.dx,
- offset.dy,
- screenSize.width - offset.dx,
- screenSize.height - offset.dy,
- );
+ final isSelected = searchFilter.isSelected(
+ context,
+ searchEmailFilter,
+ sortOrderType);
- switch(filter) {
- case QuickSearchFilter.last7Days:
- _openPopupMenuDateFilter(context, position);
- break;
- case QuickSearchFilter.sortBy:
- _openPopupMenuSortFilter(context, position);
- break;
- default:
- break;
- }
- },
- borderRadius: const BorderRadius.all(Radius.circular(10)),
- child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(10),
- color: filter.getBackgroundColor(isFilterSelected: isFilterSelected)),
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
- child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
- SvgPicture.asset(
- filter.getIcon(controller.imagePaths, isFilterSelected: isFilterSelected),
- width: 16,
- height: 16,
- fit: BoxFit.fill),
- const SizedBox(width: 4),
- Text(
- filter == QuickSearchFilter.fromMe
- ? _getQuickSearchFilterFromTitle(context)
- : filter.getTitle(
- context,
- receiveTimeType: controller.searchController.receiveTimeFiltered,
- startDate: controller.searchController.startDateFiltered,
- endDate: controller.searchController.endDateFiltered,
- sortOrderType: controller.searchController.sortOrderFiltered.value,
- ),
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- style: filter.getTextStyle(isFilterSelected: isFilterSelected),
- ),
- if (filter == QuickSearchFilter.last7Days || filter == QuickSearchFilter.fromMe)
- ... [
- const SizedBox(width: 4),
- SvgPicture.asset(
- controller.imagePaths.icChevronDown,
- width: 16,
- height: 16,
- fit: BoxFit.fill),
- ]
- ])),
- ),
+ return SearchFilterButton(
+ searchFilter: searchFilter,
+ imagePaths: controller.imagePaths,
+ isSelected: isSelected,
+ receiveTimeType: receiveTimeType,
+ startDate: startDate,
+ endDate: endDate,
+ sortOrderType: sortOrderType,
+ listAddressOfFrom: listAddressOfFrom,
+ userName: userName,
+ onSelectSearchFilterAction: _onSelectSearchFilterAction,
);
});
}
+ void _onSelectSearchFilterAction(
+ BuildContext context,
+ QuickSearchFilter searchFilter,
+ {RelativeRect? buttonPosition}
+ ) async {
+ switch(searchFilter) {
+ case QuickSearchFilter.dateTime:
+ if (buttonPosition != null) {
+ _openPopupMenuDateFilter(context, buttonPosition);
+ }
+ break;
+ case QuickSearchFilter.sortBy:
+ if (buttonPosition != null) {
+ _openPopupMenuSortFilter(context, buttonPosition);
+ }
+ break;
+ case QuickSearchFilter.from:
+ controller.selectFromSearchFilter();
+ break;
+ case QuickSearchFilter.hasAttachment:
+ controller.selectHasAttachmentSearchFilter();
+ break;
+ default:
+ break;
+ }
+ }
+
List popupMenuEmailReceiveTimeType(
BuildContext context,
EmailReceiveTimeType? receiveTimeSelected,
@@ -666,18 +642,4 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
),
);
}
-
- String _getQuickSearchFilterFromTitle(BuildContext context) {
- final searchEmailFilterFromFiled = controller.searchController.searchEmailFilter.value.from;
- if (searchEmailFilterFromFiled.length == 1) {
- if (searchEmailFilterFromFiled.first == controller.sessionCurrent?.username.value &&
- controller.sessionCurrent?.username.value.isNotEmpty == true) {
- return QuickSearchFilter.fromMe.getTitle(context);
- } else {
- return '${AppLocalizations.of(context).from_email_address_prefix} ${searchEmailFilterFromFiled.first}';
- }
- } else {
- return AppLocalizations.of(context).from_email_address_prefix;
- }
- }
}
\ No newline at end of file
diff --git a/lib/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart b/lib/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart
index 2dc8a9e9f..6f7e04c8c 100644
--- a/lib/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart
+++ b/lib/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart
@@ -2,6 +2,7 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/cupertino.dart';
+import 'package:jmap_dart_client/jmap/core/user_name.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_sort_order_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart';
@@ -11,7 +12,9 @@ enum QuickSearchFilter {
hasAttachment,
last7Days,
fromMe,
- sortBy;
+ sortBy,
+ dateTime,
+ from;
String getName(BuildContext context) {
switch(this) {
@@ -23,6 +26,12 @@ enum QuickSearchFilter {
return AppLocalizations.of(context).fromMe;
case QuickSearchFilter.sortBy:
return AppLocalizations.of(context).sortBy;
+ case QuickSearchFilter.dateTime:
+ return AppLocalizations.of(context).allTime;
+ case QuickSearchFilter.from:
+ return AppLocalizations.of(context).from_email_address_prefix;
+ default:
+ return '';
}
}
@@ -32,74 +41,109 @@ enum QuickSearchFilter {
EmailSortOrderType? sortOrderType,
DateTime? startDate,
DateTime? endDate,
+ Set? listAddressOfFrom,
+ UserName? userName
}) {
switch(this) {
case QuickSearchFilter.hasAttachment:
return AppLocalizations.of(context).hasAttachment;
case QuickSearchFilter.last7Days:
- return receiveTimeType?.getTitle(context, startDate: startDate, endDate: endDate)
- ?? AppLocalizations.of(context).allTime;
+ return AppLocalizations.of(context).last7Days;
case QuickSearchFilter.fromMe:
return AppLocalizations.of(context).fromMe;
case QuickSearchFilter.sortBy:
return sortOrderType?.getTitle(context)
?? AppLocalizations.of(context).mostRecent;
+ case QuickSearchFilter.dateTime:
+ return receiveTimeType?.getTitle(
+ context,
+ startDate: startDate,
+ endDate: endDate
+ ) ?? AppLocalizations.of(context).allTime;
+ case QuickSearchFilter.from:
+ if (listAddressOfFrom?.length != 1) {
+ return AppLocalizations.of(context).from_email_address_prefix;
+ }
+
+ if (userName?.value.isNotEmpty == true && listAddressOfFrom?.first == userName?.value) {
+ return AppLocalizations.of(context).fromMe;
+ } else {
+ return '${AppLocalizations.of(context).from_email_address_prefix} ${listAddressOfFrom?.first}';
+ }
+ default:
+ return '';
}
}
- String getIcon(ImagePaths imagePaths, {required bool isFilterSelected}) {
- if (isFilterSelected) {
- return imagePaths.icSelectedSB;
- } else {
- switch(this) {
- case QuickSearchFilter.hasAttachment:
- return imagePaths.icAttachmentSB;
- case QuickSearchFilter.last7Days:
- return imagePaths.icCalendarSB;
- case QuickSearchFilter.fromMe:
- return imagePaths.icUserSB;
- case QuickSearchFilter.sortBy:
- return imagePaths.icFilterSB;
- }
+ String getIcon(ImagePaths imagePaths, {bool isSelected = false}) {
+ switch(this) {
+ case QuickSearchFilter.hasAttachment:
+ return isSelected ? imagePaths.icSelectedSB : imagePaths.icAttachmentSB;
+ case QuickSearchFilter.last7Days:
+ return isSelected ? imagePaths.icSelectedSB : imagePaths.icCalendarSB;
+ case QuickSearchFilter.fromMe:
+ return isSelected ? imagePaths.icSelectedSB : imagePaths.icUserSB;
+ case QuickSearchFilter.sortBy:
+ return imagePaths.icFilterSB;
+ case QuickSearchFilter.dateTime:
+ return imagePaths.icCalendarSB;
+ case QuickSearchFilter.from:
+ return imagePaths.icUserSB;
}
}
- Color getBackgroundColor({required bool isFilterSelected}) {
+ Color getBackgroundColor({bool isFilterSelected = false}) {
if (isFilterSelected) {
- return AppColor.colorItemEmailSelectedDesktop;
+ return AppColor.primaryColor.withOpacity(0.06);
} else {
- return AppColor.colorButtonHeaderThread;
+ return AppColor.colorSearchFilterButton;
}
}
- TextStyle getTextStyle({required bool isFilterSelected}) {
+ Color getSuggestionBackgroundColor({bool isFilterSelected = false}) {
if (isFilterSelected) {
- return const TextStyle(
- fontSize: 13,
- fontWeight: FontWeight.w500,
- color: AppColor.colorTextButton);
+ return AppColor.primaryColor.withOpacity(0.06);
} else {
- return const TextStyle(
- fontSize: 13,
- fontWeight: FontWeight.normal,
- color: AppColor.colorTextButtonHeaderThread);
+ return AppColor.colorSuggestionSearchFilterButton.withOpacity(0.6);
+ }
+ }
+
+ Color getIconColor({bool isSelected = false}) {
+ if (isSelected) {
+ return AppColor.primaryColor;
+ } else {
+ return AppColor.colorTextBody;
}
}
bool isApplied(List listFilter) => listFilter.contains(this);
- bool isSelected(SearchEmailFilter filter) {
+ bool isSelected(
+ BuildContext context,
+ SearchEmailFilter searchFilter,
+ EmailSortOrderType sortOrderType
+ ) {
switch (this) {
case QuickSearchFilter.hasAttachment:
- return filter.hasAttachment == true;
+ return searchFilter.hasAttachment;
case QuickSearchFilter.last7Days:
return true;
case QuickSearchFilter.fromMe:
- return filter.from.length == 1;
+ return searchFilter.from.length == 1;
case QuickSearchFilter.sortBy:
- return true;
+ return sortOrderType != EmailSortOrderType.mostRecent;
+ case QuickSearchFilter.dateTime:
+ return searchFilter.emailReceiveTimeType != EmailReceiveTimeType.allTime;
+ case QuickSearchFilter.from:
+ return searchFilter.from.isNotEmpty;
}
}
- bool isTapOpenPopupMenu() => this == QuickSearchFilter.last7Days || this == QuickSearchFilter.sortBy;
+ bool isOnTapWithPositionActionSupported() =>
+ this == QuickSearchFilter.dateTime || this == QuickSearchFilter.sortBy;
+
+ bool isArrowDownIconSupported() =>
+ this == QuickSearchFilter.dateTime ||
+ this == QuickSearchFilter.from ||
+ this == QuickSearchFilter.sortBy;
}
\ No newline at end of file
diff --git a/lib/features/mailbox_dashboard/presentation/styles/search_filter_button_style.dart b/lib/features/mailbox_dashboard/presentation/styles/search_filter_button_style.dart
new file mode 100644
index 000000000..472873bfe
--- /dev/null
+++ b/lib/features/mailbox_dashboard/presentation/styles/search_filter_button_style.dart
@@ -0,0 +1,17 @@
+import 'package:core/presentation/extensions/color_extension.dart';
+import 'package:flutter/material.dart';
+
+class SearchFilterButtonStyle {
+ static const double iconSize = 16;
+ static const double deleteIconSize = 10;
+ static const double spaceSize = 4;
+
+ static const EdgeInsetsGeometry buttonPadding = EdgeInsets.symmetric(horizontal: 12, vertical: 8);
+ static const EdgeInsetsGeometry elementPadding = EdgeInsetsDirectional.only(start: 8);
+ static const BorderRadius borderRadius = BorderRadius.all(Radius.circular(10));
+
+ static const TextStyle titleStyle = TextStyle(
+ fontSize: 13,
+ fontWeight: FontWeight.normal,
+ color: AppColor.colorTextButtonHeaderThread);
+}
\ No newline at end of file
diff --git a/lib/features/mailbox_dashboard/presentation/widgets/search_filters/search_filter_button.dart b/lib/features/mailbox_dashboard/presentation/widgets/search_filters/search_filter_button.dart
new file mode 100644
index 000000000..b3613d3ef
--- /dev/null
+++ b/lib/features/mailbox_dashboard/presentation/widgets/search_filters/search_filter_button.dart
@@ -0,0 +1,133 @@
+
+import 'package:core/presentation/extensions/color_extension.dart';
+import 'package:core/presentation/resources/image_paths.dart';
+import 'package:core/presentation/views/button/tmail_button_widget.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:jmap_dart_client/jmap/core/user_name.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_sort_order_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/styles/search_filter_button_style.dart';
+
+typedef OnSelectSearchFilterAction = Function(
+ BuildContext context,
+ QuickSearchFilter searchFilter,
+ {RelativeRect? buttonPosition});
+
+class SearchFilterButton extends StatelessWidget {
+
+ final QuickSearchFilter searchFilter;
+ final bool isSelected;
+ final ImagePaths imagePaths;
+ final EmailReceiveTimeType? receiveTimeType;
+ final EmailSortOrderType? sortOrderType;
+ final DateTime? startDate;
+ final DateTime? endDate;
+ final Set? listAddressOfFrom;
+ final UserName? userName;
+ final Color? backgroundColor;
+ final OnSelectSearchFilterAction? onSelectSearchFilterAction;
+
+ const SearchFilterButton({
+ super.key,
+ required this.searchFilter,
+ required this.imagePaths,
+ this.isSelected = false,
+ this.receiveTimeType,
+ this.sortOrderType,
+ this.startDate,
+ this.endDate,
+ this.listAddressOfFrom,
+ this.userName,
+ this.backgroundColor,
+ this.onSelectSearchFilterAction,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ final childItem = Container(
+ decoration: BoxDecoration(
+ borderRadius: SearchFilterButtonStyle.borderRadius,
+ color: backgroundColor ?? searchFilter.getBackgroundColor(isFilterSelected: isSelected)),
+ padding: SearchFilterButtonStyle.buttonPadding,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SvgPicture.asset(
+ searchFilter.getIcon(imagePaths, isSelected: isSelected),
+ width: SearchFilterButtonStyle.iconSize,
+ height: SearchFilterButtonStyle.iconSize,
+ colorFilter: searchFilter.getIconColor(isSelected: isSelected).asFilter(),
+ fit: BoxFit.fill),
+ const SizedBox(width: SearchFilterButtonStyle.spaceSize),
+ Text(
+ searchFilter.getTitle(
+ context,
+ receiveTimeType: receiveTimeType,
+ startDate: startDate,
+ endDate: startDate,
+ sortOrderType: sortOrderType,
+ listAddressOfFrom: listAddressOfFrom,
+ userName: userName),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: SearchFilterButtonStyle.titleStyle,
+ ),
+ if (searchFilter.isArrowDownIconSupported())
+ Padding(
+ padding: SearchFilterButtonStyle.elementPadding,
+ child: SvgPicture.asset(
+ imagePaths.icDropDown,
+ width: SearchFilterButtonStyle.iconSize,
+ height: SearchFilterButtonStyle.iconSize,
+ colorFilter: AppColor.colorTextBody.asFilter(),
+ fit: BoxFit.fill),
+ ),
+ if (isSelected)
+ TMailButtonWidget.fromIcon(
+ icon: imagePaths.icDeleteSelection,
+ iconSize: SearchFilterButtonStyle.deleteIconSize,
+ iconColor: AppColor.colorTextBody,
+ padding: EdgeInsets.zero,
+ backgroundColor: Colors.transparent,
+ margin: SearchFilterButtonStyle.elementPadding,
+ ),
+ ]
+ )
+ );
+
+ if (onSelectSearchFilterAction != null) {
+ return Material(
+ type: MaterialType.transparency,
+ child: InkWell(
+ onTap: searchFilter.isOnTapWithPositionActionSupported()
+ ? null
+ : () => _onTapAction(context),
+ onTapDown: searchFilter.isOnTapWithPositionActionSupported()
+ ? (details) => _onTapDownAction(context, details)
+ : null,
+ borderRadius: SearchFilterButtonStyle.borderRadius,
+ child: childItem),
+ );
+ } else {
+ return childItem;
+ }
+ }
+
+ void _onTapAction(BuildContext context) {
+ onSelectSearchFilterAction?.call(context, searchFilter);
+ }
+
+ void _onTapDownAction(BuildContext context, TapDownDetails details) {
+ final screenSize = MediaQuery.sizeOf(context);
+ final offset = details.globalPosition;
+ final position = RelativeRect.fromLTRB(
+ offset.dx,
+ offset.dy,
+ screenSize.width - offset.dx,
+ screenSize.height - offset.dy);
+
+ onSelectSearchFilterAction?.call(context, searchFilter, buttonPosition: 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 d8463069d..b3e388ed1 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
@@ -1,7 +1,6 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
-import 'package:core/presentation/utils/style_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/direction_utils.dart';
@@ -23,6 +22,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad
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/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/features/mailbox_dashboard/presentation/widgets/search_filters/search_filter_button.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
@@ -65,9 +65,13 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
borderRadius: BorderRadius.all(Radius.circular(16)),
),
debounceDuration: const Duration(milliseconds: 300),
- listActionButton: QuickSearchFilter.values,
+ listActionButton: const [
+ QuickSearchFilter.hasAttachment,
+ QuickSearchFilter.last7Days,
+ QuickSearchFilter.fromMe,
+ ],
actionButtonBuilder: (context, filterAction) {
- if (filterAction is QuickSearchFilter && filterAction != QuickSearchFilter.sortBy) {
+ if (filterAction is QuickSearchFilter) {
return buildListButtonForQuickSearchForm(context, filterAction);
} else {
return const SizedBox.shrink();
@@ -217,34 +221,15 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
);
}
- Widget buildListButtonForQuickSearchForm(BuildContext context, QuickSearchFilter filter) {
+ Widget buildListButtonForQuickSearchForm(BuildContext context, QuickSearchFilter searchFilter) {
return Obx(() {
- final isFilterSelected = filter.isApplied(_searchController.listFilterOnSuggestionForm);
+ final isSelected = searchFilter.isApplied(_searchController.listFilterOnSuggestionForm);
- return Chip(
- labelPadding: const EdgeInsetsDirectional.only(
- top: 2,
- bottom: 2,
- end: 10,
- ),
- label: Text(
- filter.getName(context),
- maxLines: 1,
- overflow: CommonTextStyle.defaultTextOverFlow,
- softWrap: CommonTextStyle.defaultSoftWrap,
- style: filter.getTextStyle(isFilterSelected: isFilterSelected),
- ),
- avatar: SvgPicture.asset(
- filter.getIcon(_imagePaths, isFilterSelected: isFilterSelected),
- width: 16,
- height: 16,
- fit: BoxFit.fill),
- labelStyle: filter.getTextStyle(isFilterSelected: isFilterSelected),
- backgroundColor: filter.getBackgroundColor(isFilterSelected: isFilterSelected),
- shape: RoundedRectangleBorder(
- borderRadius: const BorderRadius.all(Radius.circular(10)),
- side: BorderSide(color: filter.getBackgroundColor(isFilterSelected: isFilterSelected)),
- ),
+ return SearchFilterButton(
+ searchFilter: searchFilter,
+ imagePaths: _imagePaths,
+ isSelected: isSelected,
+ backgroundColor: searchFilter.getSuggestionBackgroundColor(isFilterSelected: isSelected),
);
});
}
diff --git a/lib/features/search/email/presentation/search_email_view.dart b/lib/features/search/email/presentation/search_email_view.dart
index 5ed097a53..cf0fb6756 100644
--- a/lib/features/search/email/presentation/search_email_view.dart
+++ b/lib/features/search/email/presentation/search_email_view.dart
@@ -257,7 +257,7 @@ class SearchEmailView extends GetWidget
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
SvgPicture.asset(
- filter.getIcon(controller.imagePaths, isFilterSelected: filterSelected),
+ filter.getIcon(controller.imagePaths, isSelected: filterSelected),
width: 16,
height: 16,
fit: BoxFit.fill),
@@ -273,7 +273,10 @@ class SearchEmailView extends GetWidget
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
- style: filter.getTextStyle(isFilterSelected: filterSelected),
+ style: const TextStyle(
+ fontSize: 13,
+ fontWeight: FontWeight.normal,
+ color: AppColor.colorTextButtonHeaderThread),
),
if (filter == QuickSearchFilter.last7Days || filter == QuickSearchFilter.sortBy)
... [
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 15c0a092f..d30443722 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
@@ -64,7 +64,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/advanced_search_filter.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_sort_order_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/search_email_filter.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
@@ -405,9 +404,8 @@ void main() {
expect(searchController.sortOrderFiltered.value, EmailSortOrderType.oldest);
// expect filter in search controller update as expected
- mailboxDashboardController.selectQuickSearchFilterAction(QuickSearchFilter.hasAttachment);
+ mailboxDashboardController.selectHasAttachmentSearchFilter();
expect(searchController.searchEmailFilter.value.hasAttachment, true);
- mailboxDashboardController.selectQuickSearchFilterAction(QuickSearchFilter.last7Days);
mailboxDashboardController.selectReceiveTimeQuickSearchFilter(context, EmailReceiveTimeType.last30Days);
expect(searchController.searchEmailFilter.value.emailReceiveTimeType, EmailReceiveTimeType.last30Days);