compose mime
This commit is contained in:
parent
da1390fb51
commit
616d52d8fb
@ -509,6 +509,7 @@ export default function CourrierPage() {
|
||||
|
||||
// Process emails keeping exact folder names and sort by date
|
||||
const processedEmails = (data.emails || [])
|
||||
.filter((email: any) => email && email.body) // Filter out emails with no body
|
||||
.map((email: any) => ({
|
||||
id: Number(email.id),
|
||||
accountId: 1,
|
||||
@ -527,20 +528,20 @@ export default function CourrierPage() {
|
||||
raw: email.body || ''
|
||||
}));
|
||||
|
||||
// Only update unread count if we're in the Inbox folder
|
||||
if (currentView === 'INBOX') {
|
||||
const unreadInboxEmails = processedEmails.filter(
|
||||
(email: Email) => !email.read && email.folder === 'INBOX'
|
||||
).length;
|
||||
setUnreadCount(unreadInboxEmails);
|
||||
}
|
||||
|
||||
// Sort emails by date, ensuring most recent first
|
||||
const sortedEmails = processedEmails.sort((a: Email, b: Email) => {
|
||||
const dateA = new Date(a.date).getTime();
|
||||
const dateB = new Date(b.date).getTime();
|
||||
return dateB - dateA; // Most recent first
|
||||
});
|
||||
|
||||
// Only update unread count if we're in the Inbox folder
|
||||
if (currentView === 'INBOX') {
|
||||
const unreadInboxEmails = sortedEmails.filter(
|
||||
(email: Email) => !email.read && email.folder === 'INBOX'
|
||||
).length;
|
||||
setUnreadCount(unreadInboxEmails);
|
||||
}
|
||||
|
||||
if (isLoadMore) {
|
||||
// When loading more, merge with existing emails and re-sort
|
||||
|
||||
@ -84,90 +84,62 @@ export default function ComposeEmail({
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const initializeContent = async () => {
|
||||
if (!composeBodyRef.current) return;
|
||||
|
||||
let content = '';
|
||||
|
||||
if (replyTo || forwardFrom) {
|
||||
setIsLoading(true);
|
||||
if (replyTo || forwardFrom) {
|
||||
const initializeContent = async () => {
|
||||
try {
|
||||
const originalContent = replyTo?.body || forwardFrom?.body || '';
|
||||
const emailToProcess = replyTo || forwardFrom;
|
||||
if (!emailToProcess?.body) {
|
||||
console.error('No email body found to process');
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.body }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to parse email');
|
||||
}
|
||||
|
||||
const parsedEmail = await response.json();
|
||||
const originalContent = parsedEmail.html || parsedEmail.text || '';
|
||||
|
||||
// Create initial content without waiting for parsing
|
||||
content = `
|
||||
<div class="compose-area" contenteditable="true" style="min-height: 100px; padding: 10px; color: #000000;">
|
||||
<br/>
|
||||
<div id="reply-placeholder">Loading original message...</div>
|
||||
// Format the reply/forward content
|
||||
const prefix = replyTo ? '\n\n' : '\n\n---------- Forwarded message ----------\n\n';
|
||||
const quoteStyle = 'border-left: 2px solid #ccc; margin-left: 1em; padding-left: 1em;';
|
||||
const formattedContent = `
|
||||
<div><br/>${prefix}</div>
|
||||
<div style="${quoteStyle}">
|
||||
${originalContent}
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Set initial content immediately
|
||||
composeBodyRef.current.innerHTML = content;
|
||||
setLocalContent(content);
|
||||
|
||||
// Place cursor at the beginning
|
||||
const composeArea = composeBodyRef.current.querySelector('.compose-area');
|
||||
if (composeArea) {
|
||||
|
||||
// Set the content in the compose area
|
||||
if (composeBodyRef.current) {
|
||||
composeBodyRef.current.innerHTML = formattedContent;
|
||||
// Place cursor at the beginning
|
||||
const selection = window.getSelection();
|
||||
const range = document.createRange();
|
||||
const sel = window.getSelection();
|
||||
range.setStart(composeArea, 0);
|
||||
range.setStart(composeBodyRef.current.firstChild || composeBodyRef.current, 0);
|
||||
range.collapse(true);
|
||||
sel?.removeAllRanges();
|
||||
sel?.addRange(range);
|
||||
(composeArea as HTMLElement).focus();
|
||||
}
|
||||
|
||||
// Now parse the email content
|
||||
if (originalContent.trim()) {
|
||||
const decodedContent = await decodeComposeContent(originalContent);
|
||||
|
||||
const quotedContent = `
|
||||
${forwardFrom ? `
|
||||
<div style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
|
||||
---------- Forwarded message ---------<br/>
|
||||
From: ${forwardFrom.from}<br/>
|
||||
Date: ${new Date(forwardFrom.date).toLocaleString()}<br/>
|
||||
Subject: ${forwardFrom.subject}<br/>
|
||||
To: ${forwardFrom.to}<br/>
|
||||
${forwardFrom.cc ? `Cc: ${forwardFrom.cc}<br/>` : ''}
|
||||
<br/>
|
||||
${decodedContent.html || decodedContent.text || 'No content available'}
|
||||
</div>
|
||||
` : `
|
||||
<div style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
|
||||
On ${new Date(replyTo?.date || '').toLocaleString()}, ${replyTo?.from} wrote:
|
||||
</div>
|
||||
<blockquote style="margin: 0; padding-left: 1em; border-left: 2px solid #e5e7eb; color: #6b7280;">
|
||||
${decodedContent.html || decodedContent.text || 'No content available'}
|
||||
</blockquote>
|
||||
`}
|
||||
`;
|
||||
|
||||
// Replace placeholder with actual content
|
||||
const placeholder = composeBodyRef.current.querySelector('#reply-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.insertAdjacentHTML('beforebegin', quotedContent);
|
||||
placeholder.remove();
|
||||
}
|
||||
selection?.removeAllRanges();
|
||||
selection?.addRange(range);
|
||||
}
|
||||
|
||||
// Update compose state
|
||||
setComposeBody(formattedContent);
|
||||
} catch (error) {
|
||||
console.error('Error parsing email:', error);
|
||||
const placeholder = composeBodyRef.current.querySelector('#reply-placeholder');
|
||||
if (placeholder) {
|
||||
placeholder.textContent = 'Error loading original message.';
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
console.error('Error initializing compose content:', error);
|
||||
}
|
||||
} else {
|
||||
content = `<div class="compose-area" contenteditable="true" style="min-height: 100px; padding: 10px; color: #000000;"></div>`;
|
||||
composeBodyRef.current.innerHTML = content;
|
||||
setLocalContent(content);
|
||||
}
|
||||
};
|
||||
|
||||
initializeContent();
|
||||
};
|
||||
|
||||
initializeContent();
|
||||
}
|
||||
}, [replyTo, forwardFrom]);
|
||||
|
||||
const handleInput = (e: React.FormEvent<HTMLDivElement>) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user