TF-4404 Fix missing subject when perform Mail to attendees action in event email

This commit is contained in:
dab246
2026-03-25 10:30:50 +07:00
committed by Dat H. Pham
parent 93c96a2b83
commit 6a245f228a
7 changed files with 245 additions and 33 deletions
@@ -7,12 +7,10 @@ import 'package:model/email/email_action_type.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/list_email_address_extension.dart';
import 'package:model/extensions/utc_date_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
extension EmailActionTypeExtension on EmailActionType {
static const String _defaultReplyPrefix = 'Re:';
static const String _defaultForwardPrefix = 'Fwd:';
String getSubjectComposer(BuildContext? context, String subject) {
final l10n = context != null ? AppLocalizations.of(context) : null;
@@ -20,15 +18,15 @@ extension EmailActionTypeExtension on EmailActionType {
case EmailActionType.reply:
case EmailActionType.replyToList:
case EmailActionType.replyAll:
return _applyPrefix(
return EmailUtils.applyPrefix(
subject: subject,
defaultPrefix: _defaultReplyPrefix,
defaultPrefix: EmailUtils.defaultReplyPrefix,
localizedPrefix: l10n?.prefix_reply_email,
);
case EmailActionType.forward:
return _applyPrefix(
return EmailUtils.applyPrefix(
subject: subject,
defaultPrefix: _defaultForwardPrefix,
defaultPrefix: EmailUtils.defaultForwardPrefix,
localizedPrefix: l10n?.prefix_forward_email,
);
case EmailActionType.editDraft:
@@ -43,29 +41,6 @@ extension EmailActionTypeExtension on EmailActionType {
}
}
String _applyPrefix({
required String subject,
required String defaultPrefix,
String? localizedPrefix,
}) {
final trimmed = subject.trim();
final lowerSubject = trimmed.toLowerCase();
final prefixes = <String>[
defaultPrefix.toLowerCase(),
if (localizedPrefix != null) localizedPrefix.toLowerCase(),
];
final hasPrefix = prefixes.any(lowerSubject.startsWith);
if (hasPrefix) {
return subject;
}
final prefix = localizedPrefix ?? defaultPrefix;
return '$prefix $subject';
}
String getToastMessageMoveToMailboxSuccess(BuildContext context, {String? destinationPath}) {
switch(this) {
case EmailActionType.archiveMessage:
@@ -1499,7 +1499,11 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
);
}
void handleMailToAttendees(CalendarOrganizer? organizer, List<CalendarAttendee>? attendees) {
void handleMailToAttendees(
CalendarOrganizer? organizer,
List<CalendarAttendee>? attendees,
String? eventTitle,
) {
List<EmailAddress> listEmailAddressAttendees = [];
if (organizer != null) {
@@ -1516,7 +1520,10 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
listEmailAddressAttendees.removeInvalidEmails(ownEmailAddress);
log('SingleEmailController::handleMailToAttendees: listEmailAddressMailTo = $listEmailAddressMailTo');
mailboxDashBoardController.openComposer(
ComposerArguments.fromMailtoUri(listEmailAddress: listEmailAddressMailTo)
ComposerArguments.fromMailtoUri(
listEmailAddress: listEmailAddressMailTo,
subject: eventTitle,
)
);
}
@@ -21,6 +21,7 @@ import 'package:jmap_dart_client/jmap/mail/calendar/properties/event_id.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/properties/event_method.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/properties/recurrence_rule/recurrence_rule.dart';
import 'package:tmail_ui_user/features/email/domain/model/event_action.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
@@ -495,4 +496,12 @@ extension CalendarEventExtension on CalendarEvent {
excludedCalendarEvents: excludedCalendarEvents ?? this.excludedCalendarEvents,
);
}
String getMailToAttendeesEventTitle(AppLocalizations appLocalizations) {
return EmailUtils.applyPrefix(
subject: title ?? '',
defaultPrefix: EmailUtils.defaultReplyPrefix,
localizedPrefix: appLocalizations.prefix_reply_email,
);
}
}
@@ -29,9 +29,34 @@ class EmailUtils {
static const double attachmentItemHeight = 36;
static const double attachmentIcon = 20;
static const int maxMobileVisibleAttachments = 3;
static const String defaultReplyPrefix = 'Re:';
static const String defaultForwardPrefix = 'Fwd:';
EmailUtils._();
static String applyPrefix({
required String subject,
required String defaultPrefix,
String? localizedPrefix,
}) {
final trimmed = subject.trim();
final lowerSubject = trimmed.toLowerCase();
final prefixes = <String>[
defaultPrefix.toLowerCase(),
if (localizedPrefix != null) localizedPrefix.toLowerCase(),
];
final hasPrefix = prefixes.any(lowerSubject.startsWith);
if (hasPrefix) {
return subject;
}
final prefix = localizedPrefix ?? defaultPrefix;
return '$prefix $subject';
}
static Properties getPropertiesForEmailGetMethod(Session session, AccountId accountId) {
if (CapabilityIdentifier.jamesCalendarEvent.isSupported(session, accountId)) {
return ThreadConstants.propertiesCalendarEvent;
@@ -10,7 +10,11 @@ import 'package:tmail_ui_user/features/email/presentation/styles/calendar_event_
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_body_content_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_title_widget.dart';
typedef OnMailtoAttendeesAction = Function(CalendarOrganizer? organizer, List<CalendarAttendee>? participants);
typedef OnMailtoAttendeesAction = Function(
CalendarOrganizer? organizer,
List<CalendarAttendee>? participants,
String? eventTitle,
);
class CalendarEventDetailWidget extends StatelessWidget {
@@ -185,6 +185,9 @@ class CalendarEventInformationWidget extends StatelessWidget {
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
calendarEvent.getMailToAttendeesEventTitle(
AppLocalizations.of(context),
),
),
),
],