diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart index 814f7f461..0527d9dc3 100644 --- a/core/lib/presentation/extensions/color_extension.dart +++ b/core/lib/presentation/extensions/color_extension.dart @@ -65,7 +65,6 @@ extension AppColor on Color { static const backgroundCountAttachment = Color(0x681C1C1C); static const bgStatusResultSearch = Color(0xFFF5F5F7); static const bgWordSearch = Color(0x3D007AFF); - static const lineItemListColor = Color(0xFFE7E8EC); static const colorNameEmail = Color(0xFF000000); static const colorContentEmail = Color(0xFF6D7885); static const colorTextButton = Color(0xFF007AFF); @@ -108,7 +107,7 @@ extension AppColor on Color { static const colorButtonHeaderThread = Color(0x99EBEDF0); static const colorBorderBodyThread = Color(0x5CB8C1CC); static const colorBgDesktop = Color(0xFFF6F6F6); - static const colorItemEmailSelectedDesktop = Color(0x0F007AFF); + static const colorItemEmailSelectedDesktop = Color(0xFFDFEEFF); static const colorAvatar = Color(0xFFDE5E5E); static const colorFocusButton = Color(0x14818C99); static const colorBorderEmailAddressInvalid = Color(0xFFFF3347); @@ -132,18 +131,12 @@ extension AppColor on Color { static const colorBackgroundSnackBar = Color(0xFF343438); static const colorBackgroundHeaderListRuleFilter = Color(0xFFFAF7F7); static const colorBorderListRuleFilter = Color(0xFFE7E8EC); - static const colorBackgroundHeaderListForwards = Color(0xFFF8F9FA); - static const colorBorderListForwardsFilter = Color(0xFFE7E8EC); static const colorBackgroundFieldConditionRulesFilter = Color(0xFFF2F3F5); - static const colorDividerRuleFilter = Color(0xFFE7E8EC); - static const colorIconTextField = Color(0xFFB8C1CC); static const colorDeletePermanentlyButton = Color(0xffE64646); - static const colorDefaultButton = Color(0xff9AA1AD); static const colorVacationSettingExplanation = Color(0xFF686E76); static const colorBackgroundVacationSettingField = Color(0xFFF2F3F5); static const colorBackgroundNotificationVacationSetting= Color(0xFFFFF5C2); static const colorDivider = Color(0xFFE7E8EC); - static const colorDividerVertical = Color(0xFF99A2AD); static const colorCloseButton = Color(0xFF818C99); static const colorDropShadow = Color(0x0F000000); static const colorBackgroundKeyboard = Color(0xFFD2D5DC); diff --git a/core/lib/presentation/utils/theme_utils.dart b/core/lib/presentation/utils/theme_utils.dart index f02385c6e..7755ba0c0 100644 --- a/core/lib/presentation/utils/theme_utils.dart +++ b/core/lib/presentation/utils/theme_utils.dart @@ -11,6 +11,7 @@ class ThemeUtils { fontFamily: ConstantsUI.fontApp, appBarTheme: _appBarTheme, textTheme: _textTheme, + dividerTheme: _dividerTheme, visualDensity: VisualDensity.adaptivePlatformDensity, scrollbarTheme: ScrollbarThemeData( thickness: MaterialStateProperty.all(2.0), @@ -36,6 +37,13 @@ class ThemeUtils { ); } + static DividerThemeData get _dividerTheme { + return const DividerThemeData( + color: AppColor.colorDivider, + space: 0 + ); + } + static void setSystemLightUIStyle() { SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( systemNavigationBarColor: Colors.black, diff --git a/core/lib/presentation/views/button/icon_button_web.dart b/core/lib/presentation/views/button/icon_button_web.dart index fd053155a..474fb77ce 100644 --- a/core/lib/presentation/views/button/icon_button_web.dart +++ b/core/lib/presentation/views/button/icon_button_web.dart @@ -1,10 +1,9 @@ -import 'package:core/core.dart'; +import 'package:core/presentation/extensions/color_extension.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; typedef IconWebCallback = void Function(); -typedef IconWebHasPositionCallback = void Function(RelativeRect); typedef OnTapIconButtonCallbackAction = void Function(); typedef OnTapDownIconButtonCallbackAction = void Function(TapDownDetails tapDetails); @@ -51,7 +50,7 @@ Widget buildSVGIconButton({ width: iconSize, height: iconSize, fit: BoxFit.fill, - colorFilter: iconColor.asFilter(), + colorFilter: iconColor?.asFilter(), ), ); @@ -76,46 +75,6 @@ Widget buildSVGIconButton({ ); } -Widget buildIconWebHasPosition(BuildContext context, { - required Widget icon, - String? tooltip, - IconWebHasPositionCallback? onTapDown, - IconWebCallback? onTap, -}) { - return Material( - color: Colors.transparent, - shape: const CircleBorder(), - child: InkWell( - onTapDown: (detail) { - onTapDown?.call(detail.getPosition(context)); - }, - onTap: () => onTap?.call(), - borderRadius: const BorderRadius.all(Radius.circular(12)), - child: Tooltip( - message: tooltip ?? '', - child: icon, - ) - ), - ); -} - -Widget buildTextIcon(String text, { - TextStyle? textStyle, - EdgeInsetsGeometry? padding, - IconWebCallback? onTap, -}) { - return Material( - shape: const CircleBorder(), - color: Colors.transparent, - child: InkWell( - child: Padding( - padding: padding ?? const EdgeInsets.all(10), - child: Text(text, style: textStyle ?? const TextStyle(fontWeight: FontWeight.normal, fontSize: 15, color: AppColor.lineItemListColor))), - onTap: () => onTap?.call() - ) - ); -} - Widget buildTextButton(String text, { TextStyle? textStyle, double? width, @@ -188,72 +147,4 @@ Widget buildButtonWrapText(String name, { color: Colors.white)), ), ); -} - -Widget buildIconWithLowerMenu( - Widget icon, - BuildContext context, - List popupMenuItems, - Function(BuildContext context, RelativeRect? position, - List popupMenuItems) - openPopUpMenuAction, -) { - return Builder( - builder: (iconContext) { - final screenSize = MediaQuery.of(context).size; - - return buildIconWeb( - icon: icon, - onTap: () { - // get size and position of the icon - RenderBox box = iconContext.findRenderObject() as RenderBox; - Offset iconTopLeft = box.localToGlobal(Offset.zero); - final iconSize = box.size; - - // calculate the popup position for popup menu action - final popupLeft = iconTopLeft.dx + iconSize.width * 3 / 4; - final popupTop = iconTopLeft.dy + iconSize.height * 4 / 5; - final popupRight = screenSize.width - popupLeft; - final popupBottom = screenSize.height - popupRight; - final position = RelativeRect.fromLTRB( - popupLeft, popupTop, popupRight, popupBottom); - - openPopUpMenuAction(context, position, popupMenuItems); - }); - }, - ); -} - -Widget buildIconWithUpperMenu( - Widget icon, - BuildContext context, - List popupMenuItems, - Function(BuildContext context, RelativeRect? position, - List popupMenuItems) - openPopUpMenuAction, -) { - return Builder( - builder: (iconContext) { - final screenSize = MediaQuery.of(context).size; - - return buildIconWeb( - icon: icon, - onTap: () { - // get size and position of the icon - RenderBox box = iconContext.findRenderObject() as RenderBox; - Offset iconTopLeft = box.localToGlobal(Offset.zero); - final iconSize = box.size; - - // calculate the popup position for popup menu action - final popupLeft = iconTopLeft.dx + iconSize.width * 3 / 4; - final popupTop = iconTopLeft.dy - iconSize.height * 9 / 5; - final popupRight = screenSize.width - popupLeft; - final popupBottom = screenSize.height - popupRight; - final position = RelativeRect.fromLTRB( - popupLeft, popupTop, popupRight, popupBottom); - - openPopUpMenuAction(context, position, popupMenuItems); - }); - }, - ); } \ No newline at end of file diff --git a/core/lib/presentation/views/search/search_bar_view.dart b/core/lib/presentation/views/search/search_bar_view.dart index 3530586bf..1552ce1c6 100644 --- a/core/lib/presentation/views/search/search_bar_view.dart +++ b/core/lib/presentation/views/search/search_bar_view.dart @@ -1,77 +1,68 @@ -import 'package:core/core.dart'; -import 'package:flutter/foundation.dart'; +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/style_utils.dart'; +import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; typedef OnOpenSearchViewAction = Function(); class SearchBarView extends StatelessWidget { final OnOpenSearchViewAction? onOpenSearchViewAction; - final ImagePaths _imagePaths; - final double? heightSearchBar; - final EdgeInsets? padding; - final EdgeInsets? margin; + final ImagePaths imagePaths; + final EdgeInsetsGeometry? margin; final String? hintTextSearch; - final double? maxSizeWidth; - final Widget? rightButton; - final double? radius; - const SearchBarView(this._imagePaths, {Key? key, - this.heightSearchBar, - this.padding, - this.margin, - this.hintTextSearch, - this.maxSizeWidth, - this.rightButton, - this.onOpenSearchViewAction, - this.radius, + const SearchBarView({ + Key? key, + required this.imagePaths, + this.margin, + this.hintTextSearch, + this.onOpenSearchViewAction, }) : super(key: key); @override Widget build(BuildContext context) { - return Container( - key: const Key('search_bar_widget'), - alignment: Alignment.center, - height: heightSearchBar ?? 40, - width: maxSizeWidth ?? double.infinity, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(radius ?? 10), - color: AppColor.colorBgSearchBar), - padding: padding ?? EdgeInsets.zero, - margin: margin ?? EdgeInsets.zero, - child: InkWell( - onTap: onOpenSearchViewAction, - mouseCursor: SystemMouseCursors.text, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const SizedBox(width: 8), - buildIconWeb( - minSize: 40, - iconPadding: EdgeInsets.zero, - icon: SvgPicture.asset( - _imagePaths.icSearchBar, - fit: BoxFit.fill + return Padding( + padding: margin ?? EdgeInsets.zero, + child: InkWell( + onTap: onOpenSearchViewAction, + mouseCursor: SystemMouseCursors.text, + splashColor: Colors.transparent, + borderRadius: const BorderRadius.all(Radius.circular(12)), + child: Container( + alignment: Alignment.center, + height: 40, + width: double.infinity, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(12)), + color: AppColor.colorBgSearchBar + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TMailButtonWidget.fromIcon( + icon: imagePaths.icSearchBar, + backgroundColor: Colors.transparent, + onTapActionCallback: onOpenSearchViewAction ), - onTap: onOpenSearchViewAction - ), - Expanded( - child: Text( + Expanded( + child: Text( hintTextSearch ?? '', maxLines: 1, overflow: CommonTextStyle.defaultTextOverFlow, softWrap: CommonTextStyle.defaultSoftWrap, style: const TextStyle( - fontSize: kIsWeb ? 15 : 17, - color: AppColor.colorHintSearchBar)), - ), - if(rightButton != null) - rightButton! - ] - ), + fontSize: 17, + color: AppColor.colorHintSearchBar + ) + ), + ) + ] + ), ), + ), ); } } \ No newline at end of file diff --git a/lib/features/destination_picker/presentation/destination_picker_view.dart b/lib/features/destination_picker/presentation/destination_picker_view.dart index 1ecac6eca..c0781617f 100644 --- a/lib/features/destination_picker/presentation/destination_picker_view.dart +++ b/lib/features/destination_picker/presentation/destination_picker_view.dart @@ -249,7 +249,8 @@ class DestinationPickerView extends GetWidget if (actions?.canSearch() == true && controller.destinationScreenType.value == DestinationScreenType.destinationPicker) SearchBarView( - controller.imagePaths, + key: const Key('folder_search_bar_view'), + imagePaths: controller.imagePaths, margin: const EdgeInsets.all(16), hintTextSearch: AppLocalizations.of(context).hintSearchFolders, onOpenSearchViewAction: controller.enableSearch diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart index 412190aaa..75e3527db 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart @@ -25,7 +25,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { SizedBox( width: ResponsiveUtils.defaultSizeLeftMenuMobile, child: _buildScaffoldHaveDrawer(body: ThreadView())), - const VerticalDivider(color: AppColor.lineItemListColor, width: 12), + const VerticalDivider(width: 12), const Expanded(child: EmailView()), ], ); @@ -63,7 +63,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { SizedBox( width: ResponsiveUtils.defaultSizeLeftMenuMobile, child: _buildScaffoldHaveDrawer(body: const SendingQueueView())), - const VerticalDivider(color: AppColor.lineItemListColor, width: 12), + const VerticalDivider(width: 12), const Expanded(child: EmailView()), ], ); 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 3c9976fb3..31acba818 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -118,7 +118,9 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { ]), Expanded(child: Column(children: [ const SpamReportBannerWebWidget(), - const QuotasBannerWidget(), + QuotasBannerWidget( + margin: const EdgeInsetsDirectional.only(end: 16, top: 8), + ), _buildVacationNotificationMessage(context), Obx(() { if (controller.isEmptyTrashBannerEnabledOnWeb(context)) { @@ -182,7 +184,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { SizedBox( width: ResponsiveUtils.defaultSizeLeftMenuMobile, child: ThreadView()), - const VerticalDivider(color: AppColor.lineItemListColor, width: 12), + const VerticalDivider(width: 1), const Expanded(child: EmailView()), ], ), @@ -195,7 +197,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { SizedBox( width: ResponsiveUtils.defaultSizeLeftMenuMobile, child: ThreadView()), - const VerticalDivider(color: AppColor.lineItemListColor, width: 12), + const VerticalDivider(width: 1), const Expanded(child: EmailView()), ], ), @@ -276,7 +278,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { ); } }), - const Divider(color: AppColor.colorDivider, height: 1), + const Divider(), Expanded(child: ThreadView()) ]), ), diff --git a/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart b/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart index e3ec79fdf..483e9c582 100644 --- a/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart +++ b/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart @@ -45,9 +45,7 @@ class ListEmailRulesWidget extends GetWidget { fontWeight: FontWeight.w500, color: AppColor.colorTextButtonHeaderThread)), ), - const Divider( - color: AppColor.lineItemListColor, - height: 1), + const Divider(), Obx(() { log('ListEmailRulesWidget::build(): ${controller.listEmailRule}'); return ListView.separated( @@ -63,9 +61,7 @@ class ListEmailRulesWidget extends GetWidget { }, separatorBuilder: (context, index) { if (controller.listEmailRule.isNotEmpty) { - return const Divider( - color: AppColor.lineItemListColor, - height: 1); + return const Divider(); } else { return const SizedBox.shrink(); } diff --git a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart index 6ffecaab2..7de028f2b 100644 --- a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart +++ b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart @@ -112,7 +112,7 @@ class ManageAccountMenuView extends GetWidget { }), const Padding( padding: EdgeInsets.symmetric(vertical: 16), - child: Divider(color: AppColor.lineItemListColor, height: 1)), + child: Divider()), Padding( padding: const EdgeInsetsDirectional.only(start: 20, end: 10), child: Material( diff --git a/lib/features/network_connection/presentation/network_connection_banner_widget.dart b/lib/features/network_connection/presentation/network_connection_banner_widget.dart index 5ab64437f..d2944a812 100644 --- a/lib/features/network_connection/presentation/network_connection_banner_widget.dart +++ b/lib/features/network_connection/presentation/network_connection_banner_widget.dart @@ -1,18 +1,23 @@ import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/cupertino.dart'; +import 'package:get/get.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class NetworkConnectionBannerWidget extends StatelessWidget { - const NetworkConnectionBannerWidget({super.key}); + final _responsiveUtils = Get.find(); + + NetworkConnectionBannerWidget({super.key}); @override Widget build(BuildContext context) { return Container( color: AppColor.colorNetworkConnectionBannerBackground, width: double.infinity, - padding: const EdgeInsetsDirectional.symmetric(vertical: 6, horizontal: 16), + padding: _getPadding(context), + margin: const EdgeInsetsDirectional.only(bottom: 8), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -31,4 +36,12 @@ class NetworkConnectionBannerWidget extends StatelessWidget { ), ); } + + EdgeInsetsGeometry _getPadding(BuildContext context) { + if (_responsiveUtils.isMobile(context) || _responsiveUtils.isTabletLarge(context)) { + return const EdgeInsets.symmetric(horizontal: 12, vertical: 6); + } else { + return const EdgeInsets.symmetric(horizontal: 24, vertical: 6); + } + } } \ 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 7a0e698e6..b5b0a0e14 100644 --- a/lib/features/quotas/presentation/styles/quotas_banner_styles.dart +++ b/lib/features/quotas/presentation/styles/quotas_banner_styles.dart @@ -3,17 +3,13 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:flutter/material.dart'; class QuotasBannerStyles { - static const double verticalPadding = 12; + static const double verticalPadding = 8; static const double horizontalPadding = 16; - static const double topMargin = 8; - static const double startMargin = 16; - static const double endMargin = 16; - static const double bottomMargin = 8; static const double iconPadding = 16; static const double iconSize = 32; static const double titleTextSize = 17; static const double messageTextSize = 15; - static const double space = 8; + static const double space = 4; static const double borderRadius = 12; static const Color messageTextColor = AppColor.colorLabelQuotas; diff --git a/lib/features/quotas/presentation/widget/quotas_banner_widget.dart b/lib/features/quotas/presentation/widget/quotas_banner_widget.dart index fdfda656f..13df0e7c7 100644 --- a/lib/features/quotas/presentation/widget/quotas_banner_widget.dart +++ b/lib/features/quotas/presentation/widget/quotas_banner_widget.dart @@ -1,5 +1,3 @@ -import 'package:core/presentation/utils/responsive_utils.dart'; -import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; @@ -9,26 +7,25 @@ import 'package:tmail_ui_user/features/quotas/presentation/styles/quotas_banner_ class QuotasBannerWidget extends StatelessWidget { - const QuotasBannerWidget({Key? key}) : super(key: key); + final QuotasController _quotasController = Get.find(); + final EdgeInsetsGeometry? margin; + + QuotasBannerWidget({ + Key? key, + this.margin, + }) : super(key: key); @override Widget build(BuildContext context) { - final controller = Get.find(); - final responsiveUtils = Get.find(); return Obx(() { - if (controller.octetsQuota.value != null && controller.octetsQuota.value!.allowedDisplayToQuotaBanner) { - final octetQuota = controller.octetsQuota.value!; + if (_quotasController.octetsQuota.value != null && _quotasController.octetsQuota.value!.allowedDisplayToQuotaBanner) { + final octetQuota = _quotasController.octetsQuota.value!; return Container( decoration: BoxDecoration( color: octetQuota.getQuotaBannerBackgroundColor(), borderRadius: const BorderRadius.all(Radius.circular(QuotasBannerStyles.borderRadius)), ), - margin: EdgeInsetsDirectional.only( - end: QuotasBannerStyles.endMargin, - top: PlatformInfo.isWeb ? QuotasBannerStyles.topMargin : 0, - start: responsiveUtils.isWebDesktop(context) ? 0 : QuotasBannerStyles.startMargin, - bottom: responsiveUtils.isWebDesktop(context) ? 0 : QuotasBannerStyles.bottomMargin - ), + margin: margin, padding: const EdgeInsetsDirectional.symmetric( horizontal: QuotasBannerStyles.horizontalPadding, vertical: QuotasBannerStyles.verticalPadding, @@ -36,7 +33,7 @@ class QuotasBannerWidget extends StatelessWidget { child: Row( children: [ SvgPicture.asset( - octetQuota.getQuotaBannerIcon(controller.imagePaths), + octetQuota.getQuotaBannerIcon(_quotasController.imagePaths), width: QuotasBannerStyles.iconSize, height: QuotasBannerStyles.iconSize, fit: BoxFit.fill, diff --git a/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart b/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart index 98ae46d81..c0de88b04 100644 --- a/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart +++ b/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart @@ -19,6 +19,7 @@ import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rules_filter_input_field_builder.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; + import 'model/rule_filter_condition_type.dart'; class RuleFilterCreatorView extends GetWidget { @@ -457,10 +458,7 @@ class RuleFilterCreatorView extends GetWidget { onChangeAction: (value) => controller.updateRuleName(context, value),)), const Padding( padding: EdgeInsets.symmetric(vertical: 12), - child: Divider( - color: AppColor.colorDividerRuleFilter, - height: 1, - thickness: 0.2), + child: Divider(), ), Obx(() => RuleFilterTitle( conditionCombinerType: controller.conditionCombinerType.value, @@ -505,9 +503,7 @@ class RuleFilterCreatorView extends GetWidget { ), const Padding( padding: EdgeInsets.symmetric(vertical: 12), - child: Divider( - color: AppColor.colorDividerRuleFilter, - height: 1), + child: Divider(), ), Text(AppLocalizations.of(context).actionTitleRulesFilter, overflow: CommonTextStyle.defaultTextOverFlow, diff --git a/lib/features/search/email/presentation/search_email_view.dart b/lib/features/search/email/presentation/search_email_view.dart index 8c3552387..c311767f7 100644 --- a/lib/features/search/email/presentation/search_email_view.dart +++ b/lib/features/search/email/presentation/search_email_view.dart @@ -527,7 +527,7 @@ class SearchEmailView extends GetWidget if (index < listPresentationEmail.length - 1) { return Padding( padding: SearchEmailUtils.getPaddingItemListMobile(context, controller.responsiveUtils), - child: const Divider(color: AppColor.lineItemListColor, height: 1)); + child: const Divider()); } else { return const SizedBox.shrink(); } @@ -581,9 +581,8 @@ class SearchEmailView extends GetWidget child: Divider( color: index < listPresentationEmail.length - 1 && controller.selectionMode.value == SelectMode.INACTIVE - ? AppColor.lineItemListColor - : Colors.white, - height: 1 + ? null + : Colors.white ) ); }, diff --git a/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart b/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart index fe85a1d84..8b5d65837 100644 --- a/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart +++ b/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart @@ -1,4 +1,3 @@ -import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/style_utils.dart'; @@ -144,7 +143,7 @@ class SendingEmailTileWidget extends StatelessWidget { ), Padding( padding: SendingEmailTileStyle.getPaddingDividerListViewByResponsiveSize(constraints.maxWidth), - child: const Divider(color: AppColor.lineItemListColor, height: 1), + child: const Divider(), ) ], ), 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 64edbb8ee..2caebd3a1 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 @@ -13,9 +13,9 @@ class DefaultWebAppBarThreadWidgetStyle { static EdgeInsetsGeometry getPadding(BuildContext context, ResponsiveUtils responsiveUtils) { if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { - return const EdgeInsets.symmetric(horizontal: 16, vertical: 8); + return const EdgeInsets.symmetric(horizontal: 12, vertical: 8); } else { - return const EdgeInsets.symmetric(horizontal: 32, vertical: 8); + return const EdgeInsets.symmetric(horizontal: 24, vertical: 8); } } static const EdgeInsetsGeometry mailboxMenuPadding = EdgeInsets.all(5); 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 eb1156313..32f3c1c84 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 @@ -14,9 +14,9 @@ class SelectionWebAppBarThreadWidgetStyle { static EdgeInsetsGeometry getPadding(BuildContext context, ResponsiveUtils responsiveUtils) { if (responsiveUtils.isMobile(context) || responsiveUtils.isTabletLarge(context)) { - return const EdgeInsets.symmetric(horizontal: 16, vertical: 8); + return const EdgeInsets.symmetric(horizontal: 12, vertical: 8); } else { - return const EdgeInsets.symmetric(horizontal: 32, vertical: 8); + return const EdgeInsets.symmetric(horizontal: 24, vertical: 8); } } static const EdgeInsetsGeometry closeButtonPadding = EdgeInsets.all(3); 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 6aa529a89..51053e95f 100644 --- a/lib/features/thread/presentation/styles/item_email_tile_styles.dart +++ b/lib/features/thread/presentation/styles/item_email_tile_styles.dart @@ -1,6 +1,5 @@ import 'package:core/presentation/utils/responsive_utils.dart'; -import 'package:core/utils/platform_info.dart'; import 'package:flutter/cupertino.dart'; class ItemEmailTileStyles { @@ -18,31 +17,21 @@ class ItemEmailTileStyles { } } - 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); - } + static EdgeInsetsGeometry getMobilePaddingItemList(BuildContext context, ResponsiveUtils responsiveUtils) { + if (responsiveUtils.isPortraitMobile(context) || responsiveUtils.isLandscapeTablet(context)) { + return const EdgeInsets.symmetric(horizontal: 16); } else { - if (responsiveUtils.isPortraitMobile(context) || responsiveUtils.isLandscapeTablet(context)) { - return const EdgeInsets.symmetric(horizontal: 16); - } else { - return const EdgeInsets.symmetric(horizontal: 32); - } + 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 EdgeInsetsDirectional.only(start: 120, top: 2); + }else if (responsiveUtils.isTablet(context)) { return const EdgeInsets.symmetric(horizontal: 24); + } else { + return const EdgeInsets.symmetric(horizontal: 12); } } } \ No newline at end of file diff --git a/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_styles.dart b/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_styles.dart index 50d506e7e..43a32285e 100644 --- a/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_styles.dart +++ b/lib/features/thread/presentation/styles/spam_banner/spam_report_banner_styles.dart @@ -3,8 +3,6 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:flutter/material.dart'; class SpamReportBannerStyles { - static const double horizontalMargin = 16; - static const double verticalMargin = 8; static const double padding = 12; static const double borderRadius = 12; static const double space = 8; diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index 063e39418..9f25cfc38 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -56,8 +56,8 @@ class ThreadView extends GetWidget backgroundColor: Colors.white, body: Portal( child: Row(children: [ - if (supportVerticalDivider(context)) - const VerticalDivider(color: AppColor.colorDividerVertical, width: 1), + if (_supportVerticalDivider(context)) + const VerticalDivider(), Expanded(child: SafeArea( right: controller.responsiveUtils.isLandscapeMobile(context), left: controller.responsiveUtils.isLandscapeMobile(context), @@ -101,20 +101,41 @@ class ThreadView extends GetWidget : null ); }), - if (!PlatformInfo.isWeb) + if (PlatformInfo.isMobile) Obx(() { if (!controller.networkConnectionController.isNetworkConnectionAvailable()) { - return const Padding( - padding: EdgeInsetsDirectional.only(bottom: 8), - child: NetworkConnectionBannerWidget()); + return NetworkConnectionBannerWidget(); } else { return const SizedBox.shrink(); } }), - _buildSearchBarView(context), - const SpamReportBannerWidget(), - const QuotasBannerWidget(), - _buildVacationNotificationMessage(context), + SearchBarView( + key: const Key('email_search_bar_view'), + imagePaths: controller.imagePaths, + margin: _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), + ), + Obx(() { + final vacation = controller.mailboxDashBoardController.vacationResponse.value; + if (vacation?.vacationResponderIsValid == true) { + return VacationNotificationMessageWidget( + margin: _getBannerMargin(context, controller.responsiveUtils), + vacationResponse: vacation!, + actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, + actionEndNow: controller.mailboxDashBoardController.disableVacationResponder + ); + } else { + return const SizedBox.shrink(); + } + }), ], Obx(() { if (controller.mailboxDashBoardController.isEmptyTrashBannerEnabledOnMobile(context)) { @@ -147,7 +168,21 @@ class ThreadView extends GetWidget if (!controller.responsiveUtils.isDesktop(context)) _buildMarkAsMailboxReadLoading(context), Obx(() => ThreadViewLoadingBarWidget(viewState: controller.viewState.value)), - Expanded(child: _buildListEmail(context)), + Expanded( + child: Container( + alignment: Alignment.center, + color: Colors.white, + child: Obx(() { + return Visibility( + visible: controller.openingEmail.isFalse, + child: _buildResultListEmail( + context, + controller.mailboxDashBoardController.emailsInCurrentMailbox + ) + ); + }) + ) + ), Obx(() => ThreadViewBottomLoadingBarWidget(viewState: controller.viewState.value)), _buildListButtonSelectionForMobile(context), ] @@ -181,7 +216,23 @@ class ThreadView extends GetWidget ); } - bool supportVerticalDivider(BuildContext context) { + 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); } else { @@ -191,31 +242,6 @@ class ThreadView extends GetWidget } } - Widget _buildSearchBarView(BuildContext context) { - return Container( - color: Colors.white, - 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)); - } - - Widget _buildVacationNotificationMessage(BuildContext context) { - return Obx(() { - final vacation = controller.mailboxDashBoardController.vacationResponse.value; - if (vacation?.vacationResponderIsValid == true) { - return VacationNotificationMessageWidget( - margin: const EdgeInsets.only(bottom: 12, left: 12, right: 12), - vacationResponse: vacation!, - actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, - actionEndNow: controller.mailboxDashBoardController.disableVacationResponder); - } else { - return const SizedBox.shrink(); - } - }); - } - Widget _buildListButtonSelectionForMobile(BuildContext context) { return Obx(() { if ((PlatformInfo.isMobile || (PlatformInfo.isWeb && controller.isSelectionEnabled() @@ -296,21 +322,6 @@ class ThreadView extends GetWidget .build()).toList(); } - Widget _buildListEmail(BuildContext context) { - return Container( - padding: PlatformInfo.isWeb - ? const EdgeInsets.symmetric(horizontal: 4) - : EdgeInsets.zero, - alignment: Alignment.center, - color: Colors.white, - child: Obx(() { - return Visibility( - visible: controller.openingEmail.isFalse, - child: _buildResultListEmail(context, controller.mailboxDashBoardController.emailsInCurrentMailbox)); - }) - ); - } - Widget _buildResultListEmail(BuildContext context, List listPresentationEmail) { if (controller.mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE) { return listPresentationEmail.isNotEmpty @@ -354,8 +365,8 @@ class ThreadView extends GetWidget separatorBuilder: (context, index) { if (index < listPresentationEmail.length - 1) { return Padding( - padding: ItemEmailTileStyles.getPaddingItemList(context, controller.responsiveUtils), - child: const Divider(color: AppColor.lineItemListColor, height: 1)); + padding: ItemEmailTileStyles.getMobilePaddingItemList(context, controller.responsiveUtils), + child: const Divider()); } else { return const SizedBox.shrink(); } @@ -379,9 +390,8 @@ class ThreadView extends GetWidget child: Divider( color: index < listPresentationEmail.length - 1 && controller.mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE - ? AppColor.lineItemListColor + ? null : Colors.white, - height: 1 ) ); }, diff --git a/lib/features/thread/presentation/widgets/email_tile_builder.dart b/lib/features/thread/presentation/widgets/email_tile_builder.dart index c25a7899b..61023db49 100644 --- a/lib/features/thread/presentation/widgets/email_tile_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_builder.dart @@ -42,7 +42,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { type: MaterialType.transparency, child: ListTile( tileColor: isShowingEmailContent ? AppColor.colorItemEmailSelectedDesktop : null, - contentPadding: padding ?? ItemEmailTileStyles.getPaddingItemList(context, responsiveUtils), + contentPadding: padding ?? ItemEmailTileStyles.getMobilePaddingItemList(context, responsiveUtils), onTap: () => emailActionClick?.call( EmailActionType.preview, presentationEmail), @@ -98,7 +98,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { mainAxisSize: MainAxisSize.min, children: [ Padding( - padding: const EdgeInsetsDirectional.only(top: 6), + padding: const EdgeInsetsDirectional.only(top: 2), child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -121,7 +121,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { ], )), Padding( - padding: const EdgeInsetsDirectional.only(top: 6), + padding: const EdgeInsetsDirectional.only(top: 2), child: Row(children: [ Expanded(child: buildEmailPartialContent( context, 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 68129accc..80844e6d6 100644 --- a/lib/features/thread/presentation/widgets/email_tile_web_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_web_builder.dart @@ -50,14 +50,11 @@ class _EmailTileBuilderState extends State with BaseEmailItem @override Widget build(BuildContext context) { - return Container( - margin: _getMarginItem(context), - padding: widget.padding ?? _getPaddingItem(context), - decoration: _getDecorationItem(), - alignment: Alignment.center, - child: ResponsiveWidget( - responsiveUtils: responsiveUtils, - mobile: InkWell( + return ResponsiveWidget( + responsiveUtils: responsiveUtils, + mobile: Material( + type: MaterialType.transparency, + child: InkWell( onTap: () => widget.emailActionClick?.call( EmailActionType.preview, widget.presentationEmail @@ -66,151 +63,36 @@ class _EmailTileBuilderState extends State with BaseEmailItem 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), - ), - ), - 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( - width: 16, - height: 16, - 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(), - ), - ], + child: Container( + padding: widget.padding ?? _getPaddingItem(context), + decoration: _getDecorationItem(), + alignment: Alignment.center, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GestureDetector( + onTap: () => widget.emailActionClick?.call( + widget.selectAllMode == SelectMode.ACTIVE + ? EmailActionType.selection + : EmailActionType.preview, + widget.presentationEmail ), - const SizedBox(height: 8), - Row(children: [ - Expanded( - child: buildEmailPartialContent( - context, - widget.presentationEmail, - widget.isSearchEmailRunning, - widget.searchQuery - ) - ), - ]), - ]), - ) - ] - ) - ), - tablet: InkWell( - onTap: () => widget.emailActionClick?.call( - EmailActionType.preview, - widget.presentationEmail - ), - onHover: (value) => _hoverNotifier.value = value, - child: Stack( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - InkWell( - onTap: () => widget.emailActionClick?.call( - EmailActionType.selection, - widget.presentationEmail - ), - child: Padding( - padding: const EdgeInsetsDirectional.only(top: 8, end: 12), - child: ValueListenableBuilder( - valueListenable: _hoverNotifier, - builder: (context, value, child) { - return _buildAvatarIcon( - context: context, - isHovered: value - ); - } - ) - ) + child: Padding( + padding: const EdgeInsetsDirectional.only(top: 8, end: 12), + child: _buildAvatarIcon(context: context), ), - Expanded(child: Column(children: [ + ), + 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 + imagePaths.icUnreadStatus, + width: 9, + height: 9, + fit: BoxFit.fill ) ), Expanded( @@ -222,18 +104,31 @@ class _EmailTileBuilderState extends State with BaseEmailItem widget.searchQuery ) ), - ValueListenableBuilder( - valueListenable: _hoverNotifier, - builder: (context, value, child) { - if (value) { - return const SizedBox(width: 120); - } else { - return _buildDateTimeForMobileTabletScreen(context); - } - } + buildIconAnsweredOrForwarded( + width: 16, + height: 16, + 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), + const SizedBox(height: 2), Row( mainAxisSize: MainAxisSize.min, children: [ @@ -259,10 +154,10 @@ class _EmailTileBuilderState extends State with BaseEmailItem Padding( padding: const EdgeInsetsDirectional.only(start: 8), child: buildIconStar(), - ) + ), ], ), - const SizedBox(height: 8), + const SizedBox(height: 2), Row(children: [ Expanded( child: buildEmailPartialContent( @@ -273,153 +168,280 @@ class _EmailTileBuilderState extends State with BaseEmailItem ) ), ]), - ])) - ] - ), - ValueListenableBuilder( - valueListenable: _hoverNotifier, - builder: (context, value, child) { - if (value) { - return Positioned( - top: 0, - right: 0, - child: Transform( - transform: Matrix4.translationValues( - 0.0, - widget.selectAllMode == SelectMode.INACTIVE ? -5.0 : 0.0, - 0.0 - ), - child: _buildListActionButtonWhenHover(context) - ) - ); - } else { - return const SizedBox.shrink(); - } - } - ), - ], - ), + ]), + ) + ] + ), + ) ), - desktop: InkWell( + ), + tablet: Material( + type: MaterialType.transparency, + child: InkWell( onTap: () => widget.emailActionClick?.call( EmailActionType.preview, widget.presentationEmail ), onHover: (value) => _hoverNotifier.value = value, - child: Row(children: [ - Container( - padding: const EdgeInsetsDirectional.symmetric(horizontal: 16), + child: Container( + padding: widget.padding ?? _getPaddingItem(context), + decoration: _getDecorationItem(), + alignment: Alignment.center, + child: Stack( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GestureDetector( + onTap: () => widget.emailActionClick?.call( + EmailActionType.selection, + widget.presentationEmail + ), + child: Padding( + padding: const EdgeInsetsDirectional.only(top: 8, end: 12), + child: ValueListenableBuilder( + valueListenable: _hoverNotifier, + builder: (context, value, child) { + return _buildAvatarIcon( + context: context, + isHovered: value + ); + } + ) + ) + ), + 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 + ) + ), + ValueListenableBuilder( + valueListenable: _hoverNotifier, + builder: (context, value, child) { + if (value) { + return const SizedBox(width: 120); + } else { + return _buildDateTimeForMobileTabletScreen(context); + } + } + ), + ]), + const SizedBox(height: 2), + 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(), + ) + ], + ), + const SizedBox(height: 2), + Row(children: [ + Expanded( + child: buildEmailPartialContent( + context, + widget.presentationEmail, + widget.isSearchEmailRunning, + widget.searchQuery + ) + ), + ]), + ])) + ] + ), + ValueListenableBuilder( + valueListenable: _hoverNotifier, + builder: (context, value, child) { + if (value) { + return Positioned( + top: 0, + right: 0, + child: Transform( + transform: Matrix4.translationValues( + 0.0, + widget.selectAllMode == SelectMode.INACTIVE ? -5.0 : 0.0, + 0.0 + ), + child: _buildListActionButtonWhenHover(context) + ) + ); + } else { + return const SizedBox.shrink(); + } + } + ), + ], + ), + ), + ), + ), + desktop: Padding( + padding: const EdgeInsetsDirectional.only( + top: 2, + start: 3, + end: 3, + ), + child: Material( + type: MaterialType.transparency, + child: InkWell( + onTap: () => widget.emailActionClick?.call( + EmailActionType.preview, + widget.presentationEmail + ), + onHover: (value) => _hoverNotifier.value = value, + borderRadius: const BorderRadius.all(Radius.circular(14)), + child: Container( + padding: widget.padding ?? _getPaddingItem(context), + decoration: _getDecorationItem(), alignment: Alignment.center, - child: !widget.presentationEmail.hasRead - ? SvgPicture.asset( - imagePaths.icUnreadStatus, - width: 9, - height: 9, + 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 + ) + : 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 ) - : const SizedBox(width: 9) + ), + buildIconWeb( + icon: buildIconAnsweredOrForwarded(presentationEmail: widget.presentationEmail), + tooltip: messageToolTipForAnsweredOrForwarded(context, widget.presentationEmail), + iconPadding: const EdgeInsetsDirectional.only(end: 12), + splashRadius: 1 + ), + GestureDetector( + 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); + } + } + ), + ]), ), - 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); - } - } - ), - ]), + ), ), ), ); } - 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: 12, end: 12); - } - } - EdgeInsetsGeometry _getPaddingItem(BuildContext context) { if (responsiveUtils.isDesktop(context)) { return const EdgeInsets.symmetric(vertical: 4); + } else if (responsiveUtils.isTablet(context)) { + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 24); } else { - return const EdgeInsetsDirectional.only(bottom: 4, end: 8, top: 4); + return const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 12); } } - BoxDecoration _getDecorationItem() { - if ((widget.selectAllMode == SelectMode.ACTIVE && widget.presentationEmail.selectMode == SelectMode.ACTIVE) || widget.isDrag || widget.isShowingEmailContent) { + BoxDecoration? _getDecorationItem() { + if (((widget.selectAllMode == SelectMode.ACTIVE && widget.presentationEmail.selectMode == SelectMode.ACTIVE) || widget.isDrag) && + responsiveUtils.isDesktop(context) + ) { return const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(14)), color: AppColor.colorItemEmailSelectedDesktop); + } else if (widget.isShowingEmailContent && responsiveUtils.isTabletLarge(context)) { + return const BoxDecoration(color: AppColor.colorItemEmailSelectedDesktop); } else { - return const BoxDecoration(color: Colors.white); + return null; } } diff --git a/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_widget.dart b/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_widget.dart index 35ddf9ca0..3ae1bc73b 100644 --- a/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_widget.dart +++ b/lib/features/thread/presentation/widgets/spam_banner/spam_report_banner_widget.dart @@ -8,22 +8,24 @@ import 'package:tmail_ui_user/features/thread/presentation/widgets/spam_banner/s import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class SpamReportBannerWidget extends StatelessWidget { - const SpamReportBannerWidget({ Key? key }) : super(key: key); + final EdgeInsetsGeometry? margin; + final SpamReportController spamReportController; + + const SpamReportBannerWidget({ + Key? key, + required this.spamReportController, + this.margin + }) : super(key: key); @override Widget build(BuildContext context){ - final spamReportController = Get.find(); return Obx(() { if (!spamReportController.enableSpamReport || spamReportController.notShowSpamReportBanner) { return const SizedBox.shrink(); } return Container( - margin: const EdgeInsetsDirectional.only( - start: SpamReportBannerStyles.horizontalMargin, - end: SpamReportBannerStyles.horizontalMargin, - bottom: SpamReportBannerStyles.verticalMargin - ), + margin: margin, padding: const EdgeInsetsDirectional.all(SpamReportBannerStyles.padding), decoration: ShapeDecoration( color: SpamReportBannerStyles.backgroundColor,