From 33bf16d8f90789ec9da70be1c7ba0f6e97684c4e Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 13 Sep 2024 14:22:06 +0700 Subject: [PATCH] TF-3002 [MOBILE] Apply new design for SearchFilterButton --- .../extensions/color_extension.dart | 1 + .../mailbox_dashboard_view_web.dart | 1 + .../model/search/quick_search_filter.dart | 29 +- .../search_filters/search_filter_button.dart | 12 +- .../widgets/search_input_form_widget.dart | 5 +- .../presentation/search_email_controller.dart | 40 +- .../email/presentation/search_email_view.dart | 595 +++++++++--------- .../styles/search_email_view_style.dart | 99 +++ .../utils/search_email_utils.dart | 85 --- ...cupertino_action_sheet_action_builder.dart | 4 +- 10 files changed, 433 insertions(+), 438 deletions(-) create mode 100644 lib/features/search/email/presentation/styles/search_email_view_style.dart diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart index beecaf2a3..5e8fc07c9 100644 --- a/core/lib/presentation/extensions/color_extension.dart +++ b/core/lib/presentation/extensions/color_extension.dart @@ -233,6 +233,7 @@ extension AppColor on Color { static const colorFilterMessageIcon = Color(0xFF686E76); static const colorFilterMessageTitle = Color(0xFF686E76); static const colorStarredSearchFilterIcon = Color(0xFFFFCC00); + static const colorMobileSearchFilterButton = Color(0xFFEBEDF0); static const mapGradientColor = [ [Color(0xFF21D4FD), Color(0xFFB721FF)], 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 c5b4c333c..3f5d0bae8 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -557,6 +557,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { key: Key('${searchFilter.name}_search_filter_button'), searchFilter: searchFilter, imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, isSelected: isSelected, receiveTimeType: receiveTimeType, startDate: startDate, 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 d5b21cd23..9c33a2b47 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 @@ -1,6 +1,7 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/cupertino.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; @@ -83,16 +84,24 @@ enum QuickSearchFilter { } } - Color getBackgroundColor({bool isFilterSelected = false}) { - if (isFilterSelected) { + Color getBackgroundColor({bool isSelected = false}) { + if (isSelected) { return AppColor.primaryColor.withOpacity(0.06); } else { return AppColor.colorSearchFilterButton; } } - Color getSuggestionBackgroundColor({bool isFilterSelected = false}) { - if (isFilterSelected) { + Color getMobileBackgroundColor({bool isSelected = false}) { + if (isSelected) { + return AppColor.primaryColor.withOpacity(0.06); + } else { + return AppColor.colorMobileSearchFilterButton.withOpacity(0.6); + } + } + + Color getSuggestionBackgroundColor({bool isSelected = false}) { + if (isSelected) { return AppColor.primaryColor.withOpacity(0.06); } else { return AppColor.colorSuggestionSearchFilterButton.withOpacity(0.6); @@ -143,8 +152,16 @@ enum QuickSearchFilter { } } - bool isOnTapWithPositionActionSupported() => - this == QuickSearchFilter.dateTime || this == QuickSearchFilter.sortBy; + bool isOnTapWithPositionActionSupported( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if (responsiveUtils.isMobile(context)) { + return false; + } else { + return this == QuickSearchFilter.dateTime || this == QuickSearchFilter.sortBy; + } + } bool isArrowDownIconSupported() => this == QuickSearchFilter.dateTime || 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 index f14aa842d..792b478ea 100644 --- 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 @@ -1,6 +1,6 @@ - import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -24,6 +24,7 @@ class SearchFilterButton extends StatelessWidget { final QuickSearchFilter searchFilter; final bool isSelected; final ImagePaths imagePaths; + final ResponsiveUtils responsiveUtils; final EmailReceiveTimeType? receiveTimeType; final EmailSortOrderType? sortOrderType; final DateTime? startDate; @@ -41,6 +42,7 @@ class SearchFilterButton extends StatelessWidget { super.key, required this.searchFilter, required this.imagePaths, + required this.responsiveUtils, this.isSelected = false, this.receiveTimeType, this.sortOrderType, @@ -120,14 +122,14 @@ class SearchFilterButton extends StatelessWidget { return childItem; } - if (!searchFilter.isOnTapWithPositionActionSupported()) { + if (!searchFilter.isOnTapWithPositionActionSupported(context, responsiveUtils)) { return Material( type: MaterialType.transparency, child: InkWell( - onTap: !searchFilter.isOnTapWithPositionActionSupported() + onTap: !searchFilter.isOnTapWithPositionActionSupported(context, responsiveUtils) ? () => _onTapAction(context) : null, - onTapDown: searchFilter.isOnTapWithPositionActionSupported() && !isSelected + onTapDown: searchFilter.isOnTapWithPositionActionSupported(context, responsiveUtils) && !isSelected ? (details) => _onTapDownAction(context, details) : null, borderRadius: SearchFilterButtonStyle.borderRadius, @@ -155,7 +157,7 @@ class SearchFilterButton extends StatelessWidget { decoration: BoxDecoration( borderRadius: SearchFilterButtonStyle.borderRadius, color: backgroundColor ?? searchFilter.getBackgroundColor( - isFilterSelected: isSelected + isSelected: isSelected ) ), padding: buttonPadding ?? SearchFilterButtonStyle.getButtonPadding(isSelected), 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 99e8e177f..6f1d11b89 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,6 +1,7 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_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'; @@ -29,6 +30,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin { final _searchController = Get.find(); final _dashBoardController = Get.find(); final _imagePaths = Get.find(); + final _responsiveUtils = Get.find(); SearchInputFormWidget({Key? key}) : super(key: key); @@ -235,8 +237,9 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin { return SearchFilterButton( searchFilter: searchFilter, imagePaths: _imagePaths, + responsiveUtils: _responsiveUtils, isSelected: isSelected, - backgroundColor: searchFilter.getSuggestionBackgroundColor(isFilterSelected: isSelected), + backgroundColor: searchFilter.getSuggestionBackgroundColor(isSelected: isSelected), onDeleteSearchFilterAction: (searchFilter) { _searchController.deleteQuickSearchFilterFromSuggestionSearchView(searchFilter); suggestionsListState.invalidateSuggestions(); diff --git a/lib/features/search/email/presentation/search_email_controller.dart b/lib/features/search/email/presentation/search_email_controller.dart index b97ec1c5f..1f647f7b5 100644 --- a/lib/features/search/email/presentation/search_email_controller.dart +++ b/lib/features/search/email/presentation/search_email_controller.dart @@ -94,6 +94,7 @@ class SearchEmailController extends BaseController final textInputSearchController = TextEditingController(); final resultSearchScrollController = ScrollController(); final textInputSearchFocus = FocusNode(); + final listSearchFilterScrollController = ScrollController(); final currentSearchText = RxString(''); final listRecentSearch = RxList(); @@ -499,8 +500,14 @@ class SearchEmailController extends BaseController _searchEmailAction(context); } - void selectQuickSearchFilter(BuildContext context, QuickSearchFilter filter) { - _selectQuickSearchFilter(filter); + void selectHasAttachmentSearchFilter(BuildContext context) { + _updateSimpleSearchFilter( + hasAttachmentOption: const Some(true), + beforeOption: const None(), + positionOption: emailSortOrderType.value.isScrollByPosition() + ? const Some(0) + : const None() + ); _searchEmailAction(context); } @@ -517,34 +524,6 @@ class SearchEmailController extends BaseController } } - void _selectQuickSearchFilter(QuickSearchFilter filter) { - final filterSelected = checkQuickSearchFilterSelected(filter); - switch (filter) { - case QuickSearchFilter.hasAttachment: - _updateSimpleSearchFilter( - hasAttachmentOption: Some(!filterSelected), - beforeOption: const None(), - positionOption: emailSortOrderType.value.isScrollByPosition() ? const Some(0) : const None() - ); - break; - case QuickSearchFilter.last7Days: - _updateSimpleSearchFilter( - emailReceiveTimeTypeOption: optionOf(emailReceiveTimeType.value), - beforeOption: const None(), - positionOption: emailSortOrderType.value.isScrollByPosition() ? const Some(0) : const None() - ); - break; - case QuickSearchFilter.sortBy: - _updateSimpleSearchFilter( - sortOrderOption: emailSortOrderType.value.getSortOrder(), - beforeOption: const None(), - positionOption: emailSortOrderType.value.isScrollByPosition() ? const Some(0) : const None() - ); - default: - break; - } - } - void _setEmailReceiveTimeType(EmailReceiveTimeType receiveTimeType) { emailReceiveTimeType.value = receiveTimeType; } @@ -937,6 +916,7 @@ class SearchEmailController extends BaseController textInputSearchController.dispose(); textInputSearchFocus.dispose(); resultSearchScrollController.dispose(); + listSearchFilterScrollController.dispose(); _deBouncerTime.cancel(); dashBoardViewStateWorker.dispose(); dashBoardActionWorker.dispose(); diff --git a/lib/features/search/email/presentation/search_email_view.dart b/lib/features/search/email/presentation/search_email_view.dart index 9ae400820..d519dcf26 100644 --- a/lib/features/search/email/presentation/search_email_view.dart +++ b/lib/features/search/email/presentation/search_email_view.dart @@ -1,16 +1,17 @@ import 'package:core/presentation/extensions/color_extension.dart'; -import 'package:core/presentation/utils/style_utils.dart'; import 'package:core/presentation/views/button/icon_button_web.dart'; import 'package:core/presentation/views/text/text_field_builder.dart'; import 'package:core/utils/direction_utils.dart'; import 'package:core/utils/platform_info.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.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/widget/scrollbar_list_view.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart'; @@ -19,8 +20,10 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/sear 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/features/search/email/presentation/model/search_more_state.dart'; import 'package:tmail_ui_user/features/search/email/presentation/search_email_controller.dart'; +import 'package:tmail_ui_user/features/search/email/presentation/styles/search_email_view_style.dart'; import 'package:tmail_ui_user/features/search/email/presentation/utils/search_email_utils.dart'; import 'package:tmail_ui_user/features/search/email/presentation/widgets/app_bar_selection_mode.dart'; import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_receive_time_action_tile_widget.dart'; @@ -58,7 +61,10 @@ class SearchEmailView extends GetWidget Container( height: 52, color: Colors.white, - padding: SearchEmailUtils.getPaddingAppBar(context, controller.responsiveUtils), + padding: SearchEmailViewStyle.getAppBarPadding( + context, + controller.responsiveUtils + ), child: Obx(() { if (controller.selectionMode.value == SelectMode.ACTIVE) { return AppBarSelectionMode( @@ -98,10 +104,9 @@ class SearchEmailView extends GetWidget ); } else { if (controller.listResultSearch.isNotEmpty) { - return Container( - color: Colors.white, - padding: const EdgeInsets.symmetric(horizontal: 4), - child: _buildListEmailBody(context, controller.listResultSearch) + return _buildListEmailBody( + context, + controller.listResultSearch ); } else { return _buildEmptyEmail(context); @@ -164,135 +169,183 @@ class SearchEmailView extends GetWidget Widget _buildListSearchFilterAction(BuildContext context) { return Container( - margin: SearchEmailUtils.getMarginSearchFilterButton(context, controller.responsiveUtils), - padding: SearchEmailUtils.getPaddingSearchFilterButton(context, controller.responsiveUtils), - height: 60, - child: ListView( + height: 45, + margin: SearchEmailViewStyle.listSearchFilterButtonMargin, + alignment: AlignmentDirectional.centerStart, + child: ScrollbarListView( + scrollBehavior: ScrollConfiguration.of(context).copyWith( + dragDevices: { + PointerDeviceKind.touch, + PointerDeviceKind.mouse, + PointerDeviceKind.trackpad + }, + scrollbars: false + ), + scrollController: controller.listSearchFilterScrollController, + child: ListView( scrollDirection: Axis.horizontal, + shrinkWrap: true, + controller: controller.listSearchFilterScrollController, + padding: SearchEmailViewStyle.getListSearchFilterButtonPadding( + context, + controller.responsiveUtils + ), children: [ - _buildSearchFilterByContactButton(context, PrefixEmailAddress.from), - _buildSearchFilterByContactButton(context, PrefixEmailAddress.to), - ...[ - QuickSearchFilter.hasAttachment, - QuickSearchFilter.last7Days - ].map((filter) => _buildQuickSearchFilterButton(context, filter)), - _buildSearchFilterByMailboxButton(context), - _buildQuickSearchFilterButton(context, QuickSearchFilter.sortBy) + _buildSearchFilterButton(context, QuickSearchFilter.folder), + SearchEmailViewStyle.searchFilterSizeBoxMargin, + _buildSearchFilterButton(context, QuickSearchFilter.from), + SearchEmailViewStyle.searchFilterSizeBoxMargin, + _buildSearchFilterButton(context, QuickSearchFilter.to), + SearchEmailViewStyle.searchFilterSizeBoxMargin, + _buildSearchFilterButton(context, QuickSearchFilter.hasAttachment), + SearchEmailViewStyle.searchFilterSizeBoxMargin, + _buildSearchFilterButton(context, QuickSearchFilter.dateTime), + SearchEmailViewStyle.searchFilterSizeBoxMargin, + _buildSearchFilterButton(context, QuickSearchFilter.starred), + SearchEmailViewStyle.searchFilterSizeBoxMargin, + _buildSearchFilterButton(context, QuickSearchFilter.sortBy), ], + ), ), ); } - Widget _buildQuickSearchFilterButton(BuildContext context, QuickSearchFilter filter) { + Widget _buildSearchFilterButton( + BuildContext context, + QuickSearchFilter searchFilter, + ) { return Obx(() { - final filterSelected = controller.checkQuickSearchFilterSelected(filter); - return Padding( - padding: const EdgeInsets.only(right: 8), - child: InkWell( - onTap: () { - FocusScope.of(context).unfocus(); + final searchEmailFilter = controller.searchEmailFilter.value; + final sortOrderType = controller.emailSortOrderType.value; + final listAddressOfFrom = controller.listAddressOfFromFiltered; + final userName = controller.session?.username; + final startDate = controller.startDateFiltered; + final endDate = controller.endDateFiltered; + final receiveTimeType = controller.receiveTimeFiltered; + final mailbox = controller.mailboxFiltered; + final listAddressOfTo = controller.listAddressOfToFiltered; - if (filter == QuickSearchFilter.hasAttachment) { - controller.selectQuickSearchFilter(context, filter); - } else if (controller.responsiveUtils.isMobile(context)) { - if (filter == QuickSearchFilter.last7Days) { - controller.openContextMenuAction( - context, - _emailReceiveTimeCupertinoActionTile( - context, - controller.emailReceiveTimeType.value, - (receiveTime) => controller.selectReceiveTimeQuickSearchFilter(context, receiveTime))); - } else { - controller.openContextMenuAction( - context, - _emailSortOrderCupertinoActionTitle( - context, - controller.emailSortOrderType.value, - controller.selectSortOrderQuickSearchFilter - ) - ); - } - } - }, - onTapDown: (detail) { - if (!controller.responsiveUtils.isMobile(context)) { - FocusScope.of(context).unfocus(); + final isSelected = searchFilter.isSelected( + context, + searchEmailFilter, + sortOrderType, + userName); - 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, - ); - if (filter == QuickSearchFilter.last7Days) { - controller.openPopupMenuAction( - context, - position, - _popupMenuEmailReceiveTimeType( - context, - controller.emailReceiveTimeType.value, - (receiveTime) => controller.selectReceiveTimeQuickSearchFilter(context, receiveTime))); - } else if (filter == QuickSearchFilter.sortBy) { - controller.openPopupMenuAction( - context, - position, - _popupMenuEmailSortOrderType( - context, - controller.emailSortOrderType.value, - controller.selectSortOrderQuickSearchFilter - ) - ); - } - } - }, - borderRadius: const BorderRadius.all(Radius.circular(10)), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: filter.getBackgroundColor(isFilterSelected: filterSelected)), - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - SvgPicture.asset( - filter.getIcon(controller.imagePaths, isSelected: filterSelected), - width: 16, - height: 16, - fit: BoxFit.fill), - const SizedBox(width: 4), - Text( - filter.getTitle( - context, - receiveTimeType: controller.emailReceiveTimeType.value, - startDate: controller.startDateFiltered, - endDate: controller.endDateFiltered, - sortOrderType: controller.emailSortOrderType.value - ), - maxLines: 1, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - style: const TextStyle( - fontSize: 13, - fontWeight: FontWeight.normal, - color: AppColor.colorTextButtonHeaderThread), - ), - if (filter == QuickSearchFilter.last7Days || filter == QuickSearchFilter.sortBy) - ... [ - const SizedBox(width: 4), - SvgPicture.asset( - controller.imagePaths.icChevronDownOutline, - colorFilter: filterSelected - ? AppColor.primaryColor.asFilter() - : AppColor.colorDefaultRichTextButton.asFilter(), - fit: BoxFit.fill), - ] - ]) - ), - ), + return SearchFilterButton( + key: Key('mobile_${searchFilter.name}_search_filter_button'), + searchFilter: searchFilter, + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + isSelected: isSelected, + receiveTimeType: receiveTimeType, + startDate: startDate, + endDate: endDate, + sortOrderType: sortOrderType, + listAddressOfFrom: listAddressOfFrom, + listAddressOfTo: listAddressOfTo, + userName: userName, + mailbox: mailbox, + backgroundColor: searchFilter.getMobileBackgroundColor(isSelected: isSelected), + onSelectSearchFilterAction: _onSelectSearchFilterAction, ); }); } + Future _onSelectSearchFilterAction( + BuildContext context, + QuickSearchFilter searchFilter, + {RelativeRect? buttonPosition} + ) async { + switch(searchFilter) { + case QuickSearchFilter.dateTime: + if (buttonPosition != null) { + _openPopupMenuDateFilter(context, buttonPosition); + } else { + _openContextMenuDateFilter(context); + } + break; + case QuickSearchFilter.sortBy: + if (buttonPosition != null) { + _openPopupMenuSortFilter(context, buttonPosition); + } else { + _openContextMenuSortFilter(context); + } + break; + case QuickSearchFilter.from: + controller.selectContactForSearchFilter( + context, + PrefixEmailAddress.from); + break; + case QuickSearchFilter.hasAttachment: + controller.selectHasAttachmentSearchFilter(context); + break; + case QuickSearchFilter.to: + controller.selectContactForSearchFilter( + context, + PrefixEmailAddress.to); + break; + case QuickSearchFilter.folder: + controller.selectMailboxForSearchFilter( + context, + controller.mailboxFiltered); + break; + default: + break; + } + } + + void _openPopupMenuDateFilter(BuildContext context, RelativeRect position) { + controller.openPopupMenuAction( + context, + position, + _popupMenuEmailReceiveTimeType( + context, + controller.emailReceiveTimeType.value, + (receiveTime) => controller.selectReceiveTimeQuickSearchFilter( + context, + receiveTime + ) + ) + ); + } + + void _openContextMenuDateFilter(BuildContext context) { + controller.openContextMenuAction( + context, + _emailReceiveTimeCupertinoActionTile( + context, + controller.emailReceiveTimeType.value, + (receiveTime) => controller.selectReceiveTimeQuickSearchFilter( + context, + receiveTime + ) + ) + ); + } + + void _openPopupMenuSortFilter(BuildContext context, RelativeRect position) { + controller.openPopupMenuAction( + context, + position, + _popupMenuEmailSortOrderType( + context, + controller.emailSortOrderType.value, + controller.selectSortOrderQuickSearchFilter + ) + ); + } + + void _openContextMenuSortFilter(BuildContext context) { + controller.openContextMenuAction( + context, + _emailSortOrderCupertinoActionTitle( + context, + controller.emailSortOrderType.value, + controller.selectSortOrderQuickSearchFilter + ) + ); + } + List _popupMenuEmailReceiveTimeType( BuildContext context, EmailReceiveTimeType? receiveTimeSelected, @@ -320,10 +373,10 @@ class SearchEmailView extends GetWidget timeType, timeTypeCurrent: receiveTimeSelected, iconLeftPadding: controller.responsiveUtils.isMobile(context) - ? const EdgeInsets.only(left: 12, right: 16) - : const EdgeInsets.only(right: 12), + ? const EdgeInsetsDirectional.only(start: 12, end: 16) + : const EdgeInsetsDirectional.only(end: 12), iconRightPadding: controller.responsiveUtils.isMobile(context) - ? const EdgeInsets.only(right: 12) + ? const EdgeInsetsDirectional.only(end: 12) : EdgeInsets.zero, actionSelected: SvgPicture.asset( controller.imagePaths.icFilterSelected, @@ -394,20 +447,33 @@ class SearchEmailView extends GetWidget } }, child: Padding( - padding: SearchEmailUtils.getPaddingShowAllResultButton(context, controller.responsiveUtils), - child: Row(children: [ - Text(AppLocalizations.of(context).showingResultsFor, - style: const TextStyle(fontSize: 13.0, - color: AppColor.colorTextButtonHeaderThread, - fontWeight: FontWeight.w500) + padding: SearchEmailViewStyle.getShowAllResultButtonPadding( + context, + controller.responsiveUtils + ), + child: Row( + children: [ + Text( + AppLocalizations.of(context).showingResultsFor, + style: const TextStyle( + fontSize: 13.0, + color: AppColor.colorTextButtonHeaderThread, + fontWeight: FontWeight.w500 + ) ), const SizedBox(width: 4), - Expanded(child: Text('"${controller.currentSearchText.value}"', + Expanded( + child: Text( + '"${controller.currentSearchText.value}"', style: const TextStyle( - fontSize: 13.0, - color: Colors.black, - fontWeight: FontWeight.w500))) - ]) + fontSize: 13.0, + color: Colors.black, + fontWeight: FontWeight.w500 + ) + ) + ) + ] + ) ), ), ); @@ -417,16 +483,20 @@ class SearchEmailView extends GetWidget BuildContext context, List listRecentSearch ) { - return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: SearchEmailUtils.getPaddingSearchRecentTitle(context, controller.responsiveUtils), - child: Text(AppLocalizations.of(context).recent, - style: const TextStyle(fontSize: 13.0, - color: AppColor.colorTextButtonHeaderThread, - fontWeight: FontWeight.w500) + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: SearchEmailViewStyle.getSearchRecentTitleMargin( + context, + controller.responsiveUtils + ), + child: Text( + AppLocalizations.of(context).recent, + style: SearchEmailViewStyle.searchRecentTitleStyle ) - ), - ListView.builder( + ), + ListView.builder( shrinkWrap: true, primary: false, itemCount: listRecentSearch.length, @@ -436,13 +506,22 @@ class SearchEmailView extends GetWidget color: Colors.transparent, child: InkWell( child: RecentSearchItemTileWidget( - recentSearch, - contentPadding: SearchEmailUtils.getPaddingListRecentSearch(context, controller.responsiveUtils)), - onTap: () => controller.searchEmailByRecentAction(context, recentSearch), + recentSearch, + contentPadding: SearchEmailViewStyle.getListRecentSearchPadding( + context, + controller.responsiveUtils + ) + ), + onTap: () => controller.searchEmailByRecentAction( + context, + recentSearch + ), ), ); - }) - ]); + } + ) + ] + ); } Widget _buildListSuggestionSearch( @@ -458,9 +537,13 @@ class SearchEmailView extends GetWidget color: Colors.transparent, child: InkWell( child: EmailQuickSearchItemTileWidget( - listSuggestionSearch[index], - controller.currentMailbox, - contentPadding: SearchEmailUtils.getPaddingSearchSuggestionList(context, controller.responsiveUtils)), + listSuggestionSearch[index], + controller.currentMailbox, + contentPadding: SearchEmailViewStyle.getSearchSuggestionListPadding( + context, + controller.responsiveUtils + ) + ), onTap: () { final emailPreview = listSuggestionSearch[index]; final mailboxContain = emailPreview @@ -536,7 +619,7 @@ class SearchEmailView extends GetWidget searchQuery: controller.searchQuery, isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id, isSearchEmailRunning: true, - padding: SearchEmailUtils.getPaddingSearchResultList(context, controller.responsiveUtils), + padding: SearchEmailViewStyle.getPaddingSearchResultList(context, controller.responsiveUtils), mailboxContain: currentPresentationEmail.mailboxContain, emailActionClick: (action, email) { controller.pressEmailAction( @@ -573,57 +656,60 @@ class SearchEmailView extends GetWidget }, ) : ListView.separated( - controller: controller.resultSearchScrollController, - physics: const AlwaysScrollableScrollPhysics(), - key: const PageStorageKey('list_presentation_email_in_search_view'), - itemCount: listPresentationEmail.length, - itemBuilder: (context, index) { - final currentPresentationEmail = listPresentationEmail[index]; - return Obx(() => EmailTileBuilder( - presentationEmail: currentPresentationEmail, - selectAllMode: controller.selectionMode.value, - searchQuery: controller.searchQuery, - isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id, - isSearchEmailRunning: true, - padding: SearchEmailUtils.getPaddingSearchResultList(context, controller.responsiveUtils), - mailboxContain: currentPresentationEmail.mailboxContain, - emailActionClick: (action, email) { - controller.pressEmailAction( + controller: controller.resultSearchScrollController, + physics: const AlwaysScrollableScrollPhysics(), + key: const PageStorageKey('list_presentation_email_in_search_view'), + itemCount: listPresentationEmail.length, + itemBuilder: (context, index) { + final currentPresentationEmail = listPresentationEmail[index]; + return Obx(() => EmailTileBuilder( + presentationEmail: currentPresentationEmail, + selectAllMode: controller.selectionMode.value, + searchQuery: controller.searchQuery, + isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id, + isSearchEmailRunning: true, + padding: SearchEmailViewStyle.getPaddingSearchResultList( context, - action, - email, - mailboxContain: currentPresentationEmail.mailboxContain - ); - }, - onMoreActionClick: (email, position) { - if (controller.responsiveUtils.isScreenWithShortestSide(context)) { - controller.openContextMenuAction( + controller.responsiveUtils + ), + mailboxContain: currentPresentationEmail.mailboxContain, + emailActionClick: (action, email) { + controller.pressEmailAction( context, - _contextMenuActionTile(context, email) + action, + email, + mailboxContain: currentPresentationEmail.mailboxContain ); - } else { - controller.openPopupMenuAction( - context, - position, - _popupMenuActionTile(context, email) - ); - } - }, + }, + onMoreActionClick: (email, position) { + if (controller.responsiveUtils.isScreenWithShortestSide(context)) { + controller.openContextMenuAction( + context, + _contextMenuActionTile(context, email) + ); + } else { + controller.openPopupMenuAction( + context, + position, + _popupMenuActionTile(context, email) + ); + } + }, - )); - }, - separatorBuilder: (context, index) { - return Padding( - padding: ItemEmailTileStyles.getPaddingDividerWeb(context, controller.responsiveUtils), - child: Divider( - color: index < listPresentationEmail.length - 1 && - controller.selectionMode.value == SelectMode.INACTIVE - ? null - : Colors.white - ) - ); - }, - ) + )); + }, + separatorBuilder: (context, index) { + return Padding( + padding: ItemEmailTileStyles.getPaddingDividerWeb(context, controller.responsiveUtils), + child: Divider( + color: index < listPresentationEmail.length - 1 && + controller.selectionMode.value == SelectMode.INACTIVE + ? null + : Colors.white + ) + ); + }, + ) ); } @@ -681,113 +767,4 @@ class SearchEmailView extends GetWidget : const SizedBox.shrink(); })); } - - Widget _buildSearchFilterByMailboxButton(BuildContext context) { - return Obx(() { - final filterSelected = controller.searchEmailFilter.value.searchFilterByMailboxApplied; - return Padding( - padding: const EdgeInsets.only(right: 8), - child: InkWell( - onTap: () => controller.selectMailboxForSearchFilter( - context, - controller.mailboxFiltered), - borderRadius: const BorderRadius.all(Radius.circular(10)), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: filterSelected - ? AppColor.colorItemEmailSelectedDesktop - : AppColor.colorButtonHeaderThread), - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - SvgPicture.asset( - filterSelected ? controller.imagePaths.icSelectedSB : controller.imagePaths.icFolderMailbox, - width: 16, - height: 16, - fit: BoxFit.fill), - const SizedBox(width: 4), - Text( - filterSelected - ? controller.searchEmailFilter.value.getMailboxName(context) - : AppLocalizations.of(context).folder, - maxLines: 1, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - style: filterSelected - ? const TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - color: AppColor.colorTextButton) - : const TextStyle( - fontSize: 13, - fontWeight: FontWeight.normal, - color: AppColor.colorTextButtonHeaderThread) - ), - const SizedBox(width: 4), - SvgPicture.asset( - controller.imagePaths.icChevronDownOutline, - colorFilter: filterSelected - ? AppColor.primaryColor.asFilter() - : AppColor.colorDefaultRichTextButton.asFilter(), - fit: BoxFit.fill), - ]) - ), - ), - ); - }); - } - - Widget _buildSearchFilterByContactButton(BuildContext context, PrefixEmailAddress prefixEmailAddress) { - return Obx(() { - final filterSelected = controller.searchEmailFilter.value - .searchFilterByContactApplied(prefixEmailAddress); - return Padding( - padding: const EdgeInsets.only(right: 8), - child: InkWell( - onTap: () => controller.selectContactForSearchFilter(context, prefixEmailAddress), - borderRadius: const BorderRadius.all(Radius.circular(10)), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: filterSelected - ? AppColor.colorItemEmailSelectedDesktop - : AppColor.colorButtonHeaderThread), - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - SvgPicture.asset( - filterSelected ? controller.imagePaths.icSelectedSB : controller.imagePaths.icUserSB, - width: 16, - height: 16, - fit: BoxFit.fill), - const SizedBox(width: 4), - Text( - filterSelected - ? controller.searchEmailFilter.value.getNameContactApplied(context, prefixEmailAddress) - : controller.searchEmailFilter.value.getNameContactDefault(context, prefixEmailAddress), - maxLines: 1, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - style: filterSelected - ? const TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - color: AppColor.colorTextButton) - : const TextStyle( - fontSize: 13, - fontWeight: FontWeight.normal, - color: AppColor.colorTextButtonHeaderThread) - ), - const SizedBox(width: 4), - SvgPicture.asset( - controller.imagePaths.icChevronDownOutline, - colorFilter: filterSelected - ? AppColor.primaryColor.asFilter() - : AppColor.colorDefaultRichTextButton.asFilter(), - fit: BoxFit.fill), - ]) - ), - ), - ); - }); - } } \ No newline at end of file diff --git a/lib/features/search/email/presentation/styles/search_email_view_style.dart b/lib/features/search/email/presentation/styles/search_email_view_style.dart new file mode 100644 index 000000000..6f2869198 --- /dev/null +++ b/lib/features/search/email/presentation/styles/search_email_view_style.dart @@ -0,0 +1,99 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:core/utils/platform_info.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class SearchEmailViewStyle { + static const SizedBox searchFilterSizeBoxMargin = SizedBox(width: 8); + + static const TextStyle searchRecentTitleStyle = TextStyle( + fontSize: 13.0, + color: AppColor.colorTextButtonHeaderThread, + fontWeight: FontWeight.w500 + ); + + static const EdgeInsetsGeometry listSearchFilterButtonMargin = EdgeInsetsDirectional.only(top: 16); + + static EdgeInsetsGeometry? getAppBarPadding(BuildContext context, ResponsiveUtils responsiveUtils) { + if ((PlatformInfo.isWeb && responsiveUtils.isMobile(context)) || + (PlatformInfo.isMobile && responsiveUtils.isPortraitMobile(context))) { + return const EdgeInsets.symmetric(horizontal: 8); + } else { + return const EdgeInsets.symmetric(horizontal: 24); + } + } + + static EdgeInsetsGeometry getListSearchFilterButtonPadding( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if ((PlatformInfo.isWeb && responsiveUtils.isMobile(context)) || + (PlatformInfo.isMobile && responsiveUtils.isPortraitMobile(context))) { + return const EdgeInsetsDirectional.only(bottom: 10, start: 16, end: 16); + } else { + return const EdgeInsetsDirectional.only(bottom: 10, start: 32, end: 32); + } + } + + static EdgeInsetsGeometry getSearchRecentTitleMargin( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if ((PlatformInfo.isWeb && responsiveUtils.isMobile(context)) || + (PlatformInfo.isMobile && responsiveUtils.isPortraitMobile(context))) { + return const EdgeInsetsDirectional.symmetric(horizontal: 16, vertical: 8); + } else { + return const EdgeInsetsDirectional.symmetric(horizontal: 32, vertical: 8); + } + } + + static EdgeInsetsGeometry getPaddingSearchResultList( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if ((PlatformInfo.isWeb && responsiveUtils.isMobile(context)) || + (PlatformInfo.isMobile && responsiveUtils.isPortraitMobile(context))) { + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 12); + } else { + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 24); + } + } + + static EdgeInsetsGeometry getListRecentSearchPadding( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if ((PlatformInfo.isWeb && responsiveUtils.isMobile(context)) || + (PlatformInfo.isMobile && responsiveUtils.isPortraitMobile(context))) { + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 16); + } else { + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 32); + } + } + + static EdgeInsetsGeometry getShowAllResultButtonPadding( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if ((PlatformInfo.isWeb && responsiveUtils.isMobile(context)) || + (PlatformInfo.isMobile && responsiveUtils.isPortraitMobile(context))) { + return const EdgeInsetsDirectional.symmetric(horizontal: 16, vertical: 8); + } else { + return const EdgeInsetsDirectional.symmetric(horizontal: 32, vertical: 8); + } + } + + static EdgeInsetsGeometry getSearchSuggestionListPadding( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if ((PlatformInfo.isWeb && responsiveUtils.isMobile(context)) || + (PlatformInfo.isMobile && responsiveUtils.isPortraitMobile(context))) { + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 16); + } else { + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 32); + } + } +} \ No newline at end of file diff --git a/lib/features/search/email/presentation/utils/search_email_utils.dart b/lib/features/search/email/presentation/utils/search_email_utils.dart index e9ad3204b..6d92de6a4 100644 --- a/lib/features/search/email/presentation/utils/search_email_utils.dart +++ b/lib/features/search/email/presentation/utils/search_email_utils.dart @@ -1,69 +1,8 @@ import 'package:core/presentation/utils/responsive_utils.dart'; -import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; class SearchEmailUtils { - static EdgeInsets getPaddingAppBar(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb) { - if (responsiveUtils.isMobile(context)) { - return const EdgeInsets.symmetric(horizontal: 16); - } else { - return const EdgeInsets.symmetric(horizontal: 32); - } - } else { - if (responsiveUtils.isPortraitMobile(context)) { - return const EdgeInsets.symmetric(horizontal: 8); - } else { - return const EdgeInsets.symmetric(horizontal: 32); - } - } - } - - static EdgeInsets getPaddingSearchSuggestionList(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb || !responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.symmetric(horizontal: 32, vertical: 12); - } else { - return const EdgeInsets.symmetric(horizontal: 16, vertical: 12); - } - } - - static EdgeInsets getPaddingShowAllResultButton(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb || !responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.symmetric(horizontal: 32, vertical: 12); - } else { - return const EdgeInsets.symmetric(horizontal: 16, vertical: 12); - } - } - - static EdgeInsets getPaddingSearchRecentTitle(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb || !responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.symmetric(horizontal: 32, vertical: 8); - } else { - return const EdgeInsets.symmetric(horizontal: 16, vertical: 8); - } - } - - static EdgeInsets getPaddingListRecentSearch(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb || !responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.symmetric(horizontal: 32, vertical: 12); - } else { - return const EdgeInsets.symmetric(horizontal: 16, vertical: 12); - } - } - - static EdgeInsets getPaddingSearchFilterButton(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb) { - return const EdgeInsets.symmetric(vertical: 12, horizontal: 16); - } else { - if (responsiveUtils.isPortraitMobile(context)) { - return const EdgeInsets.symmetric(vertical: 12, horizontal: 16); - } else { - return const EdgeInsets.symmetric(vertical: 12, horizontal: 32); - } - } - } - static EdgeInsets getPaddingItemListMobile(BuildContext context, ResponsiveUtils responsiveUtils) { if (responsiveUtils.isPortraitMobile(context)) { return const EdgeInsets.symmetric(horizontal: 16); @@ -71,28 +10,4 @@ class SearchEmailUtils { return const EdgeInsets.symmetric(horizontal: 32); } } - - static EdgeInsets getMarginSearchFilterButton(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb) { - return const EdgeInsets.symmetric(horizontal: 20); - } else { - return EdgeInsets.zero; - } - } - - static EdgeInsetsGeometry getPaddingSearchResultList(BuildContext context, ResponsiveUtils responsiveUtils) { - return const EdgeInsetsDirectional.only(top: 8, bottom: 8, end: 8); - } - - static EdgeInsets getPaddingDividerSearchResultList(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb) { - return const EdgeInsets.symmetric(horizontal: 16); - } else { - if (responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.symmetric(horizontal: 16); - } else { - return const EdgeInsets.symmetric(horizontal: 32); - } - } - } } \ No newline at end of file diff --git a/lib/features/search/email/presentation/widgets/email_receive_time_cupertino_action_sheet_action_builder.dart b/lib/features/search/email/presentation/widgets/email_receive_time_cupertino_action_sheet_action_builder.dart index f9851dfc0..b6fbbfaa0 100644 --- a/lib/features/search/email/presentation/widgets/email_receive_time_cupertino_action_sheet_action_builder.dart +++ b/lib/features/search/email/presentation/widgets/email_receive_time_cupertino_action_sheet_action_builder.dart @@ -13,8 +13,8 @@ class EmailReceiveTimeCupertinoActionSheetActionBuilder final EmailReceiveTimeType? timeTypeCurrent; final SvgPicture? actionSelected; final Color? bgColor; - final EdgeInsets? iconLeftPadding; - final EdgeInsets? iconRightPadding; + final EdgeInsetsGeometry? iconLeftPadding; + final EdgeInsetsGeometry? iconRightPadding; EmailReceiveTimeCupertinoActionSheetActionBuilder( String actionName,