This commit is contained in:
rustmailer
2026-07-13 00:04:53 +08:00
parent adff34940c
commit 85987e39fb
18 changed files with 1153 additions and 836 deletions
+26 -6
View File
@@ -17,7 +17,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from 'react';
import React, { useCallback, useRef, useState } from 'react';
interface EmailIframeProps {
emailHtml: string;
@@ -25,16 +25,36 @@ interface EmailIframeProps {
}
const EmailIframe: React.FC<EmailIframeProps> = ({ emailHtml, height }) => {
const encodedHtml = encodeURIComponent(emailHtml);
const iframeSrc = `data:text/html;charset=utf-8,${encodedHtml}`;
const iframeRef = useRef<HTMLIFrameElement>(null);
const [iframeHeight, setIframeHeight] = useState<number>(height ?? 300);
const onLoad = useCallback(() => {
try {
const doc = iframeRef.current?.contentWindow?.document;
if (doc?.body) {
const h = Math.max(
doc.body.scrollHeight,
doc.body.offsetHeight,
doc.documentElement.scrollHeight,
doc.documentElement.offsetHeight,
);
if (h > 0) setIframeHeight(h + 20);
}
} catch {
// sandbox prevents access — keep default height
}
}, []);
return (
<iframe
src={iframeSrc}
sandbox=""
ref={iframeRef}
srcDoc={emailHtml}
sandbox="allow-same-origin"
scrolling="no"
className="w-full border-none"
title="Email Content"
style={{ height: height ?? '4000px' }}
onLoad={onLoad}
style={{ height: iframeHeight }}
/>
);
};
@@ -43,23 +43,24 @@ export function MailDisplayDrawer({ open, onOpenChange }: Props) {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className='w-full md:max-w-6xl mx-auto h-full'>
<DialogHeader className="p-4 pb-3 border-b shrink-0">
<DialogTitle>{t('mail.emailViewer')}</DialogTitle>
</DialogHeader>
<ScrollArea className="h-[calc(100vh-100px)]">
<div className='m-5'>
{isLoading ? (
<div className="p-8 text-center text-muted-foreground">{t('common.loading')}...</div>
) : error ? (
<div className="p-8 text-center text-red-500">{t('attachment.emailMessageNotFound')}</div>
) : envelope ? (
<MailMessageView envelope={envelope} />
) : (
<div className="p-8 text-center text-muted-foreground">{t('mail.noMessageSelected')}</div>
)}
</div>
</ScrollArea>
<div className="flex flex-col h-full overflow-hidden -m-6">
<DialogHeader className="p-4 pb-3 border-b shrink-0 m-0">
<DialogTitle>{t('mail.emailViewer')}</DialogTitle>
</DialogHeader>
<ScrollArea className="flex-1">
<div className='m-5'>
{isLoading ? (
<div className="p-8 text-center text-muted-foreground">{t('common.loading')}...</div>
) : error ? (
<div className="p-8 text-center text-red-500">{t('attachment.emailMessageNotFound')}</div>
) : envelope ? (
<MailMessageView envelope={envelope} />
) : (
<div className="p-8 text-center text-muted-foreground">{t('mail.noMessageSelected')}</div>
)}
</div>
</ScrollArea>
</div>
</DialogContent>
</Dialog>
)
@@ -221,7 +221,7 @@ export function MailMessageView({
};
return (
<div className="flex flex-col h-full">
<div className="flex flex-col">
{showHeader && <div className="grid gap-1 text-xs">
<div className="flex space-x-2">
<span className="font-medium text-gray-400">{t('mail.account')}:</span>
@@ -424,7 +424,7 @@ export function MailMessageView({
</span>
</div>
)}
<div className="flex-1 overflow-auto">
<div>
{loading ? (
<div className="flex justify-center items-center py-8">
<Loader className="w-6 h-6 animate-spin" />
+18 -16
View File
@@ -40,22 +40,24 @@ export function MailDisplayDrawer({ open, onOpenChange }: Props) {
onOpenChange={onOpenChange}
>
<DialogContent className='w-full md:max-w-6xl mx-auto h-full'>
<DialogHeader className="p-4 pb-3 border-b shrink-0">
<div className="flex items-center justify-between">
<DialogTitle className="flex items-center gap-2">
{t('mail.emailViewer')}
</DialogTitle>
</div>
</DialogHeader>
<ScrollArea>
<div className='m-5'>
{currentEnvelope ? (
<MailMessageView envelope={currentEnvelope} />
) : (
<div className="p-8 text-center text-muted-foreground">{t('mail.noMessageSelected')}</div>
)}
</div>
</ScrollArea>
<div className="flex flex-col h-full overflow-hidden -m-6">
<DialogHeader className="p-4 pb-3 border-b shrink-0 m-0">
<div className="flex items-center justify-between">
<DialogTitle className="flex items-center gap-2">
{t('mail.emailViewer')}
</DialogTitle>
</div>
</DialogHeader>
<ScrollArea className="flex-1">
<div className='m-5'>
{currentEnvelope ? (
<MailMessageView envelope={currentEnvelope} />
) : (
<div className="p-8 text-center text-muted-foreground">{t('mail.noMessageSelected')}</div>
)}
</div>
</ScrollArea>
</div>
</DialogContent>
</Dialog>)
}
@@ -231,7 +231,7 @@ export function MailMessageView({
};
return (
<div className="flex flex-col h-full">
<div className="flex flex-col">
{showHeader && <div className="grid gap-1 text-xs">
<div className="flex space-x-2">
<span className="font-medium text-gray-400">{t('mail.account')}:</span>
@@ -456,7 +456,7 @@ export function MailMessageView({
</span>
</div>
)}
<div className="flex-1 overflow-auto">
<div>
{loading ? (
<div className="flex justify-center items-center py-8">
<Loader className="w-6 h-6 animate-spin" />