mail page rest
This commit is contained in:
parent
a7d84f2787
commit
b53447e84d
@ -413,11 +413,76 @@ function decodeMimeContent(content: string): string {
|
|||||||
|
|
||||||
// Add this helper function
|
// Add this helper function
|
||||||
const renderEmailContent = (email: Email) => {
|
const renderEmailContent = (email: Email) => {
|
||||||
const decodedContent = decodeMimeContent(email.body);
|
try {
|
||||||
if (email.body.includes('Content-Type: text/html')) {
|
// First try to decode the MIME content
|
||||||
return <div dangerouslySetInnerHTML={{ __html: decodedContent }} />;
|
const decodedContent = decodeMimeContent(email.body);
|
||||||
|
|
||||||
|
// Check if the content is HTML
|
||||||
|
const isHtml = decodedContent.includes('<') &&
|
||||||
|
(decodedContent.includes('<html') ||
|
||||||
|
decodedContent.includes('<body') ||
|
||||||
|
decodedContent.includes('<div'));
|
||||||
|
|
||||||
|
if (isHtml) {
|
||||||
|
// Extract the body content if it exists
|
||||||
|
const bodyMatch = decodedContent.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
||||||
|
const content = bodyMatch ? bodyMatch[1] : decodedContent;
|
||||||
|
|
||||||
|
// Sanitize HTML content
|
||||||
|
const sanitizedHtml = content
|
||||||
|
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
||||||
|
.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '')
|
||||||
|
.replace(/on\w+="[^"]*"/g, '')
|
||||||
|
.replace(/on\w+='[^']*'/g, '')
|
||||||
|
.replace(/javascript:/gi, '')
|
||||||
|
.replace(/data:/gi, '')
|
||||||
|
.replace(/<meta[^>]*>/gi, '')
|
||||||
|
.replace(/<link[^>]*>/gi, '')
|
||||||
|
// Fix common encoding issues
|
||||||
|
.replace(/=C2=A0/g, ' ')
|
||||||
|
.replace(/=E2=80=93/g, '\u2013')
|
||||||
|
.replace(/=E2=80=94/g, '\u2014')
|
||||||
|
.replace(/=E2=80=98/g, '\u2018')
|
||||||
|
.replace(/=E2=80=99/g, '\u2019')
|
||||||
|
.replace(/=E2=80=9C/g, '\u201C')
|
||||||
|
.replace(/=E2=80=9D/g, '\u201D');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="prose prose-sm max-w-none"
|
||||||
|
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Format plain text content
|
||||||
|
const formattedText = decodedContent
|
||||||
|
.replace(/\n/g, '<br>')
|
||||||
|
.replace(/\t/g, ' ')
|
||||||
|
.replace(/ /g, ' ')
|
||||||
|
// Fix common encoding issues
|
||||||
|
.replace(/=C2=A0/g, ' ')
|
||||||
|
.replace(/=E2=80=93/g, '\u2013')
|
||||||
|
.replace(/=E2=80=94/g, '\u2014')
|
||||||
|
.replace(/=E2=80=98/g, '\u2018')
|
||||||
|
.replace(/=E2=80=99/g, '\u2019')
|
||||||
|
.replace(/=E2=80=9C/g, '\u201C')
|
||||||
|
.replace(/=E2=80=9D/g, '\u201D');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="prose prose-sm max-w-none whitespace-pre-wrap"
|
||||||
|
dangerouslySetInnerHTML={{ __html: formattedText }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error rendering email content:', e);
|
||||||
|
return (
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
Error rendering email content. Please try refreshing the page.
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return <div className="whitespace-pre-wrap">{decodedContent}</div>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add this helper function
|
// Add this helper function
|
||||||
@ -1028,39 +1093,7 @@ export default function CourrierPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="prose max-w-none">
|
<div className="prose max-w-none">
|
||||||
{(() => {
|
{renderEmailContent(selectedEmail)}
|
||||||
try {
|
|
||||||
const parsed = parseFullEmail(selectedEmail.body);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{/* Display HTML content if available, otherwise fallback to text */}
|
|
||||||
<div dangerouslySetInnerHTML={{
|
|
||||||
__html: parsed.html || parsed.text || decodeMimeContent(selectedEmail.body)
|
|
||||||
}} />
|
|
||||||
|
|
||||||
{/* Display attachments if present */}
|
|
||||||
{parsed.attachments && parsed.attachments.length > 0 && (
|
|
||||||
<div className="mt-6 border-t border-gray-200 pt-6">
|
|
||||||
<h3 className="text-sm font-semibold text-gray-900 mb-4">Attachments</h3>
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
{parsed.attachments.map((attachment, index) => (
|
|
||||||
<div key={index} className="flex items-center space-x-2 p-2 border rounded">
|
|
||||||
<Paperclip className="h-4 w-4 text-gray-400" />
|
|
||||||
<span className="text-sm text-gray-600 truncate">
|
|
||||||
{attachment.filename}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Error parsing email:', e);
|
|
||||||
return selectedEmail.body;
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</>
|
</>
|
||||||
@ -1141,38 +1174,32 @@ export default function CourrierPage() {
|
|||||||
</h3>
|
</h3>
|
||||||
<div className="text-xs text-gray-500 truncate">
|
<div className="text-xs text-gray-500 truncate">
|
||||||
{(() => {
|
{(() => {
|
||||||
// Get clean preview of the actual message content
|
|
||||||
let preview = '';
|
|
||||||
try {
|
try {
|
||||||
const parsed = parseFullEmail(email.body);
|
// First decode the MIME content
|
||||||
|
const decodedContent = decodeMimeContent(email.body);
|
||||||
|
|
||||||
// Try to get content from parsed email
|
// Extract preview text
|
||||||
preview = (parsed.text || parsed.html || '')
|
let preview = decodedContent
|
||||||
|
// Remove HTML tags
|
||||||
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
|
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
|
||||||
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
|
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
|
||||||
.replace(/<[^>]+>/g, '')
|
.replace(/<[^>]+>/g, ' ')
|
||||||
.replace(/ |‌|»|«|>/g, ' ')
|
// Remove email headers
|
||||||
|
.replace(/^(From|To|Sent|Subject|Date|Cc|Bcc):.*$/gim, '')
|
||||||
|
// Remove quoted text
|
||||||
|
.replace(/^>.*$/gm, '')
|
||||||
|
// Remove multiple spaces
|
||||||
.replace(/\s+/g, ' ')
|
.replace(/\s+/g, ' ')
|
||||||
.trim();
|
// Remove special characters
|
||||||
|
.replace(/ |‌|»|«|>/g, ' ')
|
||||||
// If no preview from parsed content, try direct body
|
// Fix common encoding issues
|
||||||
if (!preview) {
|
.replace(/=C2=A0/g, ' ')
|
||||||
preview = email.body
|
.replace(/=E2=80=93/g, '\u2013')
|
||||||
.replace(/<[^>]+>/g, '')
|
.replace(/=E2=80=94/g, '\u2014')
|
||||||
.replace(/ |‌|»|«|>/g, ' ')
|
.replace(/=E2=80=98/g, '\u2018')
|
||||||
.replace(/\s+/g, ' ')
|
.replace(/=E2=80=99/g, '\u2019')
|
||||||
.trim();
|
.replace(/=E2=80=9C/g, '\u201C')
|
||||||
}
|
.replace(/=E2=80=9D/g, '\u201D')
|
||||||
|
|
||||||
// Remove email artifacts and clean up
|
|
||||||
preview = preview
|
|
||||||
.replace(/^>+/gm, '')
|
|
||||||
.replace(/Content-Type:[^\n]+/g, '')
|
|
||||||
.replace(/Content-Transfer-Encoding:[^\n]+/g, '')
|
|
||||||
.replace(/--[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/g, '')
|
|
||||||
.replace(/boundary=[^\n]+/g, '')
|
|
||||||
.replace(/charset=[^\n]+/g, '')
|
|
||||||
.replace(/[\r\n]+/g, ' ')
|
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
// Take first 100 characters
|
// Take first 100 characters
|
||||||
@ -1187,12 +1214,11 @@ export default function CourrierPage() {
|
|||||||
preview += '...';
|
preview += '...';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return preview || 'No preview available';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error generating preview:', e);
|
console.error('Error generating preview:', e);
|
||||||
preview = '';
|
return 'Error loading preview';
|
||||||
}
|
}
|
||||||
|
|
||||||
return preview || 'No preview available';
|
|
||||||
})()}
|
})()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user