panel 2 courier api restore
This commit is contained in:
parent
7751094519
commit
079d0a484b
@ -74,3 +74,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Email specific styles */
|
||||
.email-content table { width: 100%; border-collapse: collapse; }
|
||||
.email-content table.table-container { width: auto; margin-bottom: 20px; }
|
||||
.email-content td, .email-content th { padding: 8px; border: 1px solid #e5e7eb; }
|
||||
.email-content img { max-width: 100%; height: auto; }
|
||||
.email-content div[style] { max-width: 100% !important; }
|
||||
.email-content * { max-width: 100% !important; word-wrap: break-word; }
|
||||
.email-content font { font-family: inherit; }
|
||||
.email-content .total-row td { border-top: 1px solid #e5e7eb; }
|
||||
.email-content a { color: #3b82f6; text-decoration: underline; }
|
||||
.email-content p { margin-bottom: 0.75em; }
|
||||
.email-content .header { margin-bottom: 1em; }
|
||||
.email-content .footer { font-size: 0.875rem; color: #6b7280; margin-top: 1em; }
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useRef, useEffect, useState } from 'react';
|
||||
import { useRef, useEffect, useState, useCallback } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
@ -84,6 +84,7 @@ export default function ComposeEmail({
|
||||
const composeBodyRef = useRef<HTMLDivElement>(null);
|
||||
const [localContent, setLocalContent] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const contentRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (replyTo || forwardFrom) {
|
||||
@ -172,14 +173,6 @@ export default function ComposeEmail({
|
||||
<p>To: ${decoded.to || ''}</p>
|
||||
<br>
|
||||
<div class="email-content prose prose-sm max-w-none dark:prose-invert">
|
||||
<style>
|
||||
/* Email-specific styles */
|
||||
.email-content table { width: 100%; border-collapse: collapse; }
|
||||
.email-content td, .email-content th { padding: 8px; border: 1px solid #e5e7eb; }
|
||||
.email-content img { max-width: 100%; height: auto; }
|
||||
.email-content div[style] { max-width: 100% !important; }
|
||||
.email-content * { max-width: 100% !important; }
|
||||
</style>
|
||||
${decoded.html || `<pre>${decoded.text || ''}</pre>`}
|
||||
</div>
|
||||
</div>
|
||||
@ -189,7 +182,9 @@ export default function ComposeEmail({
|
||||
<div class="quoted-message">
|
||||
<p>On ${formatDate(decoded.date)}, ${decoded.from || ''} wrote:</p>
|
||||
<blockquote>
|
||||
${decoded.html || `<pre>${decoded.text || ''}</pre>`}
|
||||
<div class="email-content prose prose-sm max-w-none dark:prose-invert">
|
||||
${decoded.html || `<pre>${decoded.text || ''}</pre>`}
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
`;
|
||||
@ -300,16 +295,16 @@ export default function ComposeEmail({
|
||||
|
||||
// Ensure wheel events are properly handled
|
||||
if (!(div as HTMLElement).hasAttribute('data-scroll-handler-attached')) {
|
||||
div.addEventListener('wheel', (e: Event) => {
|
||||
const wheelEvent = e as WheelEvent;
|
||||
const target = e.currentTarget as HTMLElement;
|
||||
div.addEventListener('wheel', function(this: HTMLElement, ev: Event) {
|
||||
const e = ev as WheelEvent;
|
||||
const target = this;
|
||||
|
||||
// Check if we're at the boundary of the scrollable area
|
||||
const isAtBottom = target.scrollHeight - target.scrollTop <= target.clientHeight + 1;
|
||||
const isAtTop = target.scrollTop <= 0;
|
||||
|
||||
// Only prevent default if we're not at the boundaries in the direction of scrolling
|
||||
if ((wheelEvent.deltaY > 0 && !isAtBottom) || (wheelEvent.deltaY < 0 && !isAtTop)) {
|
||||
if ((e.deltaY > 0 && !isAtBottom) || (e.deltaY < 0 && !isAtTop)) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault(); // Prevent the parent container from scrolling
|
||||
}
|
||||
|
||||
@ -105,12 +105,14 @@ export function cleanHtml(html: string): string {
|
||||
try {
|
||||
// Enhanced configuration to preserve more HTML elements for complex emails
|
||||
return DOMPurify.sanitize(html, {
|
||||
ADD_TAGS: ['style', 'meta', 'link', 'table', 'thead', 'tbody', 'tr', 'td', 'th', 'hr'],
|
||||
ADD_ATTR: ['*', 'colspan', 'rowspan', 'cellpadding', 'cellspacing', 'border', 'bgcolor', 'width', 'height', 'align', 'valign', 'class', 'id', 'style'],
|
||||
ADD_TAGS: ['style', 'meta', 'link', 'table', 'thead', 'tbody', 'tr', 'td', 'th', 'hr', 'font', 'div', 'span', 'a', 'img', 'b', 'strong', 'i', 'em', 'u', 'br', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'code', 'center', 'section', 'header', 'footer', 'article', 'nav'],
|
||||
ADD_ATTR: ['*', 'colspan', 'rowspan', 'cellpadding', 'cellspacing', 'border', 'bgcolor', 'width', 'height', 'align', 'valign', 'class', 'id', 'style', 'color', 'face', 'size', 'background', 'src', 'href', 'target', 'rel', 'alt', 'title', 'name'],
|
||||
ALLOW_UNKNOWN_PROTOCOLS: true,
|
||||
WHOLE_DOCUMENT: true,
|
||||
KEEP_CONTENT: true,
|
||||
RETURN_DOM: false
|
||||
RETURN_DOM: false,
|
||||
FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'form', 'input', 'button', 'select', 'option', 'textarea', 'canvas', 'video', 'audio'],
|
||||
FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover', 'onmouseout', 'onchange', 'onsubmit']
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error cleaning HTML:', error);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user