TF-4141 Show AI action tag in list emails
This commit is contained in:
@@ -291,6 +291,7 @@ extension AppColor on Color {
|
||||
static const lightGrayF6FAFF = Color(0xFFF6FAFF);
|
||||
static const lightGrayF7F6F9 = Color(0xFFF7F6F9);
|
||||
static const blue25AEFE = Color(0xFF25AEFE);
|
||||
static const aiActionTag = Color(0xFF7E57E3);
|
||||
|
||||
static const mapGradientColor = [
|
||||
[Color(0xFF21D4FD), Color(0xFFB721FF)],
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/labels/tag_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class AiActionTagWidget extends StatelessWidget {
|
||||
final EdgeInsetsGeometry? margin;
|
||||
|
||||
const AiActionTagWidget({super.key, this.margin});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TagWidget(
|
||||
text: AppLocalizations.of(context).actionRequired,
|
||||
backgroundColor: AppColor.aiActionTag,
|
||||
textColor: Colors.white,
|
||||
isTruncateText: true,
|
||||
showTooltip: PlatformInfo.isWeb,
|
||||
margin: margin,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TagWidget extends StatelessWidget {
|
||||
final String text;
|
||||
final double horizontalPadding;
|
||||
final Color? backgroundColor;
|
||||
final Color? textColor;
|
||||
final double? maxWidth;
|
||||
final bool isTruncateText;
|
||||
final bool showTooltip;
|
||||
final EdgeInsetsGeometry? margin;
|
||||
|
||||
const TagWidget({
|
||||
super.key,
|
||||
required this.text,
|
||||
this.horizontalPadding = 4,
|
||||
this.isTruncateText = false,
|
||||
this.showTooltip = false,
|
||||
this.backgroundColor,
|
||||
this.textColor,
|
||||
this.maxWidth,
|
||||
this.margin,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget labelText = Text(
|
||||
isTruncateText ? _truncateName(text) : text,
|
||||
style: ThemeUtils.textStyleContentCaption().copyWith(
|
||||
color: textColor,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
);
|
||||
|
||||
if (showTooltip) {
|
||||
labelText = Tooltip(
|
||||
message: text,
|
||||
child: labelText,
|
||||
);
|
||||
}
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
),
|
||||
constraints:
|
||||
maxWidth != null ? BoxConstraints(maxWidth: maxWidth!) : null,
|
||||
padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
|
||||
margin: margin,
|
||||
child: labelText,
|
||||
);
|
||||
}
|
||||
|
||||
String _truncateName(String name, {int maxLength = 16}) {
|
||||
try {
|
||||
if (name.length <= maxLength) return name;
|
||||
return '${name.substring(0, maxLength - 1)}...';
|
||||
} catch (_) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
||||
|
||||
extension HandleAiActionExtension on MailboxDashBoardController {
|
||||
bool get isAiCapabilitySupported {
|
||||
final currentAccountId = accountId.value;
|
||||
final currentSession = sessionCurrent;
|
||||
|
||||
if (currentAccountId == null || currentSession == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return SessionExtensions.linagoraAICapability.isSupported(
|
||||
currentSession,
|
||||
currentAccountId,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import 'package:tmail_ui_user/features/base/widget/keyboard/keyboard_handler_wra
|
||||
import 'package:tmail_ui_user/features/base/widget/popup_menu/popup_menu_item_action_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart';
|
||||
@@ -665,96 +666,96 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
||||
}
|
||||
return false;
|
||||
},
|
||||
child: PlatformInfo.isMobile
|
||||
? ListView.separated(
|
||||
controller: controller.resultSearchScrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
key: const PageStorageKey('list_presentation_email_in_search_view'),
|
||||
itemCount: listPresentationEmail.length,
|
||||
itemBuilder: (context, index) {
|
||||
final currentPresentationEmail = listPresentationEmail[index];
|
||||
return Obx(() => EmailTileBuilder(
|
||||
presentationEmail: currentPresentationEmail,
|
||||
selectAllMode: controller.selectionMode.value,
|
||||
searchQuery: controller.searchQuery,
|
||||
isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id,
|
||||
isSenderImportantFlagEnabled: controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value,
|
||||
isSearchEmailRunning: true,
|
||||
padding: SearchEmailViewStyle.getPaddingSearchResultList(context, controller.responsiveUtils),
|
||||
mailboxContain: currentPresentationEmail.mailboxContain,
|
||||
emailActionClick: (action, email) {
|
||||
controller.pressEmailAction(
|
||||
context,
|
||||
action,
|
||||
email,
|
||||
mailboxContain: currentPresentationEmail.mailboxContain
|
||||
);
|
||||
},
|
||||
onMoreActionClick: (email, position) =>
|
||||
controller.handleEmailMoreAction(
|
||||
context,
|
||||
email,
|
||||
position,
|
||||
),
|
||||
));
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
if (index < listPresentationEmail.length - 1) {
|
||||
return Padding(
|
||||
padding: SearchEmailUtils.getPaddingItemListMobile(context, controller.responsiveUtils),
|
||||
child: const Divider());
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
)
|
||||
: ListView.separated(
|
||||
controller: controller.resultSearchScrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
key: const PageStorageKey('list_presentation_email_in_search_view'),
|
||||
itemCount: listPresentationEmail.length,
|
||||
itemBuilder: (context, index) {
|
||||
final currentPresentationEmail = listPresentationEmail[index];
|
||||
return Obx(() => EmailTileBuilder(
|
||||
presentationEmail: currentPresentationEmail,
|
||||
selectAllMode: controller.selectionMode.value,
|
||||
searchQuery: controller.searchQuery,
|
||||
isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id,
|
||||
isSenderImportantFlagEnabled: controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value,
|
||||
isSearchEmailRunning: true,
|
||||
padding: SearchEmailViewStyle.getPaddingSearchResultList(
|
||||
child: ListView.separated(
|
||||
controller: controller.resultSearchScrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
key: const PageStorageKey('list_presentation_email_in_search_view'),
|
||||
itemCount: listPresentationEmail.length,
|
||||
itemBuilder: (context, index) => _buildEmailItem(
|
||||
context,
|
||||
listPresentationEmail[index],
|
||||
),
|
||||
separatorBuilder: (context, index) {
|
||||
final isMobile = PlatformInfo.isMobile;
|
||||
final isLastItem = index == listPresentationEmail.length - 1;
|
||||
final isInactive =
|
||||
controller.selectionMode.value == SelectMode.INACTIVE;
|
||||
|
||||
final showDivider = !isLastItem;
|
||||
|
||||
final dividerColor = isMobile
|
||||
? null
|
||||
: (showDivider && isInactive ? null : Colors.white);
|
||||
|
||||
final padding = isMobile
|
||||
? SearchEmailUtils.getPaddingItemListMobile(
|
||||
context,
|
||||
controller.responsiveUtils
|
||||
),
|
||||
mailboxContain: currentPresentationEmail.mailboxContain,
|
||||
emailActionClick: (action, email) {
|
||||
controller.pressEmailAction(
|
||||
context,
|
||||
action,
|
||||
email,
|
||||
mailboxContain: currentPresentationEmail.mailboxContain
|
||||
);
|
||||
},
|
||||
onMoreActionClick: (email, position) =>
|
||||
controller.handleEmailMoreAction(
|
||||
context,
|
||||
email,
|
||||
position,
|
||||
),
|
||||
));
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: ItemEmailTileStyles.getPaddingDividerWeb(context, controller.responsiveUtils),
|
||||
child: Divider(
|
||||
color: index < listPresentationEmail.length - 1 &&
|
||||
controller.selectionMode.value == SelectMode.INACTIVE
|
||||
? null
|
||||
: Colors.white
|
||||
controller.responsiveUtils,
|
||||
)
|
||||
);
|
||||
},
|
||||
)
|
||||
: ItemEmailTileStyles.getPaddingDividerWeb(
|
||||
context,
|
||||
controller.responsiveUtils,
|
||||
);
|
||||
|
||||
if (!showDivider) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: padding,
|
||||
child: Divider(color: dividerColor),
|
||||
);
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEmailItem(
|
||||
BuildContext context,
|
||||
PresentationEmail presentationEmail,
|
||||
) {
|
||||
final dashboardController = controller.mailboxDashBoardController;
|
||||
|
||||
return Obx(
|
||||
() {
|
||||
final isShowingEmailContent =
|
||||
dashboardController.selectedEmail.value?.id == presentationEmail.id;
|
||||
|
||||
final isSenderImportantFlagEnabled =
|
||||
dashboardController.isSenderImportantFlagEnabled.value;
|
||||
|
||||
final isAiCapabilitySupported =
|
||||
dashboardController.isAiCapabilitySupported;
|
||||
|
||||
return EmailTileBuilder(
|
||||
presentationEmail: presentationEmail,
|
||||
selectAllMode: controller.selectionMode.value,
|
||||
searchQuery: controller.searchQuery,
|
||||
isShowingEmailContent: isShowingEmailContent,
|
||||
isSenderImportantFlagEnabled: isSenderImportantFlagEnabled,
|
||||
isSearchEmailRunning: true,
|
||||
isAIEnabled: isAiCapabilitySupported,
|
||||
padding: SearchEmailViewStyle.getPaddingSearchResultList(
|
||||
context,
|
||||
controller.responsiveUtils,
|
||||
),
|
||||
mailboxContain: presentationEmail.mailboxContain,
|
||||
emailActionClick: (action, email) {
|
||||
controller.pressEmailAction(
|
||||
context,
|
||||
action,
|
||||
email,
|
||||
mailboxContain: presentationEmail.mailboxContain,
|
||||
);
|
||||
},
|
||||
onMoreActionClick: (email, position) =>
|
||||
controller.handleEmailMoreAction(
|
||||
context,
|
||||
email,
|
||||
position,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_ai_action_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_open_context_menu_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recover_deleted_message_loading_banner_widget.dart';
|
||||
@@ -495,71 +496,75 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
}
|
||||
|
||||
Widget _buildEmailItemWhenDragging(BuildContext context, PresentationEmail presentationEmail) {
|
||||
final isShowingEmailContent = controller.mailboxDashBoardController.selectedEmail.value?.id == presentationEmail.id;
|
||||
final selectModeAll = controller.mailboxDashBoardController.currentSelectMode.value;
|
||||
final isSenderImportantFlagEnabled =
|
||||
controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value;
|
||||
final dashboardController = controller.mailboxDashBoardController;
|
||||
|
||||
return EmailTileBuilder(
|
||||
key: Key('email_tile_builder_${presentationEmail.id?.asString}'),
|
||||
presentationEmail: presentationEmail,
|
||||
selectAllMode: selectModeAll,
|
||||
isShowingEmailContent: isShowingEmailContent,
|
||||
searchQuery: controller.searchQuery,
|
||||
mailboxContain: presentationEmail.mailboxContain,
|
||||
isSearchEmailRunning: controller.searchController.isSearchEmailRunning,
|
||||
isDrag: true,
|
||||
isSenderImportantFlagEnabled: isSenderImportantFlagEnabled,
|
||||
);
|
||||
return Obx(() {
|
||||
final selectAllMode = dashboardController.currentSelectMode.value;
|
||||
|
||||
final isSenderImportantFlagEnabled =
|
||||
dashboardController.isSenderImportantFlagEnabled.value;
|
||||
|
||||
final isShowingEmailContent =
|
||||
dashboardController.selectedEmail.value?.id == presentationEmail.id;
|
||||
|
||||
final isSearchEmailRunning =
|
||||
controller.searchController.isSearchEmailRunning;
|
||||
|
||||
final isAiCapabilitySupported =
|
||||
dashboardController.isAiCapabilitySupported;
|
||||
|
||||
return EmailTileBuilder(
|
||||
key: Key('email_tile_builder_${presentationEmail.id?.asString}'),
|
||||
presentationEmail: presentationEmail,
|
||||
selectAllMode: selectAllMode,
|
||||
isShowingEmailContent: isShowingEmailContent,
|
||||
searchQuery: controller.searchQuery,
|
||||
mailboxContain: presentationEmail.mailboxContain,
|
||||
isSearchEmailRunning: isSearchEmailRunning,
|
||||
isDrag: true,
|
||||
isSenderImportantFlagEnabled: isSenderImportantFlagEnabled,
|
||||
isAIEnabled: isAiCapabilitySupported,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildEmailItemNotDraggable(BuildContext context, PresentationEmail presentationEmail) {
|
||||
final isShowingEmailContent = controller.mailboxDashBoardController.selectedEmail.value?.id == presentationEmail.id;
|
||||
final selectModeAll = controller.mailboxDashBoardController.currentSelectMode.value;
|
||||
final isSenderImportantFlagEnabled =
|
||||
controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value;
|
||||
|
||||
return Dismissible(
|
||||
key: ValueKey<EmailId?>(presentationEmail.id),
|
||||
direction: controller.getSwipeDirection(
|
||||
controller.responsiveUtils.isWebDesktop(context),
|
||||
selectModeAll,
|
||||
presentationEmail
|
||||
),
|
||||
background: Container(
|
||||
color: AppColor.colorItemRecipientSelected,
|
||||
padding: const EdgeInsetsDirectional.only(start: 16),
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: AppColor.colorSpamReportBannerBackground,
|
||||
radius: 24,
|
||||
child: !presentationEmail.hasRead
|
||||
? SvgPicture.asset(
|
||||
controller.imagePaths.icMarkAsRead,
|
||||
fit: BoxFit.fill,
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
controller.imagePaths.icUnreadEmail,
|
||||
fit: BoxFit.fill,
|
||||
colorFilter: AppColor.primaryColor.asFilter(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 11),
|
||||
Text(
|
||||
!presentationEmail.hasRead
|
||||
final backgroundWidget = Container(
|
||||
color: AppColor.colorItemRecipientSelected,
|
||||
padding: const EdgeInsetsDirectional.only(start: 16),
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: AppColor.colorSpamReportBannerBackground,
|
||||
radius: 24,
|
||||
child: !presentationEmail.hasRead
|
||||
? SvgPicture.asset(
|
||||
controller.imagePaths.icMarkAsRead,
|
||||
fit: BoxFit.fill,
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
controller.imagePaths.icUnreadEmail,
|
||||
fit: BoxFit.fill,
|
||||
colorFilter: AppColor.primaryColor.asFilter(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 11),
|
||||
Text(
|
||||
!presentationEmail.hasRead
|
||||
? AppLocalizations.of(context).mark_as_read
|
||||
: AppLocalizations.of(context).mark_as_unread,
|
||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
||||
fontSize: 15,
|
||||
color: AppColor.primaryColor,
|
||||
),
|
||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
||||
fontSize: 15,
|
||||
color: AppColor.primaryColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
secondaryBackground: controller.isInArchiveMailbox(presentationEmail) == false
|
||||
);
|
||||
|
||||
final isInArchiveMailbox = controller.isInArchiveMailbox(presentationEmail);
|
||||
final secondaryBackgroundWidget = !isInArchiveMailbox
|
||||
? Container(
|
||||
color: AppColor.colorItemRecipientSelected,
|
||||
padding: const EdgeInsetsDirectional.only(end: 16),
|
||||
@@ -573,7 +578,7 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
child: SvgPicture.asset(
|
||||
controller.imagePaths.icMailboxArchived,
|
||||
fit: BoxFit.fill,
|
||||
)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 11),
|
||||
Text(
|
||||
@@ -586,24 +591,54 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
confirmDismiss: (direction) => controller.swipeEmailAction(
|
||||
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: controller.searchController.isSearchEmailRunning,
|
||||
emailActionClick: _handleEmailActionClicked,
|
||||
onMoreActionClick: (email, position) => _handleEmailContextMenuAction(context, email, position),
|
||||
),
|
||||
);
|
||||
: null;
|
||||
|
||||
final dashboardController = controller.mailboxDashBoardController;
|
||||
|
||||
return Obx(() {
|
||||
final selectModeAll = dashboardController.currentSelectMode.value;
|
||||
|
||||
final isSenderImportantFlagEnabled =
|
||||
dashboardController.isSenderImportantFlagEnabled.value;
|
||||
|
||||
final isShowingEmailContent =
|
||||
dashboardController.selectedEmail.value?.id == presentationEmail.id;
|
||||
|
||||
final isSearchEmailRunning =
|
||||
controller.searchController.isSearchEmailRunning;
|
||||
|
||||
final isAiCapabilitySupported =
|
||||
dashboardController.isAiCapabilitySupported;
|
||||
|
||||
return Dismissible(
|
||||
key: ValueKey<EmailId?>(presentationEmail.id),
|
||||
direction: controller.getSwipeDirection(
|
||||
controller.responsiveUtils.isWebDesktop(context),
|
||||
selectModeAll,
|
||||
presentationEmail
|
||||
),
|
||||
background: backgroundWidget,
|
||||
secondaryBackground: secondaryBackgroundWidget,
|
||||
confirmDismiss: (direction) => controller.swipeEmailAction(
|
||||
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,
|
||||
isAIEnabled: isAiCapabilitySupported,
|
||||
emailActionClick: _handleEmailActionClicked,
|
||||
onMoreActionClick: (email, position) =>
|
||||
_handleEmailContextMenuAction(context, email, position),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void _handleEmailActionClicked(
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:model/email/email_action_type.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/base/widget/labels/ai_action_tag_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/styles/item_email_tile_styles.dart';
|
||||
@@ -19,6 +20,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile {
|
||||
final bool isDrag;
|
||||
final bool isShowingEmailContent;
|
||||
final bool isSenderImportantFlagEnabled;
|
||||
final bool isAIEnabled;
|
||||
final OnPressEmailActionClick? emailActionClick;
|
||||
final OnMoreActionClick? onMoreActionClick;
|
||||
|
||||
@@ -30,6 +32,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile {
|
||||
this.searchQuery,
|
||||
this.isSearchEmailRunning = false,
|
||||
this.isSenderImportantFlagEnabled = true,
|
||||
this.isAIEnabled = true,
|
||||
this.mailboxContain,
|
||||
this.padding,
|
||||
this.isDrag = false,
|
||||
@@ -128,6 +131,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile {
|
||||
presentationEmail,
|
||||
isSearchEmailRunning,
|
||||
searchQuery)),
|
||||
if (_shouldShowAIAction) const AiActionTagWidget(),
|
||||
])
|
||||
),
|
||||
],
|
||||
@@ -135,4 +139,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool get _shouldShowAIAction =>
|
||||
isAIEnabled && presentationEmail.hasNeedAction;
|
||||
}
|
||||
@@ -9,6 +9,7 @@ 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/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';
|
||||
@@ -26,6 +27,7 @@ class EmailTileBuilder extends StatefulWidget {
|
||||
final bool isDrag;
|
||||
final bool isShowingEmailContent;
|
||||
final bool isSenderImportantFlagEnabled;
|
||||
final bool isAIEnabled;
|
||||
final OnPressEmailActionClick? emailActionClick;
|
||||
final OnMoreActionClick? onMoreActionClick;
|
||||
|
||||
@@ -40,6 +42,7 @@ class EmailTileBuilder extends StatefulWidget {
|
||||
this.mailboxContain,
|
||||
this.padding,
|
||||
this.isDrag = false,
|
||||
this.isAIEnabled = false,
|
||||
this.emailActionClick,
|
||||
this.onMoreActionClick,
|
||||
});
|
||||
@@ -169,6 +172,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
|
||||
widget.searchQuery
|
||||
)
|
||||
),
|
||||
if (_shouldShowAIAction) const AiActionTagWidget(),
|
||||
]),
|
||||
]),
|
||||
)
|
||||
@@ -185,6 +189,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
|
||||
isShowingEmailContent: widget.isShowingEmailContent,
|
||||
isDrag: widget.isDrag,
|
||||
isSenderImportantFlagEnabled: widget.isSenderImportantFlagEnabled,
|
||||
shouldShowAIAction: _shouldShowAIAction,
|
||||
padding: widget.padding,
|
||||
searchQuery: widget.searchQuery,
|
||||
mailboxContain: widget.mailboxContain,
|
||||
@@ -368,6 +373,8 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
|
||||
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),
|
||||
@@ -415,6 +422,9 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
|
||||
}
|
||||
}
|
||||
|
||||
bool get _shouldShowAIAction =>
|
||||
widget.isAIEnabled && widget.presentationEmail.hasNeedAction;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_hoverNotifier.dispose();
|
||||
|
||||
@@ -8,6 +8,7 @@ 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/thread/domain/model/search_query.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/mixin/base_email_item_tile.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_tile_styles.dart';
|
||||
@@ -22,6 +23,7 @@ class WebTabletBodyEmailItemWidget extends StatefulWidget {
|
||||
final bool isShowDateTimeView;
|
||||
final bool isDrag;
|
||||
final bool isSenderImportantFlagEnabled;
|
||||
final bool shouldShowAIAction;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final SearchQuery? searchQuery;
|
||||
final PresentationMailbox? mailboxContain;
|
||||
@@ -43,6 +45,7 @@ class WebTabletBodyEmailItemWidget extends StatefulWidget {
|
||||
required this.emailActionClick,
|
||||
required this.onMoreActionClick,
|
||||
this.isShowDateTimeView = false,
|
||||
this.shouldShowAIAction = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -165,6 +168,8 @@ class _WebTabletBodyEmailItemWidgetState
|
||||
widget.searchQuery,
|
||||
),
|
||||
),
|
||||
if (widget.shouldShowAIAction)
|
||||
const AiActionTagWidget(),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@last_modified": "2025-12-15T14:32:52.563522",
|
||||
"@@last_modified": "2025-12-16T11:52:06.406969",
|
||||
"initializing_data": "Initializing data...",
|
||||
"@initializing_data": {
|
||||
"type": "text",
|
||||
@@ -5135,5 +5135,11 @@
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
},
|
||||
"actionRequired": "Action Required",
|
||||
"@actionRequired": {
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -5457,4 +5457,11 @@ class AppLocalizations {
|
||||
name: 'startToAddFavoritesEmails',
|
||||
);
|
||||
}
|
||||
|
||||
String get actionRequired {
|
||||
return Intl.message(
|
||||
'Action Required',
|
||||
name: 'actionRequired',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,9 @@ class PresentationEmail with EquatableMixin, SearchSnippetMixin {
|
||||
|
||||
bool get isSubscribed => keywords?.containsKey(KeyWordIdentifierExtension.unsubscribeMail) == true;
|
||||
|
||||
bool get hasNeedAction =>
|
||||
keywords?.containsKey(KeyWordIdentifierExtension.needActionMail) == true;
|
||||
|
||||
bool get isAnsweredAndForwarded => isAnswered && isForwarded;
|
||||
|
||||
bool get withAttachments => hasAttachment == true;
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:model/email/read_actions.dart';
|
||||
|
||||
extension KeyWordIdentifierExtension on KeyWordIdentifier {
|
||||
static final unsubscribeMail = KeyWordIdentifier('\$unsubscribe');
|
||||
static final needActionMail = KeyWordIdentifier('\$need-action');
|
||||
|
||||
String generatePath() {
|
||||
return '${PatchObject.keywordsProperty}/$value';
|
||||
|
||||
Reference in New Issue
Block a user