diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index cfc862c73..507ac40c6 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -251,19 +251,18 @@ class EmailView extends GetWidget { ); } - EdgeInsetsGeometry _getMarginEmailView(BuildContext context) { + EdgeInsetsGeometry? _getMarginEmailView(BuildContext context) { if (PlatformInfo.isWeb) { if (controller.responsiveUtils.isDesktop(context)) { return const EdgeInsetsDirectional.only( end: 16, - top: 8, bottom: 16 ); } else { return const EdgeInsets.symmetric(vertical: 16); } } else { - return EdgeInsets.zero; + return null; } } 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 25c9e8bc9..b1a389a2e 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart @@ -118,7 +118,7 @@ class AdvancedFilterController extends BaseController { searchController.updateFilterEmail(sortOrderOption: searchController.sortOrderFiltered.value.getSortOrder()); searchController.updateFilterEmail( - mailbox: _destinationMailboxSelected, + mailboxOption: optionOf(_destinationMailboxSelected), subjectOption: optionOf(subjectFilterInputController.text), emailReceiveTimeType: dateFilterSelectedFormAdvancedSearch.value, hasAttachment: hasAttachment.value, @@ -397,8 +397,17 @@ class AdvancedFilterController extends BaseController { ); } else if (action is ClearDateRangeToAdvancedSearch) { _updateDateRangeTime(action.receiveTime); - } else if (action is StartSearchEmailAction && action.filter == QuickSearchFilter.from) { - _updateFromField(); + } else if (action is StartSearchEmailAction) { + switch(action.filter) { + case QuickSearchFilter.from: + _updateFromField(); + break; + case QuickSearchFilter.to: + _updateToField(); + break; + default: + break; + } } else if (action is SearchEmailByFromFieldsAction) { searchController.clearSearchFilter(); _resetAllToOriginalValue(); @@ -437,8 +446,13 @@ class AdvancedFilterController extends BaseController { } void _updateFromField() { - final listEmailAddress = searchEmailFilter.from.map((address) => EmailAddress(null, address)).toList(); - listFromEmailAddress = List.from(listEmailAddress); + listFromEmailAddress = List.from( + searchEmailFilter.from.map((address) => EmailAddress(null, address))); + } + + void _updateToField() { + listToEmailAddress= List.from( + searchEmailFilter.to.map((address) => EmailAddress(null, address))); } void onSearchAction(BuildContext context) { 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 a7d1679df..708f56902 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -240,6 +240,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo PresentationMailbox? outboxMailbox; ComposerArguments? composerArguments; List? _identities; + ScrollController? listSearchFilterScrollController; late StreamSubscription _emailAddressStreamSubscription; late StreamSubscription _emailContentStreamSubscription; @@ -297,6 +298,9 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo @override void onReady() { + if (PlatformInfo.isWeb) { + listSearchFilterScrollController = ScrollController(); + } _registerPendingEmailAddress(); _registerPendingEmailContents(); _registerPendingFileInfo(); @@ -1679,6 +1683,60 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo } } + Future selectToSearchFilter() async { + if (accountId.value == null || sessionCurrent == null) return; + + final contactArgument = ContactArguments( + accountId.value!, + sessionCurrent!, + searchController.searchEmailFilter.value.to); + + final newContact = await DialogRouter.pushGeneralDialog( + routeName: AppRoutes.contact, + arguments: contactArgument); + + if (newContact is EmailAddress) { + searchController.updateFilterEmail(toOption: Some({newContact.emailAddress})); + dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.to)); + } + } + + Future selectFolderSearchFilter() async { + if (accountId.value == null || sessionCurrent == null) return; + + final mailboxIdSelected = searchController.mailboxFiltered?.id; + + final destinationArgument = DestinationPickerArguments( + accountId.value!, + MailboxActions.select, + sessionCurrent!, + mailboxIdSelected: mailboxIdSelected); + + final destinationMailbox = PlatformInfo.isWeb + ? await DialogRouter.pushGeneralDialog( + routeName: AppRoutes.destinationPicker, + arguments: destinationArgument) + : await push( + AppRoutes.destinationPicker, + arguments: destinationArgument); + + if (destinationMailbox is! PresentationMailbox) return; + + if (destinationMailbox != PresentationMailbox.unifiedMailbox && + mailboxIdSelected != destinationMailbox.id) { + + searchController.updateFilterEmail( + mailboxOption: Some(destinationMailbox), + beforeOption: const None(), + positionOption: searchController.sortOrderFiltered.value.isScrollByPosition() + ? const Some(0) + : const None() + ); + + dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.folder)); + } + } + void selectReceiveTimeQuickSearchFilter(BuildContext context, EmailReceiveTimeType receiveTime) { log('MailboxDashBoardController::selectReceiveTimeQuickSearchFilter():receiveTime: $receiveTime'); popBack(); @@ -2694,6 +2752,9 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo @override void onClose() { + if (PlatformInfo.isWeb) { + listSearchFilterScrollController?.dispose(); + } _emailReceiveManager.closeEmailReceiveManagerStream(); if (PlatformInfo.isIOS) { _iosNotificationManager?.dispose(); diff --git a/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart index 8ee5a0aff..3141caaed 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/search_controller.dart @@ -158,7 +158,7 @@ class SearchController extends BaseController with DateRangePickerMixin { SearchQuery? text, Option? subjectOption, Set? notKeyword, - PresentationMailbox? mailbox, + Option? mailboxOption, EmailReceiveTimeType? emailReceiveTimeType, bool? hasAttachment, Option? beforeOption, @@ -173,7 +173,7 @@ class SearchController extends BaseController with DateRangePickerMixin { text: text, subjectOption: subjectOption, notKeyword: notKeyword, - mailbox: mailbox, + mailboxOption: mailboxOption, emailReceiveTimeType: emailReceiveTimeType, hasAttachment: hasAttachment, beforeOption: beforeOption, @@ -191,6 +191,8 @@ class SearchController extends BaseController with DateRangePickerMixin { DateTime? get endDateFiltered => searchEmailFilter.value.endDate?.value.toLocal(); + PresentationMailbox? get mailboxFiltered => searchEmailFilter.value.mailbox; + bool isSearchActive() => searchState.value.searchStatus == SearchStatus.ACTIVE; 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 a9858dbf1..7d917d57a 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -1,4 +1,5 @@ import 'package:core/core.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -6,10 +7,10 @@ import 'package:get/get.dart'; import 'package:model/extensions/presentation_mailbox_extension.dart'; import 'package:model/extensions/username_extension.dart'; import 'package:tmail_ui_user/features/base/widget/popup_item_no_icon_widget.dart'; +import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart'; import 'package:tmail_ui_user/features/email/presentation/email_view.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; -import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view_web.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/base_mailbox_dashboard_view.dart'; @@ -19,19 +20,19 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/sear 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/widgets/download/download_task_item_widget.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.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'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/styles/vacation_notification_message_widget_style.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; import 'package:tmail_ui_user/features/quotas/presentation/widget/quotas_banner_widget.dart'; import 'package:tmail_ui_user/features/search/email/presentation/search_email_view.dart'; import 'package:tmail_ui_user/features/search/mailbox/presentation/search_mailbox_view.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; -import 'package:tmail_ui_user/features/thread/presentation/styles/banner_delete_all_spam_emails_styles.dart'; -import 'package:tmail_ui_user/features/thread/presentation/styles/banner_empty_trash_styles.dart'; import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/banner_delete_all_spam_emails_widget.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/banner_empty_trash_widget.dart'; @@ -88,22 +89,23 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { )) ]), Expanded(child: Column(children: [ + const SizedBox(height: 16), + Obx(() => RecoverDeletedMessageLoadingBannerWidget( + isLoading: controller.isRecoveringDeletedMessage.value, + horizontalLoadingWidget: horizontalLoadingWidget, + responsiveUtils: controller.responsiveUtils, + )), + Obx(() => MarkMailboxAsReadLoadingBanner( + viewState: controller.viewStateMarkAsReadMailbox.value, + )), const SpamReportBannerWebWidget(), - QuotasBannerWidget( - margin: const EdgeInsetsDirectional.only(end: 16, top: 8), - ), + QuotasBannerWidget(), _buildVacationNotificationMessage(context), Obx(() { final presentationMailbox = controller.selectedMailbox.value; if (controller.isEmptyTrashBannerEnabledOnWeb(context, presentationMailbox)) { - return Padding( - padding: const EdgeInsetsDirectional.only( - top: BannerEmptyTrashStyles.webTopMargin, - end: BannerEmptyTrashStyles.webEndMargin - ), - child: BannerEmptyTrashWidget( - onTapAction: () => controller.emptyTrashAction(context) - ), + return BannerEmptyTrashWidget( + onTapAction: () => controller.emptyTrashAction(context) ); } else { return const SizedBox.shrink(); @@ -112,26 +114,14 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { Obx(() { final presentationMailbox = controller.selectedMailbox.value; if (controller.isEmptySpamBannerEnabledOnWeb(context, presentationMailbox)) { - return Padding( - padding: const EdgeInsetsDirectional.only( - top: BannerDeleteAllSpamEmailsStyles.webTopMargin, - end: BannerDeleteAllSpamEmailsStyles.webEndMargin - ), - child: BannerDeleteAllSpamEmailsWidget( - onTapAction: () => controller.openDialogEmptySpamFolder(context) - ), + return BannerDeleteAllSpamEmailsWidget( + onTapAction: () => controller.openDialogEmptySpamFolder(context) ); } else { return const SizedBox.shrink(); } }), - Obx(() => RecoverDeletedMessageLoadingBannerWidget( - isLoading: controller.isRecoveringDeletedMessage.value, - horizontalLoadingWidget: horizontalLoadingWidget, - responsiveUtils: controller.responsiveUtils, - )), _buildListButtonQuickSearchFilter(context), - _buildMarkAsMailboxReadLoading(context), Expanded(child: Obx(() { switch(controller.dashboardRoute.value) { case DashboardRoutes.thread: @@ -223,7 +213,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { Widget _buildThreadViewForWebDesktop(BuildContext context) { return Container( - margin: const EdgeInsetsDirectional.only(end: 16, top: 8, bottom: 16), + margin: const EdgeInsetsDirectional.only(end: 16, bottom: 16), decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(20)), border: Border.all(color: AppColor.colorBorderBodyThread, width: 1), @@ -380,37 +370,18 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { } else { return const SizedBox.shrink(); } + }), + const Spacer(), + Obx(() { + if (controller.searchController.isSearchEmailRunning && + controller.dashboardRoute.value == DashboardRoutes.thread) { + return _buildQuickSearchFilterButton(context, QuickSearchFilter.sortBy); + } else { + return const SizedBox.shrink(); + } }) - ]); - } - Widget _buildMarkAsMailboxReadLoading(BuildContext context) { - return Obx(() { - final viewState = controller.viewStateMarkAsReadMailbox.value; - return viewState.fold( - (failure) => const SizedBox.shrink(), - (success) { - if (success is MarkAsMailboxReadLoading) { - return Padding( - padding: EdgeInsets.only( - top: controller.responsiveUtils.isDesktop(context) ? 16 : 0, - left: 16, - right: 16, - bottom: controller.responsiveUtils.isDesktop(context) ? 0 : 16), - child: horizontalLoadingWidget); - } else if (success is UpdatingMarkAsMailboxReadState) { - final percent = success.countRead / success.totalUnread; - return Padding( - padding: EdgeInsets.only( - top: controller.responsiveUtils.isDesktop(context) ? 16 : 0, - left: 16, - right: 16, - bottom: controller.responsiveUtils.isDesktop(context) ? 0 : 16), - child: horizontalPercentLoadingWidget(percent)); - } - return const SizedBox.shrink(); - }); - }); + ]); } Widget _buildDownloadTaskStateWidget() { @@ -450,7 +421,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { return Obx(() { if (controller.vacationResponse.value?.vacationResponderIsValid == true) { return VacationNotificationMessageWidget( - margin: const EdgeInsetsDirectional.only(top: 8, end: 16), + margin: VacationNotificationMessageWidgetStyle.bannerMargin, vacationResponse: controller.vacationResponse.value!, actionGotoVacationSetting: controller.goToVacationSetting, actionEndNow: controller.disableVacationResponder); @@ -465,17 +436,44 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { if (controller.searchController.isSearchEmailRunning && controller.dashboardRoute.value == DashboardRoutes.thread) { return Padding( - padding: const EdgeInsetsDirectional.only(end: 16, top: 8), + padding: const EdgeInsetsDirectional.only(end: 16), child: Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - _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), + Expanded( + child: SizedBox( + height: 45, + 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, + padding: const EdgeInsetsDirectional.only(bottom: 10), + controller: controller.listSearchFilterScrollController!, + children: [ + _buildQuickSearchFilterButton(context, QuickSearchFilter.folder), + const SizedBox(width: 8), + _buildQuickSearchFilterButton(context, QuickSearchFilter.from), + const SizedBox(width: 8), + _buildQuickSearchFilterButton(context, QuickSearchFilter.to), + const SizedBox(width: 8), + _buildQuickSearchFilterButton(context, QuickSearchFilter.dateTime), + const SizedBox(width: 8), + _buildQuickSearchFilterButton(context, QuickSearchFilter.hasAttachment), + const SizedBox(width: 8), + ], + ), + ), + ) + ), ] ), ); @@ -497,6 +495,8 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { final startDate = controller.searchController.startDateFiltered; final endDate = controller.searchController.endDateFiltered; final receiveTimeType = controller.searchController.receiveTimeFiltered; + final mailbox = controller.searchController.mailboxFiltered; + final listAddressOfTo = controller.searchController.searchEmailFilter.value.to; final isSelected = searchFilter.isSelected( context, @@ -504,6 +504,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { sortOrderType); return SearchFilterButton( + key: Key('${searchFilter.name}_search_filter_button'), searchFilter: searchFilter, imagePaths: controller.imagePaths, isSelected: isSelected, @@ -512,7 +513,9 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { endDate: endDate, sortOrderType: sortOrderType, listAddressOfFrom: listAddressOfFrom, + listAddressOfTo: listAddressOfTo, userName: userName, + mailbox: mailbox, onSelectSearchFilterAction: _onSelectSearchFilterAction, ); }); @@ -540,6 +543,12 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { case QuickSearchFilter.hasAttachment: controller.selectHasAttachmentSearchFilter(); break; + case QuickSearchFilter.to: + controller.selectToSearchFilter(); + break; + case QuickSearchFilter.folder: + controller.selectFolderSearchFilter(); + break; default: break; } 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 6f7e04c8c..8b5110cd4 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 @@ -3,6 +3,8 @@ 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:model/mailbox/presentation_mailbox.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.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'; @@ -14,26 +16,9 @@ enum QuickSearchFilter { fromMe, sortBy, dateTime, - from; - - String getName(BuildContext context) { - switch(this) { - case QuickSearchFilter.hasAttachment: - return AppLocalizations.of(context).hasAttachment; - case QuickSearchFilter.last7Days: - return AppLocalizations.of(context).last7Days; - case QuickSearchFilter.fromMe: - 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 ''; - } - } + from, + to, + folder; String getTitle( BuildContext context, { @@ -42,7 +27,9 @@ enum QuickSearchFilter { DateTime? startDate, DateTime? endDate, Set? listAddressOfFrom, - UserName? userName + UserName? userName, + Set? listAddressOfTo, + PresentationMailbox? mailbox }) { switch(this) { case QuickSearchFilter.hasAttachment: @@ -61,17 +48,11 @@ enum QuickSearchFilter { 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 ''; + return AppLocalizations.of(context).from_email_address_prefix; + case QuickSearchFilter.folder: + return mailbox?.getDisplayName(context) ?? AppLocalizations.of(context).all; + case QuickSearchFilter.to: + return AppLocalizations.of(context).to_email_address_prefix; } } @@ -89,6 +70,10 @@ enum QuickSearchFilter { return imagePaths.icCalendarSB; case QuickSearchFilter.from: return imagePaths.icUserSB; + case QuickSearchFilter.to: + return imagePaths.icUserSB; + case QuickSearchFilter.folder: + return imagePaths.icFolderMailbox; } } @@ -136,6 +121,10 @@ enum QuickSearchFilter { return searchFilter.emailReceiveTimeType != EmailReceiveTimeType.allTime; case QuickSearchFilter.from: return searchFilter.from.isNotEmpty; + case QuickSearchFilter.to: + return searchFilter.to.isNotEmpty; + case QuickSearchFilter.folder: + return searchFilter.mailbox != null; } } @@ -145,5 +134,7 @@ enum QuickSearchFilter { bool isArrowDownIconSupported() => this == QuickSearchFilter.dateTime || this == QuickSearchFilter.from || + this == QuickSearchFilter.to || + this == QuickSearchFilter.folder || this == QuickSearchFilter.sortBy; } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart b/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart index 2daa71341..d40eebbe5 100644 --- a/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart +++ b/lib/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart @@ -60,7 +60,7 @@ class SearchEmailFilter with EquatableMixin, OptionParamMixin { SearchQuery? text, Option? subjectOption, Set? notKeyword, - PresentationMailbox? mailbox, + Option? mailboxOption, EmailReceiveTimeType? emailReceiveTimeType, bool? hasAttachment, Option? beforeOption, @@ -75,7 +75,7 @@ class SearchEmailFilter with EquatableMixin, OptionParamMixin { text: text ?? this.text, subject: getOptionParam(subjectOption, subject), notKeyword: notKeyword ?? this.notKeyword, - mailbox: mailbox ?? this.mailbox, + mailbox: getOptionParam(mailboxOption, mailbox), emailReceiveTimeType: emailReceiveTimeType ?? this.emailReceiveTimeType, hasAttachment: hasAttachment ?? this.hasAttachment, before: getOptionParam(beforeOption, before), diff --git a/lib/features/mailbox_dashboard/presentation/styles/mark_mailbox_as_read_loading_banner_style.dart b/lib/features/mailbox_dashboard/presentation/styles/mark_mailbox_as_read_loading_banner_style.dart new file mode 100644 index 000000000..50f62da7c --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/styles/mark_mailbox_as_read_loading_banner_style.dart @@ -0,0 +1,5 @@ +import 'package:flutter/material.dart'; + +class MarkMailboxAsReadLoadingBannerStyle { + static const EdgeInsetsGeometry bannerMargin = EdgeInsetsDirectional.only(end: 16, bottom: 8); +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/styles/recover_deleted_message_loading_banner_style.dart b/lib/features/mailbox_dashboard/presentation/styles/recover_deleted_message_loading_banner_style.dart new file mode 100644 index 000000000..b9df9edd9 --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/styles/recover_deleted_message_loading_banner_style.dart @@ -0,0 +1,26 @@ +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:core/utils/platform_info.dart'; +import 'package:flutter/material.dart'; + +class RecoverDeletedMessageLoadingBannerStyle { + static EdgeInsetsGeometry getBannerMargin( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if (PlatformInfo.isWeb) { + if (responsiveUtils.isDesktop(context)) { + return const EdgeInsetsDirectional.only(end: 16, bottom: 8); + } else if (responsiveUtils.isTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 24, end: 24); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 12, end: 12); + } + } else { + if (responsiveUtils.isPortraitTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 32, end: 32); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 16, end: 16); + } + } + } +} \ 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 index 472873bfe..97abbe6aa 100644 --- a/lib/features/mailbox_dashboard/presentation/styles/search_filter_button_style.dart +++ b/lib/features/mailbox_dashboard/presentation/styles/search_filter_button_style.dart @@ -5,6 +5,7 @@ class SearchFilterButtonStyle { static const double iconSize = 16; static const double deleteIconSize = 10; static const double spaceSize = 4; + static const double buttonSize = 35; static const EdgeInsetsGeometry buttonPadding = EdgeInsets.symmetric(horizontal: 12, vertical: 8); static const EdgeInsetsGeometry elementPadding = EdgeInsetsDirectional.only(start: 8); diff --git a/lib/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart b/lib/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart new file mode 100644 index 000000000..52f65afc5 --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart @@ -0,0 +1,37 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/mark_mailbox_as_read_loading_banner_style.dart'; + +class MarkMailboxAsReadLoadingBanner extends StatelessWidget with AppLoaderMixin { + final Either viewState; + + const MarkMailboxAsReadLoadingBanner({ + super.key, + required this.viewState, + }); + + @override + Widget build(BuildContext context) { + return viewState.fold( + (failure) => const SizedBox.shrink(), + (success) { + if (success is MarkAsMailboxReadLoading) { + return Padding( + padding: MarkMailboxAsReadLoadingBannerStyle.bannerMargin, + child: horizontalLoadingWidget); + } else if (success is UpdatingMarkAsMailboxReadState) { + final percent = success.countRead / success.totalUnread; + return Padding( + padding: MarkMailboxAsReadLoadingBannerStyle.bannerMargin, + child: horizontalPercentLoadingWidget(percent)); + } else { + return const SizedBox.shrink(); + } + } + ); + } +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/widgets/recover_deleted_message_loading_banner_widget.dart b/lib/features/mailbox_dashboard/presentation/widgets/recover_deleted_message_loading_banner_widget.dart index cebbe7782..789c648b0 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/recover_deleted_message_loading_banner_widget.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/recover_deleted_message_loading_banner_widget.dart @@ -1,6 +1,7 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/recover_deleted_message_loading_banner_style.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class RecoverDeletedMessageLoadingBannerWidget extends StatelessWidget { @@ -18,42 +19,38 @@ class RecoverDeletedMessageLoadingBannerWidget extends StatelessWidget { @override Widget build(BuildContext context) { if (isLoading) { - return Padding( - padding: EdgeInsetsDirectional.only( - top: responsiveUtils.isDesktop(context) ? 16 : 0, - end: 16, - bottom: responsiveUtils.isDesktop(context) ? 0 : 16, + return Container( + margin: RecoverDeletedMessageLoadingBannerStyle.getBannerMargin( + context, + responsiveUtils), + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 12, ), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 12, - ), - decoration: const ShapeDecoration( - color: Colors.white, - shape: RoundedRectangleBorder( - side: BorderSide( - width: 1, - color: AppColor.colorBorderBodyThread, + decoration: const ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + side: BorderSide( + width: 1, + color: AppColor.colorBorderBodyThread, + ), + borderRadius: BorderRadius.all(Radius.circular(14)), + ) + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context).bannerProgressingRecoveryMessage, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w400, + color: AppColor.primaryColor, ), - borderRadius: BorderRadius.all(Radius.circular(14)), - ) - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context).bannerProgressingRecoveryMessage, - style: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.w400, - color: AppColor.primaryColor, - ), - ), - const SizedBox(height: 12), - horizontalLoadingWidget - ], - ), + ), + const SizedBox(height: 12), + horizontalLoadingWidget + ], ), ); } else { 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 b3613d3ef..58127e75e 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 @@ -5,6 +5,7 @@ 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:model/mailbox/presentation_mailbox.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'; @@ -17,6 +18,8 @@ typedef OnSelectSearchFilterAction = Function( class SearchFilterButton extends StatelessWidget { + static const int _titleCharactersMaximum = 20; + final QuickSearchFilter searchFilter; final bool isSelected; final ImagePaths imagePaths; @@ -25,7 +28,9 @@ class SearchFilterButton extends StatelessWidget { final DateTime? startDate; final DateTime? endDate; final Set? listAddressOfFrom; + final Set? listAddressOfTo; final UserName? userName; + final PresentationMailbox? mailbox; final Color? backgroundColor; final OnSelectSearchFilterAction? onSelectSearchFilterAction; @@ -39,18 +44,33 @@ class SearchFilterButton extends StatelessWidget { this.startDate, this.endDate, this.listAddressOfFrom, + this.listAddressOfTo, this.userName, + this.mailbox, this.backgroundColor, this.onSelectSearchFilterAction, }); @override Widget build(BuildContext context) { + final filterTitle = searchFilter.getTitle( + context, + receiveTimeType: receiveTimeType, + startDate: startDate, + endDate: startDate, + sortOrderType: sortOrderType, + listAddressOfFrom: listAddressOfFrom, + userName: userName, + mailbox: mailbox, + listAddressOfTo: listAddressOfTo, + ); + final childItem = Container( decoration: BoxDecoration( borderRadius: SearchFilterButtonStyle.borderRadius, color: backgroundColor ?? searchFilter.getBackgroundColor(isFilterSelected: isSelected)), padding: SearchFilterButtonStyle.buttonPadding, + height: SearchFilterButtonStyle.buttonSize, child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -62,14 +82,9 @@ class SearchFilterButton extends StatelessWidget { fit: BoxFit.fill), const SizedBox(width: SearchFilterButtonStyle.spaceSize), Text( - searchFilter.getTitle( - context, - receiveTimeType: receiveTimeType, - startDate: startDate, - endDate: startDate, - sortOrderType: sortOrderType, - listAddressOfFrom: listAddressOfFrom, - userName: userName), + filterTitle.length > _titleCharactersMaximum + ? '${filterTitle.substring(0, _titleCharactersMaximum)}...' + : filterTitle, maxLines: 1, overflow: TextOverflow.ellipsis, style: SearchFilterButtonStyle.titleStyle, diff --git a/lib/features/manage_account/presentation/vacation/styles/vacation_notification_message_widget_style.dart b/lib/features/manage_account/presentation/vacation/styles/vacation_notification_message_widget_style.dart new file mode 100644 index 000000000..85369ac29 --- /dev/null +++ b/lib/features/manage_account/presentation/vacation/styles/vacation_notification_message_widget_style.dart @@ -0,0 +1,8 @@ + +import 'package:flutter/material.dart'; + +class VacationNotificationMessageWidgetStyle { + static const EdgeInsetsGeometry bannerMargin = EdgeInsetsDirectional.only( + end: 16, + bottom: 8); +} \ No newline at end of file diff --git a/lib/features/quotas/presentation/styles/quotas_banner_styles.dart b/lib/features/quotas/presentation/styles/quotas_banner_styles.dart index b5b0a0e14..cce3e7741 100644 --- a/lib/features/quotas/presentation/styles/quotas_banner_styles.dart +++ b/lib/features/quotas/presentation/styles/quotas_banner_styles.dart @@ -1,10 +1,10 @@ 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/material.dart'; class QuotasBannerStyles { - static const double verticalPadding = 8; - static const double horizontalPadding = 16; static const double iconPadding = 16; static const double iconSize = 32; static const double titleTextSize = 17; @@ -16,4 +16,29 @@ class QuotasBannerStyles { static const FontWeight titleFontWeight = FontWeight.w700; static const FontWeight messageFontWeight = FontWeight.w400; + + static const EdgeInsetsGeometry bannerPadding = EdgeInsetsDirectional.symmetric( + horizontal: 16, + vertical: 8, + ); + static EdgeInsetsGeometry getBannerMargin( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if (PlatformInfo.isWeb) { + if (responsiveUtils.isDesktop(context)) { + return const EdgeInsetsDirectional.only(end: 16, bottom: 8); + } else if (responsiveUtils.isTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 24, end: 24); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 12, end: 12); + } + } else { + if (responsiveUtils.isPortraitTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 32, end: 32); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 16, end: 16); + } + } + } } \ No newline at end of file diff --git a/lib/features/quotas/presentation/widget/quotas_banner_widget.dart b/lib/features/quotas/presentation/widget/quotas_banner_widget.dart index 13df0e7c7..423af7d58 100644 --- a/lib/features/quotas/presentation/widget/quotas_banner_widget.dart +++ b/lib/features/quotas/presentation/widget/quotas_banner_widget.dart @@ -8,28 +8,23 @@ import 'package:tmail_ui_user/features/quotas/presentation/styles/quotas_banner_ class QuotasBannerWidget extends StatelessWidget { final QuotasController _quotasController = Get.find(); - final EdgeInsetsGeometry? margin; - - QuotasBannerWidget({ - Key? key, - this.margin, - }) : super(key: key); + + QuotasBannerWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Obx(() { - if (_quotasController.octetsQuota.value != null && _quotasController.octetsQuota.value!.allowedDisplayToQuotaBanner) { - final octetQuota = _quotasController.octetsQuota.value!; + final octetQuota = _quotasController.octetsQuota.value; + if (octetQuota != null && octetQuota.allowedDisplayToQuotaBanner) { return Container( decoration: BoxDecoration( color: octetQuota.getQuotaBannerBackgroundColor(), borderRadius: const BorderRadius.all(Radius.circular(QuotasBannerStyles.borderRadius)), ), - margin: margin, - padding: const EdgeInsetsDirectional.symmetric( - horizontal: QuotasBannerStyles.horizontalPadding, - vertical: QuotasBannerStyles.verticalPadding, - ), + margin: QuotasBannerStyles.getBannerMargin( + context, + _quotasController.responsiveUtils), + padding: QuotasBannerStyles.bannerPadding, child: Row( children: [ SvgPicture.asset( diff --git a/lib/features/thread/presentation/styles/banner_delete_all_spam_emails_styles.dart b/lib/features/thread/presentation/styles/banner_delete_all_spam_emails_styles.dart index 6535b5e1c..f21f927b4 100644 --- a/lib/features/thread/presentation/styles/banner_delete_all_spam_emails_styles.dart +++ b/lib/features/thread/presentation/styles/banner_delete_all_spam_emails_styles.dart @@ -1,5 +1,7 @@ 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/material.dart'; class BannerDeleteAllSpamEmailsStyles { @@ -7,9 +9,6 @@ class BannerDeleteAllSpamEmailsStyles { static const double buttonBorderRadius = 20; static const double horizontalPadding = 16; static const double verticalPadding = 10; - static const double webEndMargin = 16; - static const double webTopMargin = 8; - static const double mobileMargin = 16; static const double labelTextSize = 13; static const double buttonTextSize = 17; static const double iconSize = 20; @@ -18,4 +17,25 @@ class BannerDeleteAllSpamEmailsStyles { static const Color borderStrokeColor = AppColor.colorBorderBodyThread; static const Color labelTextColor = AppColor.colorSubtitle; static const Color buttonTextColor = AppColor.toastErrorBackgroundColor; + + static EdgeInsetsGeometry getBannerMargin( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if (PlatformInfo.isWeb) { + if (responsiveUtils.isDesktop(context)) { + return const EdgeInsetsDirectional.only(end: 16, bottom: 8); + } else if (responsiveUtils.isTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 24, end: 24); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 12, end: 12); + } + } else { + if (responsiveUtils.isPortraitTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 32, end: 32); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 16, end: 16); + } + } + } } \ No newline at end of file diff --git a/lib/features/thread/presentation/styles/banner_empty_trash_styles.dart b/lib/features/thread/presentation/styles/banner_empty_trash_styles.dart index fd7704734..2a026de6c 100644 --- a/lib/features/thread/presentation/styles/banner_empty_trash_styles.dart +++ b/lib/features/thread/presentation/styles/banner_empty_trash_styles.dart @@ -1,5 +1,7 @@ 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/material.dart'; class BannerEmptyTrashStyles { @@ -7,9 +9,6 @@ class BannerEmptyTrashStyles { static const double buttonBorderRadius = 20; static const double horizontalPadding = 16; static const double verticalPadding = 10; - static const double webEndMargin = 16; - static const double webTopMargin = 8; - static const double mobileMargin = 16; static const double labelTextSize = 13; static const double buttonTextSize = 17; static const double iconSize = 20; @@ -18,4 +17,25 @@ class BannerEmptyTrashStyles { static const Color borderStrokeColor = AppColor.colorBorderBodyThread; static const Color labelTextColor = AppColor.colorSubtitle; static const Color buttonTextColor = AppColor.toastErrorBackgroundColor; + + static EdgeInsetsGeometry getBannerMargin( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if (PlatformInfo.isWeb) { + if (responsiveUtils.isDesktop(context)) { + return const EdgeInsetsDirectional.only(end: 16, bottom: 8); + } else if (responsiveUtils.isTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 24, end: 24); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 12, end: 12); + } + } else { + if (responsiveUtils.isPortraitTablet(context)) { + return const EdgeInsetsDirectional.only(bottom: 8, start: 32, end: 32); + } else { + return const EdgeInsetsDirectional.only(bottom: 8, start: 16, end: 16); + } + } + } } \ No newline at end of file diff --git a/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_web_styles.dart b/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_web_styles.dart index 99718b601..5b30d3063 100644 --- a/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_web_styles.dart +++ b/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_web_styles.dart @@ -3,11 +3,14 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:flutter/material.dart'; class SpamReportBannerWebStyles { - static const double horizontalMargin = 16; - static const double verticalMargin = 16; - static const double verticalPadding = 8; - static const double horizontalPadding = 16; static const double borderRadius = 12; static Color backgroundColor = AppColor.colorSpamReportBannerBackground.withOpacity(0.12); static const Color strokeBorderColor = AppColor.colorSpamReportBannerStrokeBorder; + + static const EdgeInsetsGeometry bannerPadding = EdgeInsetsDirectional.symmetric( + horizontal: 16, + vertical: 8); + static const EdgeInsetsGeometry bannerMargin = EdgeInsetsDirectional.only( + end: 16, + bottom: 8); } \ No newline at end of file diff --git a/lib/features/thread/presentation/styles/thread_view_style.dart b/lib/features/thread/presentation/styles/thread_view_style.dart new file mode 100644 index 000000000..e287919d3 --- /dev/null +++ b/lib/features/thread/presentation/styles/thread_view_style.dart @@ -0,0 +1,25 @@ + +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:core/utils/platform_info.dart'; +import 'package:flutter/material.dart'; + +class ThreadViewStyle { + static EdgeInsetsGeometry getBannerMargin( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if (PlatformInfo.isWeb) { + if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { + return const EdgeInsetsDirectional.only(start: 12, end: 12, bottom: 8); + } else { + return const EdgeInsetsDirectional.only(start: 24, end: 24, bottom: 8); + } + } else { + if (responsiveUtils.isPortraitMobile(context) || responsiveUtils.isLandscapeTablet(context)) { + return const EdgeInsetsDirectional.only(start: 16, end: 16, bottom: 8); + } else { + return const EdgeInsetsDirectional.only(start: 32, end: 32, bottom: 8); + } + } + } +} \ No newline at end of file diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index bc1b05bba..f3e544276 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -22,10 +22,9 @@ import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.d import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/loading_more_status.dart'; -import 'package:tmail_ui_user/features/thread/presentation/styles/banner_delete_all_spam_emails_styles.dart'; -import 'package:tmail_ui_user/features/thread/presentation/styles/banner_empty_trash_styles.dart'; import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_tile_styles.dart'; import 'package:tmail_ui_user/features/thread/presentation/styles/scroll_to_top_button_widget_styles.dart'; +import 'package:tmail_ui_user/features/thread/presentation/styles/thread_view_style.dart'; import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/app_bar/app_bar_thread_widget.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/banner_delete_all_spam_emails_widget.dart'; @@ -112,22 +111,26 @@ class ThreadView extends GetWidget SearchBarView( key: const Key('email_search_bar_view'), imagePaths: controller.imagePaths, - margin: _getBannerMargin(context, controller.responsiveUtils), + margin: ThreadViewStyle.getBannerMargin( + context, + controller.responsiveUtils), hintTextSearch: AppLocalizations.of(context).search_emails, onOpenSearchViewAction: controller.goToSearchView ), SpamReportBannerWidget( spamReportController: controller.mailboxDashBoardController.spamReportController, - margin: _getBannerMargin(context, controller.responsiveUtils), - ), - QuotasBannerWidget( - margin: _getBannerMargin(context, controller.responsiveUtils), + margin: ThreadViewStyle.getBannerMargin( + context, + controller.responsiveUtils), ), + QuotasBannerWidget(), Obx(() { final vacation = controller.mailboxDashBoardController.vacationResponse.value; if (vacation?.vacationResponderIsValid == true) { return VacationNotificationMessageWidget( - margin: _getBannerMargin(context, controller.responsiveUtils), + margin: ThreadViewStyle.getBannerMargin( + context, + controller.responsiveUtils), vacationResponse: vacation!, actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, actionEndNow: controller.mailboxDashBoardController.disableVacationResponder @@ -145,13 +148,10 @@ class ThreadView extends GetWidget Obx(() { final presentationMailbox = controller.mailboxDashBoardController.selectedMailbox.value; if (controller.mailboxDashBoardController.isEmptyTrashBannerEnabledOnMobile(context, presentationMailbox)) { - return Padding( - padding: const EdgeInsetsDirectional.symmetric( - horizontal: BannerEmptyTrashStyles.mobileMargin - ), - child: BannerEmptyTrashWidget( - onTapAction: () => controller.deleteSelectionEmailsPermanently(context, DeleteActionType.all) - ), + return BannerEmptyTrashWidget( + onTapAction: () => controller.deleteSelectionEmailsPermanently( + context, + DeleteActionType.all) ); } else { return const SizedBox.shrink(); @@ -160,13 +160,8 @@ class ThreadView extends GetWidget Obx(() { final presentationMailbox = controller.mailboxDashBoardController.selectedMailbox.value; if (controller.mailboxDashBoardController.isEmptySpamBannerEnabledOnMobile(context, presentationMailbox)) { - return Padding( - padding: const EdgeInsetsDirectional.symmetric( - horizontal: BannerDeleteAllSpamEmailsStyles.mobileMargin - ), - child: BannerDeleteAllSpamEmailsWidget( - onTapAction: () => controller.mailboxDashBoardController.openDialogEmptySpamFolder(context) - ), + return BannerDeleteAllSpamEmailsWidget( + onTapAction: () => controller.mailboxDashBoardController.openDialogEmptySpamFolder(context) ); } else { return const SizedBox.shrink(); @@ -222,22 +217,6 @@ class ThreadView extends GetWidget ); } - EdgeInsetsGeometry _getBannerMargin(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb) { - if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { - return const EdgeInsetsDirectional.only(start: 12, end: 12, bottom: 8); - } else { - return const EdgeInsetsDirectional.only(start: 24, end: 24, bottom: 8); - } - } else { - if (responsiveUtils.isPortraitMobile(context) || responsiveUtils.isLandscapeTablet(context)) { - return const EdgeInsetsDirectional.only(start: 16, end: 16, bottom: 8); - } else { - return const EdgeInsetsDirectional.only(start: 32, end: 32, bottom: 8); - } - } - } - bool _supportVerticalDivider(BuildContext context) { if (PlatformInfo.isWeb) { return controller.responsiveUtils.isTabletLarge(context); diff --git a/lib/features/thread/presentation/widgets/banner_delete_all_spam_emails_widget.dart b/lib/features/thread/presentation/widgets/banner_delete_all_spam_emails_widget.dart index 19e4d9074..79671947f 100644 --- a/lib/features/thread/presentation/widgets/banner_delete_all_spam_emails_widget.dart +++ b/lib/features/thread/presentation/widgets/banner_delete_all_spam_emails_widget.dart @@ -1,9 +1,11 @@ import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/thread/presentation/styles/banner_delete_all_spam_emails_styles.dart'; +import 'package:tmail_ui_user/features/thread/presentation/styles/banner_empty_trash_styles.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class BannerDeleteAllSpamEmailsWidget extends StatelessWidget { @@ -15,6 +17,8 @@ class BannerDeleteAllSpamEmailsWidget extends StatelessWidget { @override Widget build(BuildContext context) { final imagePaths = Get.find(); + final responsiveUtils = Get.find(); + return Container( decoration: const ShapeDecoration( color: BannerDeleteAllSpamEmailsStyles.backgroundColor, @@ -26,6 +30,7 @@ class BannerDeleteAllSpamEmailsWidget extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(BannerDeleteAllSpamEmailsStyles.borderRadius)), ), ), + margin: BannerEmptyTrashStyles.getBannerMargin(context, responsiveUtils), child: Material( color: Colors.transparent, child: InkWell( diff --git a/lib/features/thread/presentation/widgets/banner_empty_trash_widget.dart b/lib/features/thread/presentation/widgets/banner_empty_trash_widget.dart index c98d9e596..88d227a66 100644 --- a/lib/features/thread/presentation/widgets/banner_empty_trash_widget.dart +++ b/lib/features/thread/presentation/widgets/banner_empty_trash_widget.dart @@ -1,5 +1,6 @@ import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; @@ -15,6 +16,8 @@ class BannerEmptyTrashWidget extends StatelessWidget { @override Widget build(BuildContext context) { final imagePaths = Get.find(); + final responsiveUtils = Get.find(); + return Container( decoration: const ShapeDecoration( color: BannerEmptyTrashStyles.backgroundColor, @@ -26,6 +29,7 @@ class BannerEmptyTrashWidget extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(BannerEmptyTrashStyles.borderRadius)), ), ), + margin: BannerEmptyTrashStyles.getBannerMargin(context, responsiveUtils), child: Material( color: Colors.transparent, child: InkWell( diff --git a/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_web_widget.dart b/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_web_widget.dart index fdc42c4f8..a6c691cf1 100644 --- a/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_web_widget.dart +++ b/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_web_widget.dart @@ -21,20 +21,12 @@ class SpamReportBannerWebWidget extends StatelessWidget { return Obx(() { if (spamReportController.spamReportState.value == SpamReportState.disabled || spamReportController.presentationSpamMailbox.value == null) { - return const SizedBox( - height: 8, - ); + return const SizedBox.shrink(); } return Container( - margin: const EdgeInsetsDirectional.only( - end: SpamReportBannerWebStyles.horizontalMargin, - top: SpamReportBannerWebStyles.verticalMargin, - ), + margin: SpamReportBannerWebStyles.bannerMargin, width: double.infinity, - padding: const EdgeInsetsDirectional.symmetric( - horizontal: SpamReportBannerWebStyles.horizontalPadding, - vertical: SpamReportBannerWebStyles.verticalPadding, - ), + padding: SpamReportBannerWebStyles.bannerPadding, decoration: ShapeDecoration( color: SpamReportBannerWebStyles.backgroundColor, shape: const RoundedRectangleBorder(