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) {
|
||||
// Update the email content with the fetched full content
|
||||
email.content = fullContent.content;
|
||||
email.contentFetched = true;
|
||||
|
||||
// Render the content
|
||||
const sanitizedHtml = DOMPurify.sanitize(fullContent.content);
|
||||
setContent(
|
||||
<div
|
||||
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
||||
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
|
||||
/>
|
||||
);
|
||||
setDebugInfo('Rendered fetched HTML content');
|
||||
setError(null);
|
||||
setIsLoading(false);
|
||||
// Render the content - call ourselves again now that we have content
|
||||
setDebugInfo('Content fetched from API, reprocessing');
|
||||
loadContent();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 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();
|
||||
if (!formattedEmail) {
|
||||
@ -165,23 +158,13 @@ function EmailContent({ email }: { email: Email }) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if content is already HTML
|
||||
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 existing HTML content');
|
||||
} else {
|
||||
// Use mailparser for more complex formats
|
||||
console.log('Parsing email content');
|
||||
try {
|
||||
// Always try to use the mail parser first for consistency
|
||||
console.log('Parsing email content with mailparser');
|
||||
const parsedEmail = await decodeEmail(formattedEmail);
|
||||
|
||||
if (parsedEmail.html) {
|
||||
console.log('Using HTML content from parser');
|
||||
const sanitizedHtml = DOMPurify.sanitize(parsedEmail.html);
|
||||
setContent(
|
||||
<div
|
||||
@ -191,6 +174,7 @@ function EmailContent({ email }: { email: Email }) {
|
||||
);
|
||||
setDebugInfo('Rendered HTML content from parser');
|
||||
} else if (parsedEmail.text) {
|
||||
console.log('Using text content from parser');
|
||||
setContent(
|
||||
<div className="email-content whitespace-pre-wrap">
|
||||
{parsedEmail.text}
|
||||
@ -198,9 +182,36 @@ function EmailContent({ email }: { email: Email }) {
|
||||
);
|
||||
setDebugInfo('Rendered text content from parser');
|
||||
} else {
|
||||
setContent(<div className="text-gray-500">No displayable content available</div>);
|
||||
setDebugInfo('No HTML or text content in parsed email');
|
||||
// Fallback to direct display if parser didn't give us anything
|
||||
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);
|
||||
|
||||
@ -159,9 +159,17 @@ export default function ComposeEmail({
|
||||
// Now proceed with the usual decoding
|
||||
const type = replyTo ? 'reply' : 'forward';
|
||||
|
||||
// ========== MATCH PANEL 3 CONTENT HANDLING ==========
|
||||
try {
|
||||
// Parse the email to get headers and content - using the same function as panel 3
|
||||
const decoded = await decodeEmail(emailToProcess.content);
|
||||
// Get the actual email content - similar to panel 3
|
||||
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:', {
|
||||
hasHtml: !!decoded.html,
|
||||
hasText: !!decoded.text,
|
||||
@ -169,57 +177,47 @@ export default function ComposeEmail({
|
||||
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 = '';
|
||||
|
||||
if (decoded.html) {
|
||||
// Just sanitize the HTML directly - same as panel 3
|
||||
// Sanitize HTML exactly as in Panel 3
|
||||
cleanContent = DOMPurify.sanitize(decoded.html);
|
||||
} 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>`;
|
||||
} 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
|
||||
const getSafeEmailInfo = (email: any) => {
|
||||
const fromValue = email && email.from ?
|
||||
(typeof email.from === 'object' && email.from.text) ? email.from.text :
|
||||
(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';
|
||||
// Extract reliable metadata
|
||||
const from = decoded.from ||
|
||||
(emailToProcess.fromName ? `${emailToProcess.fromName} <${emailToProcess.from}>` : emailToProcess.from) ||
|
||||
'Unknown Sender';
|
||||
|
||||
const toValue = email && email.to ?
|
||||
(typeof email.to === 'object' && email.to.text) ? email.to.text :
|
||||
(Array.isArray(email.to)) ? email.to.map((t: any) => t.address || t.name || '').filter(Boolean).join(', ') : ''
|
||||
: '';
|
||||
|
||||
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 };
|
||||
};
|
||||
const date = decoded.date ?
|
||||
new Date(decoded.date).toLocaleString() :
|
||||
(emailToProcess.date ? new Date(emailToProcess.date).toLocaleString() : new Date().toLocaleString());
|
||||
|
||||
const subject = decoded.subject || emailToProcess.subject || 'No Subject';
|
||||
|
||||
// Get info from both sources and combine
|
||||
const decodedInfo = getSafeEmailInfo(decoded);
|
||||
const emailInfo = getSafeEmailInfo(emailToProcess);
|
||||
const to = decoded.to ||
|
||||
(emailToProcess.to && Array.isArray(emailToProcess.to) ?
|
||||
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
|
||||
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;">
|
||||
@ -235,10 +233,10 @@ export default function ComposeEmail({
|
||||
</div>
|
||||
` : `
|
||||
<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 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>
|
||||
`;
|
||||
|
||||
@ -303,20 +301,29 @@ export default function ComposeEmail({
|
||||
console.log('[DEBUG] Successfully set compose content with scrollable message area');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[DEBUG] Error parsing email:', error);
|
||||
// Fallback to simple content extraction
|
||||
const fallbackContent = emailToProcess.content.replace(/<[^>]*>/g, '');
|
||||
composeBodyRef.current.innerHTML = `
|
||||
console.error('[DEBUG] Error parsing email for compose:', error);
|
||||
|
||||
// Fallback to basic content display
|
||||
const errorContent = `
|
||||
<div class="compose-area" contenteditable="true">
|
||||
<br/>
|
||||
<div style="color: #ef4444;">Error loading original message.</div>
|
||||
<div style="color: #64748b; font-size: 0.875rem; margin-top: 0.5rem;">
|
||||
Technical details: ${error instanceof Error ? error.message : 'Unknown error'}
|
||||
<div style="color: #64748b;">
|
||||
---------- Original Message ---------<br/>
|
||||
${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>
|
||||
`;
|
||||
setComposeBody(fallbackContent);
|
||||
setLocalContent(fallbackContent);
|
||||
|
||||
if (composeBodyRef.current) {
|
||||
composeBodyRef.current.innerHTML = errorContent;
|
||||
setComposeBody(errorContent);
|
||||
setLocalContent(errorContent);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[DEBUG] Error initializing compose content:', error);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user