diff --git a/components/email/ComposeEmail.tsx b/components/email/ComposeEmail.tsx index 17cfcacc..b5b367b1 100644 --- a/components/email/ComposeEmail.tsx +++ b/components/email/ComposeEmail.tsx @@ -17,7 +17,6 @@ import { } from "@/components/ui/dropdown-menu"; import RichEmailEditor from '@/components/email/RichEmailEditor'; import { detectTextDirection } from '@/lib/utils/text-direction'; -import EmailContentDisplay from './EmailContentDisplay'; // Import from the centralized utils import { @@ -317,39 +316,12 @@ export default function ComposeEmail(props: ComposeEmailProps) { setSending(true); try { - // Generate the final email content - let finalContent = emailContent; - - // For reply or forward, combine the user's new content with the quoted content - if (type === 'reply' || type === 'reply-all' || type === 'forward') { - // Get the new content from the editor - const editorContent = document.querySelector('.ql-editor')?.innerHTML || ''; - - // Get the original header (either reply or forward header) - const headerContent = type === 'forward' - ? emailContent.split('
]*>([\s\S]*?)<\/blockquote>/i); - const quotedContent = quotedMatch ? quotedMatch[0] : ''; - - // Combine them - finalContent = ` -- ${editorContent} -- ${headerContent} - ${quotedContent} - `; - } - await onSend({ to, cc: cc || undefined, bcc: bcc || undefined, subject, - body: finalContent, + body: emailContent, fromAccount: selectedAccount?.id, attachments }); @@ -374,10 +346,6 @@ export default function ComposeEmail(props: ComposeEmailProps) { } }; - const handleContentChange = (html: string) => { - setEmailContent(html); - }; - return ({/* Header */} @@ -510,75 +478,14 @@ export default function ComposeEmail(props: ComposeEmailProps) {{/* Message Body */} - {(type === 'forward' || type === 'reply' || type === 'reply-all') ? ( -- {/* Editable area for user's reply */} -- ) : ( - // Regular editor for new emails --- - {/* Read-only display of original email with professional formatting */} -- - {type === 'reply' || type === 'reply-all' ? ( -- - {/* Hidden field to store the complete content for sending */} - -- {/* Get the reply header from the email content */} - {initialEmail && ( - - )} -- ) : type === 'forward' ? ( -- {/* Get the forward header from the email content */} - {initialEmail && ( - - )} -- ) : null} - - {/* Display the original content with the same quality as Panel 3 */} -- {initialEmail && initialEmail.content && ( --- )} - - )} + { + setEmailContent(html); + }} + placeholder="Write your message here..." + minHeight="320px" + /> {/* Attachments */} {attachments.length > 0 && ( diff --git a/components/email/RichEmailEditor.tsx b/components/email/RichEmailEditor.tsx index eadbb879..4b6093cd 100644 --- a/components/email/RichEmailEditor.tsx +++ b/components/email/RichEmailEditor.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { useEffect, useRef, useState, useMemo } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import 'quill/dist/quill.snow.css'; import { sanitizeHtml } from '@/lib/utils/dom-purify-config'; import { detectTextDirection } from '@/lib/utils/text-direction'; @@ -28,15 +28,6 @@ const RichEmailEditor: React.FC = ({ const quillRef = useRef (null); const [isReady, setIsReady] = useState(false); - // Determine if content is pre-formatted (for forward/reply) - const isPreFormattedContent = useMemo(() => { - return preserveFormatting && initialContent && ( - (initialContent.includes('---------- Forwarded message ----------') || - initialContent.includes('wrote:')) && - initialContent.includes(' { // Import Quill dynamically (client-side only) @@ -45,32 +36,21 @@ const RichEmailEditor: React.FC= ({ const Quill = (await import('quill')).default; - // Check if content already appears to be pre-formatted as a reply or forward - const isPreFormattedContent = initialContent && ( - (initialContent.includes('---------- Forwarded message ----------') || - initialContent.includes('wrote:')) && - initialContent.includes(' = ({ clipboard: { matchVisual: false // Disable clipboard matching for better HTML handling }, - // Don't initialize better-table if this is pre-formatted content - 'better-table': isPreFormattedContent ? false : tableModule, + // Don't initialize better-table yet - we'll do it after content is loaded + 'better-table': false, }, placeholder: placeholder, theme: 'snow', @@ -113,8 +93,7 @@ const RichEmailEditor: React.FC= ({ startsWithHtml: initialContent.trim().startsWith('<'), containsForwardedMessage: initialContent.includes('---------- Forwarded message ----------'), containsReplyIndicator: initialContent.includes('wrote:'), - hasBlockquote: initialContent.includes(' = ({ quillRef.current.setText('Error loading content'); } } else { - // Special handling for reply/forward content - if (isPreFormattedContent && preserveFormatting) { - console.log('Setting pre-formatted reply/forward content with special handling'); - - // First clear the editor and add a line break for the user to type in - quillRef.current.setText('\n\n'); - - // Set cursor at the top - quillRef.current.setSelection(0, 0); - - // Now append the quoted content as a read-only section - const quoteIndex = quillRef.current.getText().length; - quillRef.current.clipboard.dangerouslyPasteHTML(quoteIndex, sanitizedContent); - - // Set direction for the editor + // Use direct innerHTML setting for the initial content + quillRef.current.root.innerHTML = sanitizedContent; + + // Set the direction for the content + if (quillRef.current && quillRef.current.format) { quillRef.current.format('direction', direction); if (direction === 'rtl') { quillRef.current.format('align', 'right'); } } else { - // Use direct innerHTML setting for the initial content - quillRef.current.root.innerHTML = sanitizedContent; - - // Set the direction for the content - if (quillRef.current && quillRef.current.format) { - quillRef.current.format('direction', direction); - if (direction === 'rtl') { - quillRef.current.format('align', 'right'); - } - } else { - console.warn('Cannot format content: editor not fully initialized'); - } + console.warn('Cannot format content: editor not fully initialized'); } } @@ -309,17 +267,6 @@ const RichEmailEditor: React.FC= ({ console.log('Content appears to be pre-formatted as reply/forward, using as-is'); // Just do basic sanitization without additional processing sanitizedContent = sanitizeHtml(initialContent); - - // Disable formatting operations that might conflict with pre-formatted content - try { - // Disable better-table module to prevent errors with forwarded tables - if (quillRef.current.getModule('better-table')) { - // Try to disable better-table module operations - quillRef.current.getModule('better-table').tableSelection = null; - } - } catch (err) { - console.warn('Error disabling table module:', err); - } } else { // Full processing for regular content sanitizedContent = processHtmlContent(initialContent); @@ -350,52 +297,31 @@ const RichEmailEditor: React.FC = ({ quillRef.current.setText(textContent || 'No content available'); } } else { - // Special handling for reply/forward content - if (isPreFormattedContent && preserveFormatting) { - console.log('Setting pre-formatted reply/forward content with special handling'); + // SIMPLIFIED: Set content directly to the root element rather than using clipboard + if (quillRef.current && quillRef.current.root) { + // First set the content + quillRef.current.root.innerHTML = sanitizedContent; - // First clear the editor and add a line break for the user to type in - quillRef.current.setText('\n\n'); - - // Set cursor at the top - quillRef.current.setSelection(0, 0); - - // Now append the quoted content as a read-only section - const quoteIndex = quillRef.current.getText().length; - quillRef.current.clipboard.dangerouslyPasteHTML(quoteIndex, sanitizedContent); - - // Set direction for the editor - quillRef.current.format('direction', direction); - if (direction === 'rtl') { - quillRef.current.format('align', 'right'); - } - } else { - // SIMPLIFIED: Set content directly to the root element rather than using clipboard - if (quillRef.current && quillRef.current.root) { - // First set the content - quillRef.current.root.innerHTML = sanitizedContent; - - // Then safely apply formatting only if quillRef is valid - try { - if (quillRef.current && quillRef.current.format && quillRef.current.root.innerHTML.trim().length > 0) { - // Set the direction for the content - quillRef.current.format('direction', direction); - if (direction === 'rtl') { - quillRef.current.format('align', 'right'); - } - - // Force update - quillRef.current.update(); - - // Set selection to beginning - quillRef.current.setSelection(0, 0); - } else { - console.warn('Skipping format - either editor not ready or content empty'); + // Then safely apply formatting only if quillRef is valid + try { + if (quillRef.current && quillRef.current.format && quillRef.current.root.innerHTML.trim().length > 0) { + // Set the direction for the content + quillRef.current.format('direction', direction); + if (direction === 'rtl') { + quillRef.current.format('align', 'right'); } - } catch (formatError) { - console.error('Error applying formatting:', formatError); - // Continue without formatting if there's an error + + // Force update + quillRef.current.update(); + + // Set selection to beginning + quillRef.current.setSelection(0, 0); + } else { + console.warn('Skipping format - either editor not ready or content empty'); } + } catch (formatError) { + console.error('Error applying formatting:', formatError); + // Continue without formatting if there's an error } } }