TF-4171 Display tag in mailbox list

This commit is contained in:
dab246
2025-11-25 14:02:50 +07:00
committed by Dat H. Pham
parent f4302e06e8
commit 31ed2feae4
19 changed files with 1865 additions and 38 deletions
@@ -13,6 +13,7 @@ import 'package:tmail_ui_user/features/base/widget/compose_floating_button.dart'
import 'package:tmail_ui_user/features/base/widget/keyboard/keyboard_handler_wrapper.dart';
import 'package:tmail_ui_user/features/base/widget/popup_menu/popup_menu_action_group_widget.dart';
import 'package:tmail_ui_user/features/base/widget/report_message_banner.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/presentation_email_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/email/presentation/model/context_item_email_action.dart';
import 'package:tmail_ui_user/features/email/presentation/model/popup_menu_item_email_action.dart';
@@ -621,20 +622,27 @@ class ThreadView extends GetWidget<ThreadController>
presentationEmail,
direction,
),
child: EmailTileBuilder(
key: Key('email_tile_builder_${presentationEmail.id?.asString}'),
presentationEmail: presentationEmail,
selectAllMode: selectModeAll,
isShowingEmailContent: isShowingEmailContent,
isSenderImportantFlagEnabled: isSenderImportantFlagEnabled,
searchQuery: controller.searchQuery,
mailboxContain: presentationEmail.mailboxContain,
isSearchEmailRunning: isSearchEmailRunning,
isAINeedsActionEnabled: isAINeedsActionEnabled,
emailActionClick: _handleEmailActionClicked,
onMoreActionClick: (email, position) =>
_handleEmailContextMenuAction(context, email, position),
),
child: Obx(() {
final allLabels =
controller.mailboxDashBoardController.labelController.labels;
final emailLabels = presentationEmail.getLabelList(allLabels);
return EmailTileBuilder(
key: Key('email_tile_builder_${presentationEmail.id?.asString}'),
presentationEmail: presentationEmail,
selectAllMode: selectModeAll,
isShowingEmailContent: isShowingEmailContent,
isSenderImportantFlagEnabled: isSenderImportantFlagEnabled,
searchQuery: controller.searchQuery,
mailboxContain: presentationEmail.mailboxContain,
isSearchEmailRunning: controller.searchController.isSearchEmailRunning,
isAINeedsActionEnabled: isAINeedsActionEnabled,
labels: emailLabels,
emailActionClick: _handleEmailActionClicked,
onMoreActionClick: (email, position) =>
_handleEmailContextMenuAction(context, email, position),
);
}),
);
});
}
@@ -1,5 +1,6 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:labels/model/label.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
@@ -21,6 +22,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile {
final bool isShowingEmailContent;
final bool isSenderImportantFlagEnabled;
final bool isAINeedsActionEnabled;
final List<Label>? labels;
final OnPressEmailActionClick? emailActionClick;
final OnMoreActionClick? onMoreActionClick;
@@ -29,6 +31,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile {
required this.presentationEmail,
required this.selectAllMode,
required this.isShowingEmailContent,
this.labels,
this.searchQuery,
this.isSearchEmailRunning = false,
this.isSenderImportantFlagEnabled = true,
@@ -4,12 +4,14 @@ import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:flutter/material.dart';
import 'package:labels/model/label.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/base/widget/labels/ai_action_tag_widget.dart';
import 'package:tmail_ui_user/features/labels/presentation/widgets/label_list_widget.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/features/thread/presentation/mixin/base_email_item_tile.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/desktop_list_email_action_hover_widget.dart';
@@ -28,6 +30,7 @@ class EmailTileBuilder extends StatefulWidget {
final bool isShowingEmailContent;
final bool isSenderImportantFlagEnabled;
final bool isAINeedsActionEnabled;
final List<Label>? labels;
final OnPressEmailActionClick? emailActionClick;
final OnMoreActionClick? onMoreActionClick;
@@ -36,6 +39,7 @@ class EmailTileBuilder extends StatefulWidget {
required this.presentationEmail,
required this.selectAllMode,
required this.isShowingEmailContent,
this.labels,
this.searchQuery,
this.isSearchEmailRunning = false,
this.isSenderImportantFlagEnabled = true,
@@ -370,34 +374,102 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
}
Widget _buildSubjectAndContent() {
return LayoutBuilder(builder: (context, constraints) {
return Row(children: [
final emailTitle = widget.presentationEmail.getEmailTitle();
return Row(
children: [
if (widget.presentationEmail.hasCalendarEvent)
buildCalendarEventIcon(context: context, presentationEmail: widget.presentationEmail),
if (widget.presentationEmail.isMarkAsImportant && widget.isSenderImportantFlagEnabled)
buildCalendarEventIcon(
context: context,
presentationEmail: widget.presentationEmail,
),
if (widget.presentationEmail.isMarkAsImportant &&
widget.isSenderImportantFlagEnabled)
buildMarkAsImportantIcon(context),
if (_shouldShowAIAction)
const AiActionTagWidget(margin: EdgeInsetsDirectional.only(end: 12)),
if (widget.presentationEmail.getEmailTitle().isNotEmpty)
Container(
constraints: BoxConstraints(maxWidth: constraints.maxWidth / 2),
padding: const EdgeInsetsDirectional.only(end: 12),
child: buildEmailTitle(
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery
)),
Expanded(
child: buildEmailPartialContent(
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery
child: LayoutBuilder(
builder: (_, constraints) {
final maxWidth = constraints.maxWidth;
double horizontalPadding = 12;
final maxWidthNoPadding = maxWidth - horizontalPadding * 2;
final labelTagsMaxWidth = emailTitle.isNotEmpty
? maxWidthNoPadding * 0.4
: maxWidthNoPadding * 0.5;
final emailTitleMaxWidth = widget.labels?.isNotEmpty == true
? maxWidthNoPadding * 0.4
: maxWidthNoPadding * 0.5;
return Row(
children: [
if (widget.labels?.isNotEmpty == true) ...[
Container(
constraints: BoxConstraints(
maxWidth: labelTagsMaxWidth,
),
padding: EdgeInsetsDirectional.only(
end: horizontalPadding,
),
child: LabelTagListWidget(tags: widget.labels!),
),
if (emailTitle.isNotEmpty)
Container(
constraints: BoxConstraints(
maxWidth: emailTitleMaxWidth,
),
padding: EdgeInsetsDirectional.only(
end: horizontalPadding,
),
child: buildEmailTitle(
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery,
),
),
Expanded(
child: buildEmailPartialContent(
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery,
),
),
] else ...[
if (emailTitle.isNotEmpty)
Container(
constraints: BoxConstraints(
maxWidth: emailTitleMaxWidth,
),
padding: EdgeInsetsDirectional.only(
end: horizontalPadding,
),
child: buildEmailTitle(
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery,
),
),
Expanded(
child: buildEmailPartialContent(
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery,
),
),
],
],
);
},
),
),
]);
});
],
);
}
Widget _buildAvatarIcon({