diff --git a/components/email/email-viewer.tsx b/components/email/email-viewer.tsx index 1f0e34ce..41fc6d1a 100644 --- a/components/email/email-viewer.tsx +++ b/components/email/email-viewer.tsx @@ -2296,8 +2296,12 @@ export function EmailViewer({ htmlContent = email.bodyValues[email.htmlBody[0].partId].value; // Prefer textBody when HTML is auto-generated minimal wrapper (no rich formatting). // Server-generated HTML from text/plain emails often lacks
tags, collapsing newlines. - const hasTextBody = email.textBody?.[0]?.partId && email.bodyValues[email.textBody[0].partId]; - if (hasTextBody && htmlContent) { + // Per RFC 8621, an HTML-only email exposes the same partId in both htmlBody and textBody — + // in that case there is no real plain-text alternative, so always render the HTML. + const textPartId = email.textBody?.[0]?.partId; + const htmlPartId = email.htmlBody[0].partId; + const hasDistinctTextBody = !!textPartId && textPartId !== htmlPartId && !!email.bodyValues[textPartId]; + if (hasDistinctTextBody && htmlContent) { useHtmlVersion = hasMeaningfulHtmlBody(htmlContent); } else { useHtmlVersion = !!htmlContent; @@ -4562,34 +4566,50 @@ export function EmailViewer({
{/* External Content Controls */} {hasBlockedContent && !allowExternalContent && externalContentPolicy !== 'allow' && ( -
- {externalContentPolicy === 'ask' && ( - - )} - {email.from?.[0]?.email && ( - - )} +
+
+ +
+
+
+
+ External Content +
+
+ {t('external_content_warning')} +
+
+
+ {externalContentPolicy === 'ask' && ( + + )} + {email.from?.[0]?.email && ( + + )} +
+
)} diff --git a/components/email/thread-conversation-view.tsx b/components/email/thread-conversation-view.tsx index 48fe735c..1d0843f0 100644 --- a/components/email/thread-conversation-view.tsx +++ b/components/email/thread-conversation-view.tsx @@ -331,8 +331,12 @@ function EmailCard({ htmlContent = email.bodyValues[email.htmlBody[0].partId].value; // Prefer textBody when HTML is auto-generated minimal wrapper (no rich formatting). // Server-generated HTML from text/plain emails often lacks
tags, collapsing newlines. - const hasTextBody = email.textBody?.[0]?.partId && email.bodyValues[email.textBody[0].partId]; - if (hasTextBody && htmlContent) { + // Per RFC 8621, an HTML-only email exposes the same partId in both htmlBody and textBody — + // in that case there is no real plain-text alternative, so always render the HTML. + const textPartId = email.textBody?.[0]?.partId; + const htmlPartId = email.htmlBody[0].partId; + const hasDistinctTextBody = !!textPartId && textPartId !== htmlPartId && !!email.bodyValues[textPartId]; + if (hasDistinctTextBody && htmlContent) { useHtmlVersion = hasMeaningfulHtmlBody(htmlContent); } else { useHtmlVersion = !!htmlContent;