From d7656a087cdea7ac310ee3fb1c721d30ef032daa Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 9 Aug 2023 19:02:06 +0700 Subject: [PATCH] TF-1983 Convert mailbox item tile builder to StatefulWidget (cherry picked from commit 6aafea0339d556f8c0266d40c0de61ba24166fec) --- .../presentation/destination_picker_view.dart | 48 +-- ...on_picker_search_mailbox_item_builder.dart | 2 +- .../mailbox/presentation/mailbox_view.dart | 59 +-- .../presentation/mailbox_view_web.dart | 49 +-- .../label_mailbox_item_widget_styles.dart | 17 + .../leading_mailbox_item_widget_styles.dart | 21 + .../styles/mailbox_icon_widget_styles.dart | 6 + .../styles/mailbox_item_widget_styles.dart | 7 + .../trailing_mailbox_item_widget_styles.dart | 10 + .../widgets/label_mailbox_item_widget.dart | 84 ++++ .../widgets/leading_mailbox_item_widget.dart | 88 ++++ .../widgets/mailbox_folder_tile_builder.dart | 385 ------------------ .../widgets/mailbox_icon_widget.dart | 62 +++ .../widgets/mailbox_item_widget.dart | 255 ++++++++++++ .../widgets/trailing_mailbox_item_widget.dart | 84 ++++ ...ailbox_visibility_folder_tile_builder.dart | 2 +- .../mailbox_searched_item_builder.dart | 2 +- .../presentation_mailbox_extension.dart | 12 +- 18 files changed, 706 insertions(+), 487 deletions(-) create mode 100644 lib/features/mailbox/presentation/styles/label_mailbox_item_widget_styles.dart create mode 100644 lib/features/mailbox/presentation/styles/leading_mailbox_item_widget_styles.dart create mode 100644 lib/features/mailbox/presentation/styles/mailbox_icon_widget_styles.dart create mode 100644 lib/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart create mode 100644 lib/features/mailbox/presentation/styles/trailing_mailbox_item_widget_styles.dart create mode 100644 lib/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart create mode 100644 lib/features/mailbox/presentation/widgets/leading_mailbox_item_widget.dart delete mode 100644 lib/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart create mode 100644 lib/features/mailbox/presentation/widgets/mailbox_icon_widget.dart create mode 100644 lib/features/mailbox/presentation/widgets/mailbox_item_widget.dart create mode 100644 lib/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart diff --git a/lib/features/destination_picker/presentation/destination_picker_view.dart b/lib/features/destination_picker/presentation/destination_picker_view.dart index 2286cbb5b..fa14bdd23 100644 --- a/lib/features/destination_picker/presentation/destination_picker_view.dart +++ b/lib/features/destination_picker/presentation/destination_picker_view.dart @@ -27,7 +27,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_action import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_item_widget.dart'; import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/create_mailbox_name_input_decoration_builder.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; @@ -359,35 +359,29 @@ class DestinationPickerView extends GetWidget key: const Key('children_tree_mailbox_child'), isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND, paddingChild: const EdgeInsetsDirectional.only(start: 14), - parent: (MailBoxFolderTileBuilder( - context, - _imagePaths, - mailboxNode, - lastNode: lastNode, - mailboxActions: actions, - mailboxIdAlreadySelected: mailboxIdSelected, - mailboxDisplayed: MailboxDisplayed.destinationPicker) - ..addOnClickOpenMailboxNodeAction((node) => _pickMailboxNode(context, node)) - ..addOnClickExpandMailboxNodeAction((mailboxNode) => - controller.toggleMailboxFolder(mailboxNode, controller.destinationListScrollController)) - ).build(), + parent: MailboxItemWidget( + mailboxNode: mailboxNode, + mailboxActions: actions, + mailboxIdAlreadySelected: mailboxIdSelected, + mailboxDisplayed: MailboxDisplayed.destinationPicker, + onOpenMailboxFolderClick: (node) => _pickMailboxNode(context, node), + onExpandFolderActionClick: (mailboxNode) => controller.toggleMailboxFolder(mailboxNode, controller.destinationListScrollController), + ), children: _buildListChildTileWidget( - context, - mailboxNode, - mailboxIdSelected, - actions: actions) + context, + mailboxNode, + mailboxIdSelected, + actions: actions + ) ).build(); } else { - return (MailBoxFolderTileBuilder( - context, - _imagePaths, - mailboxNode, - lastNode: lastNode, - mailboxDisplayed: MailboxDisplayed.destinationPicker, - mailboxIdAlreadySelected: mailboxIdSelected, - mailboxActions: actions) - ..addOnClickOpenMailboxNodeAction((node) => _pickMailboxNode(context, node)) - ).build(); + return MailboxItemWidget( + mailboxNode: mailboxNode, + mailboxDisplayed: MailboxDisplayed.destinationPicker, + mailboxIdAlreadySelected: mailboxIdSelected, + mailboxActions: actions, + onOpenMailboxFolderClick: (node) => _pickMailboxNode(context, node), + ); }}) .toList() ?? []; } diff --git a/lib/features/destination_picker/presentation/widgets/destination_picker_search_mailbox_item_builder.dart b/lib/features/destination_picker/presentation/widgets/destination_picker_search_mailbox_item_builder.dart index eddb3be3d..ce7f9cc81 100644 --- a/lib/features/destination_picker/presentation/widgets/destination_picker_search_mailbox_item_builder.dart +++ b/lib/features/destination_picker/presentation/widgets/destination_picker_search_mailbox_item_builder.dart @@ -119,7 +119,7 @@ class DestinationPickerSearchMailboxItemBuilder extends StatelessWidget { ); } else if (_presentationMailbox.isTeamMailboxes) { return Text( - _presentationMailbox.emailTeamMailBoxes ?? '', + _presentationMailbox.emailTeamMailBoxes, maxLines: 1, softWrap: CommonTextStyle.defaultSoftWrap, overflow: CommonTextStyle.defaultTextOverFlow, diff --git a/lib/features/mailbox/presentation/mailbox_view.dart b/lib/features/mailbox/presentation/mailbox_view.dart index 27197d9c6..701ffc21b 100644 --- a/lib/features/mailbox/presentation/mailbox_view.dart +++ b/lib/features/mailbox/presentation/mailbox_view.dart @@ -9,7 +9,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/base_mailbox_view.da import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/bottom_bar_selection_mailbox_widget.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_item_widget.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/sending_queue_mailbox_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/quotas/presentation/quotas_view.dart'; @@ -212,7 +212,7 @@ class MailboxView extends BaseMailboxView { children: [ Expanded( child: Text( - AppLocalizations.of(context).mailBoxes, + AppLocalizations.of(context).folders, style: const TextStyle( fontSize: 20, color: Colors.black, @@ -338,47 +338,26 @@ class MailboxView extends BaseMailboxView { key: const Key('children_tree_mailbox_child'), isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND, paddingChild: const EdgeInsetsDirectional.only(start: 14), - parent: Obx(() => (MailBoxFolderTileBuilder( - context, - imagePaths, - mailboxNode, - lastNode: lastNode, - allSelectMode: controller.currentSelectMode.value, - mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value) - ..addOnLongPressMailboxNodeAction((mailboxNode) { - openMailboxMenuActionOnMobile( - context, - imagePaths, - mailboxNode.item, - controller - ); - }) - ..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item)) - ..addOnClickExpandMailboxNodeAction((mailboxNode) => - controller.toggleMailboxFolder(mailboxNode, controller.mailboxListScrollController)) - ..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode)) - ).build()), + parent: Obx(() => MailboxItemWidget( + mailboxNode: mailboxNode, + selectionMode: controller.currentSelectMode.value, + mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value, + onLongPressMailboxNodeAction: (mailboxNode) => openMailboxMenuActionOnMobile(context, imagePaths, mailboxNode.item, controller), + onOpenMailboxFolderClick: (mailboxNode) => controller.openMailbox(context, mailboxNode.item), + onExpandFolderActionClick: (mailboxNode) => controller.toggleMailboxFolder(mailboxNode, controller.mailboxListScrollController), + onSelectMailboxFolderClick: (mailboxNode) => controller.selectMailboxNode(mailboxNode), + )), children: _buildListChildTileWidget(context, mailboxNode) ).build(); } else { - return Obx(() => (MailBoxFolderTileBuilder( - context, - imagePaths, - mailboxNode, - lastNode: lastNode, - allSelectMode: controller.currentSelectMode.value, - mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value) - ..addOnLongPressMailboxNodeAction((mailboxNode) { - openMailboxMenuActionOnMobile( - context, - imagePaths, - mailboxNode.item, - controller - ); - }) - ..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item)) - ..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode)) - ).build()); + return Obx(() => MailboxItemWidget( + mailboxNode: mailboxNode, + selectionMode: controller.currentSelectMode.value, + mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value, + onLongPressMailboxNodeAction: (mailboxNode) => openMailboxMenuActionOnMobile(context, imagePaths, mailboxNode.item, controller), + onOpenMailboxFolderClick: (mailboxNode) => controller.openMailbox(context, mailboxNode.item), + onSelectMailboxFolderClick: (mailboxNode) => controller.selectMailboxNode(mailboxNode) + )); } }).toList() ?? []; } diff --git a/lib/features/mailbox/presentation/mailbox_view_web.dart b/lib/features/mailbox/presentation/mailbox_view_web.dart index 32f0ac315..5051a19d7 100644 --- a/lib/features/mailbox/presentation/mailbox_view_web.dart +++ b/lib/features/mailbox/presentation/mailbox_view_web.dart @@ -7,7 +7,7 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/base_mailbox_view.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_item_widget.dart'; import 'package:tmail_ui_user/features/quotas/presentation/quotas_view.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; @@ -262,17 +262,14 @@ class MailboxView extends BaseMailboxView { key: const Key('children_tree_mailbox_child'), isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND, paddingChild: const EdgeInsetsDirectional.only(start: 14), - parent: Obx(() => (MailBoxFolderTileBuilder( - context, - imagePaths, - mailboxNode, - responsiveUtils: responsiveUtils, - lastNode: lastNode, - mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value) - ..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item)) - ..addOnClickExpandMailboxNodeAction((mailboxNode) => - controller.toggleMailboxFolder(mailboxNode, controller.mailboxListScrollController)) - ..addOnClickOpenMenuMailboxNodeAction((position, mailboxNode) { + parent: Obx(() => MailboxItemWidget( + mailboxNode: mailboxNode, + mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value, + onOpenMailboxFolderClick: (mailboxNode) => controller.openMailbox(context, mailboxNode.item), + onExpandFolderActionClick: (mailboxNode) => controller.toggleMailboxFolder(mailboxNode, controller.mailboxListScrollController), + onSelectMailboxFolderClick: controller.selectMailboxNode, + onDragItemAccepted: _handleDragItemAccepted, + onMenuActionClick: (position, mailboxNode) { openMailboxMenuActionOnWeb( context, imagePaths, @@ -281,22 +278,18 @@ class MailboxView extends BaseMailboxView { mailboxNode.item, controller ); - }) - ..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode)) - ..addOnDragEmailToMailboxAccepted(_handleDragItemAccepted) - ).build()), + }, + )), children: _buildListChildTileWidget(context, mailboxNode) ).build(); } else { - return Obx(() => (MailBoxFolderTileBuilder( - context, - imagePaths, - mailboxNode, - responsiveUtils: responsiveUtils, - lastNode: lastNode, - mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value) - ..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item)) - ..addOnClickOpenMenuMailboxNodeAction((position, mailboxNode) { + return Obx(() => MailboxItemWidget( + mailboxNode: mailboxNode, + mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value, + onOpenMailboxFolderClick: (mailboxNode) => controller.openMailbox(context, mailboxNode.item), + onSelectMailboxFolderClick: controller.selectMailboxNode, + onDragItemAccepted: _handleDragItemAccepted, + onMenuActionClick: (position, mailboxNode) { openMailboxMenuActionOnWeb( context, imagePaths, @@ -305,10 +298,8 @@ class MailboxView extends BaseMailboxView { mailboxNode.item, controller ); - }) - ..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode)) - ..addOnDragEmailToMailboxAccepted(_handleDragItemAccepted) - ).build()); + }, + )); } }).toList() ?? []; } diff --git a/lib/features/mailbox/presentation/styles/label_mailbox_item_widget_styles.dart b/lib/features/mailbox/presentation/styles/label_mailbox_item_widget_styles.dart new file mode 100644 index 000000000..6f3741d2c --- /dev/null +++ b/lib/features/mailbox/presentation/styles/label_mailbox_item_widget_styles.dart @@ -0,0 +1,17 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class LabelMailboxItemWidgetStyles { + static const double labelTeamMailboxTextSize = 16; + static const double labelFolderTextSize = 15; + static const double teamMailboxTextSize = 15; + + static const Color labelTeamMailboxTextColor = Colors.black; + static const Color labelFolderTextColor = AppColor.colorNameEmail; + static const Color teamMailboxTextColor = AppColor.colorEmailAddressFull; + + static const FontWeight labelTeamMailboxTextFontWeight = FontWeight.bold; + static const FontWeight labelFolderTextFontWeight = FontWeight.normal; + static const FontWeight teamMailboxTextFontWeight = FontWeight.w400; +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/styles/leading_mailbox_item_widget_styles.dart b/lib/features/mailbox/presentation/styles/leading_mailbox_item_widget_styles.dart new file mode 100644 index 000000000..22563ce17 --- /dev/null +++ b/lib/features/mailbox/presentation/styles/leading_mailbox_item_widget_styles.dart @@ -0,0 +1,21 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/utils/direction_utils.dart'; +import 'package:flutter/cupertino.dart'; + +class LeadingMailboxItemWidgetStyles { + static const double expandIconSize = 15; + static const double expandIconSplashRadius = 12; + static const double emptyBoxSize = 32; + + static const Color displayColor = AppColor.primaryColor; + static const Color normalColor = AppColor.colorIconUnSubscribedMailbox; + + static const EdgeInsetsGeometry expandIconPadding = EdgeInsetsDirectional.only(start: 8); + + static Matrix4 mailboxIconTransform(BuildContext context) => Matrix4.translationValues( + DirectionUtils.isDirectionRTLByLanguage(context) ? 0.0 : -4.0, + 0.0, + 0.0 + ); +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/styles/mailbox_icon_widget_styles.dart b/lib/features/mailbox/presentation/styles/mailbox_icon_widget_styles.dart new file mode 100644 index 000000000..58592e1ab --- /dev/null +++ b/lib/features/mailbox/presentation/styles/mailbox_icon_widget_styles.dart @@ -0,0 +1,6 @@ + +import 'package:core/utils/platform_info.dart'; + +class MailboxIconWidgetStyles { + static const double iconSize = PlatformInfo.isWeb ? 24 : 20; +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart b/lib/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart new file mode 100644 index 000000000..ca551b0bf --- /dev/null +++ b/lib/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart @@ -0,0 +1,7 @@ + +class MailboxItemWidgetStyles { + static const double selectionIconSize = 20; + static const double space = 4; + static const double padding = 8; + static const double borderRadius = 8; +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/styles/trailing_mailbox_item_widget_styles.dart b/lib/features/mailbox/presentation/styles/trailing_mailbox_item_widget_styles.dart new file mode 100644 index 000000000..7059d89e7 --- /dev/null +++ b/lib/features/mailbox/presentation/styles/trailing_mailbox_item_widget_styles.dart @@ -0,0 +1,10 @@ + +import 'package:core/utils/platform_info.dart'; +import 'package:flutter/cupertino.dart'; + +class TrailingMailboxItemWidgetStyles { + static const double menuIconSize = 20; + + static const EdgeInsetsGeometry countEmailsPadding = EdgeInsetsDirectional.only(start: PlatformInfo.isWeb ? 10 : 12); + static const EdgeInsetsGeometry menuIconPadding = EdgeInsetsDirectional.only(start: 8); +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart b/lib/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart new file mode 100644 index 000000000..381e0ba24 --- /dev/null +++ b/lib/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart @@ -0,0 +1,84 @@ + +import 'package:core/presentation/views/text/text_overflow_builder.dart'; +import 'package:flutter/material.dart'; +import 'package:model/extensions/presentation_mailbox_extension.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/styles/label_mailbox_item_widget_styles.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_method_action_define.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart'; + +class LabelMailboxItemWidget extends StatelessWidget { + + final MailboxNode mailboxNode; + final bool showTrailing; + final bool isItemHovered; + final OnClickOpenMenuMailboxNodeAction? onMenuActionClick; + + const LabelMailboxItemWidget({ + super.key, + required this.mailboxNode, + this.showTrailing = true, + this.isItemHovered = false, + this.onMenuActionClick, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (showTrailing) + Row( + children: [ + Expanded( + child: TextOverflowBuilder( + mailboxNode.item.getDisplayName(context), + style: TextStyle( + fontSize: _mailboxNameTextSize, + color: _mailboxNameTextColor, + fontWeight: _mailboxNameTextFontWeight + ), + ), + ), + TrailingMailboxItemWidget( + mailboxNode: mailboxNode, + isItemHovered: isItemHovered, + onMenuActionClick: onMenuActionClick + ) + ], + ) + else + TextOverflowBuilder( + mailboxNode.item.getDisplayName(context), + style: TextStyle( + fontSize: _mailboxNameTextSize, + color: _mailboxNameTextColor, + fontWeight: _mailboxNameTextFontWeight + ), + ), + if (mailboxNode.item.isTeamMailboxes) + TextOverflowBuilder( + mailboxNode.item.emailTeamMailBoxes, + style: const TextStyle( + fontSize: LabelMailboxItemWidgetStyles.teamMailboxTextSize, + color: LabelMailboxItemWidgetStyles.teamMailboxTextColor, + fontWeight: LabelMailboxItemWidgetStyles.teamMailboxTextFontWeight + ), + ) + ], + ); + } + + double get _mailboxNameTextSize => mailboxNode.item.isTeamMailboxes + ? LabelMailboxItemWidgetStyles.labelTeamMailboxTextSize + : LabelMailboxItemWidgetStyles.labelFolderTextSize; + + Color get _mailboxNameTextColor => mailboxNode.item.isTeamMailboxes + ? LabelMailboxItemWidgetStyles.labelTeamMailboxTextColor + : LabelMailboxItemWidgetStyles.labelFolderTextColor; + + FontWeight get _mailboxNameTextFontWeight => mailboxNode.item.isTeamMailboxes + ? LabelMailboxItemWidgetStyles.labelTeamMailboxTextFontWeight + : LabelMailboxItemWidgetStyles.labelFolderTextFontWeight; +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/widgets/leading_mailbox_item_widget.dart b/lib/features/mailbox/presentation/widgets/leading_mailbox_item_widget.dart new file mode 100644 index 000000000..98faeb38d --- /dev/null +++ b/lib/features/mailbox/presentation/widgets/leading_mailbox_item_widget.dart @@ -0,0 +1,88 @@ + +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:core/utils/direction_utils.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:model/extensions/presentation_mailbox_extension.dart'; +import 'package:model/mailbox/expand_mode.dart'; +import 'package:model/mailbox/select_mode.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/styles/leading_mailbox_item_widget_styles.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_method_action_define.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_icon_widget.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class LeadingMailboxItemWidget extends StatelessWidget { + + final MailboxNode mailboxNode; + final SelectMode selectionMode; + final OnSelectMailboxNodeAction? onSelectMailboxFolderClick; + final OnClickExpandMailboxNodeAction? onExpandFolderActionClick; + + const LeadingMailboxItemWidget({ + super.key, + required this.mailboxNode, + this.selectionMode = SelectMode.INACTIVE, + this.onExpandFolderActionClick, + this.onSelectMailboxFolderClick, + }); + + @override + Widget build(BuildContext context) { + final imagePaths = Get.find(); + + return Row(children: [ + if (mailboxNode.hasChildren()) + Padding( + padding: LeadingMailboxItemWidgetStyles.expandIconPadding, + child: buildIconWeb( + icon: SvgPicture.asset( + _getExpandIcon(context, imagePaths), + colorFilter: _expandIconColor.asFilter(), + fit: BoxFit.fill, + ), + splashRadius: LeadingMailboxItemWidgetStyles.expandIconSplashRadius, + iconPadding: EdgeInsets.zero, + minSize: LeadingMailboxItemWidgetStyles.expandIconSize, + tooltip: _getExpandTooltipMessage(context), + onTap: () => onExpandFolderActionClick?.call(mailboxNode) + ), + ) + else + const SizedBox(width: LeadingMailboxItemWidgetStyles.emptyBoxSize), + Transform( + transform: LeadingMailboxItemWidgetStyles.mailboxIconTransform(context), + child: MailboxIconWidget( + mailboxNode: mailboxNode, + selectionMode: selectionMode, + onSelectMailboxFolderClick: onSelectMailboxFolderClick + ) + ), + ]); + } + + String _getExpandIcon(BuildContext context, ImagePaths imagePaths) { + if (mailboxNode.expandMode == ExpandMode.EXPAND) { + return imagePaths.icArrowBottom; + } else { + return DirectionUtils.isDirectionRTLByLanguage(context) + ? imagePaths.icArrowLeft + : imagePaths.icArrowRight; + } + } + + Color get _expandIconColor { + return mailboxNode.item.allowedToDisplay + ? LeadingMailboxItemWidgetStyles.displayColor + : LeadingMailboxItemWidgetStyles.normalColor; + } + + String _getExpandTooltipMessage(BuildContext context) { + return mailboxNode.expandMode == ExpandMode.EXPAND + ? AppLocalizations.of(context).collapse + : AppLocalizations.of(context).expand; + } +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart b/lib/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart deleted file mode 100644 index 77d02a3fc..000000000 --- a/lib/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart +++ /dev/null @@ -1,385 +0,0 @@ -import 'package:core/presentation/extensions/color_extension.dart'; -import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/presentation/utils/responsive_utils.dart'; -import 'package:core/presentation/views/button/icon_button_web.dart'; -import 'package:core/presentation/views/text/text_overflow_builder.dart'; -import 'package:core/utils/direction_utils.dart'; -import 'package:core/utils/platform_info.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; -import 'package:model/email/presentation_email.dart'; -import 'package:model/extensions/presentation_mailbox_extension.dart'; -import 'package:model/mailbox/expand_mode.dart'; -import 'package:model/mailbox/presentation_mailbox.dart'; -import 'package:model/mailbox/select_mode.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_method_action_define.dart'; -import 'package:tmail_ui_user/features/mailbox/presentation/widgets/count_of_emails_widget.dart'; -import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; - -class MailBoxFolderTileBuilder { - - final MailboxNode _mailboxNode; - final BuildContext _context; - final ImagePaths _imagePaths; - final ResponsiveUtils? responsiveUtils; - final SelectMode allSelectMode; - final MailboxDisplayed mailboxDisplayed; - final MailboxNode? lastNode; - final PresentationMailbox? mailboxNodeSelected; - final MailboxActions? mailboxActions; - final MailboxId? mailboxIdAlreadySelected; - - OnClickExpandMailboxNodeAction? _onExpandFolderActionClick; - OnClickOpenMailboxNodeAction? _onOpenMailboxFolderClick; - OnSelectMailboxNodeAction? _onSelectMailboxFolderClick; - OnClickOpenMenuMailboxNodeAction? _onMenuActionClick; - OnDragEmailToMailboxAccepted? _onDragItemAccepted; - OnLongPressMailboxNodeAction? _onLongPressMailboxNodeAction; - - bool isHoverItem = false; - - MailBoxFolderTileBuilder( - this._context, - this._imagePaths, - this._mailboxNode, - { - this.allSelectMode = SelectMode.INACTIVE, - this.mailboxDisplayed = MailboxDisplayed.mailbox, - this.lastNode, - this.mailboxNodeSelected, - this.mailboxActions, - this.responsiveUtils, - this.mailboxIdAlreadySelected - } - ); - - void addOnClickExpandMailboxNodeAction(OnClickExpandMailboxNodeAction onExpandFolderActionClick) { - _onExpandFolderActionClick = onExpandFolderActionClick; - } - - void addOnClickOpenMailboxNodeAction(OnClickOpenMailboxNodeAction onOpenMailboxFolderClick) { - _onOpenMailboxFolderClick = onOpenMailboxFolderClick; - } - - void addOnSelectMailboxNodeAction(OnSelectMailboxNodeAction onSelectMailboxFolderClick) { - _onSelectMailboxFolderClick = onSelectMailboxFolderClick; - } - - void addOnClickOpenMenuMailboxNodeAction(OnClickOpenMenuMailboxNodeAction onMenuActionClick) { - _onMenuActionClick = onMenuActionClick; - } - - void addOnDragEmailToMailboxAccepted(OnDragEmailToMailboxAccepted onDragItemAccepted) { - _onDragItemAccepted = onDragItemAccepted; - } - - void addOnLongPressMailboxNodeAction(OnLongPressMailboxNodeAction onLongPressMailboxNodeAction) { - _onLongPressMailboxNodeAction = onLongPressMailboxNodeAction; - } - - Widget build() { - if (responsiveUtils?.isWebDesktop(_context) == true && mailboxDisplayed == MailboxDisplayed.mailbox) { - return DragTarget>( - builder: (_, __, ___) => _buildMailboxItem(_context), - onAccept: (emails) => _onDragItemAccepted?.call(emails, _mailboxNode.item), - ); - } else { - return _buildMailboxItem(_context); - } - } - - Widget _buildMailboxItem(BuildContext context) { - if (mailboxDisplayed == MailboxDisplayed.mailbox) { - if (PlatformInfo.isWeb) { - return StatefulBuilder( - builder: (context, setState) { - return InkWell( - onTap: () => _onOpenMailboxFolderClick?.call(_mailboxNode), - onHover: (value) => setState(() => isHoverItem = value), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - color: backgroundColorItem), - padding: const EdgeInsets.all(8), - child: Row( - children: [ - _buildLeadingMailboxItem(context), - const SizedBox(width: 4), - Expanded(child: _buildTitleFolderItem(context)), - ]) - ), - ); - } - ); - } else { - return Material( - color: Colors.transparent, - child: InkWell( - onLongPress: () => _onLongPressMailboxNodeAction?.call(_mailboxNode), - onTap: () => allSelectMode == SelectMode.ACTIVE - ? _onSelectMailboxFolderClick?.call(_mailboxNode) - : _onOpenMailboxFolderClick?.call(_mailboxNode), - borderRadius: const BorderRadius.all(Radius.circular(8)), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - color: backgroundColorItem), - padding: const EdgeInsets.all(8), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - children: [ - _buildLeadingMailboxItem(context), - const SizedBox(width: 8), - Expanded(child: _buildTitleFolderItem(context)), - _buildSelectedIcon(), - ]), - ] - ), - ), - ), - ); - } - } else { - return AbsorbPointer( - absorbing: !_mailboxNode.isActivated, - child: Opacity( - opacity: _mailboxNode.isActivated ? 1.0 : 0.3, - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: () => !_isSelectActionNoValid - ? _onOpenMailboxFolderClick?.call(_mailboxNode) - : null, - customBorder: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8))), - hoverColor: AppColor.colorMailboxHovered, - child: Container( - padding: const EdgeInsets.symmetric(vertical: 8), - color: _mailboxNode.isSelected - ? AppColor.colorItemSelected - : Colors.transparent, - child: Row(children: [ - _buildLeadingMailboxItem(context), - const SizedBox(width: 8), - Expanded(child: _buildTitleFolderItem(context, showTrailingItem: false)), - _buildSelectedIcon(), - const SizedBox(width: 8), - ]) - ), - ), - ), - ), - ); - } - } - - Widget _buildLeadingMailboxItem(BuildContext context) { - return Row(children: [ - if (_mailboxNode.hasChildren()) - Row(children: [ - const SizedBox(width: 8), - buildIconWeb( - icon: SvgPicture.asset( - _mailboxNode.expandMode == ExpandMode.EXPAND - ? _imagePaths.icArrowBottom - : DirectionUtils.isDirectionRTLByLanguage(context) ? _imagePaths.icArrowLeft : _imagePaths.icArrowRight, - colorFilter: _mailboxNode.item.allowedToDisplay - ? AppColor.primaryColor.asFilter() - : AppColor.colorIconUnSubscribedMailbox.asFilter(), - fit: BoxFit.fill, - ), - splashRadius: 12, - iconPadding: EdgeInsets.zero, - minSize: 15, - tooltip: _mailboxNode.expandMode == ExpandMode.EXPAND - ? AppLocalizations.of(_context).collapse - : AppLocalizations.of(_context).expand, - onTap: () => _onExpandFolderActionClick?.call(_mailboxNode) - ), - ]) - else - const SizedBox(width: 32), - Transform( - transform: Matrix4.translationValues( - DirectionUtils.isDirectionRTLByLanguage(context) ? 0.0 : -4.0, - 0.0, - 0.0 - ), - child: _buildLeadingIcon() - ), - ]); - } - - Widget _buildTrailingItemForMailboxView(BuildContext context) { - if (PlatformInfo.isWeb) { - if (isHoverItem) { - return _buildMenuIcon(context); - } else if (_mailboxNode.item.countUnreadEmails > 0 && _mailboxNode.item.allowedToDisplayCountOfUnreadEmails) { - return Padding( - padding: const EdgeInsetsDirectional.only(start: 10), - child: CountOfEmailsWidget(value: _mailboxNode.item.countUnReadEmailsAsString), - ); - } else if (_mailboxNode.item.countTotalEmails > 0 && _mailboxNode.item.allowedToDisplayCountOfTotalEmails) { - return Padding( - padding: const EdgeInsetsDirectional.only(start: 10), - child: CountOfEmailsWidget(value: _mailboxNode.item.countTotalEmailsAsString), - ); - } else { - return const SizedBox(); - } - } else { - if (_mailboxNode.item.countUnreadEmails > 0 && _mailboxNode.item.allowedToDisplayCountOfUnreadEmails) { - return Padding( - padding: const EdgeInsetsDirectional.only(start: 12), - child: CountOfEmailsWidget(value: _mailboxNode.item.countUnReadEmailsAsString), - ); - } else if (_mailboxNode.item.countTotalEmails > 0 && _mailboxNode.item.allowedToDisplayCountOfTotalEmails) { - return Padding( - padding: const EdgeInsetsDirectional.only(start: 12), - child: CountOfEmailsWidget(value: _mailboxNode.item.countTotalEmailsAsString), - ); - } else { - return const SizedBox(); - } - } - } - - Widget _buildLeadingIcon() { - if (PlatformInfo.isWeb) { - return _buildLeadingIconTeamMailboxes(); - } else { - return allSelectMode == SelectMode.ACTIVE - ? _buildSelectModeIcon() - : _buildLeadingIconTeamMailboxes(); - } - } - - Widget _buildLeadingIconTeamMailboxes() { - if (!_mailboxNode.item.isPersonal) { - return _buildLeadingIconForChildOfTeamMailboxes(); - } else { - return _buildMailboxIcon(); - } - } - - Widget _buildLeadingIconForChildOfTeamMailboxes() { - if (_mailboxNode.item.hasParentId()) { - return _buildMailboxIcon(); - } else { - return const SizedBox(); - } - } - - Widget _buildTitleFolderItem(BuildContext context, {bool showTrailingItem = true}) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Expanded( - child: TextOverflowBuilder( - _mailboxNode.item.getDisplayName(context), - style: TextStyle( - fontSize: _mailboxNode.item.isTeamMailboxes ? 16 : 15, - color: _mailboxNode.item.isTeamMailboxes ? Colors.black : AppColor.colorNameEmail, - fontWeight: _mailboxNode.item.isTeamMailboxes ? FontWeight.bold : FontWeight.normal), - ), - ), - if (showTrailingItem) - _buildTrailingItemForMailboxView(context) - ], - ), - if(_mailboxNode.item.isTeamMailboxes) - TextOverflowBuilder( - (_mailboxNode.item.emailTeamMailBoxes ?? ''), - style: const TextStyle( - fontSize: 13, - color: AppColor.colorEmailAddressFull, - fontWeight: FontWeight.w400), - ) - ], - ); - } - - Widget _buildMailboxIcon() { - return SvgPicture.asset(_mailboxNode.item.getMailboxIcon(_imagePaths), - width: PlatformInfo.isWeb ? 20 : 24, - height: PlatformInfo.isWeb ? 20 : 24, - fit: BoxFit.fill); - } - - Widget _buildMenuIcon(BuildContext context) { - return Padding( - padding: const EdgeInsetsDirectional.only(start: 8), - child: InkWell( - onTapDown: (detail) { - final screenSize = MediaQuery.of(_context).size; - final offset = detail.globalPosition; - final position = RelativeRect.fromLTRB( - offset.dx, - offset.dy, - screenSize.width - offset.dx, - screenSize.height - offset.dy, - ); - _onMenuActionClick?.call(position, _mailboxNode); - }, - onTap: () => {}, - child: SvgPicture.asset(_imagePaths.icComposerMenu, - width: 20, - height: 20, - fit: BoxFit.fill)), - ); - } - - Widget _buildSelectModeIcon() { - return InkWell( - onTap: () => _onSelectMailboxFolderClick?.call(_mailboxNode), - child: SvgPicture.asset( - _mailboxNode.selectMode == SelectMode.ACTIVE - ? _imagePaths.icSelected - : _imagePaths.icUnSelected, - width: PlatformInfo.isWeb ? 20 : 24, - height: PlatformInfo.isWeb ? 20 : 24, - fit: BoxFit.fill) - ); - } - - Color get backgroundColorItem { - if (mailboxDisplayed == MailboxDisplayed.destinationPicker) { - return Colors.white; - } else { - if (mailboxNodeSelected?.id == _mailboxNode.item.id || isHoverItem) { - return AppColor.colorBgMailboxSelected; - } else { - return Colors.transparent; - } - } - } - - Widget _buildSelectedIcon() { - if (_isSelectActionNoValid) { - return SvgPicture.asset( - _imagePaths.icSelectedSB, - width: 20, - height: 20, - fit: BoxFit.fill); - } else { - return const SizedBox.shrink(); - } - } - - bool get _isSelectActionNoValid => _mailboxNode.item.id == mailboxIdAlreadySelected && - mailboxDisplayed == MailboxDisplayed.destinationPicker && - ( - mailboxActions == MailboxActions.select || - mailboxActions == MailboxActions.create || - mailboxActions == MailboxActions.moveEmail - ); -} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/widgets/mailbox_icon_widget.dart b/lib/features/mailbox/presentation/widgets/mailbox_icon_widget.dart new file mode 100644 index 000000000..bd3abe274 --- /dev/null +++ b/lib/features/mailbox/presentation/widgets/mailbox_icon_widget.dart @@ -0,0 +1,62 @@ + +import 'package:core/presentation/resources/image_paths.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'; +import 'package:model/extensions/presentation_mailbox_extension.dart'; +import 'package:model/mailbox/select_mode.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/styles/mailbox_icon_widget_styles.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_method_action_define.dart'; + +class MailboxIconWidget extends StatelessWidget { + + final MailboxNode mailboxNode; + final SelectMode selectionMode; + final OnSelectMailboxNodeAction? onSelectMailboxFolderClick; + + const MailboxIconWidget({ + super.key, + required this.mailboxNode, + this.selectionMode = SelectMode.INACTIVE, + this.onSelectMailboxFolderClick, + }); + + @override + Widget build(BuildContext context) { + final imagePaths = Get.find(); + + if (_isSelectionActivatedOnMobile) { + return InkWell( + onTap: () => onSelectMailboxFolderClick?.call(mailboxNode), + child: SvgPicture.asset( + _getSelectionIcon(imagePaths), + width: MailboxIconWidgetStyles.iconSize, + height: MailboxIconWidgetStyles.iconSize, + fit: BoxFit.fill + ) + ); + } else { + if (mailboxNode.item.isPersonal || mailboxNode.item.hasParentId()) { + return SvgPicture.asset( + mailboxNode.item.getMailboxIcon(imagePaths), + width: MailboxIconWidgetStyles.iconSize, + height: MailboxIconWidgetStyles.iconSize, + fit: BoxFit.fill + ); + } else { + return const SizedBox(); + } + } + } + + bool get _isSelectionActivatedOnMobile => PlatformInfo.isMobile && selectionMode == SelectMode.ACTIVE; + + String _getSelectionIcon(ImagePaths imagePaths) { + return mailboxNode.selectMode == SelectMode.ACTIVE + ? imagePaths.icSelected + : imagePaths.icUnSelected; + } +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/widgets/mailbox_item_widget.dart b/lib/features/mailbox/presentation/widgets/mailbox_item_widget.dart new file mode 100644 index 000000000..d00fd8393 --- /dev/null +++ b/lib/features/mailbox/presentation/widgets/mailbox_item_widget.dart @@ -0,0 +1,255 @@ +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/utils/platform_info.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/email/presentation_email.dart'; +import 'package:model/mailbox/presentation_mailbox.dart'; +import 'package:model/mailbox/select_mode.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_method_action_define.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/leading_mailbox_item_widget.dart'; + +class MailboxItemWidget extends StatefulWidget { + + final MailboxNode mailboxNode; + final SelectMode selectionMode; + final MailboxDisplayed mailboxDisplayed; + final PresentationMailbox? mailboxNodeSelected; + final MailboxActions? mailboxActions; + final MailboxId? mailboxIdAlreadySelected; + + final OnClickExpandMailboxNodeAction? onExpandFolderActionClick; + final OnClickOpenMailboxNodeAction? onOpenMailboxFolderClick; + final OnSelectMailboxNodeAction? onSelectMailboxFolderClick; + final OnClickOpenMenuMailboxNodeAction? onMenuActionClick; + final OnDragEmailToMailboxAccepted? onDragItemAccepted; + final OnLongPressMailboxNodeAction? onLongPressMailboxNodeAction; + + const MailboxItemWidget({ + super.key, + required this.mailboxNode, + this.selectionMode = SelectMode.INACTIVE, + this.mailboxDisplayed = MailboxDisplayed.mailbox, + this.mailboxNodeSelected, + this.mailboxActions, + this.mailboxIdAlreadySelected, + this.onExpandFolderActionClick, + this.onOpenMailboxFolderClick, + this.onSelectMailboxFolderClick, + this.onMenuActionClick, + this.onDragItemAccepted, + this.onLongPressMailboxNodeAction, + }); + + @override + State createState() => _MailboxItemWidgetState(); +} + +class _MailboxItemWidgetState extends State { + + final _responsiveUtils = Get.find(); + final _imagePaths = Get.find(); + + bool _isItemHovered = false; + + @override + Widget build(BuildContext context) { + if (_responsiveUtils.isWebDesktop(context) && widget.mailboxDisplayed == MailboxDisplayed.mailbox) { + return DragTarget>( + builder: (context, candidateEmails, rejectedEmails) { + return InkWell( + onTap: () => widget.onOpenMailboxFolderClick?.call(widget.mailboxNode), + onHover: (value) => setState(() => _isItemHovered = value), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(MailboxItemWidgetStyles.borderRadius)), + color: backgroundColorItem + ), + padding: const EdgeInsets.all(MailboxItemWidgetStyles.padding), + child: Row( + children: [ + LeadingMailboxItemWidget( + mailboxNode: widget.mailboxNode, + selectionMode: widget.selectionMode, + onSelectMailboxFolderClick: widget.onSelectMailboxFolderClick, + onExpandFolderActionClick: widget.onExpandFolderActionClick, + ), + const SizedBox(width: MailboxItemWidgetStyles.space), + Expanded( + child: LabelMailboxItemWidget( + mailboxNode: widget.mailboxNode, + isItemHovered: _isItemHovered, + onMenuActionClick: widget.onMenuActionClick + ) + ), + ] + ) + ), + ); + }, + onAccept: (emails) => widget.onDragItemAccepted?.call(emails, widget.mailboxNode.item), + ); + } else { + if (widget.mailboxDisplayed == MailboxDisplayed.mailbox) { + if (PlatformInfo.isWeb) { + return InkWell( + onTap: () => widget.onOpenMailboxFolderClick?.call(widget.mailboxNode), + onHover: (value) => setState(() => _isItemHovered = value), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(MailboxItemWidgetStyles.borderRadius)), + color: backgroundColorItem + ), + padding: const EdgeInsets.all(MailboxItemWidgetStyles.padding), + child: Row( + children: [ + LeadingMailboxItemWidget( + mailboxNode: widget.mailboxNode, + selectionMode: widget.selectionMode, + onSelectMailboxFolderClick: widget.onSelectMailboxFolderClick, + onExpandFolderActionClick: widget.onExpandFolderActionClick, + ), + const SizedBox(width: MailboxItemWidgetStyles.space), + Expanded( + child: LabelMailboxItemWidget( + mailboxNode: widget.mailboxNode, + isItemHovered: _isItemHovered, + onMenuActionClick: widget.onMenuActionClick + ) + ), + ] + ) + ), + ); + } else { + return Material( + color: Colors.transparent, + child: InkWell( + onLongPress: () => widget.onLongPressMailboxNodeAction?.call(widget.mailboxNode), + onTap: () => widget.selectionMode == SelectMode.ACTIVE + ? widget.onSelectMailboxFolderClick?.call(widget.mailboxNode) + : widget.onOpenMailboxFolderClick?.call(widget.mailboxNode), + borderRadius: const BorderRadius.all(Radius.circular(MailboxItemWidgetStyles.borderRadius)), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(MailboxItemWidgetStyles.borderRadius)), + color: backgroundColorItem + ), + padding: const EdgeInsets.all(MailboxItemWidgetStyles.padding), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + children: [ + LeadingMailboxItemWidget( + mailboxNode: widget.mailboxNode, + selectionMode: widget.selectionMode, + onSelectMailboxFolderClick: widget.onSelectMailboxFolderClick, + onExpandFolderActionClick: widget.onExpandFolderActionClick, + ), + const SizedBox(width: MailboxItemWidgetStyles.padding), + Expanded( + child: LabelMailboxItemWidget( + mailboxNode: widget.mailboxNode, + isItemHovered: _isItemHovered, + onMenuActionClick: widget.onMenuActionClick + ) + ), + if (_isSelectActionNoValid) + SvgPicture.asset( + _imagePaths.icSelectedSB, + width: MailboxItemWidgetStyles.selectionIconSize, + height: MailboxItemWidgetStyles.selectionIconSize, + fit: BoxFit.fill + ) + ] + ), + ] + ), + ), + ), + ); + } + } else { + return AbsorbPointer( + absorbing: !widget.mailboxNode.isActivated, + child: Opacity( + opacity: widget.mailboxNode.isActivated ? 1.0 : 0.3, + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: () => !_isSelectActionNoValid + ? widget.onOpenMailboxFolderClick?.call(widget.mailboxNode) + : null, + customBorder: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8))), + hoverColor: AppColor.colorMailboxHovered, + child: Container( + padding: const EdgeInsets.symmetric(vertical: MailboxItemWidgetStyles.padding), + color: widget.mailboxNode.isSelected + ? AppColor.colorItemSelected + : Colors.transparent, + child: Row( + children: [ + LeadingMailboxItemWidget( + mailboxNode: widget.mailboxNode, + selectionMode: widget.selectionMode, + onSelectMailboxFolderClick: widget.onSelectMailboxFolderClick, + onExpandFolderActionClick: widget.onExpandFolderActionClick, + ), + const SizedBox(width: MailboxItemWidgetStyles.padding), + Expanded( + child: LabelMailboxItemWidget( + mailboxNode: widget.mailboxNode, + showTrailing: false, + isItemHovered: _isItemHovered, + onMenuActionClick: widget.onMenuActionClick + ) + ), + if (_isSelectActionNoValid) + SvgPicture.asset( + _imagePaths.icSelectedSB, + width: MailboxItemWidgetStyles.selectionIconSize, + height: MailboxItemWidgetStyles.selectionIconSize, + fit: BoxFit.fill + ), + const SizedBox(width: MailboxItemWidgetStyles.padding), + ] + ) + ), + ), + ), + ), + ); + } + } + } + + Color get backgroundColorItem { + if (widget.mailboxDisplayed == MailboxDisplayed.destinationPicker) { + return Colors.white; + } else { + if (widget.mailboxNodeSelected?.id == widget.mailboxNode.item.id || _isItemHovered) { + return AppColor.colorBgMailboxSelected; + } else { + return Colors.transparent; + } + } + } + + bool get _isSelectActionNoValid => widget.mailboxNode.item.id == widget.mailboxIdAlreadySelected && + widget.mailboxDisplayed == MailboxDisplayed.destinationPicker && + ( + widget.mailboxActions == MailboxActions.select || + widget.mailboxActions == MailboxActions.create || + widget.mailboxActions == MailboxActions.moveEmail + ); +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart b/lib/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart new file mode 100644 index 000000000..8b8ec635b --- /dev/null +++ b/lib/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart @@ -0,0 +1,84 @@ + +import 'package:core/presentation/resources/image_paths.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'; +import 'package:model/extensions/presentation_mailbox_extension.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/styles/trailing_mailbox_item_widget_styles.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_method_action_define.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/count_of_emails_widget.dart'; + +class TrailingMailboxItemWidget extends StatelessWidget { + + final MailboxNode mailboxNode; + final bool isItemHovered; + final OnClickOpenMenuMailboxNodeAction? onMenuActionClick; + + const TrailingMailboxItemWidget({ + super.key, + required this.mailboxNode, + this.isItemHovered = false, + this.onMenuActionClick, + }); + + @override + Widget build(BuildContext context) { + final imagePaths = Get.find(); + + if (PlatformInfo.isWeb) { + if (isItemHovered) { + return Padding( + padding: TrailingMailboxItemWidgetStyles.menuIconPadding, + child: InkWell( + onTapDown: (detail) { + final screenSize = MediaQuery.of(context).size; + final offset = detail.globalPosition; + final position = RelativeRect.fromLTRB( + offset.dx, + offset.dy, + screenSize.width - offset.dx, + screenSize.height - offset.dy, + ); + onMenuActionClick?.call(position, mailboxNode); + }, + onTap: () => {}, + child: SvgPicture.asset( + imagePaths.icComposerMenu, + width: TrailingMailboxItemWidgetStyles.menuIconSize, + height: TrailingMailboxItemWidgetStyles.menuIconSize, + fit: BoxFit.fill + ) + ), + ); + } else if (mailboxNode.item.countUnreadEmails > 0 && mailboxNode.item.allowedToDisplayCountOfUnreadEmails) { + return Padding( + padding: TrailingMailboxItemWidgetStyles.countEmailsPadding, + child: CountOfEmailsWidget(value: mailboxNode.item.countUnReadEmailsAsString), + ); + } else if (mailboxNode.item.countTotalEmails > 0 && mailboxNode.item.allowedToDisplayCountOfTotalEmails) { + return Padding( + padding: TrailingMailboxItemWidgetStyles.countEmailsPadding, + child: CountOfEmailsWidget(value: mailboxNode.item.countTotalEmailsAsString), + ); + } else { + return const SizedBox(); + } + } else { + if (mailboxNode.item.countUnreadEmails > 0 && mailboxNode.item.allowedToDisplayCountOfUnreadEmails) { + return Padding( + padding: TrailingMailboxItemWidgetStyles.countEmailsPadding, + child: CountOfEmailsWidget(value: mailboxNode.item.countUnReadEmailsAsString), + ); + } else if (mailboxNode.item.countTotalEmails > 0 && mailboxNode.item.allowedToDisplayCountOfTotalEmails) { + return Padding( + padding: TrailingMailboxItemWidgetStyles.countEmailsPadding, + child: CountOfEmailsWidget(value: mailboxNode.item.countTotalEmailsAsString), + ); + } else { + return const SizedBox(); + } + } + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart b/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart index 57c5bef00..a86c725bf 100644 --- a/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart +++ b/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart @@ -103,7 +103,7 @@ class MailBoxVisibilityFolderTileBuilder extends StatelessWidget { ), if (_mailboxNode.item.isTeamMailboxes) Text( - _mailboxNode.item.emailTeamMailBoxes ?? '', + _mailboxNode.item.emailTeamMailBoxes, maxLines: 1, softWrap: CommonTextStyle.defaultSoftWrap, overflow: CommonTextStyle.defaultTextOverFlow, diff --git a/lib/features/search/mailbox/presentation/widgets/mailbox_searched_item_builder.dart b/lib/features/search/mailbox/presentation/widgets/mailbox_searched_item_builder.dart index 5a770ce40..4b36dbcf6 100644 --- a/lib/features/search/mailbox/presentation/widgets/mailbox_searched_item_builder.dart +++ b/lib/features/search/mailbox/presentation/widgets/mailbox_searched_item_builder.dart @@ -225,7 +225,7 @@ class _MailboxSearchedItemBuilderState extends State ); } else if (widget._presentationMailbox.isTeamMailboxes) { return TextOverflowBuilder( - (widget._presentationMailbox.emailTeamMailBoxes ?? ''), + widget._presentationMailbox.emailTeamMailBoxes, style: const TextStyle( fontSize: 11, color: AppColor.colorEmailAddressFull, diff --git a/model/lib/extensions/presentation_mailbox_extension.dart b/model/lib/extensions/presentation_mailbox_extension.dart index ae3fb5bef..81965fe45 100644 --- a/model/lib/extensions/presentation_mailbox_extension.dart +++ b/model/lib/extensions/presentation_mailbox_extension.dart @@ -52,9 +52,15 @@ extension PresentationMailboxExtension on PresentationMailbox { return countTotalEmails <= 999 ? '$countTotalEmails' : '999+'; } - String? get emailTeamMailBoxes => namespace?.value.substring( - (namespace?.value.indexOf('[') ?? 0) + 1, - namespace?.value.indexOf(']')); + String get emailTeamMailBoxes { + final name = namespace?.value ?? ''; + if (name.isNotEmpty == true && + name.indexOf('[') > 0 && + name.indexOf(']') > name.indexOf('[')) { + return name.substring(name.indexOf('[') + 1, name.indexOf(']')); + } + return name; + } bool get allowedToDisplay => isSubscribedMailbox || isDefault;