courrier multi account restore compose

This commit is contained in:
alma 2025-04-28 21:01:19 +02:00
parent be119e02c6
commit 6b3d93fce4
2 changed files with 61 additions and 40 deletions

View File

@ -71,26 +71,38 @@ export default function EmailPanel({
// Create a formatted version of the email content
const formattedEmail = useMemo(() => {
if (!email) return null;
if (!email) {
console.log('EmailPanel: No email provided');
return null;
}
try {
console.log('EmailPanel: Raw email content:', {
content: email.content,
html: email.html,
text: email.text,
formattedContent: email.formattedContent
});
// Handle different content structures
let content = '';
if (email.formattedContent) {
// If we already have formatted content, use that
console.log('EmailPanel: Using formattedContent');
content = email.formattedContent;
} else if (typeof email.content === 'string') {
// Direct string content
console.log('EmailPanel: Using direct string content');
content = email.content;
} else if (email.content && typeof email.content === 'object') {
// Object with text/html properties (new structure)
console.log('EmailPanel: Using object content:', email.content);
content = email.content.html || email.content.text || '';
} else {
// Fallback to html or text properties
console.log('EmailPanel: Using fallback content');
content = email.html || email.text || '';
}
console.log('EmailPanel: Final formatted content:', content);
// Return a new email object with the formatted content
return {
...email,
@ -98,7 +110,7 @@ export default function EmailPanel({
formattedContent: content
};
} catch (error) {
console.error('Error formatting email content:', error);
console.error('EmailPanel: Error formatting email content:', error);
return email;
}
}, [email]);

View File

@ -24,38 +24,32 @@ interface EmailAddress {
address: string;
}
interface EmailAttachment {
filename: string;
contentType: string;
size: number;
path?: string;
content?: string;
}
interface EmailMessage {
id: string;
messageId?: string;
subject: string;
uid: number;
from: EmailAddress[];
to: EmailAddress[];
cc?: EmailAddress[];
bcc?: EmailAddress[];
date: Date | string;
flags?: {
seen: boolean;
flagged: boolean;
answered: boolean;
deleted: boolean;
draft: boolean;
subject: string;
date: string;
flags: string[];
attachments: EmailAttachment[];
content?: string | {
text?: string;
html?: string;
};
preview?: string;
content?: string;
html?: string;
text?: string;
formattedContent?: string;
hasAttachments?: boolean;
attachments?: Array<{
filename: string;
contentType: string;
size: number;
path?: string;
content?: string;
}>;
folder?: string;
size?: number;
contentFetched?: boolean;
}
interface EmailPreviewProps {
@ -107,34 +101,46 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
// Format the email content
const formattedContent = useMemo(() => {
if (!email) return '';
if (!email) {
console.log('EmailPreview: No email provided');
return '';
}
try {
console.log('EmailPreview: Raw email content:', {
content: email.content,
html: email.html,
text: email.text,
formattedContent: email.formattedContent
});
// Get the content in order of preference
let content = '';
if (email.formattedContent) {
// If we already have formatted content, use that
console.log('EmailPreview: Using formattedContent');
content = email.formattedContent;
} else if (typeof email.content === 'string') {
// Direct string content
console.log('EmailPreview: Using direct string content');
content = email.content;
} else if (email.content && typeof email.content === 'object') {
// Object with text/html properties (new structure)
console.log('EmailPreview: Using object content:', email.content);
content = email.content.html || email.content.text || '';
} else {
// Fallback to html or text properties
console.log('EmailPreview: Using fallback content');
content = email.html || email.text || '';
}
console.log('EmailPreview: Content before sanitization:', content);
// Sanitize the content for display
return sanitizeHtml(content, {
ADD_TAGS: ['table', 'thead', 'tbody', 'tr', 'td', 'th'],
ADD_ATTR: ['target', 'rel', 'colspan', 'rowspan', 'style', 'class', 'id', 'border'],
ALLOW_DATA_ATTR: false
});
const sanitizedContent = sanitizeHtml(content);
console.log('EmailPreview: Final sanitized content:', sanitizedContent);
return sanitizedContent;
} catch (error) {
console.error('Error formatting email content:', error);
console.error('EmailPreview: Error formatting email content:', error);
return '';
}
}, [email]);
@ -164,6 +170,9 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
const sender = email.from && email.from.length > 0 ? email.from[0] : undefined;
// Update the array access to use proper type checking
const hasAttachments = email.attachments && email.attachments.length > 0;
return (
<Card className="flex flex-col h-full overflow-hidden border-0 shadow-none">
{/* Email header */}
@ -223,7 +232,7 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
</div>
{/* Attachments */}
{email.attachments && email.attachments.length > 0 && (
{hasAttachments && (
<div className="px-6 py-3 border-b bg-muted/30">
<div className="text-sm font-medium mb-2">Attachments</div>
<div className="flex flex-wrap gap-2">