courrier clean 2$

This commit is contained in:
alma 2025-04-26 20:57:42 +02:00
parent ccf129f1a4
commit 91751b23ca

View File

@ -1,10 +1,8 @@
'use client';
import { useState, useRef, useEffect } from 'react';
// Remove direct import of server components
import {
X, Paperclip, ChevronDown, ChevronUp, SendHorizontal, Loader2,
AlignLeft, AlignRight
X, Paperclip, ChevronDown, ChevronUp, SendHorizontal, Loader2
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
@ -88,7 +86,6 @@ interface LegacyComposeEmailProps {
interface ComposeEmailProps {
initialEmail?: EmailMessage | null;
type?: 'new' | 'reply' | 'reply-all' | 'forward';
initialRTL?: boolean;
onClose: () => void;
onSend: (emailData: {
to: string;
@ -119,7 +116,7 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
}
// Continue with modern implementation for new props
const { initialEmail, type = 'new', initialRTL, onClose, onSend } = props;
const { initialEmail, type = 'new', onClose, onSend } = props;
// Email form state
const [to, setTo] = useState<string>('');
@ -130,7 +127,6 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
const [showCc, setShowCc] = useState<boolean>(false);
const [showBcc, setShowBcc] = useState<boolean>(false);
const [sending, setSending] = useState<boolean>(false);
const [isRTL, setIsRTL] = useState<boolean>(initialRTL || false);
const [attachments, setAttachments] = useState<Array<{
name: string;
content: string;
@ -141,13 +137,6 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
const editorRef = useRef<HTMLDivElement>(null);
const attachmentInputRef = useRef<HTMLInputElement>(null);
// Initialize RTL state from prop if provided
useEffect(() => {
if (initialRTL !== undefined) {
setIsRTL(initialRTL);
}
}, [initialRTL]);
// Initialize the form when replying to or forwarding an email
useEffect(() => {
if (initialEmail && type !== 'new') {
@ -187,12 +176,6 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
// Focus editor after initializing
setTimeout(() => {
if (editorRef.current) {
// First set the direction correctly on the editor
editorRef.current.dir = isRTL ? 'rtl' : 'ltr';
editorRef.current.style.textAlign = isRTL ? 'right' : 'left';
editorRef.current.style.direction = isRTL ? 'rtl' : 'ltr';
// Then focus and position cursor
editorRef.current.focus();
try {
@ -202,8 +185,6 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
const range = document.createRange();
if (editorRef.current.firstChild) {
// For RTL, place cursor at the right side (beginning for RTL)
// For LTR, place cursor at the left side (beginning for LTR)
range.setStart(editorRef.current.firstChild, 0);
range.collapse(true);
@ -220,7 +201,7 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
console.error('Error formatting email:', error);
}
}
}, [initialEmail, type, isRTL]);
}, [initialEmail, type]);
// Handle attachment selection
const handleAttachmentClick = () => {
@ -263,7 +244,7 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
setAttachments(current => current.filter((_, i) => i !== index));
};
// Handle editor input with improved support for direction
// Handle editor input
const handleEditorInput = () => {
if (editorRef.current) {
// Store the current selection/cursor position
@ -272,11 +253,6 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
const offset = range?.startOffset || 0;
const container = range?.startContainer;
// Maintain consistent direction attributes
editorRef.current.dir = isRTL ? 'rtl' : 'ltr';
editorRef.current.style.textAlign = isRTL ? 'right' : 'left';
editorRef.current.style.direction = isRTL ? 'rtl' : 'ltr';
// Capture the content
setEmailContent(editorRef.current.innerHTML);
@ -297,29 +273,7 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
}
};
// Toggle text direction for the entire editor
const toggleTextDirection = () => {
// Since we're only writing in English, we'll simplify this function to just use LTR
setIsRTL(false);
if (editorRef.current) {
// Save current content
const content = editorRef.current.innerHTML;
// Set to LTR mode only
editorRef.current.dir = 'ltr';
editorRef.current.style.textAlign = 'left';
editorRef.current.style.direction = 'ltr';
// Update state
setEmailContent(editorRef.current.innerHTML);
// Focus the editor again
editorRef.current.focus();
}
};
// Send email without modifying pre-formatted content
// Send email
const handleSend = async () => {
if (!to) {
alert('Please specify at least one recipient');
@ -334,7 +288,7 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
cc: cc || undefined,
bcc: bcc || undefined,
subject,
body: emailContent, // Use the raw edited content
body: emailContent,
attachments
});
@ -446,33 +400,20 @@ export default function ComposeEmail(props: ComposeEmailAllProps) {
<div className="space-y-2">
<div className="flex items-center justify-between">
<label htmlFor="body" className="text-sm font-medium">Message</label>
<Button
variant="outline"
size="sm"
onClick={toggleTextDirection}
className="h-8 px-3 text-xs"
>
{isRTL ?
<><AlignLeft className="h-4 w-4 mr-1" /> Switch to LTR</> :
<><AlignRight className="h-4 w-4 mr-1" /> Switch to RTL</>
}
</Button>
</div>
{/* Email editor with correct text direction settings */}
{/* Email editor - standard LTR for English content */}
<div className="border rounded-md overflow-hidden">
<div
ref={editorRef}
contentEditable={!sending}
className="w-full p-4 min-h-[300px] focus:outline-none"
onInput={handleEditorInput}
// Use dangerouslySetInnerHTML without sanitizing again to preserve our formatting
dangerouslySetInnerHTML={{ __html: emailContent }}
dir={isRTL ? 'rtl' : 'ltr'}
dir="ltr"
style={{
textAlign: isRTL ? 'right' : 'left',
direction: isRTL ? 'rtl' : 'ltr',
// Remove unicodeBidi which can cause text reversal issues
textAlign: 'left',
direction: 'ltr',
}}
/>
</div>
@ -568,35 +509,12 @@ function LegacyAdapter({
replyTo,
forwardFrom
}: LegacyComposeEmailProps) {
// Check if the user has RTL preference
const [preferRTL, setPreferRTL] = useState<boolean>(false);
// If not showing compose, return null
if (!showCompose) {
return null;
}
// Detect RTL content in body on initialization - improve detection logic
useEffect(() => {
if (!composeBody) return;
// Only detect RTL if we're creating a new message, not for replies/forwards
if (originalEmail) return;
// Better RTL detection based on common RTL languages (Arabic, Hebrew, Persian, Urdu, etc.)
// Look for substantial presence of RTL characters, not just any single RTL character
const rtlRegex = /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/;
// Count RTL characters
const rtlCount = (composeBody.match(rtlRegex) || []).length;
// Only set RTL mode if there's a significant number of RTL characters
// This prevents accidentally enabling RTL mode for text that just has a few RTL characters
if (rtlCount > 5) {
console.log('Significant RTL text detected - setting editor to RTL mode');
setPreferRTL(true);
} else {
// Keep the default LTR mode for Latin/English text
setPreferRTL(false);
}
}, [composeBody, originalEmail]);
// Determine the type from the original email or subject
// Determine email type
const determineType = (): 'new' | 'reply' | 'reply-all' | 'forward' => {
if (originalEmail) {
return originalEmail.type;
@ -613,18 +531,8 @@ function LegacyAdapter({
return 'new';
};
// Convert legacy attachments format to new format
const convertAttachments = () => {
return (attachments || []).map((att: any) => ({
name: att.name || 'attachment',
content: typeof att.content === 'string' ? att.content : '',
type: att.type || 'application/octet-stream'
}));
};
// Create an EmailMessage compatible object from composeBody
// This is crucial for displaying original content in replies/forwards
const createEmailMessageFromContent = (): EmailMessage | null => {
// Create email message object if needed for replies/forwards
const emailForCompose = (() => {
const type = determineType();
// Only create an email object if we're replying or forwarding
@ -632,8 +540,6 @@ function LegacyAdapter({
return null;
}
// For forwarded content, we need to preserve all the original formatting
// The composeBody already contains the formatted message with headers
return {
id: 'temp-id',
messageId: '',
@ -641,29 +547,18 @@ function LegacyAdapter({
from: [{ name: '', address: '' }],
to: [{ name: '', address: '' }],
date: new Date(),
// Always use the full composeBody to ensure nested forwards are preserved
content: composeBody,
html: composeBody,
hasAttachments: false
};
};
// If not showing compose, return null
if (!showCompose) {
return null;
}
// Create email message from content if available
const emailForCompose = createEmailMessageFromContent();
const type = determineType();
})();
return (
<div className="fixed inset-0 bg-gray-600/30 backdrop-blur-sm z-50 flex items-center justify-center">
<div className="w-full max-w-2xl max-h-[90vh] bg-white rounded-xl shadow-xl overflow-auto mx-4">
<ComposeEmail
initialEmail={emailForCompose}
type={type}
initialRTL={preferRTL}
type={determineType()}
onClose={() => {
onCancel?.();
setShowCompose(false);