TF-3002 [WEB] Apply new design for SearchFilterButton
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<svg width="11" height="10" viewBox="0 0 11 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.0221 0.263604C10.3735 0.615076 10.3735 1.18492 10.0221 1.5364L6.55864 5L10.0221 8.46362C10.3442 8.7858 10.3711 9.29148 10.1026 9.64424L10.0221 9.73641C9.67058 10.0879 9.10073 10.0879 8.74926 9.73641L5.28564 6.273L1.82204 9.73641C1.47057 10.0879 0.90072 10.0879 0.549248 9.73641C0.197777 9.38494 0.197777 8.81509 0.549248 8.46362L4.01264 5L0.549248 1.5364C0.227066 1.21421 0.200217 0.708534 0.468703 0.355769L0.549248 0.263604C0.90072 -0.087868 1.47057 -0.087868 1.82204 0.263604L5.28564 3.727L8.74926 0.263604C9.10073 -0.087868 9.67058 -0.087868 10.0221 0.263604Z" fill="#818C99"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 698 B |
@@ -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)],
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1286,13 +1286,16 @@ class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
||||
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 {
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+18
-27
@@ -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<void> 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
? <String>{fromEmailFilter.email!}
|
||||
: <String>{};
|
||||
updateFilterEmail(fromOption: Some(newListEmailAddress));
|
||||
}
|
||||
return;
|
||||
case QuickSearchFilter.sortBy:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void addFilterToSuggestionForm(QuickSearchFilter filter) {
|
||||
if (listFilterOnSuggestionForm.contains(filter)) {
|
||||
listFilterOnSuggestionForm.remove(filter);
|
||||
|
||||
@@ -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<PopupMenuEntry> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String>? 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<QuickSearchFilter> 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
+133
@@ -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<String>? 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);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
||||
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<SearchEmailController>
|
||||
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)
|
||||
... [
|
||||
|
||||
+1
-3
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user