mail page fix design
This commit is contained in:
parent
127765069f
commit
525a7db670
@ -328,93 +328,98 @@ const initialSidebarItems = [
|
||||
}
|
||||
];
|
||||
|
||||
function getReplyBody(email: Email, type: 'reply' | 'reply-all' | 'forward'): string {
|
||||
function getReplyBody(email: Email, type: 'reply' | 'reply-all' | 'forward' = 'reply') {
|
||||
if (!email.body) return '';
|
||||
|
||||
try {
|
||||
// Split email into headers and body
|
||||
const [headersPart, ...bodyParts] = email.body.split('\r\n\r\n');
|
||||
if (!headersPart || bodyParts.length === 0) {
|
||||
throw new Error('Invalid email format: missing headers or body');
|
||||
}
|
||||
|
||||
const body = bodyParts.join('\r\n\r\n');
|
||||
|
||||
// Parse headers using Infomaniak MIME decoder
|
||||
const headerInfo = parseEmailHeaders(headersPart);
|
||||
const boundary = extractBoundary(headersPart);
|
||||
|
||||
let content = '';
|
||||
|
||||
// If it's a multipart email
|
||||
let content = '';
|
||||
let headers = '';
|
||||
let body = '';
|
||||
|
||||
// Split headers and body
|
||||
const parts = email.body.split('\r\n\r\n');
|
||||
if (parts.length > 1) {
|
||||
headers = parts[0];
|
||||
body = parts.slice(1).join('\r\n\r\n');
|
||||
} else {
|
||||
body = email.body;
|
||||
}
|
||||
|
||||
// Handle multipart emails
|
||||
if (headers.includes('multipart/alternative')) {
|
||||
const boundary = headers.match(/boundary="([^"]+)"/)?.[1];
|
||||
if (boundary) {
|
||||
const parts = body.split(`--${boundary}`);
|
||||
|
||||
// Find HTML part first, fallback to text part
|
||||
const htmlPart = parts.find(part => part.toLowerCase().includes('content-type: text/html'));
|
||||
const textPart = parts.find(part => part.toLowerCase().includes('content-type: text/plain'));
|
||||
|
||||
const selectedPart = htmlPart || textPart;
|
||||
if (selectedPart) {
|
||||
const [partHeaders, ...partBodyParts] = selectedPart.split('\r\n\r\n');
|
||||
const partBody = partBodyParts.join('\r\n\r\n');
|
||||
const partHeaderInfo = parseEmailHeaders(partHeaders);
|
||||
|
||||
content = partHeaderInfo.encoding === 'quoted-printable'
|
||||
? decodeQuotedPrintable(partBody, partHeaderInfo.charset)
|
||||
: partBody;
|
||||
for (const part of parts) {
|
||||
if (part.includes('text/html')) {
|
||||
content = part.split('\r\n\r\n')[1] || '';
|
||||
break;
|
||||
} else if (part.includes('text/plain')) {
|
||||
content = part.split('\r\n\r\n')[1] || '';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
content = headerInfo.encoding === 'quoted-printable'
|
||||
? decodeQuotedPrintable(body, headerInfo.charset)
|
||||
: body;
|
||||
}
|
||||
|
||||
// Convert plain text to HTML if needed
|
||||
if (!headerInfo.contentType.includes('text/html')) {
|
||||
content = content
|
||||
.split('\n')
|
||||
.map(line => {
|
||||
if (!line.trim()) return '<br>';
|
||||
if (line.startsWith('>')) {
|
||||
return `<p class="text-gray-600" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;">${line}</p>`;
|
||||
}
|
||||
return `<p dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;">${line}</p>`;
|
||||
})
|
||||
.join('');
|
||||
}
|
||||
|
||||
// Clean HTML content
|
||||
content = cleanHtml(content);
|
||||
|
||||
const date = new Date(email.date).toLocaleString();
|
||||
|
||||
if (type === 'forward') {
|
||||
return `
|
||||
<div class="prose max-w-none" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;">
|
||||
<div class="border-l-4 border-gray-300 pl-4 my-4">
|
||||
<p class="text-sm text-gray-600 mb-2" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;"><strong>From:</strong> ${email.from}</p>
|
||||
<p class="text-sm text-gray-600 mb-2" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;"><strong>Date:</strong> ${date}</p>
|
||||
<p class="text-sm text-gray-600 mb-2" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;"><strong>Subject:</strong> ${email.subject}</p>
|
||||
<p class="text-sm text-gray-600 mb-2" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;"><strong>To:</strong> ${Array.isArray(email.to) ? email.to.join(', ') : email.to}</p>
|
||||
<div class="mt-4 prose-sm" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;">${content}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
return `
|
||||
<div class="prose max-w-none" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;">
|
||||
<div class="border-l-4 border-gray-300 pl-4 my-4">
|
||||
<p class="text-sm text-gray-600 mb-2" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;">On ${date}, ${email.from} wrote:</p>
|
||||
<div class="mt-4 prose-sm" dir="ltr" style="unicode-bidi: bidi-override; direction: ltr;">${content}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing email body:', error);
|
||||
return '';
|
||||
} else if (headers.includes('text/html')) {
|
||||
content = body;
|
||||
} else if (headers.includes('text/plain')) {
|
||||
// Convert plain text to HTML while preserving formatting
|
||||
content = body
|
||||
.replace(/\r\n/g, '<br>')
|
||||
.replace(/\n/g, '<br>')
|
||||
.replace(/\r/g, '<br>');
|
||||
}
|
||||
|
||||
// Clean and sanitize HTML content
|
||||
content = content
|
||||
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
|
||||
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
|
||||
.replace(/<meta[^>]*>/gi, '')
|
||||
.replace(/<link[^>]*>/gi, '')
|
||||
.replace(/<base[^>]*>/gi, '')
|
||||
.replace(/<title[^>]*>[\s\S]*?<\/title>/gi, '')
|
||||
.replace(/<head[^>]*>[\s\S]*?<\/head>/gi, '')
|
||||
.replace(/<body[^>]*>/gi, '')
|
||||
.replace(/<\/body>/gi, '')
|
||||
.replace(/<html[^>]*>/gi, '')
|
||||
.replace(/<\/html>/gi, '')
|
||||
.replace(/<!DOCTYPE[^>]*>/gi, '')
|
||||
.replace(/<!--[\s\S]*?-->/gi, '');
|
||||
|
||||
// Clean up any remaining HTML entities
|
||||
content = content
|
||||
.replace(/ /g, ' ')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'");
|
||||
|
||||
// Format the reply/forward content
|
||||
let formattedContent = '';
|
||||
if (type === 'forward') {
|
||||
formattedContent = `
|
||||
<div class="prose max-w-none" dir="ltr">
|
||||
<div class="border-l-4 border-gray-300 pl-4 my-4">
|
||||
<p class="text-sm text-gray-600 mb-2">Forwarded message from ${email.from}</p>
|
||||
<p class="text-sm text-gray-600 mb-2">Date: ${new Date(email.date).toLocaleString()}</p>
|
||||
<p class="text-sm text-gray-600 mb-2">Subject: ${email.subject}</p>
|
||||
<p class="text-sm text-gray-600 mb-2">To: ${email.to}</p>
|
||||
${email.cc ? `<p class="text-sm text-gray-600 mb-2">Cc: ${email.cc}</p>` : ''}
|
||||
<div class="mt-4 prose-sm">${content}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
formattedContent = `
|
||||
<div class="prose max-w-none" dir="ltr">
|
||||
<div class="border-l-4 border-gray-300 pl-4 my-4">
|
||||
<p class="text-sm text-gray-600 mb-2">On ${new Date(email.date).toLocaleString()}, ${email.from} wrote:</p>
|
||||
<div class="mt-4 prose-sm">${content}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return formattedContent;
|
||||
}
|
||||
|
||||
export default function CourrierPage() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user