courrier preview
This commit is contained in:
parent
0251b08113
commit
fba2b1213f
@ -346,112 +346,51 @@ export function formatReplyEmail(originalEmail: EmailMessage | LegacyEmailMessag
|
|||||||
// Get header information
|
// Get header information
|
||||||
const { fromStr, dateStr, subject } = getFormattedHeaderInfo(originalEmail);
|
const { fromStr, dateStr, subject } = getFormattedHeaderInfo(originalEmail);
|
||||||
|
|
||||||
// Extract content using centralized utility - get simpler text version when possible
|
// Extract just the text content for a clean reply
|
||||||
const { text: originalTextContent, html: originalHtmlContent } = extractEmailContent(originalEmail);
|
let emailText = '';
|
||||||
|
|
||||||
// Simpler approach - prefer text content when available for clean replies
|
|
||||||
let replyBody = '';
|
|
||||||
let textReply = '';
|
|
||||||
|
|
||||||
// Create a header that works in both HTML and plain text
|
// Try to get text directly from content.text first
|
||||||
const headerHtml = `<div style="margin-top: 20px; margin-bottom: 10px; color: #666;">On ${dateStr}, ${fromStr} wrote:</div>`;
|
if (originalEmail.content && typeof originalEmail.content === 'object' && originalEmail.content.text) {
|
||||||
|
emailText = originalEmail.content.text;
|
||||||
// Use extracted text content when available for cleaner replies
|
|
||||||
if (originalTextContent) {
|
|
||||||
// Use text content with proper line breaks - limit to a reasonable size
|
|
||||||
const maxChars = 1500;
|
|
||||||
const truncatedText = originalTextContent.length > maxChars
|
|
||||||
? originalTextContent.slice(0, maxChars) + '... [message truncated]'
|
|
||||||
: originalTextContent;
|
|
||||||
|
|
||||||
replyBody = `
|
|
||||||
${headerHtml}
|
|
||||||
<blockquote style="margin: 10px 0; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
|
||||||
${truncatedText.replace(/\n/g, '<br>')}
|
|
||||||
</blockquote>
|
|
||||||
`;
|
|
||||||
|
|
||||||
textReply = `
|
|
||||||
On ${dateStr}, ${fromStr} wrote:
|
|
||||||
> ${truncatedText.split('\n').join('\n> ')}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
// If no text, try to sanitize and simplify HTML
|
// Otherwise, fall back to extractEmailContent which tries various formats
|
||||||
else if (originalHtmlContent) {
|
else {
|
||||||
try {
|
const { text } = extractEmailContent(originalEmail);
|
||||||
// Sanitize the original HTML to remove problematic elements and simplify
|
emailText = text;
|
||||||
const sanitizedHtml = sanitizeHtml(originalHtmlContent);
|
}
|
||||||
|
|
||||||
// Extract the text content from the sanitized HTML for the plaintext version
|
// Create simple reply with header
|
||||||
const tempDiv = document.createElement('div');
|
const cleanReplyHeader = `<div style="margin: 20px 0 10px 0; color: #666; border-bottom: 1px solid #eee; padding-bottom: 10px;">On ${dateStr}, ${fromStr} wrote:</div>`;
|
||||||
tempDiv.innerHTML = sanitizedHtml;
|
|
||||||
const extractedText = tempDiv.textContent || tempDiv.innerText || '';
|
// Limit text to reasonable size and format as simple HTML
|
||||||
|
const maxChars = 1000;
|
||||||
// Limit to a reasonable size
|
const truncatedText = emailText.length > maxChars
|
||||||
const maxChars = 1500;
|
? emailText.slice(0, maxChars) + '... [message truncated]'
|
||||||
const truncatedText = extractedText.length > maxChars
|
: emailText;
|
||||||
? extractedText.slice(0, maxChars) + '... [message truncated]'
|
|
||||||
: extractedText;
|
const cleanHtml = `
|
||||||
|
${cleanReplyHeader}
|
||||||
replyBody = `
|
<blockquote style="margin: 0; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
||||||
${headerHtml}
|
<p>${truncatedText.replace(/\n/g, '</p><p>')}</p>
|
||||||
<blockquote style="margin: 10px 0; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
</blockquote>
|
||||||
${truncatedText.replace(/\n/g, '<br>')}
|
`;
|
||||||
</blockquote>
|
|
||||||
`;
|
// Plain text version
|
||||||
|
const plainText = `
|
||||||
textReply = `
|
|
||||||
On ${dateStr}, ${fromStr} wrote:
|
On ${dateStr}, ${fromStr} wrote:
|
||||||
> ${truncatedText.split('\n').join('\n> ')}
|
> ${truncatedText.split('\n').join('\n> ')}
|
||||||
`;
|
`;
|
||||||
} catch (error) {
|
|
||||||
console.error('Error processing HTML for reply:', error);
|
|
||||||
// Fallback to a basic template if everything fails
|
|
||||||
replyBody = `
|
|
||||||
${headerHtml}
|
|
||||||
<blockquote style="margin: 10px 0; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
|
||||||
[Original message content could not be processed]
|
|
||||||
</blockquote>
|
|
||||||
`;
|
|
||||||
|
|
||||||
textReply = `
|
|
||||||
On ${dateStr}, ${fromStr} wrote:
|
|
||||||
> [Original message content could not be processed]
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Empty or unrecognized content
|
|
||||||
replyBody = `
|
|
||||||
${headerHtml}
|
|
||||||
<blockquote style="margin: 10px 0; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
|
||||||
[Original message content not available]
|
|
||||||
</blockquote>
|
|
||||||
`;
|
|
||||||
|
|
||||||
textReply = `
|
|
||||||
On ${dateStr}, ${fromStr} wrote:
|
|
||||||
> [Original message content not available]
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the content with proper direction
|
|
||||||
const processed = processContentWithDirection(replyBody);
|
|
||||||
|
|
||||||
// Extract any inline images as attachments
|
|
||||||
const inlineImages = extractInlineImages(originalHtmlContent);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
to,
|
to,
|
||||||
cc,
|
cc,
|
||||||
subject: subject.startsWith('Re:') ? subject : `Re: ${subject}`,
|
subject: subject.startsWith('Re:') ? subject : `Re: ${subject}`,
|
||||||
content: {
|
content: {
|
||||||
text: textReply.trim(),
|
text: plainText.trim(),
|
||||||
html: processed.html,
|
html: cleanHtml,
|
||||||
isHtml: true,
|
isHtml: true,
|
||||||
direction: processed.direction
|
direction: 'ltr'
|
||||||
},
|
}
|
||||||
// Include inline images as attachments if any were found
|
|
||||||
attachments: inlineImages.length > 0 ? inlineImages : undefined
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,17 +414,23 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe
|
|||||||
// Get header information
|
// Get header information
|
||||||
const { fromStr, toStr, ccStr, dateStr, subject } = getFormattedHeaderInfo(originalEmail);
|
const { fromStr, toStr, ccStr, dateStr, subject } = getFormattedHeaderInfo(originalEmail);
|
||||||
|
|
||||||
// Extract content using centralized utility - get simpler text version when possible
|
// Extract just the text content for a clean forward
|
||||||
const { text: originalTextContent, html: originalHtmlContent } = extractEmailContent(originalEmail);
|
let emailText = '';
|
||||||
|
|
||||||
// Simpler approach - prefer text content when available for clean forwards
|
|
||||||
let forwardBody = '';
|
|
||||||
let textForward = '';
|
|
||||||
|
|
||||||
// Create metadata header that works in both HTML and plain text
|
// Try to get text directly from content.text first
|
||||||
const headerHtml = `
|
if (originalEmail.content && typeof originalEmail.content === 'object' && originalEmail.content.text) {
|
||||||
<div style="margin-top: 20px; color: #666;">
|
emailText = originalEmail.content.text;
|
||||||
<div>---------- Forwarded message ---------</div>
|
}
|
||||||
|
// Otherwise, fall back to extractEmailContent which tries various formats
|
||||||
|
else {
|
||||||
|
const { text } = extractEmailContent(originalEmail);
|
||||||
|
emailText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create simple forward with metadata header
|
||||||
|
const cleanForwardHeader = `
|
||||||
|
<div style="margin: 20px 0 10px 0; color: #666; border-bottom: 1px solid #eee; padding-bottom: 10px;">
|
||||||
|
<div><strong>---------- Forwarded message ---------</strong></div>
|
||||||
<div><strong>From:</strong> ${fromStr}</div>
|
<div><strong>From:</strong> ${fromStr}</div>
|
||||||
<div><strong>Date:</strong> ${dateStr}</div>
|
<div><strong>Date:</strong> ${dateStr}</div>
|
||||||
<div><strong>Subject:</strong> ${subject || ''}</div>
|
<div><strong>Subject:</strong> ${subject || ''}</div>
|
||||||
@ -494,22 +439,21 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Use extracted text content when available for cleaner forwards
|
// Limit text to reasonable size and format as simple HTML
|
||||||
if (originalTextContent) {
|
const maxChars = 1500;
|
||||||
// Use text content with proper line breaks - limit to a reasonable size
|
const truncatedText = emailText.length > maxChars
|
||||||
const maxChars = 2000;
|
? emailText.slice(0, maxChars) + '... [message truncated]'
|
||||||
const truncatedText = originalTextContent.length > maxChars
|
: emailText;
|
||||||
? originalTextContent.slice(0, maxChars) + '... [message truncated]'
|
|
||||||
: originalTextContent;
|
const cleanHtml = `
|
||||||
|
${cleanForwardHeader}
|
||||||
forwardBody = `
|
<blockquote style="margin: 0; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
||||||
${headerHtml}
|
<p>${truncatedText.replace(/\n/g, '</p><p>')}</p>
|
||||||
<blockquote style="margin-top: 10px; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
</blockquote>
|
||||||
${truncatedText.replace(/\n/g, '<br>')}
|
`;
|
||||||
</blockquote>
|
|
||||||
`;
|
// Plain text version
|
||||||
|
const plainText = `
|
||||||
textForward = `
|
|
||||||
---------- Forwarded message ---------
|
---------- Forwarded message ---------
|
||||||
From: ${fromStr}
|
From: ${fromStr}
|
||||||
Date: ${dateStr}
|
Date: ${dateStr}
|
||||||
@ -518,114 +462,26 @@ To: ${toStr}
|
|||||||
${ccStr ? `Cc: ${ccStr}\n` : ''}
|
${ccStr ? `Cc: ${ccStr}\n` : ''}
|
||||||
|
|
||||||
${truncatedText}
|
${truncatedText}
|
||||||
`;
|
`;
|
||||||
}
|
|
||||||
// If no text, try to sanitize and simplify HTML
|
|
||||||
else if (originalHtmlContent) {
|
|
||||||
try {
|
|
||||||
// Sanitize the original HTML to remove problematic elements and simplify
|
|
||||||
const sanitizedHtml = sanitizeHtml(originalHtmlContent);
|
|
||||||
|
|
||||||
// Extract the text content from the sanitized HTML for the plaintext version
|
|
||||||
const tempDiv = document.createElement('div');
|
|
||||||
tempDiv.innerHTML = sanitizedHtml;
|
|
||||||
const extractedText = tempDiv.textContent || tempDiv.innerText || '';
|
|
||||||
|
|
||||||
// Limit to a reasonable size
|
|
||||||
const maxChars = 2000;
|
|
||||||
const truncatedText = extractedText.length > maxChars
|
|
||||||
? extractedText.slice(0, maxChars) + '... [message truncated]'
|
|
||||||
: extractedText;
|
|
||||||
|
|
||||||
forwardBody = `
|
|
||||||
${headerHtml}
|
|
||||||
<blockquote style="margin-top: 10px; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
|
||||||
${truncatedText.replace(/\n/g, '<br>')}
|
|
||||||
</blockquote>
|
|
||||||
`;
|
|
||||||
|
|
||||||
textForward = `
|
|
||||||
---------- Forwarded message ---------
|
|
||||||
From: ${fromStr}
|
|
||||||
Date: ${dateStr}
|
|
||||||
Subject: ${subject || ''}
|
|
||||||
To: ${toStr}
|
|
||||||
${ccStr ? `Cc: ${ccStr}\n` : ''}
|
|
||||||
|
|
||||||
${truncatedText}
|
// Check if original has attachments
|
||||||
`;
|
const attachments = originalEmail.attachments || [];
|
||||||
} catch (error) {
|
|
||||||
console.error('Error processing HTML for forward:', error);
|
|
||||||
// Fallback to a basic template if everything fails
|
|
||||||
forwardBody = `
|
|
||||||
${headerHtml}
|
|
||||||
<blockquote style="margin-top: 10px; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
|
||||||
[Original message content could not be processed]
|
|
||||||
</blockquote>
|
|
||||||
`;
|
|
||||||
|
|
||||||
textForward = `
|
|
||||||
---------- Forwarded message ---------
|
|
||||||
From: ${fromStr}
|
|
||||||
Date: ${dateStr}
|
|
||||||
Subject: ${subject || ''}
|
|
||||||
To: ${toStr}
|
|
||||||
${ccStr ? `Cc: ${ccStr}\n` : ''}
|
|
||||||
|
|
||||||
[Original message content could not be processed]
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Empty or unrecognized content
|
|
||||||
forwardBody = `
|
|
||||||
${headerHtml}
|
|
||||||
<blockquote style="margin-top: 10px; padding-left: 10px; border-left: 2px solid #ddd; color: #505050;">
|
|
||||||
[Original message content not available]
|
|
||||||
</blockquote>
|
|
||||||
`;
|
|
||||||
|
|
||||||
textForward = `
|
|
||||||
---------- Forwarded message ---------
|
|
||||||
From: ${fromStr}
|
|
||||||
Date: ${dateStr}
|
|
||||||
Subject: ${subject || ''}
|
|
||||||
To: ${toStr}
|
|
||||||
${ccStr ? `Cc: ${ccStr}\n` : ''}
|
|
||||||
|
|
||||||
[Original message content not available]
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the content with proper direction
|
|
||||||
const processed = processContentWithDirection(forwardBody);
|
|
||||||
|
|
||||||
// Check if the original email has attachments
|
|
||||||
const originalAttachments = originalEmail.attachments || [];
|
|
||||||
|
|
||||||
// Extract any inline images and add to attachments
|
|
||||||
const inlineImages = extractInlineImages(originalHtmlContent);
|
|
||||||
|
|
||||||
// Combine original attachments and inline images
|
|
||||||
const combinedAttachments = [
|
|
||||||
...originalAttachments.map(att => ({
|
|
||||||
filename: att.filename || 'attachment',
|
|
||||||
contentType: att.contentType || 'application/octet-stream',
|
|
||||||
content: att.content
|
|
||||||
})),
|
|
||||||
...inlineImages
|
|
||||||
];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
to: '',
|
to: '',
|
||||||
subject: subject.startsWith('Fwd:') ? subject : `Fwd: ${subject}`,
|
subject: subject.startsWith('Fwd:') ? subject : `Fwd: ${subject}`,
|
||||||
content: {
|
content: {
|
||||||
text: textForward.trim(),
|
text: plainText.trim(),
|
||||||
html: processed.html,
|
html: cleanHtml,
|
||||||
isHtml: true,
|
isHtml: true,
|
||||||
direction: 'ltr'
|
direction: 'ltr'
|
||||||
},
|
},
|
||||||
// Include attachments if any were found
|
// Only include attachments if they exist
|
||||||
attachments: combinedAttachments.length > 0 ? combinedAttachments : undefined
|
attachments: attachments.length > 0 ? attachments.map(att => ({
|
||||||
|
filename: att.filename || 'attachment',
|
||||||
|
contentType: att.contentType || 'application/octet-stream',
|
||||||
|
content: att.content
|
||||||
|
})) : undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user