courrier preview
This commit is contained in:
parent
1f6032941a
commit
cdd5bd98bc
@ -45,11 +45,35 @@ export default function EmailDetailView({
|
||||
// Render email content based on the email body
|
||||
const renderEmailContent = () => {
|
||||
try {
|
||||
console.log('EmailDetailView renderEmailContent', {
|
||||
// Enhanced debugging to trace exactly what's in the content
|
||||
console.log('EmailDetailView renderEmailContent - DETAILED DEBUG', {
|
||||
emailId: email.id,
|
||||
subject: email.subject,
|
||||
hasContent: !!email.content,
|
||||
contentType: typeof email.content,
|
||||
contentKeys: email.content && typeof email.content === 'object' ? Object.keys(email.content) : [],
|
||||
contentStringLength: typeof email.content === 'string' ? email.content.length : 'N/A',
|
||||
contentHtmlLength: email.content && typeof email.content === 'object' && 'html' in email.content && typeof (email.content as any).html === 'string'
|
||||
? ((email.content as any).html as string).length
|
||||
: 0,
|
||||
contentTextLength: email.content && typeof email.content === 'object' && 'text' in email.content && typeof (email.content as any).text === 'string'
|
||||
? ((email.content as any).text as string).length
|
||||
: 0,
|
||||
contentSample: typeof email.content === 'string'
|
||||
? email.content.substring(0, 100)
|
||||
: (email.content && typeof email.content === 'object' && 'html' in email.content && typeof (email.content as any).html === 'string'
|
||||
? ((email.content as any).html as string).substring(0, 100)
|
||||
: (email.content && typeof email.content === 'object' && 'text' in email.content && typeof (email.content as any).text === 'string'
|
||||
? ((email.content as any).text as string).substring(0, 100)
|
||||
: 'N/A')),
|
||||
hasHtml: !!email.html,
|
||||
hasText: !!email.text
|
||||
htmlLength: email.html?.length || 0,
|
||||
htmlSample: email.html?.substring(0, 100) || 'N/A',
|
||||
hasText: !!email.text,
|
||||
textLength: email.text?.length || 0,
|
||||
textSample: email.text?.substring(0, 100) || 'N/A',
|
||||
contentIsNull: email.content === null,
|
||||
contentIsUndefined: email.content === undefined,
|
||||
});
|
||||
|
||||
// Determine what content to use and how to handle it
|
||||
@ -59,15 +83,29 @@ export default function EmailDetailView({
|
||||
// If content is a string, use it directly
|
||||
if (typeof email.content === 'string') {
|
||||
contentToUse = email.content;
|
||||
console.log('Using email.content as string', contentToUse.substring(0, 50));
|
||||
}
|
||||
// If content is an object with html/text properties
|
||||
else if (typeof email.content === 'object') {
|
||||
contentToUse = email.content.html || email.content.text || '';
|
||||
const contentObj = email.content as {html?: string; text?: string};
|
||||
if (contentObj.html) {
|
||||
contentToUse = contentObj.html;
|
||||
console.log('Using email.content.html', contentToUse.substring(0, 50));
|
||||
} else if (contentObj.text) {
|
||||
// Convert plain text to HTML
|
||||
contentToUse = contentObj.text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/\n/g, '<br>');
|
||||
console.log('Using email.content.text (converted)', contentToUse.substring(0, 50));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fall back to html or text properties if content is not available
|
||||
else if (email.html) {
|
||||
contentToUse = email.html;
|
||||
console.log('Using fallback email.html', contentToUse.substring(0, 50));
|
||||
}
|
||||
else if (email.text) {
|
||||
// Convert plain text to HTML with line breaks
|
||||
@ -76,6 +114,15 @@ export default function EmailDetailView({
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/\n/g, '<br>');
|
||||
console.log('Using fallback email.text (converted)', contentToUse.substring(0, 50));
|
||||
}
|
||||
|
||||
// Log if no content was found
|
||||
if (!contentToUse) {
|
||||
console.error('No renderable content found in email!', {
|
||||
id: email.id,
|
||||
subject: email.subject
|
||||
});
|
||||
}
|
||||
|
||||
// Return content or fallback message
|
||||
|
||||
@ -61,6 +61,84 @@ export const useEmailState = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Normalize email content structure to ensure consistency
|
||||
const normalizeEmailContent = useCallback((emailData: any): any => {
|
||||
if (!emailData) return emailData;
|
||||
|
||||
// Create a clone to avoid modifying the original
|
||||
const normalizedEmail = { ...emailData };
|
||||
|
||||
// Log the incoming email structure
|
||||
console.log(`[NORMALIZE_EMAIL] Processing email ${normalizedEmail.id || 'unknown'}: ${normalizedEmail.subject || 'No subject'}`);
|
||||
|
||||
try {
|
||||
// Handle content field normalization
|
||||
if (!normalizedEmail.content) {
|
||||
// Create content object if it doesn't exist
|
||||
normalizedEmail.content = { html: '', text: '' };
|
||||
|
||||
// Try to populate content from html/text fields
|
||||
if (normalizedEmail.html) {
|
||||
normalizedEmail.content.html = normalizedEmail.html;
|
||||
console.log(`[NORMALIZE_EMAIL] Populated content.html from email.html (${normalizedEmail.html.length} chars)`);
|
||||
}
|
||||
|
||||
if (normalizedEmail.text) {
|
||||
normalizedEmail.content.text = normalizedEmail.text;
|
||||
console.log(`[NORMALIZE_EMAIL] Populated content.text from email.text (${normalizedEmail.text.length} chars)`);
|
||||
}
|
||||
}
|
||||
// If content is a string, convert to object format
|
||||
else if (typeof normalizedEmail.content === 'string') {
|
||||
const htmlContent = normalizedEmail.content;
|
||||
normalizedEmail.content = {
|
||||
html: htmlContent,
|
||||
text: htmlContent.replace(/<[^>]*>/g, '') // Simple HTML to text conversion
|
||||
};
|
||||
console.log(`[NORMALIZE_EMAIL] Converted string content to object (${htmlContent.length} chars)`);
|
||||
}
|
||||
// Ensure content object has both html and text properties
|
||||
else if (typeof normalizedEmail.content === 'object') {
|
||||
if (!normalizedEmail.content.html && normalizedEmail.content.text) {
|
||||
// Convert text to simple HTML if only text exists
|
||||
normalizedEmail.content.html = normalizedEmail.content.text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/\n/g, '<br>');
|
||||
console.log(`[NORMALIZE_EMAIL] Created HTML content from text (${normalizedEmail.content.text.length} chars)`);
|
||||
} else if (!normalizedEmail.content.text && normalizedEmail.content.html) {
|
||||
// Create plain text version if only HTML exists
|
||||
normalizedEmail.content.text = normalizedEmail.content.html.replace(/<[^>]*>/g, '');
|
||||
console.log(`[NORMALIZE_EMAIL] Created text content from HTML (${normalizedEmail.content.html.length} chars)`);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure html and text properties are also set for backward compatibility
|
||||
if (normalizedEmail.content?.html && !normalizedEmail.html) {
|
||||
normalizedEmail.html = normalizedEmail.content.html;
|
||||
}
|
||||
|
||||
if (normalizedEmail.content?.text && !normalizedEmail.text) {
|
||||
normalizedEmail.text = normalizedEmail.content.text;
|
||||
}
|
||||
|
||||
console.log(`[NORMALIZE_EMAIL] Normalized email content structure successfully`, {
|
||||
hasContentObj: !!normalizedEmail.content,
|
||||
contentHtmlLength: normalizedEmail.content?.html?.length || 0,
|
||||
contentTextLength: normalizedEmail.content?.text?.length || 0,
|
||||
hasHtml: !!normalizedEmail.html,
|
||||
hasText: !!normalizedEmail.text
|
||||
});
|
||||
|
||||
return normalizedEmail;
|
||||
} catch (error) {
|
||||
console.error(`[NORMALIZE_EMAIL] Error normalizing email content:`, error);
|
||||
// Return the original data if normalization fails
|
||||
return emailData;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Load emails from the server
|
||||
const loadEmails = useCallback(async (page: number, perPage: number, isLoadMore: boolean = false) => {
|
||||
// CRITICAL FIX: Do important validation before setting loading state
|
||||
@ -355,9 +433,11 @@ export const useEmailState = () => {
|
||||
|
||||
if (existingEmail && existingEmail.contentFetched) {
|
||||
// Use the existing email if it has content already
|
||||
// ENHANCEMENT: Apply content normalization before selecting the email
|
||||
const normalizedEmail = normalizeEmailContent(existingEmail);
|
||||
dispatch({
|
||||
type: 'SELECT_EMAIL',
|
||||
payload: { emailId, accountId, folder, email: existingEmail }
|
||||
payload: { emailId, accountId, folder, email: normalizedEmail }
|
||||
});
|
||||
|
||||
// Mark as read if not already
|
||||
@ -386,10 +466,13 @@ export const useEmailState = () => {
|
||||
// Mark the email as read on the server
|
||||
markEmailAsRead(emailId, true, effectiveAccountId);
|
||||
|
||||
// ENHANCEMENT: Apply content normalization before selecting the email
|
||||
const normalizedEmailData = normalizeEmailContent(emailData);
|
||||
|
||||
// Select the email
|
||||
dispatch({
|
||||
type: 'SELECT_EMAIL',
|
||||
payload: { emailId, accountId: effectiveAccountId, folder, email: emailData }
|
||||
payload: { emailId, accountId: effectiveAccountId, folder, email: normalizedEmailData }
|
||||
});
|
||||
} catch (error) {
|
||||
logEmailOp('ERROR', `Failed to select email: ${error instanceof Error ? error.message : String(error)}`);
|
||||
@ -400,7 +483,7 @@ export const useEmailState = () => {
|
||||
} finally {
|
||||
dispatch({ type: 'SET_LOADING', payload: false });
|
||||
}
|
||||
}, [state.emails, logEmailOp]);
|
||||
}, [state.emails, logEmailOp, normalizeEmailContent]);
|
||||
|
||||
// Toggle email selection for multi-select
|
||||
const toggleEmailSelection = useCallback((emailId: string) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user