mail page fix design dang

This commit is contained in:
alma 2025-04-21 22:13:07 +02:00
parent 30684cb3b9
commit 795211f785
2 changed files with 65 additions and 47 deletions

View File

@ -41,7 +41,7 @@ import {
import DOMPurify from 'isomorphic-dompurify';
import ComposeEmail from '@/components/ComposeEmail';
interface Account {
export interface Account {
id: number;
name: string;
email: string;
@ -49,7 +49,7 @@ interface Account {
folders?: string[];
}
interface Email {
export interface Email {
id: number;
accountId: number;
from: string;

View File

@ -7,6 +7,7 @@ import { Label } from '@/components/ui/label';
import { Paperclip, X } from 'lucide-react';
import { Textarea } from '@/components/ui/textarea';
import { decodeComposeContent, encodeComposeContent } from '@/lib/compose-mime-decoder';
import { Email } from '@/app/courrier/page';
interface ComposeEmailProps {
showCompose: boolean;
@ -32,6 +33,16 @@ interface ComposeEmailProps {
content: string;
type: 'reply' | 'reply-all' | 'forward';
};
onSend: (email: Email) => void;
onCancel: () => void;
onBodyChange?: (body: string) => void;
initialTo?: string;
initialSubject?: string;
initialBody?: string;
initialCc?: string;
initialBcc?: string;
replyTo?: Email;
forwardFrom?: Email;
}
export default function ComposeEmail({
@ -54,68 +65,75 @@ export default function ComposeEmail({
attachments,
setAttachments,
handleSend,
originalEmail
originalEmail,
onSend,
onCancel,
onBodyChange,
initialTo,
initialSubject,
initialBody,
initialCc,
initialBcc,
replyTo,
forwardFrom
}: ComposeEmailProps) {
const composeBodyRef = useRef<HTMLDivElement>(null);
const [localContent, setLocalContent] = useState('');
useEffect(() => {
if (composeBodyRef.current) {
// Only initialize once when empty or first loading
if (!composeBody || composeBody.trim() === '') {
// Simple structure with one area for new text and one for original
composeBodyRef.current.innerHTML = `
<div id="new-reply-area" dir="ltr" style="margin-bottom: 20px; min-height: 40px;"></div>
<div id="original-email" dir="ltr" style="border-top: 1px solid #e0e0e0; padding-top: 10px; color: #555;">
${composeBody ? decodeComposeContent(composeBody) : ''}
</div>
`;
// Place cursor at the beginning of new reply area
const newReplyArea = composeBodyRef.current.querySelector('#new-reply-area');
if (newReplyArea) {
const range = document.createRange();
const sel = window.getSelection();
range.setStart(newReplyArea, 0);
range.collapse(true);
sel?.removeAllRanges();
sel?.addRange(range);
}
} else {
// For existing content, just update the original email part
const originalEmailDiv = composeBodyRef.current.querySelector('#original-email');
if (originalEmailDiv) {
originalEmailDiv.innerHTML = decodeComposeContent(composeBody);
}
// Initialize the content structure
const originalContent = originalEmail?.content || '';
composeBodyRef.current.innerHTML = `
<div id="new-reply-area" dir="ltr" style="margin-bottom: 20px; min-height: 40px;"></div>
<div id="original-email" dir="ltr" style="border-top: 1px solid #e0e0e0; padding-top: 10px; color: #555;">
${originalContent}
</div>
`;
// Place cursor at the beginning of new reply area
const newReplyArea = composeBodyRef.current.querySelector('#new-reply-area');
if (newReplyArea) {
const range = document.createRange();
const sel = window.getSelection();
range.setStart(newReplyArea, 0);
range.collapse(true);
sel?.removeAllRanges();
sel?.addRange(range);
}
}
}, []); // Only run once on initial mount, not on every composeBody change
}, [originalEmail]); // Run when originalEmail changes
// Modified input handler to prevent nested structures
const handleInput = (e: React.FormEvent<HTMLDivElement>) => {
// Get raw content from the editable div
const currentContent = e.currentTarget.innerHTML;
// Store the original content reference
const originalEmailDiv = e.currentTarget.querySelector('#original-email');
const originalContent = originalEmailDiv?.innerHTML || '';
// Extract user-typed content (everything before original-email div)
const userContent = currentContent.split('<div id="original-email"')[0];
if (!composeBodyRef.current) return;
// Get the new reply content
const newReplyArea = composeBodyRef.current.querySelector('#new-reply-area');
const originalEmailArea = composeBodyRef.current.querySelector('#original-email');
if (!newReplyArea || !originalEmailArea) return;
const newReplyContent = newReplyArea.innerHTML;
const originalContent = originalEmailArea.innerHTML;
// Update local state
setLocalContent(userContent);
// Combine new reply and original formatted correctly
const combinedContent = `
${userContent}
setComposeBody(newReplyContent);
// Combine both contents while maintaining formatting
const formattedContent = `
<div id="new-reply-area" dir="ltr" style="margin-bottom: 20px; min-height: 40px;">
${newReplyContent}
</div>
<div id="original-email" dir="ltr" style="border-top: 1px solid #e0e0e0; padding-top: 10px; color: #555;">
${originalContent}
</div>
`;
// Update the compose body
setComposeBody(combinedContent);
// Update the compose form
if (onBodyChange) {
onBodyChange(formattedContent);
}
};
const handleFileAttachment = async (e: React.ChangeEvent<HTMLInputElement>) => {