TF-4301 Add "Create a new label" button in Label As menus and wire up tagging in email view

This commit is contained in:
dab246
2026-02-04 13:53:01 +07:00
committed by Dat H. Pham
parent 061793846e
commit 190ccc7bc3
29 changed files with 600 additions and 247 deletions
@@ -19,19 +19,18 @@ import 'package:tmail_ui_user/main/routes/dialog_router.dart';
extension AddLabelToThreadExtension on ThreadDetailController {
Future<void> openAddLabelToEmailDialogModal() async {
if (!mailboxDashBoardController.isLabelAvailable) return;
final labels = mailboxDashBoardController.labelController.labels;
if (emailsInThreadDetailInfo.isEmpty || labels.isEmpty) {
if (!mailboxDashBoardController.isLabelAvailable ||
emailsInThreadDetailInfo.isEmpty) {
return;
}
final labelController = mailboxDashBoardController.labelController;
final labels = labelController.labels;
final threadLabels =
emailsInThreadDetailInfo.findCommonLabelsInThread(labels: labels);
final emailIds = emailsInThreadDetailInfo.emailIdsToDisplay(true);
await DialogRouter().openDialogModal(
final newLabel = await DialogRouter().openDialogModal(
child: AddLabelToEmailModal(
labels: labels,
emailLabels: threadLabels,
@@ -43,9 +42,17 @@ extension AddLabelToThreadExtension on ThreadDetailController {
currentEmailIds: emailIds,
);
},
onCreateANewLabelAction: () => labelController.onCreateALabelAction(
accountId: accountId,
shouldPop: true,
),
),
dialogLabel: 'add-label-to-thread-modal',
);
if (newLabel is Label) {
toggleLabelToThread(newLabel, isSelected: true);
}
}
void toggleLabelToThread(
@@ -15,6 +15,9 @@ import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action
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';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/labels/presentation/extensions/handle_label_action_type_extension.dart';
import 'package:tmail_ui_user/features/labels/presentation/label_controller.dart';
import 'package:tmail_ui_user/features/labels/presentation/models/label_action_type.dart';
import 'package:tmail_ui_user/features/labels/presentation/widgets/label_item_context_menu.dart';
import 'package:tmail_ui_user/features/labels/presentation/widgets/label_list_context_menu.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
@@ -125,7 +128,6 @@ extension OnThreadDetailActionClick on ThreadDetailController {
_moveToMailbox(mailboxId, threadDetailActionType);
break;
case EmailActionType.labelAs:
if (!mailboxDashBoardController.isLabelAvailable) return;
openAddLabelToEmailDialogModal();
break;
default:
@@ -144,9 +146,7 @@ extension OnThreadDetailActionClick on ThreadDetailController {
? EmailActionType.unMarkAsStarred
: EmailActionType.markAsStarred,
EmailActionType.moveToMailbox,
if (mailboxDashBoardController.isLabelAvailable &&
mailboxDashBoardController.labelController.labels.isNotEmpty)
EmailActionType.labelAs,
if (mailboxDashBoardController.isLabelAvailable) EmailActionType.labelAs,
if (!threadDetailIsArchived && !threadDetailIsTeamMailbox) EmailActionType.archiveMessage,
threadDetailIsSpam ? EmailActionType.unSpam : EmailActionType.moveToSpam,
threadDetailIsTrashed
@@ -175,6 +175,7 @@ extension OnThreadDetailActionClick on ThreadDetailController {
);
} else {
final submenuController = PopupSubmenuController();
final labelController = mailboxDashBoardController.labelController;
final popupMenuItemEmailActions = moreActions.map((actionType) {
return PopupMenuItemEmailAction(
@@ -187,12 +188,16 @@ extension OnThreadDetailActionClick on ThreadDetailController {
actionType: actionType,
imagePaths: imagePaths,
emailInThreadDetailInfos: emailsInThreadDetailInfo,
labels: mailboxDashBoardController.labelController.labels,
labels: labelController.labels,
onSelectLabelAction: (label, isSelected) {
toggleLabelToThread(label, isSelected: isSelected);
submenuController.hide();
popBack();
},
onCreateANewLabelAction: () => _handleCreateLabelFromSubmenu(
submenuController: submenuController,
labelController: labelController,
)
),
);
}).toList();
@@ -215,6 +220,19 @@ extension OnThreadDetailActionClick on ThreadDetailController {
}
}
void _handleCreateLabelFromSubmenu({
required PopupSubmenuController submenuController,
required LabelController labelController,
}) {
submenuController.hide();
popBack();
labelController.handleLabelActionType(
actionType: LabelActionType.create,
accountId: accountId,
onLabelActionCallback: (label) => toggleLabelToThread(label, isSelected: true),
);
}
bool _shouldHandleAction(EmailActionType action) {
if (action != EmailActionType.labelAs) {
return true;
@@ -228,9 +246,10 @@ extension OnThreadDetailActionClick on ThreadDetailController {
required ImagePaths imagePaths,
required List<EmailInThreadDetailInfo> emailInThreadDetailInfos,
required List<Label>? labels,
OnSelectLabelAction? onSelectLabelAction,
required OnSelectLabelAction onSelectLabelAction,
required OnCreateANewLabelAction onCreateANewLabelAction,
}) {
if (actionType == EmailActionType.labelAs && labels?.isNotEmpty == true) {
if (actionType == EmailActionType.labelAs) {
final listLabels = labels ?? [];
final threadLabels =
emailInThreadDetailInfos.findCommonLabelsInThread(labels: listLabels);
@@ -239,8 +258,8 @@ extension OnThreadDetailActionClick on ThreadDetailController {
labelList: listLabels,
emailLabels: threadLabels,
imagePaths: imagePaths,
onSelectLabelAction: (label, isSelected) =>
onSelectLabelAction?.call(label, isSelected),
onSelectLabelAction: onSelectLabelAction,
onCreateANewLabelAction: onCreateANewLabelAction,
);
}
return null;