mail page rest

This commit is contained in:
alma 2025-04-21 14:55:14 +02:00
parent 1311ffb815
commit 1e3a8fb50f

View File

@ -1557,56 +1557,75 @@ export default function CourrierPage() {
};
// Add handleReply function
const handleReply = (type: 'reply' | 'replyAll' | 'forward') => {
if (!selectedEmail) return;
const handleReply = async (type: 'reply' | 'replyAll' | 'forward') => {
// First, ensure we have the full email content
if (!selectedEmail) {
setError('No email selected');
return;
}
const getReplySubject = () => {
const subject = selectedEmail.subject;
if (type === 'forward') {
return subject.startsWith('Fwd:') ? subject : `Fwd: ${subject}`;
}
return subject.startsWith('Re:') ? subject : `Re: ${subject}`;
};
const getReplyTo = () => {
switch (type) {
case 'reply':
return selectedEmail.from;
case 'replyAll':
// For Reply All, only put the original sender in To
return selectedEmail.from;
case 'forward':
return '';
}
};
const getReplyCc = () => {
if (type === 'replyAll') {
// For Reply All, put all other recipients in CC, excluding the sender and current user
const allRecipients = new Set([
...(selectedEmail.to?.split(',') || []),
...(selectedEmail.cc?.split(',') || [])
]);
// Remove the sender and current user from CC
allRecipients.delete(selectedEmail.from);
allRecipients.delete(accounts[1]?.email);
return Array.from(allRecipients)
.map(email => email.trim())
.filter(email => email) // Remove empty strings
.join(', ');
}
return '';
};
const getReplyBody = () => {
if (!selectedEmail.body) {
try {
// Fetch the full email content
const response = await fetch(`/api/mail/${selectedEmail.id}`);
if (!response.ok) {
throw new Error('Failed to fetch email content');
}
const emailData = await response.json();
// Update the selected email with the full content
setSelectedEmail(prev => {
if (!prev) return null;
return {
...prev,
body: emailData.body,
to: emailData.to,
cc: emailData.cc,
bcc: emailData.bcc
};
});
} catch (error) {
console.error('Error fetching email content:', error);
// Show error to user
setError('Failed to load email content. Please try again.');
return;
}
}
// Helper functions for reply composition
const getReplySubject = (): string => {
if (!selectedEmail) return '';
const prefix = type === 'forward' ? 'Fwd:' : 'Re:';
return `${prefix} ${selectedEmail.subject}`;
};
const getReplyTo = (): string => {
if (!selectedEmail) return '';
if (type === 'forward') return '';
return selectedEmail.from;
};
const getReplyCc = (): string => {
if (!selectedEmail) return '';
if (type === 'forward' || type === 'reply') return '';
return selectedEmail.cc || '';
};
const getReplyBody = (): string => {
if (!selectedEmail?.body) return '';
try {
// Now we can safely parse the full email content
const parsed = parseFullEmail(selectedEmail.body);
let originalContent = '';
// Get the content from either HTML or text part
if (parsed.html) {
// Use the existing MIME decoding for HTML content
originalContent = decodeMIME(parsed.html, 'quoted-printable', 'utf-8');
// Convert HTML to plain text for the reply
originalContent = parsed.html
originalContent = originalContent
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
.replace(/<br\s*\/?>/gi, '\n')
@ -1631,12 +1650,15 @@ export default function CourrierPage() {
.replace(/\n{3,}/g, '\n\n')
.trim();
} else if (parsed.text) {
originalContent = parsed.text.trim();
// Use the existing MIME decoding for plain text content
originalContent = decodeMIME(parsed.text, 'quoted-printable', 'utf-8').trim();
} else {
// Fallback to raw body if parsing fails
originalContent = selectedEmail.body
.replace(/<[^>]+>/g, '')
.trim();
// Fallback to raw body if parsing fails, but still try to decode it
originalContent = decodeMIME(
selectedEmail.body.replace(/<[^>]+>/g, ''),
'quoted-printable',
'utf-8'
).trim();
}
// Clean up the content
@ -1690,27 +1712,30 @@ export default function CourrierPage() {
replyHeader = `\n\nOn ${formattedDate}, ${selectedEmail.from} wrote:\n`;
}
// Indent the original content
const indentedContent = originalContent
.split('\n')
.map(line => line ? `> ${line}` : '>') // Keep empty lines as '>' for better readability
.join('\n');
return `${replyHeader}${indentedContent}`;
return replyHeader + originalContent;
} catch (error) {
console.error('Error formatting reply:', error);
return `\n\nOn ${new Date(selectedEmail.date).toLocaleString()}, ${selectedEmail.from} wrote:\n> ${selectedEmail.body}`;
console.error('Error preparing reply body:', error);
return '';
}
};
// Open compose modal with reply details
setShowCompose(true);
setComposeTo(getReplyTo());
setComposeSubject(getReplySubject());
setComposeBody(getReplyBody());
setComposeCc(getReplyCc());
// Prepare the reply email
const replyEmail = {
to: getReplyTo(),
cc: getReplyCc(),
subject: getReplySubject(),
body: getReplyBody()
};
// Update the compose form with the reply content
setComposeTo(replyEmail.to);
setComposeCc(replyEmail.cc);
setComposeSubject(replyEmail.subject);
setComposeBody(replyEmail.body);
setComposeBcc('');
// Show CC field automatically for Reply All
// Show the compose form and CC field for Reply All
setShowCompose(true);
setShowCc(type === 'replyAll');
setShowBcc(false);
setAttachments([]);