courrier clean 2
This commit is contained in:
parent
97fb21a632
commit
051bcb08a4
@ -340,20 +340,6 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug the email object structure
|
||||
console.log('Forwarding email object:', {
|
||||
id: initialEmail.id,
|
||||
subject: initialEmail.subject,
|
||||
fromLength: initialEmail.from?.length,
|
||||
from: initialEmail.from,
|
||||
to: initialEmail.to,
|
||||
date: initialEmail.date,
|
||||
hasContent: Boolean(initialEmail.content),
|
||||
contentLength: initialEmail.content?.length,
|
||||
hasHtml: Boolean(initialEmail.html),
|
||||
htmlLength: initialEmail.html?.length
|
||||
});
|
||||
|
||||
try {
|
||||
// Format subject with Fwd: prefix if needed
|
||||
const subjectBase = initialEmail.subject || '(No subject)';
|
||||
@ -364,62 +350,58 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
|
||||
|
||||
setSubject(subject);
|
||||
|
||||
// Format the forwarded message with a well-structured header
|
||||
// Format the forwarded message as a simple text representation with clean formatting
|
||||
let forwardedText = '';
|
||||
|
||||
// Format the "From" field
|
||||
const fromString = Array.isArray(initialEmail.from) && initialEmail.from.length > 0
|
||||
? initialEmail.from.map(addr => addr.name
|
||||
? `${addr.name} <${addr.address}>`
|
||||
: addr.address).join(', ')
|
||||
: 'Unknown';
|
||||
|
||||
// Format the "To" field
|
||||
const toString = Array.isArray(initialEmail.to) && initialEmail.to.length > 0
|
||||
? initialEmail.to.map(addr => addr.name
|
||||
? `${addr.name} <${addr.address}>`
|
||||
: addr.address).join(', ')
|
||||
: '';
|
||||
|
||||
// Format the date
|
||||
const dateString = initialEmail.date
|
||||
? typeof initialEmail.date === 'string'
|
||||
? new Date(initialEmail.date).toLocaleString()
|
||||
: initialEmail.date.toLocaleString()
|
||||
: new Date().toLocaleString();
|
||||
|
||||
// Create a clean header with inline styles only - no external CSS
|
||||
const headerHtml = `
|
||||
<div style="border-top: 1px solid #e1e1e1; margin-top: 20px; padding-top: 15px; font-family: Arial, sans-serif; color: #333;">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<div style="font-weight: normal; margin-bottom: 10px;">---------- Forwarded message ---------</div>
|
||||
<div><b>From:</b> ${fromString}</div>
|
||||
<div><b>Date:</b> ${dateString}</div>
|
||||
<div><b>Subject:</b> ${subjectBase}</div>
|
||||
<div><b>To:</b> ${toString}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
// Create a simple text representation of the forwarded header
|
||||
forwardedText += '---------- Forwarded message ---------\n';
|
||||
forwardedText += `From: ${fromString}\n`;
|
||||
forwardedText += `Date: ${dateString}\n`;
|
||||
forwardedText += `Subject: ${subjectBase}\n`;
|
||||
forwardedText += `To: ${toString}\n\n`;
|
||||
|
||||
// Default content is a clear "no content" message
|
||||
let contentHtml = '<div style="color: #666; font-style: italic; padding: 15px; font-size: 14px; border: 1px dashed #ccc; margin: 15px 0; text-align: center; background-color: #f9f9f9; border-radius: 4px;">No content available in original email</div>';
|
||||
|
||||
// Check if we have content to forward
|
||||
// Add the content - clean and sanitize the HTML to prevent formatting issues
|
||||
if (initialEmail.content || initialEmail.html || initialEmail.text) {
|
||||
// Use the most complete version of content available
|
||||
contentHtml = DOMPurify.sanitize(
|
||||
initialEmail.content || initialEmail.html ||
|
||||
`<pre style="white-space: pre-wrap;">${initialEmail.text || ''}</pre>`,
|
||||
{
|
||||
ADD_ATTR: ['style', 'class'],
|
||||
ALLOW_DATA_ATTR: true,
|
||||
USE_PROFILES: { html: true }
|
||||
}
|
||||
);
|
||||
// Try to extract text from HTML content
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = initialEmail.content || initialEmail.html || initialEmail.text || '';
|
||||
|
||||
// Get the text content, preserving line breaks
|
||||
let cleanContent = tempDiv.textContent || tempDiv.innerText || '';
|
||||
|
||||
// Add the clean content
|
||||
forwardedText += cleanContent;
|
||||
} else {
|
||||
forwardedText += 'No content available in original email';
|
||||
}
|
||||
|
||||
// Set the original content for display
|
||||
setOriginalContent(`${headerHtml}<div class="forwarded-content" style="color: #333;">${contentHtml}</div>`);
|
||||
// Set the forwarded text as the original content (plain text preserves formatting better)
|
||||
setOriginalContent(forwardedText);
|
||||
|
||||
// Leave the editorRef empty to allow user to type their message
|
||||
// Keep user message separate
|
||||
setUserMessage('');
|
||||
setBody('');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error formatting forwarded email:', error);
|
||||
setBody('<div style="color: #666; font-style: italic;">Error formatting forwarded email content</div>');
|
||||
@ -483,12 +465,23 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
|
||||
try {
|
||||
setSending(true);
|
||||
|
||||
// Combine user message with original content for forwarded emails
|
||||
let finalBody = '';
|
||||
|
||||
if (type === 'forward' && originalContent) {
|
||||
// Format the user message + forwarded content properly
|
||||
finalBody = `${userMessage}\n\n${originalContent}`;
|
||||
} else {
|
||||
// For other cases, use the current body
|
||||
finalBody = editorRef.current?.innerHTML || body;
|
||||
}
|
||||
|
||||
await onSend({
|
||||
to,
|
||||
cc: cc || undefined,
|
||||
bcc: bcc || undefined,
|
||||
subject,
|
||||
body: editorRef.current?.innerHTML || body,
|
||||
body: finalBody,
|
||||
attachments
|
||||
});
|
||||
|
||||
@ -507,12 +500,8 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
|
||||
const content = editorRef.current.innerHTML;
|
||||
setUserMessage(content);
|
||||
|
||||
// Combine user message with original content
|
||||
if (originalContent) {
|
||||
setBody(`${content}<div class="quote-divider"></div>${originalContent}`);
|
||||
} else {
|
||||
setBody(content);
|
||||
}
|
||||
// Simply update body with user message - we'll combine with original content when sending
|
||||
setBody(content);
|
||||
}
|
||||
};
|
||||
|
||||
@ -648,58 +637,21 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Original content display with visual separation - editable for replies/forwards */}
|
||||
{/* Original content display with visual separation - now as plain text for better reliability */}
|
||||
{type !== 'new' && originalContent && (
|
||||
<div className="border-t">
|
||||
<div className="px-4 py-2 bg-gray-50 text-xs font-medium text-gray-500">
|
||||
{type === 'forward' ? 'Forwarded content (editable)' : 'Original message (editable)'}
|
||||
{type === 'forward' ? 'Forwarded content' : 'Original message'}
|
||||
</div>
|
||||
<div
|
||||
className="p-4 bg-gray-50 text-sm original-content"
|
||||
contentEditable={!sending}
|
||||
dangerouslySetInnerHTML={{ __html: originalContent }}
|
||||
<pre
|
||||
className="p-4 bg-gray-50 text-sm original-content font-mono whitespace-pre-wrap overflow-auto"
|
||||
style={{
|
||||
opacity: 1.0,
|
||||
overflow: 'auto',
|
||||
whiteSpace: 'pre-wrap',
|
||||
wordBreak: 'break-word',
|
||||
overflowWrap: 'break-word'
|
||||
lineHeight: '1.5',
|
||||
maxHeight: '400px'
|
||||
}}
|
||||
onInput={(e) => {
|
||||
// Prevent default behavior that might cause text flow issues
|
||||
e.preventDefault();
|
||||
|
||||
// Get the current caret position to restore it later
|
||||
const selection = window.getSelection();
|
||||
const range = selection?.getRangeAt(0);
|
||||
const offset = range?.startOffset || 0;
|
||||
const node = range?.startContainer;
|
||||
|
||||
// Update content
|
||||
const target = e.target as HTMLDivElement;
|
||||
setOriginalContent(target.innerHTML);
|
||||
|
||||
// Update the complete body without disturbing the text flow
|
||||
const userPart = editorRef.current?.innerHTML || '';
|
||||
setBody(`${userPart}<div class="quote-divider"></div>${target.innerHTML}`);
|
||||
|
||||
// Try to restore cursor position after state update
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (selection && range && node && node.parentNode) {
|
||||
// Attempt to find the same node
|
||||
const newRange = document.createRange();
|
||||
newRange.setStart(node, Math.min(offset, node.textContent?.length || 0));
|
||||
newRange.collapse(true);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(newRange);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error restoring cursor position:', err);
|
||||
}
|
||||
}, 0);
|
||||
}}
|
||||
/>
|
||||
>
|
||||
{originalContent}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user