From f18c4ef122df96249eba80b8a30f39e96aae7d75 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 6 Dec 2023 01:28:03 +0700 Subject: [PATCH] Fix padding item email in Thread and Search Signed-off-by: dab246 (cherry picked from commit 377085ba9054c6eb4c8e3d8388821473b3335962) --- .../dialog/confirmation_dialog_builder.dart | 1 - .../mailbox_dashboard_view_web.dart | 28 +- .../widgets/top_bar_thread_selection.dart | 200 +++--- .../email/presentation/search_email_view.dart | 45 +- .../utils/search_email_utils.dart | 42 +- .../mixin/base_email_item_tile.dart | 49 +- ...fault_web_app_bar_thread_widget_style.dart | 9 +- .../mobile_app_bar_thread_widget_style.dart | 9 +- ...ction_web_app_bar_thread_widget_style.dart | 9 +- .../styles/item_email_tile_styles.dart | 32 + .../thread/presentation/thread_view.dart | 48 +- .../default_web_app_bar_thread_widget.dart | 4 +- .../app_bar/mobile_app_bar_thread_widget.dart | 4 +- .../selection_web_app_bar_thread_widget.dart | 4 +- .../widgets/email_tile_builder.dart | 193 +++--- .../widgets/email_tile_web_builder.dart | 569 ++++++++---------- 16 files changed, 647 insertions(+), 599 deletions(-) diff --git a/core/lib/presentation/views/dialog/confirmation_dialog_builder.dart b/core/lib/presentation/views/dialog/confirmation_dialog_builder.dart index ad9fe6fdd..ecad63eee 100644 --- a/core/lib/presentation/views/dialog/confirmation_dialog_builder.dart +++ b/core/lib/presentation/views/dialog/confirmation_dialog_builder.dart @@ -1,7 +1,6 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; typedef OnConfirmButtonAction = void Function(); typedef OnCancelButtonAction = void Function(); 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 dba45d73c..3c9976fb3 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -61,10 +61,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { Container( width: ResponsiveUtils.defaultSizeMenu, color: Colors.white, - padding: EdgeInsets.only( - left: AppUtils.isDirectionRTL(context) ? 0 : 28, - right: AppUtils.isDirectionRTL(context) ? 28 : 0, - ), + padding: const EdgeInsetsDirectional.only(start: 28), alignment: Alignment.center, height: 80, child: Row(children: [ @@ -246,26 +243,21 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { Widget _buildThreadViewForWebDesktop(BuildContext context) { return Container( - margin: EdgeInsets.only( - right: AppUtils.isDirectionRTL(context) ? 0 : 16, - left: AppUtils.isDirectionRTL(context) ? 16 : 0, - top: 8, - bottom: 16 - ), + margin: const EdgeInsetsDirectional.only(end: 16, top: 8, bottom: 16), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), + borderRadius: const BorderRadius.all(Radius.circular(20)), border: Border.all(color: AppColor.colorBorderBodyThread, width: 1), color: Colors.white), child: ClipRRect( - borderRadius: BorderRadius.circular(20), + borderRadius: const BorderRadius.all(Radius.circular(20)), child: Column(children: [ Obx(() { - if (controller.isSelectionEnabled()) { + final listEmailSelected = controller.listEmailSelected; + if (controller.isSelectionEnabled() && listEmailSelected.isNotEmpty) { return Padding( - padding: const EdgeInsets.all(12.0), + padding: const EdgeInsets.symmetric(vertical: 8.5, horizontal: 16), child: TopBarThreadSelection( - context, - controller.listEmailSelected, + listEmailSelected, controller.mapMailboxById, onCancelSelection: () => controller.dispatchAction(CancelSelectionAllEmailAction()), @@ -275,11 +267,11 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { listEmails, actionType )), - ).build(), + ), ); } else { return Padding( - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), child: _buildListButtonTopBar(context), ); } diff --git a/lib/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart b/lib/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart index 1fc685714..82270ce26 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart @@ -1,9 +1,8 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/presentation/views/button/icon_button_web.dart'; -import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +import 'package:core/presentation/views/button/tmail_button_widget.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/email/email_action_type.dart'; @@ -14,125 +13,138 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; typedef OnEmailActionTypeAction = Function(List listEmail, EmailActionType actionType); -class TopBarThreadSelection { +class TopBarThreadSelection extends StatelessWidget{ final imagePaths = Get.find(); - final BuildContext context; final List listEmail; final Map mapMailbox; final OnEmailActionTypeAction? onEmailActionTypeAction; final VoidCallback? onCancelSelection; TopBarThreadSelection( - this.context, this.listEmail, - this.mapMailbox, { - this.onEmailActionTypeAction, - this.onCancelSelection, - }); + this.mapMailbox, + { + super.key, + this.onEmailActionTypeAction, + this.onCancelSelection, + } + ); - Widget build() { + @override + Widget build(BuildContext context) { final canDeletePermanently = listEmail.isAllCanDeletePermanently(mapMailbox); final canSpamAndMove = listEmail.isAllCanSpamAndMove(mapMailbox); final isAllSpam = listEmail.isAllSpam(mapMailbox); final isAllBelongToTheSameMailbox = listEmail.isAllBelongToTheSameMailbox(mapMailbox); return Row(children: [ - buildIconWeb( - icon: SvgPicture.asset( - imagePaths.icClose, - colorFilter: AppColor.colorTextButton.asFilter(), - fit: BoxFit.fill), - tooltip: AppLocalizations.of(context).cancel, - onTap: onCancelSelection), - Text(AppLocalizations.of(context).count_email_selected(listEmail.length), - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.w500, - color: AppColor.colorTextButton)), + TMailButtonWidget.fromIcon( + icon: imagePaths.icClose, + iconColor: AppColor.primaryColor, + tooltipMessage: AppLocalizations.of(context).cancel, + backgroundColor: Colors.transparent, + iconSize: 28, + padding: const EdgeInsets.all(3), + onTapActionCallback: onCancelSelection + ), + Text( + AppLocalizations.of(context).count_email_selected(listEmail.length), + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: AppColor.colorTextButton + ) + ), const SizedBox(width: 30), - buildIconWeb( - icon: SvgPicture.asset( - listEmail.isAllEmailRead - ? imagePaths.icUnread - : imagePaths.icRead, - fit: BoxFit.fill), - tooltip: listEmail.isAllEmailRead - ? AppLocalizations.of(context).mark_as_unread - : AppLocalizations.of(context).mark_as_read, - onTap: () => onEmailActionTypeAction?.call( - List.from(listEmail), - listEmail.isAllEmailRead - ? EmailActionType.markAsUnread - : EmailActionType.markAsRead)), - buildIconWeb( - icon: SvgPicture.asset( - listEmail.isAllEmailStarred - ? imagePaths.icUnStar - : imagePaths.icStar, - fit: BoxFit.fill), - tooltip: listEmail.isAllEmailStarred - ? AppLocalizations.of(context).un_star - : AppLocalizations.of(context).star, - onTap: () => onEmailActionTypeAction?.call( - List.from(listEmail), - listEmail.isAllEmailStarred - ? EmailActionType.unMarkAsStarred - : EmailActionType.markAsStarred)), + TMailButtonWidget.fromIcon( + icon: listEmail.isAllEmailRead + ? imagePaths.icUnread + : imagePaths.icRead, + tooltipMessage: listEmail.isAllEmailRead + ? AppLocalizations.of(context).mark_as_unread + : AppLocalizations.of(context).mark_as_read, + backgroundColor: Colors.transparent, + iconSize: 24, + onTapActionCallback: () => onEmailActionTypeAction?.call( + List.from(listEmail), + listEmail.isAllEmailRead ? EmailActionType.markAsUnread : EmailActionType.markAsRead + ) + ), + TMailButtonWidget.fromIcon( + icon: listEmail.isAllEmailStarred + ? imagePaths.icUnStar + : imagePaths.icStar, + tooltipMessage: listEmail.isAllEmailStarred + ? AppLocalizations.of(context).un_star + : AppLocalizations.of(context).star, + backgroundColor: Colors.transparent, + iconSize: 24, + onTapActionCallback: () => onEmailActionTypeAction?.call( + List.from(listEmail), + listEmail.isAllEmailStarred ? EmailActionType.unMarkAsStarred : EmailActionType.markAsStarred + ) + ), if (canSpamAndMove) ...[ - buildIconWeb( - icon: SvgPicture.asset(imagePaths.icMove, fit: BoxFit.fill), - tooltip: AppLocalizations.of(context).move, - onTap: () => onEmailActionTypeAction?.call( + TMailButtonWidget.fromIcon( + icon: imagePaths.icMove, + iconSize: 22, + tooltipMessage: AppLocalizations.of(context).move, + backgroundColor: Colors.transparent, + onTapActionCallback: () => onEmailActionTypeAction?.call( + List.from(listEmail), + EmailActionType.moveToMailbox + ) + ), + TMailButtonWidget.fromIcon( + icon: isAllSpam ? imagePaths.icNotSpam : imagePaths.icSpam, + backgroundColor: Colors.transparent, + iconSize: 24, + tooltipMessage: isAllSpam + ? AppLocalizations.of(context).un_spam + : AppLocalizations.of(context).mark_as_spam, + onTapActionCallback: () { + if (isAllSpam) { + onEmailActionTypeAction?.call( List.from(listEmail), - EmailActionType.moveToMailbox)), - buildIconWeb( - icon: SvgPicture.asset( - isAllSpam ? imagePaths.icNotSpam : imagePaths.icSpam, - fit: BoxFit.fill), - tooltip: isAllSpam - ? AppLocalizations.of(context).un_spam - : AppLocalizations.of(context).mark_as_spam, - onTap: () { - if (isAllSpam) { - onEmailActionTypeAction?.call( - List.from(listEmail), - EmailActionType.unSpam); - } else { - onEmailActionTypeAction?.call( - List.from(listEmail.listEmailCanSpam(mapMailbox)), - EmailActionType.moveToSpam); - } - }) + EmailActionType.unSpam + ); + } else { + onEmailActionTypeAction?.call( + List.from(listEmail.listEmailCanSpam(mapMailbox)), + EmailActionType.moveToSpam + ); + } + } + ) ], if (isAllBelongToTheSameMailbox) - buildIconWeb( - icon: SvgPicture.asset( - canDeletePermanently - ? imagePaths.icDeleteComposer - : imagePaths.icDelete, - colorFilter: canDeletePermanently - ? AppColor.colorDeletePermanentlyButton.asFilter() - : AppColor.primaryColor.asFilter(), - width: 20, - height: 20, - fit: BoxFit.fill), - tooltip: canDeletePermanently - ? AppLocalizations.of(context).delete_permanently - : AppLocalizations.of(context).move_to_trash, - onTap: () { + TMailButtonWidget.fromIcon( + icon: imagePaths.icDeleteComposer, + backgroundColor: Colors.transparent, + iconSize: 20, + iconColor: canDeletePermanently + ? AppColor.colorDeletePermanentlyButton + : AppColor.primaryColor, + tooltipMessage: canDeletePermanently + ? AppLocalizations.of(context).delete_permanently + : AppLocalizations.of(context).move_to_trash, + onTapActionCallback: () { if (canDeletePermanently) { onEmailActionTypeAction?.call( - List.from(listEmail), - EmailActionType.deletePermanently); + List.from(listEmail), + EmailActionType.deletePermanently + ); } else { onEmailActionTypeAction?.call( - List.from(listEmail), - EmailActionType.moveToTrash); + List.from(listEmail), + EmailActionType.moveToTrash + ); } - }), + } + ), ]); } } \ No newline at end of file diff --git a/lib/features/search/email/presentation/search_email_view.dart b/lib/features/search/email/presentation/search_email_view.dart index e16267c8e..8c3552387 100644 --- a/lib/features/search/email/presentation/search_email_view.dart +++ b/lib/features/search/email/presentation/search_email_view.dart @@ -29,6 +29,7 @@ import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_s import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_sort_by_cupertino_action_sheet_action_builder.dart'; import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/search_more_email_state.dart'; +import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_tile_styles.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart' if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/empty_emails_widget.dart'; @@ -483,11 +484,10 @@ class SearchEmailView extends GetWidget return false; }, child: PlatformInfo.isMobile - ? ListView.builder( + ? ListView.separated( controller: controller.resultSearchScrollController, physics: const AlwaysScrollableScrollPhysics(), key: const PageStorageKey('list_presentation_email_in_search_view'), - itemExtent: _getItemExtent(context), itemCount: listPresentationEmail.length, itemBuilder: (context, index) { final currentPresentationEmail = listPresentationEmail[index]; @@ -497,8 +497,7 @@ class SearchEmailView extends GetWidget searchQuery: controller.searchQuery, isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id, isSearchEmailRunning: true, - padding: SearchEmailUtils.getPaddingSearchResultList(context, controller.responsiveUtils), - paddingDivider: SearchEmailUtils.getPaddingDividerSearchResultList(context, controller.responsiveUtils), + padding: SearchEmailUtils.getPaddingItemListMobile(context, controller.responsiveUtils), mailboxContain: currentPresentationEmail.mailboxContain, emailActionClick: (action, email) { controller.pressEmailAction( @@ -523,15 +522,23 @@ class SearchEmailView extends GetWidget } }, )); - } + }, + separatorBuilder: (BuildContext context, int index) { + if (index < listPresentationEmail.length - 1) { + return Padding( + padding: SearchEmailUtils.getPaddingItemListMobile(context, controller.responsiveUtils), + child: const Divider(color: AppColor.lineItemListColor, height: 1)); + } else { + return const SizedBox.shrink(); + } + }, ) : ScrollbarListView( scrollController: controller.resultSearchScrollController, - child: ListView.builder( + child: ListView.separated( controller: controller.resultSearchScrollController, physics: const AlwaysScrollableScrollPhysics(), key: const PageStorageKey('list_presentation_email_in_search_view'), - itemExtent: _getItemExtent(context), itemCount: listPresentationEmail.length, itemBuilder: (context, index) { final currentPresentationEmail = listPresentationEmail[index]; @@ -542,7 +549,6 @@ class SearchEmailView extends GetWidget isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id, isSearchEmailRunning: true, padding: SearchEmailUtils.getPaddingSearchResultList(context, controller.responsiveUtils), - paddingDivider: SearchEmailUtils.getPaddingDividerSearchResultList(context, controller.responsiveUtils), mailboxContain: currentPresentationEmail.mailboxContain, emailActionClick: (action, email) { controller.pressEmailAction( @@ -566,21 +572,26 @@ class SearchEmailView extends GetWidget ); } }, + )); - } + }, + separatorBuilder: (context, index) { + return Padding( + padding: ItemEmailTileStyles.getPaddingDividerWeb(context, controller.responsiveUtils), + child: Divider( + color: index < listPresentationEmail.length - 1 && + controller.selectionMode.value == SelectMode.INACTIVE + ? AppColor.lineItemListColor + : Colors.white, + height: 1 + ) + ); + }, ) ) ); } - double? _getItemExtent(BuildContext context) { - if (PlatformInfo.isWeb) { - return controller.responsiveUtils.isDesktop(context) ? 52 : 95; - } else { - return null; - } - } - Widget _buildLoadingView() { return Obx(() => controller.viewState.value.fold( (failure) => const SizedBox.shrink(), 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 ed10efeee..e9ad3204b 100644 --- a/lib/features/search/email/presentation/utils/search_email_utils.dart +++ b/lib/features/search/email/presentation/utils/search_email_utils.dart @@ -6,10 +6,14 @@ import 'package:flutter/material.dart'; class SearchEmailUtils { static EdgeInsets getPaddingAppBar(BuildContext context, ResponsiveUtils responsiveUtils) { if (PlatformInfo.isWeb) { - return const EdgeInsets.symmetric(horizontal: 16); + if (responsiveUtils.isMobile(context)) { + return const EdgeInsets.symmetric(horizontal: 16); + } else { + return const EdgeInsets.symmetric(horizontal: 32); + } } else { - if (responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.symmetric(horizontal: 10); + if (responsiveUtils.isPortraitMobile(context)) { + return const EdgeInsets.symmetric(horizontal: 8); } else { return const EdgeInsets.symmetric(horizontal: 32); } @@ -49,31 +53,35 @@ class SearchEmailUtils { } static EdgeInsets getPaddingSearchFilterButton(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb || !responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.all(12); - } else { + 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); + } else { + return const EdgeInsets.symmetric(horizontal: 32); } } static EdgeInsets getMarginSearchFilterButton(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb || !responsiveUtils.isScreenWithShortestSide(context)) { + if (PlatformInfo.isWeb) { return const EdgeInsets.symmetric(horizontal: 20); } else { return EdgeInsets.zero; } } - static EdgeInsets getPaddingSearchResultList(BuildContext context, ResponsiveUtils responsiveUtils) { - if (PlatformInfo.isWeb) { - return const EdgeInsets.only(left: 10); - } else { - if (responsiveUtils.isScreenWithShortestSide(context)) { - return const EdgeInsets.symmetric(horizontal: 16, vertical: 5); - } else { - return const EdgeInsets.symmetric(horizontal: 32, vertical: 5); - } - } + static EdgeInsetsGeometry getPaddingSearchResultList(BuildContext context, ResponsiveUtils responsiveUtils) { + return const EdgeInsetsDirectional.only(top: 8, bottom: 8, end: 8); } static EdgeInsets getPaddingDividerSearchResultList(BuildContext context, ResponsiveUtils responsiveUtils) { diff --git a/lib/features/thread/presentation/mixin/base_email_item_tile.dart b/lib/features/thread/presentation/mixin/base_email_item_tile.dart index b15477b18..cf37c63d3 100644 --- a/lib/features/thread/presentation/mixin/base_email_item_tile.dart +++ b/lib/features/thread/presentation/mixin/base_email_item_tile.dart @@ -216,31 +216,34 @@ mixin BaseEmailItemTile { fit: BoxFit.fill); } - Widget buildIconAvatarText(PresentationEmail email, { - double? iconSize, - TextStyle? textStyle - }) { + Widget buildIconAvatarText( + PresentationEmail email, + { + double? iconSize, + TextStyle? textStyle + } + ) { return Container( - width: iconSize ?? 56, - height: iconSize ?? 56, - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular((iconSize ?? 56) * 0.5), - border: Border.all(color: Colors.transparent), - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - stops: const [0.0, 1.0], - colors: email.avatarColors), - color: AppColor.avatarColor - ), - child: Text( - email.getAvatarText(), - style: textStyle ?? const TextStyle( - fontSize: 20, - color: Colors.white, - fontWeight: FontWeight.w500) + width: iconSize ?? ItemEmailTileStyles.avatarIconSize, + height: iconSize ?? ItemEmailTileStyles.avatarIconSize, + alignment: Alignment.center, + decoration: ShapeDecoration( + shape: const CircleBorder(), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + stops: const [0.0, 1.0], + colors: email.avatarColors ) + ), + child: Text( + email.getAvatarText(), + style: textStyle ?? const TextStyle( + fontSize: 22, + color: Colors.white, + fontWeight: FontWeight.w500 + ) + ) ); } diff --git a/lib/features/thread/presentation/styles/app_bar/default_web_app_bar_thread_widget_style.dart b/lib/features/thread/presentation/styles/app_bar/default_web_app_bar_thread_widget_style.dart index 4d7cf4b1d..64edbb8ee 100644 --- a/lib/features/thread/presentation/styles/app_bar/default_web_app_bar_thread_widget_style.dart +++ b/lib/features/thread/presentation/styles/app_bar/default_web_app_bar_thread_widget_style.dart @@ -1,5 +1,6 @@ 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/thread/domain/model/filter_message_option.dart'; @@ -10,7 +11,13 @@ class DefaultWebAppBarThreadWidgetStyle { static const Color backgroundColor = Colors.white; - static const EdgeInsetsGeometry padding = EdgeInsets.symmetric(vertical: 8, horizontal: 16); + static EdgeInsetsGeometry getPadding(BuildContext context, ResponsiveUtils responsiveUtils) { + if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { + return const EdgeInsets.symmetric(horizontal: 16, vertical: 8); + } else { + return const EdgeInsets.symmetric(horizontal: 32, vertical: 8); + } + } static const EdgeInsetsGeometry mailboxMenuPadding = EdgeInsets.all(5); static const EdgeInsetsGeometry titlePadding = EdgeInsets.symmetric(horizontal: 16); diff --git a/lib/features/thread/presentation/styles/app_bar/mobile_app_bar_thread_widget_style.dart b/lib/features/thread/presentation/styles/app_bar/mobile_app_bar_thread_widget_style.dart index 593e247ab..fd5810d0e 100644 --- a/lib/features/thread/presentation/styles/app_bar/mobile_app_bar_thread_widget_style.dart +++ b/lib/features/thread/presentation/styles/app_bar/mobile_app_bar_thread_widget_style.dart @@ -1,5 +1,6 @@ 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/thread/domain/model/filter_message_option.dart'; @@ -11,7 +12,13 @@ class MobileAppBarThreadWidgetStyle { static const Color backgroundColor = Colors.white; static const Color backButtonColor = AppColor.primaryColor; - static const EdgeInsetsGeometry padding = EdgeInsets.symmetric(vertical: 8, horizontal: 16); + static EdgeInsetsGeometry getPadding(BuildContext context, ResponsiveUtils responsiveUtils) { + if (responsiveUtils.isPortraitMobile(context) || responsiveUtils.isLandscapeTablet(context)) { + return const EdgeInsets.symmetric(horizontal: 16, vertical: 8); + } else { + return const EdgeInsets.symmetric(horizontal: 32, vertical: 8); + } + } static const TextStyle editButtonStyle = TextStyle( fontSize: 17, diff --git a/lib/features/thread/presentation/styles/app_bar/selection_web_app_bar_thread_widget_style.dart b/lib/features/thread/presentation/styles/app_bar/selection_web_app_bar_thread_widget_style.dart index f4f3d4218..eb1156313 100644 --- a/lib/features/thread/presentation/styles/app_bar/selection_web_app_bar_thread_widget_style.dart +++ b/lib/features/thread/presentation/styles/app_bar/selection_web_app_bar_thread_widget_style.dart @@ -1,5 +1,6 @@ import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/material.dart'; class SelectionWebAppBarThreadWidgetStyle { @@ -11,7 +12,13 @@ class SelectionWebAppBarThreadWidgetStyle { static const Color backgroundColor = Colors.white; static const Color cancelButtonColor = AppColor.primaryColor; - static const EdgeInsetsGeometry padding = EdgeInsets.symmetric(vertical: 8, horizontal: 16); + static EdgeInsetsGeometry getPadding(BuildContext context, ResponsiveUtils responsiveUtils) { + if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { + return const EdgeInsets.symmetric(horizontal: 16, vertical: 8); + } else { + return const EdgeInsets.symmetric(horizontal: 32, vertical: 8); + } + } static const EdgeInsetsGeometry closeButtonPadding = EdgeInsets.all(3); static const TextStyle emailCounterStyle = TextStyle( diff --git a/lib/features/thread/presentation/styles/item_email_tile_styles.dart b/lib/features/thread/presentation/styles/item_email_tile_styles.dart index 2c2c6c83f..6aa529a89 100644 --- a/lib/features/thread/presentation/styles/item_email_tile_styles.dart +++ b/lib/features/thread/presentation/styles/item_email_tile_styles.dart @@ -1,9 +1,13 @@ import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:core/utils/platform_info.dart'; import 'package:flutter/cupertino.dart'; class ItemEmailTileStyles { + static const double avatarIconSize = 60.0; + static const double horizontalTitleGap = 8.0; + static EdgeInsetsGeometry getSpaceCalendarEventIcon(BuildContext context, ResponsiveUtils responsiveUtils) { if (responsiveUtils.isScreenWithShortestSide(context)) { return const EdgeInsetsDirectional.only(end: 4); @@ -13,4 +17,32 @@ class ItemEmailTileStyles { return const EdgeInsetsDirectional.only(end: 8); } } + + static EdgeInsetsGeometry getPaddingItemList(BuildContext context, ResponsiveUtils responsiveUtils) { + if (PlatformInfo.isWeb) { + if (responsiveUtils.isDesktop(context)) { + return const EdgeInsetsDirectional.only(start: 120); + } else if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { + return const EdgeInsets.symmetric(horizontal: 16); + } else { + return const EdgeInsets.symmetric(horizontal: 32); + } + } else { + if (responsiveUtils.isPortraitMobile(context) || responsiveUtils.isLandscapeTablet(context)) { + return const EdgeInsets.symmetric(horizontal: 16); + } else { + return const EdgeInsets.symmetric(horizontal: 32); + } + } + } + + static EdgeInsetsGeometry getPaddingDividerWeb(BuildContext context, ResponsiveUtils responsiveUtils) { + if (responsiveUtils.isDesktop(context)) { + return const EdgeInsetsDirectional.only(start: 120); + } else if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { + return const EdgeInsets.symmetric(horizontal: 12); + } else { + return const EdgeInsets.symmetric(horizontal: 24); + } + } } \ 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 bdeb4790b..063e39418 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -22,6 +22,7 @@ import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.da import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.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/thread_controller.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/app_bar/app_bar_thread_widget.dart'; @@ -193,10 +194,8 @@ class ThreadView extends GetWidget Widget _buildSearchBarView(BuildContext context) { return Container( color: Colors.white, - padding: EdgeInsets.symmetric( - horizontal: 16, - vertical: controller.responsiveUtils.isWebNotDesktop(context) ? 8 : 0), - margin: EdgeInsets.only(bottom: PlatformInfo.isMobile ? 8 : 0), + padding: ItemEmailTileStyles.getPaddingItemList(context, controller.responsiveUtils), + margin: EdgeInsets.only(bottom: !controller.responsiveUtils.isWebDesktop(context) ? 8 : 0), child: SearchBarView(controller.imagePaths, hintTextSearch: AppLocalizations.of(context).search_emails, onOpenSearchViewAction: controller.goToSearchView)); @@ -346,14 +345,21 @@ class ThreadView extends GetWidget return false; }, child: PlatformInfo.isMobile - ? ListView.builder( + ? ListView.separated( key: const PageStorageKey('list_presentation_email_in_threads'), controller: controller.listEmailController, physics: const AlwaysScrollableScrollPhysics(), - padding: EdgeInsets.zero, - itemExtent: _getItemExtent(context), itemCount: listPresentationEmail.length, - itemBuilder: (context, index) => Obx(() => _buildEmailItem(context, listPresentationEmail[index])) + itemBuilder: (context, index) => Obx(() => _buildEmailItemNotDraggable(context, listPresentationEmail[index])), + separatorBuilder: (context, index) { + if (index < listPresentationEmail.length - 1) { + return Padding( + padding: ItemEmailTileStyles.getPaddingItemList(context, controller.responsiveUtils), + child: const Divider(color: AppColor.lineItemListColor, height: 1)); + } else { + return const SizedBox.shrink(); + } + }, ) : Focus( focusNode: controller.focusNodeKeyBoard, @@ -361,14 +367,24 @@ class ThreadView extends GetWidget onKey: controller.handleKeyEvent, child: ScrollbarListView( scrollController: controller.listEmailController, - child: ListView.builder( + child: ListView.separated( key: const PageStorageKey('list_presentation_email_in_threads'), controller: controller.listEmailController, physics: const AlwaysScrollableScrollPhysics(), - padding: EdgeInsets.zero, - itemExtent: _getItemExtent(context), itemCount: listPresentationEmail.length, - itemBuilder: (context, index) => Obx(() => _buildEmailItem(context, listPresentationEmail[index])) + itemBuilder: (context, index) => Obx(() => _buildEmailItem(context, listPresentationEmail[index])), + separatorBuilder: (context, index) { + return Padding( + padding: ItemEmailTileStyles.getPaddingDividerWeb(context, controller.responsiveUtils), + child: Divider( + color: index < listPresentationEmail.length - 1 && + controller.mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE + ? AppColor.lineItemListColor + : Colors.white, + height: 1 + ) + ); + }, ), ), ) @@ -546,14 +562,6 @@ class ThreadView extends GetWidget ); } - double? _getItemExtent(BuildContext context) { - if (PlatformInfo.isWeb) { - return controller.responsiveUtils.isDesktop(context) ? 52 : 98; - } else { - return null; - } - } - Widget _buildEmptyEmail(BuildContext context) { return Obx(() => controller.viewState.value.fold( (failure) => const SizedBox.shrink(), diff --git a/lib/features/thread/presentation/widgets/app_bar/default_web_app_bar_thread_widget.dart b/lib/features/thread/presentation/widgets/app_bar/default_web_app_bar_thread_widget.dart index d787bd232..b4129c664 100644 --- a/lib/features/thread/presentation/widgets/app_bar/default_web_app_bar_thread_widget.dart +++ b/lib/features/thread/presentation/widgets/app_bar/default_web_app_bar_thread_widget.dart @@ -1,5 +1,6 @@ import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/style_utils.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:flutter/material.dart'; @@ -13,6 +14,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class DefaultWebAppBarThreadWidget extends StatelessWidget { final _imagePaths = Get.find(); + final _responsiveUtils = Get.find(); final PresentationMailbox? mailboxSelected; final FilterMessageOption filterOption; @@ -34,7 +36,7 @@ class DefaultWebAppBarThreadWidget extends StatelessWidget { return LayoutBuilder(builder: (context, constraints) { return Container( color: DefaultWebAppBarThreadWidgetStyle.backgroundColor, - padding: DefaultWebAppBarThreadWidgetStyle.padding, + padding: DefaultWebAppBarThreadWidgetStyle.getPadding(context, _responsiveUtils), constraints: const BoxConstraints(minHeight: DefaultWebAppBarThreadWidgetStyle.minHeight), child: Row( children: [ diff --git a/lib/features/thread/presentation/widgets/app_bar/mobile_app_bar_thread_widget.dart b/lib/features/thread/presentation/widgets/app_bar/mobile_app_bar_thread_widget.dart index 09105d810..ffd7df49a 100644 --- a/lib/features/thread/presentation/widgets/app_bar/mobile_app_bar_thread_widget.dart +++ b/lib/features/thread/presentation/widgets/app_bar/mobile_app_bar_thread_widget.dart @@ -1,5 +1,6 @@ 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:get/get.dart'; @@ -14,6 +15,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class MobileAppBarThreadWidget extends StatelessWidget { final _imagePaths = Get.find(); + final _responsiveUtils = Get.find(); final PresentationMailbox? mailboxSelected; final List listEmailSelected; @@ -43,7 +45,7 @@ class MobileAppBarThreadWidget extends StatelessWidget { return LayoutBuilder(builder: (context, constraints) { return Container( color: MobileAppBarThreadWidgetStyle.backgroundColor, - padding: MobileAppBarThreadWidgetStyle.padding, + padding: MobileAppBarThreadWidgetStyle.getPadding(context, _responsiveUtils), constraints: const BoxConstraints(minHeight: MobileAppBarThreadWidgetStyle.minHeight), child: Stack( alignment: AlignmentDirectional.center, diff --git a/lib/features/thread/presentation/widgets/app_bar/selection_web_app_bar_thread_widget.dart b/lib/features/thread/presentation/widgets/app_bar/selection_web_app_bar_thread_widget.dart index 4a0175a0a..66126719a 100644 --- a/lib/features/thread/presentation/widgets/app_bar/selection_web_app_bar_thread_widget.dart +++ b/lib/features/thread/presentation/widgets/app_bar/selection_web_app_bar_thread_widget.dart @@ -1,5 +1,6 @@ import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/style_utils.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:flutter/material.dart'; @@ -16,6 +17,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class SelectionWebAppBarThreadWidget extends StatelessWidget { final _imagePaths = Get.find(); + final _responsiveUtils = Get.find(); final PresentationMailbox? mailboxSelected; final List listEmailSelected; @@ -42,7 +44,7 @@ class SelectionWebAppBarThreadWidget extends StatelessWidget { Widget build(BuildContext context) { return Container( color: SelectionWebAppBarThreadWidgetStyle.backgroundColor, - padding: SelectionWebAppBarThreadWidgetStyle.padding, + padding: SelectionWebAppBarThreadWidgetStyle.getPadding(context, _responsiveUtils), constraints: const BoxConstraints(minHeight: SelectionWebAppBarThreadWidgetStyle.minHeight), child: Row( children: [ diff --git a/lib/features/thread/presentation/widgets/email_tile_builder.dart b/lib/features/thread/presentation/widgets/email_tile_builder.dart index 4043223eb..c25a7899b 100644 --- a/lib/features/thread/presentation/widgets/email_tile_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_builder.dart @@ -7,6 +7,7 @@ import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/select_mode.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/presentation/mixin/base_email_item_tile.dart'; +import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_tile_styles.dart'; class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { @@ -16,7 +17,6 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { final SearchQuery? searchQuery; final bool isSearchEmailRunning; final EdgeInsetsGeometry? padding; - final EdgeInsetsGeometry? paddingDivider; final bool isDrag; final bool isShowingEmailContent; final OnPressEmailActionClick? emailActionClick; @@ -31,7 +31,6 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { this.isSearchEmailRunning = false, this.mailboxContain, this.padding, - this.paddingDivider, this.isDrag = false, this.emailActionClick, this.onMoreActionClick, @@ -40,105 +39,99 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { @override Widget build(BuildContext context) { return Material( - color: Colors.transparent, - child: Column( - children: [ - ListTile( - tileColor: isShowingEmailContent ? AppColor.colorItemEmailSelectedDesktop : null, - contentPadding: padding ?? const EdgeInsetsDirectional.symmetric(horizontal: 16, vertical: 5), - onTap: () => emailActionClick?.call( - EmailActionType.preview, - presentationEmail), - onLongPress: () => emailActionClick?.call( - EmailActionType.selection, - presentationEmail), - leading: GestureDetector( - onTap: () => emailActionClick?.call( - selectAllMode == SelectMode.ACTIVE - ? EmailActionType.selection - : EmailActionType.preview, - presentationEmail), - child: Container( - width: 56, - height: 56, - color: Colors.transparent, - alignment: Alignment.center, - child: selectAllMode == SelectMode.ACTIVE - ? buildIconAvatarSelection(context, presentationEmail) - : buildIconAvatarText(presentationEmail) - ) + type: MaterialType.transparency, + child: ListTile( + tileColor: isShowingEmailContent ? AppColor.colorItemEmailSelectedDesktop : null, + contentPadding: padding ?? ItemEmailTileStyles.getPaddingItemList(context, responsiveUtils), + onTap: () => emailActionClick?.call( + EmailActionType.preview, + presentationEmail), + onLongPress: () => emailActionClick?.call( + EmailActionType.selection, + presentationEmail), + minLeadingWidth: ItemEmailTileStyles.avatarIconSize, + horizontalTitleGap: ItemEmailTileStyles.horizontalTitleGap, + leading: GestureDetector( + onTap: () => emailActionClick?.call( + selectAllMode == SelectMode.ACTIVE + ? EmailActionType.selection + : EmailActionType.preview, + presentationEmail), + child: Container( + width: ItemEmailTileStyles.avatarIconSize, + height: ItemEmailTileStyles.avatarIconSize, + alignment: Alignment.center, + child: selectAllMode == SelectMode.ACTIVE + ? buildIconAvatarSelection(context, presentationEmail) + : buildIconAvatarText(presentationEmail) + ) + ), + title: Row( + children: [ + if (!presentationEmail.hasRead) + Padding( + padding: const EdgeInsetsDirectional.only(end: 5), + child: SvgPicture.asset( + imagePaths.icUnreadStatus, + width: 9, + height: 9, + fit: BoxFit.fill)), + Expanded(child: buildInformationSender( + context, + presentationEmail, + mailboxContain, + isSearchEmailRunning, + searchQuery)), + buildIconAnsweredOrForwarded(width: 16, height: 16, presentationEmail: presentationEmail), + if (presentationEmail.hasAttachment == true) + Padding( + padding: const EdgeInsetsDirectional.only(start: 8), + child: buildIconAttachment()), + Padding( + padding: const EdgeInsetsDirectional.only(end: 4, start: 8), + child: buildDateTime(context, presentationEmail)), + buildIconChevron(), + ], + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsetsDirectional.only(top: 6), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (presentationEmail.hasCalendarEvent) + buildCalendarEventIcon(context: context, presentationEmail: presentationEmail), + Expanded(child: buildEmailTitle( + context, + presentationEmail, + isSearchEmailRunning, + searchQuery)), + buildMailboxContain( + context, + isSearchEmailRunning, + presentationEmail), + if (presentationEmail.hasStarred) + Padding( + padding: const EdgeInsetsDirectional.only(start: 8), + child: buildIconStar(), + ) + ], + )), + Padding( + padding: const EdgeInsetsDirectional.only(top: 6), + child: Row(children: [ + Expanded(child: buildEmailPartialContent( + context, + presentationEmail, + isSearchEmailRunning, + searchQuery)), + ]) ), - title: Row( - children: [ - if (!presentationEmail.hasRead) - Padding( - padding: const EdgeInsetsDirectional.only(end: 5), - child: SvgPicture.asset( - imagePaths.icUnreadStatus, - width: 9, - height: 9, - fit: BoxFit.fill)), - Expanded(child: buildInformationSender( - context, - presentationEmail, - mailboxContain, - isSearchEmailRunning, - searchQuery)), - buildIconAnsweredOrForwarded(width: 16, height: 16, presentationEmail: presentationEmail), - if (presentationEmail.hasAttachment == true) - Padding( - padding: const EdgeInsetsDirectional.only(start: 8), - child: buildIconAttachment()), - Padding( - padding: const EdgeInsetsDirectional.only(end: 4, start: 8), - child: buildDateTime(context, presentationEmail)), - buildIconChevron(), - ], - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsetsDirectional.only(top: 6), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (presentationEmail.hasCalendarEvent) - buildCalendarEventIcon(context: context, presentationEmail: presentationEmail), - Expanded(child: buildEmailTitle( - context, - presentationEmail, - isSearchEmailRunning, - searchQuery)), - buildMailboxContain( - context, - isSearchEmailRunning, - presentationEmail), - if (presentationEmail.hasStarred) - Padding( - padding: const EdgeInsetsDirectional.only(start: 8), - child: buildIconStar(), - ) - ], - )), - Padding( - padding: const EdgeInsetsDirectional.only(top: 6), - child: Row(children: [ - Expanded(child: buildEmailPartialContent( - context, - presentationEmail, - isSearchEmailRunning, - searchQuery)), - ]) - ), - ], - ), - ), - Padding( - padding: paddingDivider ?? const EdgeInsetsDirectional.symmetric(horizontal: 16), - child: const Divider(color: AppColor.lineItemListColor, height: 1)), - ], + ], + ), ), ); } diff --git a/lib/features/thread/presentation/widgets/email_tile_web_builder.dart b/lib/features/thread/presentation/widgets/email_tile_web_builder.dart index b83cbdf16..68129accc 100644 --- a/lib/features/thread/presentation/widgets/email_tile_web_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_web_builder.dart @@ -21,8 +21,7 @@ class EmailTileBuilder extends StatefulWidget { final PresentationMailbox? mailboxContain; final SearchQuery? searchQuery; final bool isSearchEmailRunning; - final EdgeInsets? padding; - final EdgeInsets? paddingDivider; + final EdgeInsetsGeometry? padding; final bool isDrag; final bool isShowingEmailContent; final OnPressEmailActionClick? emailActionClick; @@ -37,7 +36,6 @@ class EmailTileBuilder extends StatefulWidget { this.isSearchEmailRunning = false, this.mailboxContain, this.padding, - this.paddingDivider, this.isDrag = false, this.emailActionClick, this.onMoreActionClick, @@ -54,138 +52,125 @@ class _EmailTileBuilderState extends State with BaseEmailItem Widget build(BuildContext context) { return Container( margin: _getMarginItem(context), - padding: _getPaddingItem(context), + padding: widget.padding ?? _getPaddingItem(context), decoration: _getDecorationItem(), alignment: Alignment.center, child: ResponsiveWidget( responsiveUtils: responsiveUtils, - mobile: Stack( - alignment: Alignment.bottomCenter, - children: [ - InkWell( - onTap: () => widget.emailActionClick?.call( - EmailActionType.preview, - widget.presentationEmail + mobile: InkWell( + onTap: () => widget.emailActionClick?.call( + EmailActionType.preview, + widget.presentationEmail + ), + onLongPress: () => widget.emailActionClick?.call( + EmailActionType.selection, + widget.presentationEmail + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InkWell( + onTap: () => widget.emailActionClick?.call( + widget.selectAllMode == SelectMode.ACTIVE + ? EmailActionType.selection + : EmailActionType.preview, + widget.presentationEmail + ), + child: Padding( + padding: const EdgeInsetsDirectional.only(top: 8, end: 12), + child: _buildAvatarIcon(context: context), + ), ), - onLongPress: () => widget.emailActionClick?.call( - EmailActionType.selection, - widget.presentationEmail - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - InkWell( - onTap: () => widget.emailActionClick?.call( - widget.selectAllMode == SelectMode.ACTIVE - ? EmailActionType.selection - : EmailActionType.preview, - widget.presentationEmail + Expanded( + child: Column(children: [ + Row(children: [ + if (!widget.presentationEmail.hasRead) + Padding( + padding: const EdgeInsetsDirectional.only(end: 5), + child: SvgPicture.asset( + imagePaths.icUnreadStatus, + width: 9, + height: 9, + fit: BoxFit.fill + ) + ), + Expanded( + child: buildInformationSender( + context, + widget.presentationEmail, + widget.mailboxContain, + widget.isSearchEmailRunning, + widget.searchQuery + ) ), - child: Padding( - padding: const EdgeInsetsDirectional.only(top: 8, end: 12), - child: _buildAvatarIcon(context: context), + buildIconAnsweredOrForwarded( + width: 16, + height: 16, + presentationEmail: widget.presentationEmail ), - ), - Expanded( - child: Column(children: [ - Row(children: [ - if (!widget.presentationEmail.hasRead) - Padding( - padding: const EdgeInsetsDirectional.only(end: 5), - child: SvgPicture.asset( - imagePaths.icUnreadStatus, - width: 9, - height: 9, - fit: BoxFit.fill - ) - ), - Expanded( - child: buildInformationSender( - context, - widget.presentationEmail, - widget.mailboxContain, - widget.isSearchEmailRunning, - widget.searchQuery - ) - ), - buildIconAnsweredOrForwarded( + if (widget.presentationEmail.hasAttachment == true) + Padding( + padding: const EdgeInsetsDirectional.only(start: 8), + child: SvgPicture.asset( + imagePaths.icAttachment, width: 16, height: 16, + fit: BoxFit.fill + ) + ), + Padding( + padding: const EdgeInsetsDirectional.only( + end: 4, + start: 8 + ), + child: buildDateTime(context, widget.presentationEmail) + ), + buildIconChevron() + ]), + const SizedBox(height: 8), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.presentationEmail.hasCalendarEvent) + buildCalendarEventIcon( + context: context, presentationEmail: widget.presentationEmail ), - if (widget.presentationEmail.hasAttachment == true) - Padding( - padding: const EdgeInsetsDirectional.only(start: 8), - child: SvgPicture.asset( - imagePaths.icAttachment, - width: 16, - height: 16, - fit: BoxFit.fill - ) - ), - Padding( - padding: const EdgeInsetsDirectional.only( - end: 4, - start: 8 - ), - child: buildDateTime(context, widget.presentationEmail) - ), - buildIconChevron() - ]), - const SizedBox(height: 8), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (widget.presentationEmail.hasCalendarEvent) - buildCalendarEventIcon( - context: context, - presentationEmail: widget.presentationEmail - ), - Expanded( - child: buildEmailTitle( - context, - widget.presentationEmail, - widget.isSearchEmailRunning, - widget.searchQuery - ) - ), - buildMailboxContain( - context, - widget.isSearchEmailRunning, - widget.presentationEmail - ), - if (widget.presentationEmail.hasStarred) - Padding( - padding: const EdgeInsetsDirectional.only(start: 8), - child: buildIconStar(), - ), - ], + Expanded( + child: buildEmailTitle( + context, + widget.presentationEmail, + widget.isSearchEmailRunning, + widget.searchQuery + ) ), - const SizedBox(height: 8), - Row(children: [ - Expanded( - child: buildEmailPartialContent( - context, - widget.presentationEmail, - widget.isSearchEmailRunning, - widget.searchQuery - ) + buildMailboxContain( + context, + widget.isSearchEmailRunning, + widget.presentationEmail + ), + if (widget.presentationEmail.hasStarred) + Padding( + padding: const EdgeInsetsDirectional.only(start: 8), + child: buildIconStar(), ), - ]), - ]), - ) - ] + ], + ), + const SizedBox(height: 8), + Row(children: [ + Expanded( + child: buildEmailPartialContent( + context, + widget.presentationEmail, + widget.isSearchEmailRunning, + widget.searchQuery + ) + ), + ]), + ]), ) - ), - if (widget.selectAllMode == SelectMode.INACTIVE) - Transform( - transform: Matrix4.translationValues(0.0, 10.0, 0.0), - child: const Divider( - color: AppColor.lineItemListColor, - height: 1 - ) - ), - ], + ] + ) ), tablet: InkWell( onTap: () => widget.emailActionClick?.call( @@ -216,89 +201,79 @@ class _EmailTileBuilderState extends State with BaseEmailItem ) ) ), - Expanded(child: Stack( - alignment: Alignment.bottomCenter, - children: [ - Column(children: [ - Row(children: [ - if (!widget.presentationEmail.hasRead) - Padding( - padding: const EdgeInsetsDirectional.only(end: 5), - child: SvgPicture.asset( - imagePaths.icUnreadStatus, - width: 9, - height: 9, - fit: BoxFit.fill - ) - ), - Expanded( - child: buildInformationSender( - context, - widget.presentationEmail, - widget.mailboxContain, - widget.isSearchEmailRunning, - widget.searchQuery - ) - ), - ValueListenableBuilder( - valueListenable: _hoverNotifier, - builder: (context, value, child) { - if (value) { - return const SizedBox(width: 120); - } else { - return _buildDateTimeForMobileTabletScreen(context); - } - } - ), - ]), - const SizedBox(height: 8), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (widget.presentationEmail.hasCalendarEvent) - buildCalendarEventIcon( - context: context, - presentationEmail: widget.presentationEmail - ), - Expanded( - child: buildEmailTitle( - context, - widget.presentationEmail, - widget.isSearchEmailRunning, - widget.searchQuery - ) - ), - buildMailboxContain( - context, - widget.isSearchEmailRunning, - widget.presentationEmail - ), - if (widget.presentationEmail.hasStarred) - Padding( - padding: const EdgeInsetsDirectional.only(start: 8), - child: buildIconStar(), - ) - ], + Expanded(child: Column(children: [ + Row(children: [ + if (!widget.presentationEmail.hasRead) + Padding( + padding: const EdgeInsetsDirectional.only(end: 5), + child: SvgPicture.asset( + imagePaths.icUnreadStatus, + width: 9, + height: 9, + fit: BoxFit.fill + ) ), - const SizedBox(height: 8), - Row(children: [ - Expanded( - child: buildEmailPartialContent( - context, - widget.presentationEmail, - widget.isSearchEmailRunning, - widget.searchQuery - ) + Expanded( + child: buildInformationSender( + context, + widget.presentationEmail, + widget.mailboxContain, + widget.isSearchEmailRunning, + widget.searchQuery + ) + ), + ValueListenableBuilder( + valueListenable: _hoverNotifier, + builder: (context, value, child) { + if (value) { + return const SizedBox(width: 120); + } else { + return _buildDateTimeForMobileTabletScreen(context); + } + } + ), + ]), + const SizedBox(height: 8), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.presentationEmail.hasCalendarEvent) + buildCalendarEventIcon( + context: context, + presentationEmail: widget.presentationEmail ), - ]), - ]), - if (widget.selectAllMode == SelectMode.INACTIVE) - Transform( - transform: Matrix4.translationValues(0.0, 10.0, 0.0), - child: const Divider(color: AppColor.lineItemListColor, height: 1), + Expanded( + child: buildEmailTitle( + context, + widget.presentationEmail, + widget.isSearchEmailRunning, + widget.searchQuery + ) ), - ], - )) + buildMailboxContain( + context, + widget.isSearchEmailRunning, + widget.presentationEmail + ), + if (widget.presentationEmail.hasStarred) + Padding( + padding: const EdgeInsetsDirectional.only(start: 8), + child: buildIconStar(), + ) + ], + ), + const SizedBox(height: 8), + Row(children: [ + Expanded( + child: buildEmailPartialContent( + context, + widget.presentationEmail, + widget.isSearchEmailRunning, + widget.searchQuery + ) + ), + ]), + ])) ] ), ValueListenableBuilder( @@ -331,102 +306,90 @@ class _EmailTileBuilderState extends State with BaseEmailItem widget.presentationEmail ), onHover: (value) => _hoverNotifier.value = value, - child: Stack( - alignment: Alignment.bottomCenter, - children: [ - Row(children: [ - Container( - padding: const EdgeInsetsDirectional.symmetric(horizontal: 16), - alignment: Alignment.center, - child: !widget.presentationEmail.hasRead - ? SvgPicture.asset( - imagePaths.icUnreadStatus, - width: 9, - height: 9, - fit: BoxFit.fill - ) - : const SizedBox(width: 9) - ), - buildIconWeb( - icon: SvgPicture.asset( - widget.presentationEmail.hasStarred - ? imagePaths.icStar - : imagePaths.icUnStar, - width: 16, - height: 16, + child: Row(children: [ + Container( + padding: const EdgeInsetsDirectional.symmetric(horizontal: 16), + alignment: Alignment.center, + child: !widget.presentationEmail.hasRead + ? SvgPicture.asset( + imagePaths.icUnreadStatus, + width: 9, + height: 9, fit: BoxFit.fill - ), - tooltip: widget.presentationEmail.hasStarred - ? AppLocalizations.of(context).starred - : AppLocalizations.of(context).not_starred, - onTap: () => widget.emailActionClick?.call( - widget.presentationEmail.hasStarred - ? EmailActionType.unMarkAsStarred - : EmailActionType.markAsStarred, - widget.presentationEmail ) - ), - buildIconWeb( - icon: buildIconAnsweredOrForwarded(presentationEmail: widget.presentationEmail), - tooltip: messageToolTipForAnsweredOrForwarded(context, widget.presentationEmail), - iconPadding: const EdgeInsetsDirectional.only(end: 12), - splashRadius: 1 - ), - InkWell( - onTap: () => widget.emailActionClick?.call( - EmailActionType.selection, - widget.presentationEmail - ), - child: ValueListenableBuilder( - valueListenable: _hoverNotifier, - builder: (context, value, child) { - return _buildAvatarIcon( - context: context, - isHovered: value, - iconSize: 32, - textStyle: const TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Colors.white - ) - ); - } - ), - ), - const SizedBox(width: 10), - SizedBox( - width: 160, - child: buildInformationSender( - context, - widget.presentationEmail, - widget.mailboxContain, - widget.isSearchEmailRunning, - widget.searchQuery - ) - ), - const SizedBox(width: 24), - Expanded(child: _buildSubjectAndContent()), - const SizedBox(width: 16), - ValueListenableBuilder( - valueListenable: _hoverNotifier, - builder: (context, value, child) { - if (value) { - return _buildListActionButtonWhenHover(context); - } else { - return _buildDateTimeForDesktopScreen(context); - } - } - ), - ]), - if ( widget.selectAllMode == SelectMode.INACTIVE) - Transform( - transform: Matrix4.translationValues(0.0, 10, 0.0), - child: const Padding( - padding: EdgeInsetsDirectional.only(start: 120), - child: Divider(color: AppColor.lineItemListColor, height: 1) - ), - ) - ]), + : const SizedBox(width: 9) + ), + buildIconWeb( + icon: SvgPicture.asset( + widget.presentationEmail.hasStarred + ? imagePaths.icStar + : imagePaths.icUnStar, + width: 16, + height: 16, + fit: BoxFit.fill + ), + tooltip: widget.presentationEmail.hasStarred + ? AppLocalizations.of(context).starred + : AppLocalizations.of(context).not_starred, + onTap: () => widget.emailActionClick?.call( + widget.presentationEmail.hasStarred + ? EmailActionType.unMarkAsStarred + : EmailActionType.markAsStarred, + widget.presentationEmail + ) + ), + buildIconWeb( + icon: buildIconAnsweredOrForwarded(presentationEmail: widget.presentationEmail), + tooltip: messageToolTipForAnsweredOrForwarded(context, widget.presentationEmail), + iconPadding: const EdgeInsetsDirectional.only(end: 12), + splashRadius: 1 + ), + InkWell( + onTap: () => widget.emailActionClick?.call( + EmailActionType.selection, + widget.presentationEmail + ), + child: ValueListenableBuilder( + valueListenable: _hoverNotifier, + builder: (context, value, child) { + return _buildAvatarIcon( + context: context, + isHovered: value, + iconSize: 32, + textStyle: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Colors.white + ) + ); + } + ), + ), + const SizedBox(width: 10), + SizedBox( + width: 160, + child: buildInformationSender( + context, + widget.presentationEmail, + widget.mailboxContain, + widget.isSearchEmailRunning, + widget.searchQuery + ) + ), + const SizedBox(width: 24), + Expanded(child: _buildSubjectAndContent()), + const SizedBox(width: 16), + ValueListenableBuilder( + valueListenable: _hoverNotifier, + builder: (context, value, child) { + if (value) { + return _buildListActionButtonWhenHover(context); + } else { + return _buildDateTimeForDesktopScreen(context); + } + } + ), + ]), ), ), ); @@ -435,28 +398,28 @@ class _EmailTileBuilderState extends State with BaseEmailItem EdgeInsetsGeometry _getMarginItem(BuildContext context) { if (responsiveUtils.isDesktop(context)) { return const EdgeInsets.only(top: 3); + } else if (responsiveUtils.isTablet(context)) { + return const EdgeInsetsDirectional.only(top: 3, start: 24, end: 24); } else { - return const EdgeInsetsDirectional.only(top: 3, start: 16, end: 16); + return const EdgeInsetsDirectional.only(top: 3, start: 12, end: 12); } } EdgeInsetsGeometry _getPaddingItem(BuildContext context) { if (responsiveUtils.isDesktop(context)) { - return const EdgeInsets.symmetric(vertical: 8); + return const EdgeInsets.symmetric(vertical: 4); } else { - return const EdgeInsetsDirectional.only(bottom: 8, end: 8, top: 8); + return const EdgeInsetsDirectional.only(bottom: 4, end: 8, top: 4); } } BoxDecoration _getDecorationItem() { if ((widget.selectAllMode == SelectMode.ACTIVE && widget.presentationEmail.selectMode == SelectMode.ACTIVE) || widget.isDrag || widget.isShowingEmailContent) { - return BoxDecoration( - borderRadius: BorderRadius.circular(14), + return const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(14)), color: AppColor.colorItemEmailSelectedDesktop); } else { - return BoxDecoration( - borderRadius: BorderRadius.circular(0), - color: Colors.white); + return const BoxDecoration(color: Colors.white); } }