panel 2 courier api restore
This commit is contained in:
parent
78c8823a01
commit
6eb06a5dc2
@ -135,24 +135,17 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
if (mounted) {
|
if (mounted) {
|
||||||
// Update the email content with the fetched full content
|
// Update the email content with the fetched full content
|
||||||
email.content = fullContent.content;
|
email.content = fullContent.content;
|
||||||
|
email.contentFetched = true;
|
||||||
|
|
||||||
// Render the content
|
// Render the content - call ourselves again now that we have content
|
||||||
const sanitizedHtml = DOMPurify.sanitize(fullContent.content);
|
setDebugInfo('Content fetched from API, reprocessing');
|
||||||
setContent(
|
loadContent();
|
||||||
<div
|
return;
|
||||||
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
|
||||||
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
setDebugInfo('Rendered fetched HTML content');
|
|
||||||
setError(null);
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use existing content if available
|
// Use existing content if available
|
||||||
console.log('Using existing content for email');
|
console.log('Processing content for email:', email.id);
|
||||||
|
|
||||||
const formattedEmail = email.content.trim();
|
const formattedEmail = email.content.trim();
|
||||||
if (!formattedEmail) {
|
if (!formattedEmail) {
|
||||||
@ -165,23 +158,13 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if content is already HTML
|
try {
|
||||||
if (formattedEmail.startsWith('<') && formattedEmail.endsWith('>')) {
|
// Always try to use the mail parser first for consistency
|
||||||
// Content is likely HTML, sanitize and display directly
|
console.log('Parsing email content with mailparser');
|
||||||
const sanitizedHtml = DOMPurify.sanitize(formattedEmail);
|
|
||||||
setContent(
|
|
||||||
<div
|
|
||||||
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
|
||||||
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
setDebugInfo('Rendered existing HTML content');
|
|
||||||
} else {
|
|
||||||
// Use mailparser for more complex formats
|
|
||||||
console.log('Parsing email content');
|
|
||||||
const parsedEmail = await decodeEmail(formattedEmail);
|
const parsedEmail = await decodeEmail(formattedEmail);
|
||||||
|
|
||||||
if (parsedEmail.html) {
|
if (parsedEmail.html) {
|
||||||
|
console.log('Using HTML content from parser');
|
||||||
const sanitizedHtml = DOMPurify.sanitize(parsedEmail.html);
|
const sanitizedHtml = DOMPurify.sanitize(parsedEmail.html);
|
||||||
setContent(
|
setContent(
|
||||||
<div
|
<div
|
||||||
@ -191,6 +174,7 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
);
|
);
|
||||||
setDebugInfo('Rendered HTML content from parser');
|
setDebugInfo('Rendered HTML content from parser');
|
||||||
} else if (parsedEmail.text) {
|
} else if (parsedEmail.text) {
|
||||||
|
console.log('Using text content from parser');
|
||||||
setContent(
|
setContent(
|
||||||
<div className="email-content whitespace-pre-wrap">
|
<div className="email-content whitespace-pre-wrap">
|
||||||
{parsedEmail.text}
|
{parsedEmail.text}
|
||||||
@ -198,9 +182,36 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
);
|
);
|
||||||
setDebugInfo('Rendered text content from parser');
|
setDebugInfo('Rendered text content from parser');
|
||||||
} else {
|
} else {
|
||||||
setContent(<div className="text-gray-500">No displayable content available</div>);
|
// Fallback to direct display if parser didn't give us anything
|
||||||
setDebugInfo('No HTML or text content in parsed email');
|
if (formattedEmail.startsWith('<') && formattedEmail.endsWith('>')) {
|
||||||
|
// Content is likely HTML, sanitize and display directly
|
||||||
|
const sanitizedHtml = DOMPurify.sanitize(formattedEmail);
|
||||||
|
setContent(
|
||||||
|
<div
|
||||||
|
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
||||||
|
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
setDebugInfo('Rendered raw HTML content');
|
||||||
|
} else {
|
||||||
|
// Just display as text
|
||||||
|
setContent(
|
||||||
|
<div className="email-content whitespace-pre-wrap">
|
||||||
|
{formattedEmail}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
setDebugInfo('Rendered raw text content');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (parseError) {
|
||||||
|
console.error('Error parsing email with mailparser:', parseError);
|
||||||
|
// Fallback to direct display if parser fails
|
||||||
|
if (formattedEmail.startsWith('<') && formattedEmail.endsWith('>')) {
|
||||||
|
// Content is likely HTML, sanitize and display directly
|
||||||
|
const sanitizedHtml = DOMPurify.sanitize(formattedEmail);
|
||||||
|
setContent(
|
||||||
|
<div
|
||||||
|
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
||||||
}
|
}
|
||||||
|
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|||||||
@ -159,9 +159,17 @@ export default function ComposeEmail({
|
|||||||
// Now proceed with the usual decoding
|
// Now proceed with the usual decoding
|
||||||
const type = replyTo ? 'reply' : 'forward';
|
const type = replyTo ? 'reply' : 'forward';
|
||||||
|
|
||||||
|
// ========== MATCH PANEL 3 CONTENT HANDLING ==========
|
||||||
try {
|
try {
|
||||||
// Parse the email to get headers and content - using the same function as panel 3
|
// Get the actual email content - similar to panel 3
|
||||||
const decoded = await decodeEmail(emailToProcess.content);
|
const formattedEmail = emailToProcess.content.trim();
|
||||||
|
if (!formattedEmail) {
|
||||||
|
throw new Error("Email content is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the email just like panel 3
|
||||||
|
const decoded = await decodeEmail(formattedEmail);
|
||||||
|
|
||||||
console.log('[DEBUG] Decoded email for compose:', {
|
console.log('[DEBUG] Decoded email for compose:', {
|
||||||
hasHtml: !!decoded.html,
|
hasHtml: !!decoded.html,
|
||||||
hasText: !!decoded.text,
|
hasText: !!decoded.text,
|
||||||
@ -169,57 +177,47 @@ export default function ComposeEmail({
|
|||||||
subject: decoded.subject
|
subject: decoded.subject
|
||||||
});
|
});
|
||||||
|
|
||||||
// This is exactly how panel 3 handles email content - simple sanitization of HTML or showing text
|
// Get clean content similar to Panel 3
|
||||||
let cleanContent = '';
|
let cleanContent = '';
|
||||||
|
|
||||||
if (decoded.html) {
|
if (decoded.html) {
|
||||||
// Just sanitize the HTML directly - same as panel 3
|
// Sanitize HTML exactly as in Panel 3
|
||||||
cleanContent = DOMPurify.sanitize(decoded.html);
|
cleanContent = DOMPurify.sanitize(decoded.html);
|
||||||
} else if (decoded.text) {
|
} else if (decoded.text) {
|
||||||
// Use whitespace-pre-wrap for text - same as panel 3
|
// Format text content with proper whitespace like Panel 3
|
||||||
cleanContent = `<div class="whitespace-pre-wrap">${decoded.text}</div>`;
|
cleanContent = `<div class="whitespace-pre-wrap">${decoded.text}</div>`;
|
||||||
} else {
|
} else {
|
||||||
cleanContent = '<div>No displayable content available</div>';
|
// Fallback to raw content if parsing failed
|
||||||
|
if (formattedEmail.startsWith('<') && formattedEmail.endsWith('>')) {
|
||||||
|
cleanContent = DOMPurify.sanitize(formattedEmail);
|
||||||
|
} else {
|
||||||
|
cleanContent = `<div class="whitespace-pre-wrap">${formattedEmail}</div>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to safely extract email information
|
// Extract reliable metadata
|
||||||
const getSafeEmailInfo = (email: any) => {
|
const from = decoded.from ||
|
||||||
const fromValue = email && email.from ?
|
(emailToProcess.fromName ? `${emailToProcess.fromName} <${emailToProcess.from}>` : emailToProcess.from) ||
|
||||||
(typeof email.from === 'object' && email.from.text) ? email.from.text :
|
'Unknown Sender';
|
||||||
(Array.isArray(email.from) && email.from[0]) ?
|
|
||||||
(email.from[0].name || email.from[0].address) : 'Unknown Sender'
|
|
||||||
: 'Unknown Sender';
|
|
||||||
|
|
||||||
const dateValue = email && email.date ?
|
|
||||||
new Date(email.date).toLocaleString() : new Date().toLocaleString();
|
|
||||||
|
|
||||||
const subjectValue = email && email.subject ? email.subject : 'No Subject';
|
|
||||||
|
|
||||||
const toValue = email && email.to ?
|
const date = decoded.date ?
|
||||||
(typeof email.to === 'object' && email.to.text) ? email.to.text :
|
new Date(decoded.date).toLocaleString() :
|
||||||
(Array.isArray(email.to)) ? email.to.map((t: any) => t.address || t.name || '').filter(Boolean).join(', ') : ''
|
(emailToProcess.date ? new Date(emailToProcess.date).toLocaleString() : new Date().toLocaleString());
|
||||||
: '';
|
|
||||||
|
const subject = decoded.subject || emailToProcess.subject || 'No Subject';
|
||||||
const ccValue = email && email.cc ?
|
|
||||||
(typeof email.cc === 'object' && email.cc.text) ? email.cc.text :
|
|
||||||
(Array.isArray(email.cc) && email.cc.length > 0) ?
|
|
||||||
email.cc.map((c: any) => c.address || c.name || '').filter(Boolean).join(', ') : ''
|
|
||||||
: '';
|
|
||||||
|
|
||||||
return { from: fromValue, date: dateValue, subject: subjectValue, to: toValue, cc: ccValue };
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get info from both sources and combine
|
const to = decoded.to ||
|
||||||
const decodedInfo = getSafeEmailInfo(decoded);
|
(emailToProcess.to && Array.isArray(emailToProcess.to) ?
|
||||||
const emailInfo = getSafeEmailInfo(emailToProcess);
|
emailToProcess.to.map((t: any) => t.address || t.name || '').filter(Boolean).join(', ') :
|
||||||
|
emailToProcess.to) ||
|
||||||
|
'';
|
||||||
|
|
||||||
|
const cc = decoded.cc ||
|
||||||
|
(emailToProcess.cc && Array.isArray(emailToProcess.cc) ?
|
||||||
|
emailToProcess.cc.map((c: any) => c.address || c.name || '').filter(Boolean).join(', ') :
|
||||||
|
emailToProcess.cc) ||
|
||||||
|
'';
|
||||||
|
|
||||||
// Use the most complete information available
|
|
||||||
const from = decodedInfo.from !== 'Unknown Sender' ? decodedInfo.from : emailInfo.from;
|
|
||||||
const date = decodedInfo.date;
|
|
||||||
const subject = decodedInfo.subject !== 'No Subject' ? decodedInfo.subject : emailInfo.subject;
|
|
||||||
const to = decodedInfo.to || emailInfo.to;
|
|
||||||
const cc = decodedInfo.cc || emailInfo.cc;
|
|
||||||
|
|
||||||
// Format the content based on reply type
|
// Format the content based on reply type
|
||||||
const quotedContent = type === 'forward' ? `
|
const quotedContent = type === 'forward' ? `
|
||||||
<div class="forwarded-message" style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
|
<div class="forwarded-message" style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
|
||||||
@ -235,10 +233,10 @@ export default function ComposeEmail({
|
|||||||
</div>
|
</div>
|
||||||
` : `
|
` : `
|
||||||
<div class="quoted-message" style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
|
<div class="quoted-message" style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
|
||||||
On ${decoded.date ? decoded.date.toLocaleString() : new Date().toLocaleString()}, ${decoded.from || 'Unknown Sender'} wrote:
|
On ${date}, ${from} wrote:
|
||||||
</div>
|
</div>
|
||||||
<div class="message-content prose prose-sm max-w-none" style="margin: 10px 0 0 10px; padding: 10px; border-left: 2px solid #e5e7eb; border: 1px solid #e5e7eb; border-radius: 4px; max-height: 300px; overflow-y: auto; color: #374151;">
|
<div class="message-content prose prose-sm max-w-none" style="margin: 10px 0 0 10px; padding: 10px; border-left: 2px solid #e5e7eb; border: 1px solid #e5e7eb; border-radius: 4px; max-height: 300px; overflow-y: auto; color: #374151;">
|
||||||
${cleanContent}
|
${cleanContent || '<div>No content available</div>'}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -303,20 +301,29 @@ export default function ComposeEmail({
|
|||||||
console.log('[DEBUG] Successfully set compose content with scrollable message area');
|
console.log('[DEBUG] Successfully set compose content with scrollable message area');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[DEBUG] Error parsing email:', error);
|
console.error('[DEBUG] Error parsing email for compose:', error);
|
||||||
// Fallback to simple content extraction
|
|
||||||
const fallbackContent = emailToProcess.content.replace(/<[^>]*>/g, '');
|
// Fallback to basic content display
|
||||||
composeBodyRef.current.innerHTML = `
|
const errorContent = `
|
||||||
<div class="compose-area" contenteditable="true">
|
<div class="compose-area" contenteditable="true">
|
||||||
<br/>
|
<br/>
|
||||||
<div style="color: #ef4444;">Error loading original message.</div>
|
<div style="color: #64748b;">
|
||||||
<div style="color: #64748b; font-size: 0.875rem; margin-top: 0.5rem;">
|
---------- Original Message ---------<br/>
|
||||||
Technical details: ${error instanceof Error ? error.message : 'Unknown error'}
|
${emailToProcess.subject ? `Subject: ${emailToProcess.subject}<br/>` : ''}
|
||||||
|
${emailToProcess.from ? `From: ${emailToProcess.from}<br/>` : ''}
|
||||||
|
${emailToProcess.date ? `Date: ${new Date(emailToProcess.date).toLocaleString()}<br/>` : ''}
|
||||||
|
</div>
|
||||||
|
<div style="color: #64748b; border-left: 2px solid #e5e7eb; padding-left: 10px; margin: 10px 0;">
|
||||||
|
${emailToProcess.preview || 'No content available'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
setComposeBody(fallbackContent);
|
|
||||||
setLocalContent(fallbackContent);
|
if (composeBodyRef.current) {
|
||||||
|
composeBodyRef.current.innerHTML = errorContent;
|
||||||
|
setComposeBody(errorContent);
|
||||||
|
setLocalContent(errorContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[DEBUG] Error initializing compose content:', error);
|
console.error('[DEBUG] Error initializing compose content:', error);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user