Skip to content

TF-3894 Fix blank email content when opening email #3896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions integration_test/mixin/scenario_utils_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ mixin ScenarioUtilsMixin {
session: mailboxDashBoardController.sessionCurrent!,
accountId: mailboxDashBoardController.accountId.value!,
emailActionType: EmailActionType.compose,
ownEmailAddress: mailboxDashBoardController.ownEmailAddress.value,
subject: provisioningEmail.subject,
emailContent: provisioningEmail.content,
toRecipients: {EmailAddress(null, provisioningEmail.toEmail)},
Expand Down
3 changes: 2 additions & 1 deletion lib/features/base/base_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -424,11 +424,12 @@ abstract class BaseController extends GetxController
BuildContext context,
Session? session,
AccountId? accountId,
String ownEmailAddress,
) {
if (PlatformInfo.isMobile) {
showLogoutConfirmDialog(
context: context,
userAddress: session?.getOwnEmailAddressOrEmpty() ?? '',
userAddress: ownEmailAddress,
onConfirmAction: () => _handleLogoutAction(session, accountId),
);
} else {
Expand Down
42 changes: 42 additions & 0 deletions lib/features/base/mixin/own_email_address_mixin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:core/utils/app_logger.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';

mixin OwnEmailAddressMixin {
static const String emptyOwnEmailAddress = '';

final RxString ownEmailAddress = RxString('');
Session? sessionCurrent;

void synchronizeOwnEmailAddress(String emailAddress) {
log('$runtimeType::synchronizeOwnEmailAddress:OwnEmailAddress = ${ownEmailAddress.value}, NewEmailAddress = $emailAddress');
if (ownEmailAddress.value.trim().isNotEmpty) return;
ownEmailAddress.value = emailAddress;
}

void updateOwnEmailAddressFromIdentities(List<Identity> listIdentities) {
if (ownEmailAddress.value.trim().isNotEmpty) return;

if (listIdentities.isEmpty) {
synchronizeOwnEmailAddress(emptyOwnEmailAddress);
ownEmailAddress.refresh();
return;
}

final identityEmailAddress = listIdentities.firstOrNull?.email ?? '';
final domain = EmailUtils.getDomainByEmailAddress(identityEmailAddress);
final userEmailAddress =
Comment on lines +29 to +31
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still not understand this point

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We create the exact email the user is using. Because identity has many different emails, only the domain is the same.

sessionCurrent?.generateOwnEmailAddressFromDomain(domain) ?? '';
log('$runtimeType::updateOwnEmailAddressFromIdentities: UserEmailAddress = $userEmailAddress');

if (userEmailAddress.isNotEmpty) {
synchronizeOwnEmailAddress(userEmailAddress);
} else {
synchronizeOwnEmailAddress(emptyOwnEmailAddress);
ownEmailAddress.refresh();
}
}
}
9 changes: 8 additions & 1 deletion lib/features/composer/presentation/composer_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ class ComposerController extends BaseController

TransformHtmlEmailContentInteractor get transformHtmlEmailContentInteractor => _transformHtmlEmailContentInteractor;

String get ownEmailAddress =>
mailboxDashBoardController.ownEmailAddress.value;

late Worker uploadInlineImageWorker;
late Worker dashboardViewStateWorker;
late bool _isEmailBodyLoaded;
Expand Down Expand Up @@ -513,6 +516,7 @@ class ComposerController extends BaseController
session: session,
accountId: accountId,
emailActionType: arguments.emailActionType,
ownEmailAddress: ownEmailAddress,
subject: subjectEmail.value ?? '',
emailContent: emailContent,
fromSender: arguments.presentationEmail?.from ?? {},
Expand Down Expand Up @@ -687,7 +691,7 @@ class ComposerController extends BaseController
required EmailActionType actionType,
String? listPost,
}) {
final senderEmailAddress = mailboxDashBoardController.sessionCurrent?.getOwnEmailAddressOrEmpty();
final senderEmailAddress = ownEmailAddress;
final isSender = presentationEmail.from
.asList()
.any((element) => element.emailAddress.isNotEmpty && element.emailAddress == senderEmailAddress);
Expand Down Expand Up @@ -932,6 +936,7 @@ class ComposerController extends BaseController
session: session,
accountId: accountId,
emailActionType: arguments.emailActionType,
ownEmailAddress: ownEmailAddress,
subject: subjectEmail.value ?? '',
emailContent: emailContent,
fromSender: arguments.presentationEmail?.from ?? {},
Expand Down Expand Up @@ -2082,6 +2087,7 @@ class ComposerController extends BaseController
session: session,
accountId: accountId,
emailActionType: arguments.emailActionType,
ownEmailAddress: ownEmailAddress,
subject: subjectEmail.value ?? '',
emailContent: emailContent,
fromSender: arguments.presentationEmail?.from ?? {},
Expand Down Expand Up @@ -2132,6 +2138,7 @@ class ComposerController extends BaseController
session: mailboxDashBoardController.sessionCurrent!,
accountId: mailboxDashBoardController.accountId.value!,
emailActionType: composerArguments.value!.emailActionType,
ownEmailAddress: ownEmailAddress,
subject: subjectEmail.value ?? '',
emailContent: emailContent,
fromSender: composerArguments.value!.presentationEmail?.from ?? {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:model/email/email_action_type.dart';
import 'package:model/extensions/identity_extension.dart';
import 'package:model/extensions/list_email_address_extension.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/state/button_state.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
Expand Down Expand Up @@ -80,12 +81,18 @@ extension ComposerPrintDraftExtension on ComposerController {
pattern: currentTime.toPatternForPrinting(locale.toLanguageTag()),
);
}
String accountDisplayName = ownEmailAddress;
if (accountDisplayName.trim().isEmpty) {
accountDisplayName = mailboxDashBoardController
.sessionCurrent
?.getOwnEmailAddressOrUsername() ?? '';
}
log('ComposerPrintDraftExtension::_showPrintDraftsDialog:receiveTime = $receiveTime | emailActionType = $emailActionType');
final childWidget = PointerInterceptor(
child: PrintDraftDialogView(
emailPrint: DraftEmailPrint(
appName: appLocalizations.app_name,
userName: mailboxDashBoardController.ownEmailAddress.value,
userName: accountDisplayName,
attachments: uploadController.allAttachmentsUploaded,
emailContent: emailContent,
fromPrefix: appLocalizations.from_email_address_prefix,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/mail_priority_header.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/identity_extension.dart';
Expand All @@ -26,8 +25,8 @@ extension CreateEmailRequestExtension on CreateEmailRequest {
Set<EmailAddress> createSenders() {
if (identity?.email?.isNotEmpty == true) {
return { identity!.toEmailAddress() };
} else if (session.getOwnEmailAddressOrEmpty().isNotEmpty) {
return { EmailAddress(null, session.getOwnEmailAddressOrEmpty()) };
} else if (ownEmailAddress.isNotEmpty) {
return { EmailAddress(null, ownEmailAddress) };
} else {
return {};
}
Expand All @@ -36,8 +35,8 @@ extension CreateEmailRequestExtension on CreateEmailRequest {
String createMdnEmailAddress() {
if (emailActionType == EmailActionType.editDraft && fromSender?.isNotEmpty == true) {
return fromSender!.first.emailAddress;
} else if (session.getOwnEmailAddressOrEmpty().isNotEmpty) {
return session.getOwnEmailAddressOrEmpty();
} else if (ownEmailAddress.isNotEmpty) {
return ownEmailAddress;
} else {
return '';
}
Expand All @@ -52,8 +51,8 @@ extension CreateEmailRequestExtension on CreateEmailRequest {

return identity?.replyTo?.isNotEmpty == true
? identity!.replyTo!
: session.getOwnEmailAddressOrEmpty().isNotEmpty
? {EmailAddress(null, session.getOwnEmailAddressOrEmpty())}
: ownEmailAddress.isNotEmpty
? {EmailAddress(null, ownEmailAddress)}
: null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class CreateEmailRequest with EquatableMixin {
final Session session;
final AccountId accountId;
final EmailActionType emailActionType;
final String ownEmailAddress;
final String subject;
final String emailContent;
final bool hasRequestReadReceipt;
Expand Down Expand Up @@ -51,6 +52,7 @@ class CreateEmailRequest with EquatableMixin {
required this.session,
required this.accountId,
required this.emailActionType,
required this.ownEmailAddress,
required this.subject,
required this.emailContent,
this.fromSender,
Expand Down Expand Up @@ -88,6 +90,7 @@ class CreateEmailRequest with EquatableMixin {
session,
accountId,
emailActionType,
ownEmailAddress,
subject,
emailContent,
fromSender,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1508,7 +1508,11 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
return;
}

final receiverEmailAddress = _getReceiverEmailAddress(currentEmail!) ?? session!.getOwnEmailAddressOrEmpty();
String receiverEmailAddress = _getReceiverEmailAddress(currentEmail!)
?? ownEmailAddress;
if (receiverEmailAddress.trim().isEmpty) {
receiverEmailAddress = session!.getOwnEmailAddressOrUsername();
}
log('SingleEmailController::_handleSendReceiptToSenderAction():receiverEmailAddress: $receiverEmailAddress');
final mdnToSender = _generateMDN(context, currentEmail!, receiverEmailAddress);
final sendReceiptRequest = SendReceiptToSenderRequest(
Expand Down Expand Up @@ -1816,10 +1820,13 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
}

_printEmailButtonState = ButtonState.disabled;

String accountDisplayName = ownEmailAddress;
if (accountDisplayName.trim().isEmpty) {
accountDisplayName = session?.getOwnEmailAddressOrUsername() ?? '';
}
consumeState(emailActionReactor.printEmail(
email,
ownEmailAddress: mailboxDashBoardController.ownEmailAddress.value,
ownEmailAddress: accountDisplayName,
emailLoaded: currentEmailLoaded.value!,
));
}
Expand Down Expand Up @@ -2324,8 +2331,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {

listEmailAddressAttendees.addAll(listEmailAddress);

final currentUserEmail = mailboxDashBoardController.ownEmailAddress.value;
final listEmailAddressMailTo = listEmailAddressAttendees.removeInvalidEmails(currentUserEmail);
final listEmailAddressMailTo =
listEmailAddressAttendees.removeInvalidEmails(ownEmailAddress);
log('SingleEmailController::handleMailToAttendees: listEmailAddressMailTo = $listEmailAddressMailTo');
mailboxDashBoardController.openComposer(
ComposerArguments.fromMailtoUri(listEmailAddress: listEmailAddressMailTo)
Expand All @@ -2341,8 +2348,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
}
}

String getOwnEmailAddress() => session?.getOwnEmailAddressOrEmpty() ?? '';

void onHtmlContentClippedAction(bool isClipped) {
log('SingleEmailController::onHtmlContentClippedAction:isClipped = $isClipped');
isEmailContentClipped.value = isClipped;
Expand Down
11 changes: 4 additions & 7 deletions lib/features/email/presentation/email_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class EmailView extends GetWidget<SingleEmailController> {
position: position,
responsiveUtils: controller.responsiveUtils,
imagePaths: controller.imagePaths,
username: controller.session?.username,
ownEmailAddress: controller.ownEmailAddress,
handleEmailAction: (email, action) => controller.handleEmailAction(context, email, action),
additionalActions: [],
emailIsRead: presentationEmail.hasRead,
Expand Down Expand Up @@ -194,7 +194,7 @@ class EmailView extends GetWidget<SingleEmailController> {
responsiveUtils: controller.responsiveUtils,
emailLoaded: emailLoaded,
presentationEmail: currentEmail,
userName: controller.getOwnEmailAddress(),
userName: controller.ownEmailAddress,
emailActionCallback: controller.pressEmailAction,
);
}),
Expand Down Expand Up @@ -289,7 +289,7 @@ class EmailView extends GetWidget<SingleEmailController> {
position: position,
responsiveUtils: controller.responsiveUtils,
imagePaths: controller.imagePaths,
username: controller.session?.username,
ownEmailAddress: controller.ownEmailAddress,
handleEmailAction: (email, action) => controller.handleEmailAction(context, email, action),
additionalActions: [
EmailActionType.forward,
Expand Down Expand Up @@ -362,10 +362,7 @@ class EmailView extends GetWidget<SingleEmailController> {
),
calendarEventReplying: controller.calendarEventProcessing,
attendanceStatus: controller.attendanceStatus.value,
ownEmailAddress: controller
.mailboxDashBoardController
.ownEmailAddress
.value,
ownEmailAddress: controller.ownEmailAddress,
onMailtoAttendeesAction: controller.handleMailToAttendees,
openEmailAddressDetailAction: (_, emailAddress) => controller.openEmailAddressDialog(emailAddress),
isFree: controller.isCalendarEventFree,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
Expand Down Expand Up @@ -527,7 +526,7 @@ class EmailActionReactor with MessageDialogActionMixin {
required RelativeRect? position,
required ResponsiveUtils responsiveUtils,
required ImagePaths imagePaths,
required UserName? username,
required String ownEmailAddress,
required void Function(
PresentationEmail presentationEmail,
EmailActionType action,
Expand All @@ -542,7 +541,7 @@ class EmailActionReactor with MessageDialogActionMixin {
final moreActions = [
if (additionalActions.contains(EmailActionType.forward))
EmailActionType.forward,
if (presentationEmail.getCountMailAddressWithoutMe(username?.value ?? '') > 1 &&
if (presentationEmail.getCountMailAddressWithoutMe(ownEmailAddress) > 1 &&
additionalActions.contains(EmailActionType.replyAll))
EmailActionType.replyAll,
if (EmailUtils.isReplyToListEnabled(presentationEmail.listPost ?? '') &&
Expand Down
10 changes: 10 additions & 0 deletions lib/features/email/presentation/utils/email_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,14 @@ class EmailUtils {
? [attachments.first]
: attachments.sublist(0, possibleDisplayedCount);
}

static String getDomainByEmailAddress(String emailAddress) {
try {
MailAddress mailAddress = MailAddress.validateAddress(emailAddress);
return mailAddress.domain.asString();
} catch (e) {
logError('EmailUtils::getDomainByEmailAddress:Exception is $e');
return '';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ class EmailPreviewerController extends ReloadableController {
consumeState(_previewEmailFromEmlFileInteractor.execute(
PreviewEmailEMLRequest(
accountId: _accountId!,
ownEmailAddress: _session!.getOwnEmailAddressOrEmpty(),
ownEmailAddress: _session!.getOwnEmailAddressOrUsername(),
blobId: success.blobId,
email: success.email,
locale: Localizations.localeOf(currentContext!),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,12 @@ class IdentityCreatorController extends BaseController with DragDropFileMixin im
.toSet()
.toList();

if(session?.getOwnEmailAddressOrEmpty().isNotEmpty == true
&& !listEmailAddressDefault.any((emailAddress) => emailAddress.email == session?.getOwnEmailAddressOrEmpty())) {
listEmailAddressDefault.add(EmailAddress(
null,
session?.getOwnEmailAddressOrEmpty(),
));
final ownEmailAddress = arguments?.ownerEmailAddress ?? '';
final isOwnEmailAddressInList = listEmailAddressDefault
.any((emailAddress) => emailAddress.email == ownEmailAddress);

if (ownEmailAddress.isNotEmpty && !isOwnEmailAddressInList) {
listEmailAddressDefault.add(EmailAddress(null, ownEmailAddress));
}
listEmailAddressOfReplyTo.add(noneEmailAddress);
listEmailAddressOfReplyTo.addAll(listEmailAddressDefault);
Expand All @@ -385,11 +385,9 @@ class IdentityCreatorController extends BaseController with DragDropFileMixin im
void _setDefaultEmailAddressList() {
listEmailAddressOfReplyTo.add(noneEmailAddress);

if (session?.getOwnEmailAddressOrEmpty().isNotEmpty == true) {
final userEmailAddress = EmailAddress(
null,
session?.getOwnEmailAddressOrEmpty(),
);
final ownEmailAddress = arguments?.ownerEmailAddress ?? '';
if (ownEmailAddress.isNotEmpty) {
final userEmailAddress = EmailAddress(null, ownEmailAddress);
listEmailAddressDefault.add(userEmailAddress);
listEmailAddressOfReplyTo.addAll(listEmailAddressDefault);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_i
class IdentityCreatorArguments with EquatableMixin {
final AccountId accountId;
final Session session;
final String ownerEmailAddress;
final IdentityActionType actionType;
final PublicAssetsInIdentityArguments? publicAssetsInIdentityArguments;
final bool? isDefault;
Expand All @@ -17,6 +18,7 @@ class IdentityCreatorArguments with EquatableMixin {
IdentityCreatorArguments(
this.accountId,
this.session,
this.ownerEmailAddress,
{
this.identity,
this.publicAssetsInIdentityArguments,
Expand Down
Loading
Loading