TF-3759 Always show dot icon when open popup menu of more action in mailbox view

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-06-16 04:15:30 +07:00
committed by Dat H. Pham
parent b558dd48d1
commit aeaea7b8b2
8 changed files with 148 additions and 97 deletions
@@ -210,7 +210,7 @@ abstract class BaseMailboxView extends GetWidget<MailboxController>
onMenuActionClick: PlatformInfo.isMobile
? null
: (position, mailboxNode) {
controller.openMailboxContextMenuAction(
return controller.openMailboxContextMenuAction(
context,
position,
mailboxNode.item,
@@ -64,7 +64,7 @@ extension HandleMailboxActionExtension on MailboxController {
);
}
void openMailboxContextMenuAction(
Future<void> openMailboxContextMenuAction(
BuildContext context,
RelativeRect position,
PresentationMailbox mailbox,
@@ -85,9 +85,9 @@ extension HandleMailboxActionExtension on MailboxController {
AppLocalizations.of(context),
);
if (contextMenuActions.isEmpty) return;
if (contextMenuActions.isEmpty) return Future.value();
openBottomSheetContextMenuAction(
return openBottomSheetContextMenuAction(
context: context,
itemActions: contextMenuActions,
onContextMenuActionClick: (menuAction) => handleMailboxAction(
@@ -106,7 +106,7 @@ extension HandleMailboxActionExtension on MailboxController {
isSubAddressingSupported,
);
if (popupMenuActions.isEmpty) return;
if (popupMenuActions.isEmpty) return Future.value();
final popupMenuItems = popupMenuActions.map((menuAction) {
return PopupMenuItem(
@@ -121,7 +121,7 @@ extension HandleMailboxActionExtension on MailboxController {
);
}).toList();
openPopupMenuAction(context, position, popupMenuItems);
return openPopupMenuAction(context, position, popupMenuItems);
}
}
}
@@ -5,7 +5,7 @@ import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
typedef OnClickOpenMailboxAction = void Function(PresentationMailbox);
typedef OnClickOpenMenuMailboxAction = void Function(RelativeRect, PresentationMailbox);
typedef OnClickOpenMenuMailboxAction = Future<void> Function(RelativeRect, PresentationMailbox);
typedef OnSelectMailboxAction = void Function(PresentationMailbox);
typedef OnDragEmailToMailboxAccepted = void Function(List<PresentationEmail>, PresentationMailbox);
typedef OnLongPressMailboxAction = void Function(PresentationMailbox);
@@ -13,7 +13,7 @@ typedef OnLongPressMailboxAction = void Function(PresentationMailbox);
typedef OnClickExpandMailboxNodeAction = void Function(MailboxNode, GlobalKey itemKey);
typedef OnClickOpenMailboxNodeAction = void Function(MailboxNode);
typedef OnSelectMailboxNodeAction = void Function(MailboxNode);
typedef OnClickOpenMenuMailboxNodeAction = void Function(RelativeRect, MailboxNode);
typedef OnClickOpenMenuMailboxNodeAction = Future<void> Function(RelativeRect, MailboxNode);
typedef OnLongPressMailboxNodeAction = void Function(MailboxNode);
typedef OnClickSubscribeMailboxAction = void Function(MailboxNode);
typedef OnEmptyMailboxActionCallback = void Function(MailboxNode);
@@ -2,13 +2,16 @@ 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/theme_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.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/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/empty_mailbox_popup_dialog_widget.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_expand_button.dart';
@@ -47,6 +50,7 @@ class _LabelMailboxItemWidgetState extends State<LabelMailboxItemWidget> {
final _imagePaths = Get.find<ImagePaths>();
bool _popupVisible = false;
bool _morePopupMenuVisible = false;
@override
Widget build(BuildContext context) {
@@ -104,7 +108,7 @@ class _LabelMailboxItemWidgetState extends State<LabelMailboxItemWidget> {
responsiveUtils: _responsiveUtils,
imagePaths: _imagePaths,
isItemHovered: widget.isItemHovered,
onMenuActionClick: widget.onMenuActionClick,
isShowMoreButton: _shouldShowMorePopupMenu,
);
final childWidget = Row(
@@ -122,6 +126,45 @@ class _LabelMailboxItemWidgetState extends State<LabelMailboxItemWidget> {
onPopupVisibleChange: _onPopupVisibleChange,
),
),
if (_showCleanButton(context) && !_shouldShowMorePopupMenu)
const Padding(
padding: TrailingMailboxItemWidgetStyles.menuIconPadding,
child: SizedBox(width: TrailingMailboxItemWidgetStyles.menuIconSize),
),
if (_showMoreButton(context))
Offstage(
offstage: !_shouldShowMorePopupMenu,
child: TMailButtonWidget.fromIcon(
margin: _responsiveUtils.isDesktop(context) &&
widget.mailboxNode.item.allowedHasEmptyAction
? EdgeInsets.zero
: TrailingMailboxItemWidgetStyles.menuIconMargin,
icon: _imagePaths.icMoreVertical,
iconSize: widget.mailboxNode.item.isTeamMailboxes
? 17
: TrailingMailboxItemWidgetStyles.menuIconSize,
padding: widget.mailboxNode.item.isTeamMailboxes
? const EdgeInsets.all(3)
: TrailingMailboxItemWidgetStyles.menuIconPadding,
backgroundColor: _morePopupMenuVisible
? Theme.of(context).colorScheme.outline.withOpacity(0.08)
: TrailingMailboxItemWidgetStyles.menuIconBackgroundColor,
onTapActionAtPositionCallback: (position) {
if (!_responsiveUtils.isScreenWithShortestSide(context)) {
_onMorePopupMenuVisibleChange(true);
}
widget.onMenuActionClick
?.call(position, widget.mailboxNode)
.whenComplete(() {
if (context.mounted &&
!_responsiveUtils.isScreenWithShortestSide(context)) {
_onMorePopupMenuVisibleChange(false);
}
});
},
),
),
trailingWidget,
],
);
@@ -153,13 +196,24 @@ class _LabelMailboxItemWidgetState extends State<LabelMailboxItemWidget> {
}
}
void _onMorePopupMenuVisibleChange(bool visible) {
if (_morePopupMenuVisible != visible) {
setState(() => _morePopupMenuVisible = visible);
}
}
bool get _shouldShowPopup => widget.isItemHovered || _popupVisible;
bool get _shouldShowMorePopupMenu =>
widget.isItemHovered || _morePopupMenuVisible;
bool _showCleanButton(BuildContext context) {
return _responsiveUtils.isWebDesktop(context) &&
widget.mailboxNode.item.allowedHasEmptyAction;
}
bool _showMoreButton(BuildContext context) => PlatformInfo.isWeb;
TextStyle get _displayNameTextStyle {
if (widget.isSelected) {
return ThemeUtils.textStyleInter700(
@@ -1,13 +1,11 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.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 {
@@ -16,7 +14,7 @@ class TrailingMailboxItemWidget extends StatelessWidget {
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
final bool isItemHovered;
final OnClickOpenMenuMailboxNodeAction? onMenuActionClick;
final bool isShowMoreButton;
const TrailingMailboxItemWidget({
super.key,
@@ -24,28 +22,14 @@ class TrailingMailboxItemWidget extends StatelessWidget {
required this.imagePaths,
required this.responsiveUtils,
this.isItemHovered = false,
this.onMenuActionClick,
this.isShowMoreButton = false,
});
@override
Widget build(BuildContext context) {
if (PlatformInfo.isWeb) {
if (isItemHovered) {
return TMailButtonWidget.fromIcon(
margin: responsiveUtils.isDesktop(context) && mailboxNode.item.allowedHasEmptyAction
? EdgeInsets.zero
: TrailingMailboxItemWidgetStyles.menuIconMargin,
icon: imagePaths.icMoreVertical,
iconSize: mailboxNode.item.isTeamMailboxes
? 17
: TrailingMailboxItemWidgetStyles.menuIconSize,
padding: mailboxNode.item.isTeamMailboxes
? const EdgeInsets.all(3)
: TrailingMailboxItemWidgetStyles.menuIconPadding,
backgroundColor: TrailingMailboxItemWidgetStyles.menuIconBackgroundColor,
onTapActionAtPositionCallback: (position) => onMenuActionClick?.call(position, mailboxNode),
);
} else if (responsiveUtils.isDesktop(context) && mailboxNode.item.allowedHasEmptyAction) {
if (isShowMoreButton ||
responsiveUtils.isDesktop(context) && mailboxNode.item.allowedHasEmptyAction) {
return const SizedBox();
} else if (mailboxNode.item.allowedToDisplayCountOfUnreadEmails) {
return Padding(