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 { try {
if (!email.body) { if (!email.body) {
if (mounted) { if (mounted) {
setContent(null); setContent(<div className="text-gray-500">No content available</div>);
setIsLoading(false); setIsLoading(false);
} }
return; return;
@ -124,7 +124,7 @@ function EmailContent({ email }: { email: Email }) {
const formattedEmail = email.body.trim(); const formattedEmail = email.body.trim();
if (!formattedEmail) { if (!formattedEmail) {
if (mounted) { if (mounted) {
setContent(null); setContent(<div className="text-gray-500">No content available</div>);
setIsLoading(false); setIsLoading(false);
} }
return; return;
@ -137,7 +137,7 @@ function EmailContent({ email }: { email: Email }) {
setContent( setContent(
<div <div
className="email-content prose prose-sm max-w-none dark:prose-invert" 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) { } else if (parsedEmail.text) {
@ -147,7 +147,7 @@ function EmailContent({ email }: { email: Email }) {
</div> </div>
); );
} else { } else {
setContent(null); setContent(<div className="text-gray-500">No content available</div>);
} }
setError(null); setError(null);
setIsLoading(false); setIsLoading(false);
@ -181,7 +181,7 @@ function EmailContent({ email }: { email: Email }) {
return <div className="text-red-500">{error}</div>; 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) { function renderEmailContent(email: Email) {
@ -330,15 +330,29 @@ function getReplyBody(email: Email, type: 'reply' | 'reply-all' | 'forward' = 'r
function EmailPreview({ email }: { email: Email }) { function EmailPreview({ email }: { email: Email }) {
const [preview, setPreview] = useState<string>(''); const [preview, setPreview] = useState<string>('');
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => { useEffect(() => {
let mounted = true; let mounted = true;
async function loadPreview() { async function loadPreview() {
if (!email?.body) {
if (mounted) setPreview('No content available');
return;
}
setIsLoading(true);
try { try {
const decoded = await decodeEmail(email.body); const decoded = await decodeEmail(email.body);
if (mounted) { 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); setError(null);
} }
} catch (err) { } catch (err) {
@ -347,6 +361,8 @@ function EmailPreview({ email }: { email: Email }) {
setError('Error generating preview'); setError('Error generating preview');
setPreview(''); setPreview('');
} }
} finally {
if (mounted) setIsLoading(false);
} }
} }
@ -355,7 +371,11 @@ function EmailPreview({ email }: { email: Email }) {
return () => { return () => {
mounted = false; mounted = false;
}; };
}, [email.body]); }, [email?.body]);
if (isLoading) {
return <span className="text-gray-400">Loading preview...</span>;
}
if (error) { if (error) {
return <span className="text-red-500 text-xs">{error}</span>; 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 }), body: JSON.stringify({ email: emailToProcess.body }),
}); });
const data = await response.json();
if (!response.ok) { 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 // Format the reply/forward content
const quotedContent = forwardFrom ? ` const quotedContent = forwardFrom ? `
<div style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;"> <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/> To: ${emailToProcess.to}<br/>
${emailToProcess.cc ? `Cc: ${emailToProcess.cc}<br/>` : ''} ${emailToProcess.cc ? `Cc: ${emailToProcess.cc}<br/>` : ''}
<br/> <br/>
${parsedEmail.html || parsedEmail.text || 'No content available'} ${data.html || data.text || 'No content available'}
</div> </div>
` : ` ` : `
<div style="border-top: 1px solid #e5e7eb; padding-top: 20px; margin-top: 20px; color: #6b7280; font-size: 0.875rem;"> <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: On ${new Date(emailToProcess.date).toLocaleString()}, ${emailToProcess.from} wrote:
</div> </div>
<blockquote style="margin: 0; padding-left: 1em; border-left: 2px solid #e5e7eb; color: #6b7280;"> <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> </blockquote>
`; `;
@ -160,6 +159,7 @@ export default function ComposeEmail({
// Update compose state // Update compose state
setComposeBody(formattedContent); setComposeBody(formattedContent);
setLocalContent(formattedContent);
} }
} catch (error) { } catch (error) {
console.error('Error initializing compose content:', error); console.error('Error initializing compose content:', error);
@ -171,6 +171,8 @@ export default function ComposeEmail({
</div> </div>
`; `;
composeBodyRef.current.innerHTML = errorContent; composeBodyRef.current.innerHTML = errorContent;
setComposeBody(errorContent);
setLocalContent(errorContent);
} }
} }
}; };