panel 2 courier api restore
This commit is contained in:
parent
94fb7453b5
commit
28a6478ea0
@ -113,179 +113,20 @@ export default function ComposeEmail({
|
|||||||
// Check if we have content
|
// Check if we have content
|
||||||
if (!emailToProcess?.content) {
|
if (!emailToProcess?.content) {
|
||||||
console.error('[DEBUG] No email content found to process');
|
console.error('[DEBUG] No email content found to process');
|
||||||
|
composeBodyRef.current.innerHTML = `
|
||||||
// Try to use body property if content is not available (for backward compatibility)
|
<div class="compose-area" contenteditable="true">
|
||||||
if (emailToProcess && 'body' in emailToProcess && emailToProcess.body) {
|
<br/>
|
||||||
console.log('[DEBUG] Using body property as fallback for content');
|
<div style="color: #ef4444;">Unable to load original message content.</div>
|
||||||
emailToProcess.content = emailToProcess.body;
|
</div>
|
||||||
} else if (emailToProcess) {
|
`;
|
||||||
console.log('[DEBUG] Attempting to fetch email content directly');
|
setIsLoading(false);
|
||||||
try {
|
return;
|
||||||
// Fetch the email content if not available
|
|
||||||
const response = await fetch(`/api/courrier/${emailToProcess.id}?folder=${encodeURIComponent(emailToProcess.folder || 'INBOX')}&fetchFull=true`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to fetch email content: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fullContent = await response.json();
|
|
||||||
console.log('[DEBUG] API response for full email content:', {
|
|
||||||
hasContent: !!fullContent?.content,
|
|
||||||
hasBody: !!fullContent?.body,
|
|
||||||
hasHtml: !!fullContent?.html,
|
|
||||||
hasText: !!fullContent?.text,
|
|
||||||
contentLength: fullContent?.content?.length || 0
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the email content with the fetched full content
|
|
||||||
if (fullContent && fullContent.content) {
|
|
||||||
console.log('[DEBUG] Successfully fetched content for reply/forward');
|
|
||||||
emailToProcess.content = fullContent.content;
|
|
||||||
} else if (fullContent && fullContent.body) {
|
|
||||||
console.log('[DEBUG] Successfully fetched body for reply/forward');
|
|
||||||
emailToProcess.content = fullContent.body;
|
|
||||||
} else if (fullContent && fullContent.html) {
|
|
||||||
console.log('[DEBUG] Successfully fetched HTML for reply/forward');
|
|
||||||
emailToProcess.content = fullContent.html;
|
|
||||||
} else if (fullContent && fullContent.text) {
|
|
||||||
console.log('[DEBUG] Successfully fetched TEXT for reply/forward');
|
|
||||||
emailToProcess.content = fullContent.text;
|
|
||||||
} else {
|
|
||||||
console.error('[DEBUG] No usable content found in API response');
|
|
||||||
|
|
||||||
// Try using fullContent directly if it's a string
|
|
||||||
if (typeof fullContent === 'string' && fullContent.length > 0) {
|
|
||||||
console.log('[DEBUG] Using fullContent string directly');
|
|
||||||
emailToProcess.content = fullContent;
|
|
||||||
} else {
|
|
||||||
throw new Error('No content in fetched email');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure we actually have content
|
|
||||||
if (!emailToProcess.content || emailToProcess.content.trim().length === 0) {
|
|
||||||
console.error('[DEBUG] Content still empty after fetch, using fallback');
|
|
||||||
// Use any available preview or raw data
|
|
||||||
emailToProcess.content = emailToProcess.preview ||
|
|
||||||
(fullContent.raw ? fullContent.raw : 'Email content unavailable');
|
|
||||||
}
|
|
||||||
} catch (fetchError) {
|
|
||||||
console.error('[DEBUG] Error fetching email content:', fetchError);
|
|
||||||
composeBodyRef.current.innerHTML = `
|
|
||||||
<div class="compose-area" contenteditable="true">
|
|
||||||
<br/>
|
|
||||||
<div style="color: #ef4444;">Error: No original message content available.</div>
|
|
||||||
<div style="color: #64748b; font-size: 0.875rem; margin-top: 0.5rem;">
|
|
||||||
Please select the email again or try refreshing the page.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
setIsLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No emailToProcess available
|
|
||||||
composeBodyRef.current.innerHTML = `
|
|
||||||
<div class="compose-area" contenteditable="true">
|
|
||||||
<br/>
|
|
||||||
<div style="color: #ef4444;">Error: No email selected for reply/forward.</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
setIsLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add more debug logging to track content fetching
|
|
||||||
console.log('[DEBUG] Sending content to parse-email API, content type:',
|
|
||||||
typeof emailToProcess!.content,
|
|
||||||
'length:', emailToProcess!.content.length,
|
|
||||||
'starts with:', emailToProcess!.content.substring(0, 50)
|
|
||||||
);
|
|
||||||
|
|
||||||
let emailContent;
|
|
||||||
let parseSuccess = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Parse the original email using the API
|
|
||||||
const response = await fetch('/api/parse-email', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ email: emailToProcess.content }),
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('[DEBUG] Parse-email API response status:', response.status);
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log('[DEBUG] Parse-email API response:', {
|
|
||||||
hasHtml: !!data.html,
|
|
||||||
hasText: !!data.text,
|
|
||||||
subject: data.subject,
|
|
||||||
error: data.error
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(data.error || 'Failed to parse email');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prioritize HTML content if available, fallback to text
|
|
||||||
emailContent = data.html || data.text || '';
|
|
||||||
|
|
||||||
// Add a fallback check if both HTML and text are empty
|
|
||||||
if (!emailContent.trim()) {
|
|
||||||
// Try to extract content from the raw source
|
|
||||||
console.log('[DEBUG] Empty content from parser, using raw content as fallback');
|
|
||||||
emailContent = emailToProcess.content;
|
|
||||||
|
|
||||||
// If content looks like HTML, use it directly, otherwise wrap in pre tags
|
|
||||||
if (!emailContent.startsWith('<') || !emailContent.endsWith('>')) {
|
|
||||||
emailContent = `<pre style="white-space: pre-wrap; word-break: break-word;">${emailContent}</pre>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseSuccess = true;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[DEBUG] API parse error:', error);
|
|
||||||
// Try to use the content directly if API fails
|
|
||||||
emailContent = emailToProcess.content;
|
|
||||||
|
|
||||||
// If content looks like HTML, use it directly, otherwise wrap in pre tags
|
|
||||||
if (!emailContent.startsWith('<') || !emailContent.endsWith('>')) {
|
|
||||||
emailContent = `<pre style="white-space: pre-wrap; word-break: break-word;">${emailContent}</pre>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!emailContent || !emailContent.trim()) {
|
|
||||||
console.warn('[DEBUG] No content available after parsing, trying direct content');
|
|
||||||
// Final fallback: Try to use direct content or preview
|
|
||||||
emailContent = emailToProcess.content || emailToProcess.preview ||
|
|
||||||
(emailToProcess.body ?
|
|
||||||
`<pre style="white-space: pre-wrap; word-break: break-word;">${emailToProcess.body}</pre>` :
|
|
||||||
'<div>No content available in the original message</div>');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the reply/forward content
|
// Format the reply/forward content
|
||||||
const formatQuotedContent = (content: string) => {
|
const type = replyTo ? 'reply' : 'forward';
|
||||||
// First try to clean up any problematic formatting
|
|
||||||
let cleanedContent = content;
|
// Use simple, reliable formatting for the quoted content
|
||||||
|
|
||||||
// If content is very short or empty, add a clear message
|
|
||||||
if (!cleanedContent || cleanedContent.trim().length < 10) {
|
|
||||||
return `<div style="color: #888; font-style: italic;">Original message was empty or could not be loaded</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're working with plain text, make it readable
|
|
||||||
if (!cleanedContent.includes('<') || !cleanedContent.includes('>')) {
|
|
||||||
return `<pre style="white-space: pre-wrap; word-break: break-word; font-family: ui-sans-serif, system-ui, sans-serif; margin: 0;">${cleanedContent}</pre>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For HTML content, ensure it's properly contained
|
|
||||||
return cleanedContent;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Process email content
|
|
||||||
const formatEmailAddresses = (addresses: any) => {
|
const formatEmailAddresses = (addresses: any) => {
|
||||||
if (!addresses) return 'Unknown';
|
if (!addresses) return 'Unknown';
|
||||||
if (typeof addresses === 'string') return addresses;
|
if (typeof addresses === 'string') return addresses;
|
||||||
@ -294,25 +135,53 @@ export default function ComposeEmail({
|
|||||||
}
|
}
|
||||||
return String(addresses);
|
return String(addresses);
|
||||||
};
|
};
|
||||||
|
|
||||||
const quotedContent = forwardFrom ? `
|
// Extract plain text content for reliable display
|
||||||
|
let emailContent = '';
|
||||||
|
try {
|
||||||
|
// Parse the original email to get clean content
|
||||||
|
const response = await fetch('/api/parse-email', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ email: emailToProcess.content }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
emailContent = data.text || '';
|
||||||
|
// If no text content, try to extract from HTML
|
||||||
|
if (!emailContent && data.html) {
|
||||||
|
// Create a temporary div to extract text from HTML
|
||||||
|
const tempDiv = document.createElement('div');
|
||||||
|
tempDiv.innerHTML = data.html;
|
||||||
|
emailContent = tempDiv.textContent || tempDiv.innerText || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[DEBUG] Error parsing email:', error);
|
||||||
|
// Fallback to simple content extraction
|
||||||
|
emailContent = emailToProcess.content.replace(/<[^>]*>/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;">
|
<div class="forwarded-message" style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
|
||||||
---------- Forwarded message ---------<br/>
|
---------- Forwarded message ---------<br/>
|
||||||
From: ${formatEmailAddresses(emailToProcess?.from) || 'Unknown Sender'}<br/>
|
From: ${formatEmailAddresses(emailToProcess.from) || 'Unknown Sender'}<br/>
|
||||||
Date: ${new Date(emailToProcess?.date || Date.now()).toLocaleString()}<br/>
|
Date: ${new Date(emailToProcess.date || Date.now()).toLocaleString()}<br/>
|
||||||
Subject: ${emailToProcess?.subject || 'No Subject'}<br/>
|
Subject: ${emailToProcess.subject || 'No Subject'}<br/>
|
||||||
To: ${formatEmailAddresses(emailToProcess?.to) || ''}<br/>
|
To: ${formatEmailAddresses(emailToProcess.to) || ''}<br/>
|
||||||
${emailToProcess?.cc ? `Cc: ${formatEmailAddresses(emailToProcess.cc)}<br/>` : ''}
|
${emailToProcess.cc ? `Cc: ${formatEmailAddresses(emailToProcess.cc)}<br/>` : ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="message-content" style="margin-top: 10px; border: 1px solid #e5e7eb; padding: 10px; border-radius: 4px; max-height: 300px; overflow-y: auto; color: #374151;">
|
<div class="message-content" style="margin-top: 10px; border: 1px solid #e5e7eb; padding: 10px; border-radius: 4px; max-height: 300px; overflow-y: auto; color: #374151;">
|
||||||
${formatQuotedContent(emailContent)}
|
<pre style="white-space: pre-wrap; word-break: break-word; font-family: system-ui, sans-serif; margin: 0;">${emailContent}</pre>
|
||||||
</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 ${new Date(emailToProcess?.date || Date.now()).toLocaleString()}, ${formatEmailAddresses(emailToProcess?.from) || 'Unknown Sender'} wrote:
|
On ${new Date(emailToProcess.date || Date.now()).toLocaleString()}, ${formatEmailAddresses(emailToProcess.from) || 'Unknown Sender'} wrote:
|
||||||
</div>
|
</div>
|
||||||
<div class="message-content" 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" 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;">
|
||||||
${formatQuotedContent(emailContent)}
|
<pre style="white-space: pre-wrap; word-break: break-word; font-family: system-ui, sans-serif; margin: 0;">${emailContent}</pre>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -364,7 +233,7 @@ export default function ComposeEmail({
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault(); // Prevent the parent container from scrolling
|
e.preventDefault(); // Prevent the parent container from scrolling
|
||||||
}
|
}
|
||||||
}, { passive: false });
|
}, { passive: false }); // Important for preventDefault to work
|
||||||
|
|
||||||
// Mark this element as having a scroll handler attached
|
// Mark this element as having a scroll handler attached
|
||||||
(container as HTMLElement).setAttribute('data-scroll-handler-attached', 'true');
|
(container as HTMLElement).setAttribute('data-scroll-handler-attached', 'true');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user