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

View File

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