compose mime

This commit is contained in:
alma 2025-04-24 20:40:10 +02:00
parent 0dbc7706cd
commit 87a0879166
2 changed files with 34 additions and 12 deletions

View File

@ -115,7 +115,7 @@ function EmailContent({ email }: { email: Email }) {
try {
if (!email.body) {
if (mounted) {
setContent(null);
setContent(<div className="text-gray-500">No content available</div>);
setIsLoading(false);
}
return;
@ -124,7 +124,7 @@ function EmailContent({ email }: { email: Email }) {
const formattedEmail = email.body.trim();
if (!formattedEmail) {
if (mounted) {
setContent(null);
setContent(<div className="text-gray-500">No content available</div>);
setIsLoading(false);
}
return;
@ -137,7 +137,7 @@ function EmailContent({ email }: { email: Email }) {
setContent(
<div
className="email-content prose prose-sm max-w-none dark:prose-invert"
dangerouslySetInnerHTML={{ __html: parsedEmail.html }}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(parsedEmail.html) }}
/>
);
} else if (parsedEmail.text) {
@ -147,7 +147,7 @@ function EmailContent({ email }: { email: Email }) {
</div>
);
} else {
setContent(null);
setContent(<div className="text-gray-500">No content available</div>);
}
setError(null);
setIsLoading(false);
@ -181,7 +181,7 @@ function EmailContent({ email }: { email: Email }) {
return <div className="text-red-500">{error}</div>;
}
return content;
return content || <div className="text-gray-500">No content available</div>;
}
function renderEmailContent(email: Email) {
@ -330,15 +330,29 @@ function getReplyBody(email: Email, type: 'reply' | 'reply-all' | 'forward' = 'r
function EmailPreview({ email }: { email: Email }) {
const [preview, setPreview] = useState<string>('');
const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
let mounted = true;
async function loadPreview() {
if (!email?.body) {
if (mounted) setPreview('No content available');
return;
}
setIsLoading(true);
try {
const decoded = await decodeEmail(email.body);
if (mounted) {
setPreview(decoded.text || cleanHtml(decoded.html || ''));
if (decoded.text) {
setPreview(decoded.text.substring(0, 150) + '...');
} else if (decoded.html) {
const cleanText = decoded.html.replace(/<[^>]*>/g, ' ').trim();
setPreview(cleanText.substring(0, 150) + '...');
} else {
setPreview('No preview available');
}
setError(null);
}
} catch (err) {
@ -347,6 +361,8 @@ function EmailPreview({ email }: { email: Email }) {
setError('Error generating preview');
setPreview('');
}
} finally {
if (mounted) setIsLoading(false);
}
}
@ -355,7 +371,11 @@ function EmailPreview({ email }: { email: Email }) {
return () => {
mounted = false;
};
}, [email.body]);
}, [email?.body]);
if (isLoading) {
return <span className="text-gray-400">Loading preview...</span>;
}
if (error) {
return <span className="text-red-500 text-xs">{error}</span>;

View File

@ -113,12 +113,11 @@ export default function ComposeEmail({
body: JSON.stringify({ email: emailToProcess.body }),
});
const data = await response.json();
if (!response.ok) {
throw new Error('Failed to parse email');
throw new Error(data.error || 'Failed to parse email');
}
const parsedEmail = await response.json();
// Format the reply/forward content
const quotedContent = forwardFrom ? `
<div style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;">
@ -129,14 +128,14 @@ export default function ComposeEmail({
To: ${emailToProcess.to}<br/>
${emailToProcess.cc ? `Cc: ${emailToProcess.cc}<br/>` : ''}
<br/>
${parsedEmail.html || parsedEmail.text || 'No content available'}
${data.html || data.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(emailToProcess.date).toLocaleString()}, ${emailToProcess.from} wrote:
</div>
<blockquote style="margin: 0; padding-left: 1em; border-left: 2px solid #e5e7eb; color: #6b7280;">
${parsedEmail.html || parsedEmail.text || 'No content available'}
${data.html || data.text || 'No content available'}
</blockquote>
`;
@ -160,6 +159,7 @@ export default function ComposeEmail({
// Update compose state
setComposeBody(formattedContent);
setLocalContent(formattedContent);
}
} catch (error) {
console.error('Error initializing compose content:', error);
@ -171,6 +171,8 @@ export default function ComposeEmail({
</div>
`;
composeBodyRef.current.innerHTML = errorContent;
setComposeBody(errorContent);
setLocalContent(errorContent);
}
}
};