diff --git a/components/ComposeEmail.tsx b/components/ComposeEmail.tsx index 8d97f599..82c3f667 100644 --- a/components/ComposeEmail.tsx +++ b/components/ComposeEmail.tsx @@ -6,6 +6,7 @@ import { Input } from '@/components/ui/input'; 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'; interface ComposeEmailProps { showCompose: boolean; @@ -54,23 +55,15 @@ export default function ComposeEmail({ useEffect(() => { if (composeBodyRef.current) { - // Remove any existing content - composeBodyRef.current.innerHTML = ''; - - // Create a temporary div to parse the HTML - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = composeBody; - - // Append the parsed content to the contentEditable div - while (tempDiv.firstChild) { - composeBodyRef.current.appendChild(tempDiv.firstChild); - } + const decodedContent = decodeComposeContent(composeBody); + composeBodyRef.current.innerHTML = decodedContent; } }, [composeBody]); const handleInput = (e: React.FormEvent) => { if (composeBodyRef.current) { - setComposeBody(composeBodyRef.current.innerHTML); + const encodedContent = encodeComposeContent(composeBodyRef.current.innerHTML); + setComposeBody(encodedContent); } }; @@ -228,12 +221,9 @@ export default function ComposeEmail({ ref={composeBodyRef} contentEditable onInput={handleInput} - className="w-full h-full mt-1 bg-white border border-gray-300 rounded-md p-2 text-gray-900 overflow-y-auto prose max-w-none" + className="w-full h-full mt-1 bg-white border border-gray-300 rounded-md p-2 text-gray-900 overflow-y-auto" style={{ - minHeight: '200px', - direction: 'inherit' as const, - textAlign: 'start', - unicodeBidi: 'plaintext' + minHeight: '200px' }} /> diff --git a/lib/compose-mime-decoder.ts b/lib/compose-mime-decoder.ts new file mode 100644 index 00000000..0185bbca --- /dev/null +++ b/lib/compose-mime-decoder.ts @@ -0,0 +1,82 @@ +/** + * Simple MIME decoder for compose message box + * Handles basic email content and text direction + */ + +export function decodeComposeContent(content: string): string { + if (!content) return ''; + + // Simple text direction detection + const hasRtlChars = /[\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]/.test(content); + const direction = hasRtlChars ? 'rtl' : 'ltr'; + + // Basic HTML cleaning + let cleaned = content + // Remove script and style tags + .replace(/]*>[\s\S]*?<\/script>/gi, '') + .replace(/]*>[\s\S]*?<\/style>/gi, '') + // Remove meta tags + .replace(/]*>/gi, '') + // Remove head and title + .replace(/]*>[\s\S]*?<\/head>/gi, '') + .replace(/]*>[\s\S]*?<\/title>/gi, '') + // Preserve body attributes + .replace(/]*>/gi, (match) => { + const dir = match.match(/dir=["'](rtl|ltr)["']/i)?.[1] || direction; + return ``; + }) + .replace(/<\/body>/gi, '') + // Remove html tags + .replace(/]*>/gi, '') + .replace(/<\/html>/gi, '') + // Handle basic formatting + .replace(//gi, '\n') + .replace(/]*>/gi, '\n') + .replace(/<\/p>/gi, '\n') + .replace(/]*>/gi, '\n') + .replace(/<\/div>/gi, '\n') + // Handle lists + .replace(/]*>/gi, '\n') + .replace(/<\/ul>/gi, '\n') + .replace(/]*>/gi, '\n') + .replace(/<\/ol>/gi, '\n') + .replace(/]*>/gi, '• ') + .replace(/<\/li>/gi, '\n') + // Handle basic text formatting + .replace(/]*>/gi, '**') + .replace(/<\/strong>/gi, '**') + .replace(/]*>/gi, '**') + .replace(/<\/b>/gi, '**') + .replace(/]*>/gi, '*') + .replace(/<\/em>/gi, '*') + .replace(/]*>/gi, '*') + .replace(/<\/i>/gi, '*') + // Handle links + .replace(/]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '$2 ($1)') + // Handle basic entities + .replace(/ /g, ' ') + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/'/g, "'") + // Clean up whitespace + .replace(/\s+/g, ' ') + .trim(); + + // Wrap in a div with proper direction + return `
${cleaned}
`; +} + +export function encodeComposeContent(content: string): string { + if (!content) return ''; + + // Basic HTML encoding + return content + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(/\n/g, '
'); +} \ No newline at end of file