courrier preview
This commit is contained in:
parent
9cde8ac9d0
commit
a82fb22b93
@ -86,7 +86,18 @@ export default function EmailPanel({
|
|||||||
'text' in email.content &&
|
'text' in email.content &&
|
||||||
'direction' in email.content) {
|
'direction' in email.content) {
|
||||||
console.log('EmailPanel: Email already in standardized format');
|
console.log('EmailPanel: Email already in standardized format');
|
||||||
return email as EmailMessage;
|
|
||||||
|
// Normalize address format before returning
|
||||||
|
const normalizedEmail = {
|
||||||
|
...email,
|
||||||
|
// Ensure from, to, cc are strings as expected by the EmailMessage interface
|
||||||
|
from: normalizeAddress(email.from),
|
||||||
|
to: normalizeAddress(email.to),
|
||||||
|
cc: email.cc ? normalizeAddress(email.cc) : undefined,
|
||||||
|
bcc: email.bcc ? normalizeAddress(email.bcc) : undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
return normalizedEmail as EmailMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the adapter utility to convert to the standardized format
|
// Use the adapter utility to convert to the standardized format
|
||||||
@ -103,8 +114,8 @@ export default function EmailPanel({
|
|||||||
return {
|
return {
|
||||||
id: email.id || 'unknown',
|
id: email.id || 'unknown',
|
||||||
subject: email.subject || 'Error displaying email',
|
subject: email.subject || 'Error displaying email',
|
||||||
from: email.from || '',
|
from: normalizeAddress(email.from) || '',
|
||||||
to: email.to || '',
|
to: normalizeAddress(email.to) || '',
|
||||||
date: email.date || new Date().toISOString(),
|
date: email.date || new Date().toISOString(),
|
||||||
flags: [],
|
flags: [],
|
||||||
content: {
|
content: {
|
||||||
@ -234,4 +245,41 @@ export default function EmailPanel({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to normalize address to string format
|
||||||
|
function normalizeAddress(address: any): string {
|
||||||
|
if (!address) return '';
|
||||||
|
|
||||||
|
// If already a string, return as is
|
||||||
|
if (typeof address === 'string') {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If array of EmailAddress objects
|
||||||
|
if (Array.isArray(address)) {
|
||||||
|
return address.map(addr => {
|
||||||
|
if (typeof addr === 'object' && addr !== null) {
|
||||||
|
// Handle EmailAddress object
|
||||||
|
if ('name' in addr && 'address' in addr) {
|
||||||
|
return addr.name && addr.name !== addr.address
|
||||||
|
? `${addr.name} <${addr.address}>`
|
||||||
|
: addr.address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return String(addr || '');
|
||||||
|
}).join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle single EmailAddress object
|
||||||
|
if (typeof address === 'object' && address !== null) {
|
||||||
|
if ('name' in address && 'address' in address) {
|
||||||
|
return address.name && address.name !== address.address
|
||||||
|
? `${address.name} <${address.address}>`
|
||||||
|
: address.address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback
|
||||||
|
return String(address);
|
||||||
}
|
}
|
||||||
@ -30,6 +30,19 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
|
|||||||
console.log('EmailPreview: Input email type:', typeof email);
|
console.log('EmailPreview: Input email type:', typeof email);
|
||||||
console.log('EmailPreview: Input email properties:', Object.keys(email));
|
console.log('EmailPreview: Input email properties:', Object.keys(email));
|
||||||
|
|
||||||
|
// Check if from field is an array or string and log it
|
||||||
|
if (email.from) {
|
||||||
|
console.log('EmailPreview: From field type:', Array.isArray(email.from) ?
|
||||||
|
'array' : typeof email.from);
|
||||||
|
|
||||||
|
if (Array.isArray(email.from)) {
|
||||||
|
console.log('EmailPreview: From array length:', email.from.length);
|
||||||
|
if (email.from.length > 0) {
|
||||||
|
console.log('EmailPreview: First from item type:', typeof email.from[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (email.content) {
|
if (email.content) {
|
||||||
console.log('EmailPreview: Content type:', typeof email.content);
|
console.log('EmailPreview: Content type:', typeof email.content);
|
||||||
if (typeof email.content === 'object') {
|
if (typeof email.content === 'object') {
|
||||||
@ -59,6 +72,8 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
|
|||||||
id: adapted.id,
|
id: adapted.id,
|
||||||
subject: adapted.subject,
|
subject: adapted.subject,
|
||||||
from: adapted.from,
|
from: adapted.from,
|
||||||
|
fromType: typeof adapted.from,
|
||||||
|
isFromArray: Array.isArray(adapted.from),
|
||||||
content: adapted.content ? {
|
content: adapted.content ? {
|
||||||
isHtml: adapted.content.isHtml,
|
isHtml: adapted.content.isHtml,
|
||||||
direction: adapted.content.direction,
|
direction: adapted.content.direction,
|
||||||
@ -124,10 +139,32 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
|
|||||||
// Debug output for content structure
|
// Debug output for content structure
|
||||||
console.log('EmailPreview: Standardized Email Content:', standardizedEmail.content);
|
console.log('EmailPreview: Standardized Email Content:', standardizedEmail.content);
|
||||||
|
|
||||||
// Extract sender from string (name <email@example.com>)
|
// Extract sender from various possible formats - handle both string and array formats
|
||||||
const senderInfo = standardizedEmail.from.match(/^(?:"?([^"]*)"?\s)?<?([^\s>]+@[^\s>]+)>?$/);
|
let senderName = '';
|
||||||
const senderName = senderInfo ? senderInfo[1] || senderInfo[2] : standardizedEmail.from;
|
let senderEmail = '';
|
||||||
const senderEmail = senderInfo ? senderInfo[2] : standardizedEmail.from;
|
|
||||||
|
// Handle 'from' field which might be a string or an array of EmailAddress objects
|
||||||
|
if (standardizedEmail.from) {
|
||||||
|
if (Array.isArray(standardizedEmail.from)) {
|
||||||
|
// If it's an array of EmailAddress objects
|
||||||
|
if (standardizedEmail.from.length > 0) {
|
||||||
|
const sender = standardizedEmail.from[0];
|
||||||
|
if (typeof sender === 'object') {
|
||||||
|
senderName = sender.name || sender.address || '';
|
||||||
|
senderEmail = sender.address || '';
|
||||||
|
} else {
|
||||||
|
// Handle case where array contains strings
|
||||||
|
senderName = String(sender);
|
||||||
|
senderEmail = String(sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (typeof standardizedEmail.from === 'string') {
|
||||||
|
// If it's a string, try to extract name and email with regex
|
||||||
|
const senderInfo = standardizedEmail.from.match(/^(?:"?([^"]*)"?\s)?<?([^\s>]+@[^\s>]+)>?$/);
|
||||||
|
senderName = senderInfo ? senderInfo[1] || senderInfo[2] : standardizedEmail.from;
|
||||||
|
senderEmail = senderInfo ? senderInfo[2] : standardizedEmail.from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for attachments
|
// Check for attachments
|
||||||
const hasAttachments = standardizedEmail.attachments && standardizedEmail.attachments.length > 0;
|
const hasAttachments = standardizedEmail.attachments && standardizedEmail.attachments.length > 0;
|
||||||
|
|||||||
@ -13,10 +13,51 @@ export function adaptLegacyEmail(email: LegacyEmailMessage): EmailMessage {
|
|||||||
const content: EmailContent = normalizeContent(email);
|
const content: EmailContent = normalizeContent(email);
|
||||||
|
|
||||||
// Convert email addresses to string format as required by EmailMessage interface
|
// Convert email addresses to string format as required by EmailMessage interface
|
||||||
const from = formatAddressesToString(normalizeAddresses(email.from));
|
// Handle both array and string formats for email fields
|
||||||
const to = formatAddressesToString(normalizeAddresses(email.to));
|
let from: string;
|
||||||
const cc = email.cc ? formatAddressesToString(normalizeAddresses(email.cc)) : undefined;
|
let to: string;
|
||||||
const bcc = email.bcc ? formatAddressesToString(normalizeAddresses(email.bcc)) : undefined;
|
let cc: string | undefined;
|
||||||
|
let bcc: string | undefined;
|
||||||
|
|
||||||
|
// Handle 'from' field
|
||||||
|
if (Array.isArray(email.from)) {
|
||||||
|
from = formatAddressesToString(normalizeAddresses(email.from));
|
||||||
|
} else if (typeof email.from === 'object' && 'address' in email.from) {
|
||||||
|
from = formatAddressesToString([email.from as EmailAddress]);
|
||||||
|
} else {
|
||||||
|
from = String(email.from || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle 'to' field
|
||||||
|
if (Array.isArray(email.to)) {
|
||||||
|
to = formatAddressesToString(normalizeAddresses(email.to));
|
||||||
|
} else if (typeof email.to === 'object' && 'address' in email.to) {
|
||||||
|
to = formatAddressesToString([email.to as EmailAddress]);
|
||||||
|
} else {
|
||||||
|
to = String(email.to || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle optional 'cc' field
|
||||||
|
if (email.cc) {
|
||||||
|
if (Array.isArray(email.cc)) {
|
||||||
|
cc = formatAddressesToString(normalizeAddresses(email.cc));
|
||||||
|
} else if (typeof email.cc === 'object' && 'address' in email.cc) {
|
||||||
|
cc = formatAddressesToString([email.cc as EmailAddress]);
|
||||||
|
} else {
|
||||||
|
cc = String(email.cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle optional 'bcc' field
|
||||||
|
if (email.bcc) {
|
||||||
|
if (Array.isArray(email.bcc)) {
|
||||||
|
bcc = formatAddressesToString(normalizeAddresses(email.bcc));
|
||||||
|
} else if (typeof email.bcc === 'object' && 'address' in email.bcc) {
|
||||||
|
bcc = formatAddressesToString([email.bcc as EmailAddress]);
|
||||||
|
} else {
|
||||||
|
bcc = String(email.bcc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert flags if needed
|
// Convert flags if needed
|
||||||
const flags: string[] = normalizeFlags(email.flags);
|
const flags: string[] = normalizeFlags(email.flags);
|
||||||
@ -200,25 +241,7 @@ function normalizeAddresses(addresses: string | EmailAddress[] | undefined): Ema
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(addresses)) {
|
// Handle string
|
||||||
// If already in EmailAddress format, return as is
|
|
||||||
if (addresses.length > 0 && typeof addresses[0] === 'object') {
|
|
||||||
return addresses as EmailAddress[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise convert string elements to EmailAddress objects
|
|
||||||
return addresses.map((addr: any) => {
|
|
||||||
if (typeof addr === 'string') {
|
|
||||||
return {
|
|
||||||
name: addr.split('@')[0] || '',
|
|
||||||
address: addr
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle single address as string
|
|
||||||
if (typeof addresses === 'string') {
|
if (typeof addresses === 'string') {
|
||||||
// Check if format is "Name <email@example.com>"
|
// Check if format is "Name <email@example.com>"
|
||||||
const match = addresses.match(/^([^<]+)<([^>]+)>$/);
|
const match = addresses.match(/^([^<]+)<([^>]+)>$/);
|
||||||
@ -229,12 +252,56 @@ function normalizeAddresses(addresses: string | EmailAddress[] | undefined): Ema
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple email address
|
||||||
return [{
|
return [{
|
||||||
name: addresses.split('@')[0] || '',
|
name: addresses.split('@')[0] || '',
|
||||||
address: addresses
|
address: addresses
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle array
|
||||||
|
if (Array.isArray(addresses)) {
|
||||||
|
// If already in EmailAddress format, return as is
|
||||||
|
if (addresses.length > 0 && typeof addresses[0] === 'object' && 'address' in addresses[0]) {
|
||||||
|
return addresses as EmailAddress[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise convert string elements to EmailAddress objects
|
||||||
|
return addresses.map((addr: any) => {
|
||||||
|
if (typeof addr === 'string') {
|
||||||
|
// Check if format is "Name <email@example.com>"
|
||||||
|
const match = addr.match(/^([^<]+)<([^>]+)>$/);
|
||||||
|
if (match) {
|
||||||
|
return {
|
||||||
|
name: match[1].trim(),
|
||||||
|
address: match[2].trim()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: addr.split('@')[0] || '',
|
||||||
|
address: addr
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's already an object with address property
|
||||||
|
if (typeof addr === 'object' && addr !== null && 'address' in addr) {
|
||||||
|
return {
|
||||||
|
name: addr.name || addr.address.split('@')[0] || '',
|
||||||
|
address: addr.address
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback for unexpected formats
|
||||||
|
return {
|
||||||
|
name: '',
|
||||||
|
address: String(addr || '')
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unexpected type - return empty array
|
||||||
|
console.warn(`Unexpected addresses format: ${typeof addresses}`, addresses);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,10 @@ import DOMPurify from 'isomorphic-dompurify';
|
|||||||
import {
|
import {
|
||||||
EmailMessage,
|
EmailMessage,
|
||||||
EmailContent,
|
EmailContent,
|
||||||
EmailAddress
|
EmailAddress,
|
||||||
|
LegacyEmailMessage
|
||||||
} from '@/types/email';
|
} from '@/types/email';
|
||||||
import { adaptLegacyEmail } from './email-adapters';
|
import { adaptLegacyEmail } from '@/lib/utils/email-adapters';
|
||||||
import { decodeInfomaniakEmail, adaptMimeEmail, isMimeFormat } from './email-mime-decoder';
|
import { decodeInfomaniakEmail, adaptMimeEmail, isMimeFormat } from './email-mime-decoder';
|
||||||
|
|
||||||
// Reset any existing hooks to start clean
|
// Reset any existing hooks to start clean
|
||||||
@ -48,15 +49,26 @@ export function detectTextDirection(text: string): 'ltr' | 'rtl' {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Format email addresses for display
|
* Format email addresses for display
|
||||||
|
* Can handle both array of EmailAddress objects or a string
|
||||||
*/
|
*/
|
||||||
export function formatEmailAddresses(addresses: EmailAddress[]): string {
|
export function formatEmailAddresses(addresses: EmailAddress[] | string | undefined): string {
|
||||||
if (!addresses || addresses.length === 0) return '';
|
if (!addresses) return '';
|
||||||
|
|
||||||
return addresses.map(addr =>
|
// If already a string, return as is
|
||||||
addr.name && addr.name !== addr.address
|
if (typeof addresses === 'string') {
|
||||||
? `${addr.name} <${addr.address}>`
|
return addresses;
|
||||||
: addr.address
|
}
|
||||||
).join(', ');
|
|
||||||
|
// If array, format each address
|
||||||
|
if (Array.isArray(addresses) && addresses.length > 0) {
|
||||||
|
return addresses.map(addr =>
|
||||||
|
addr.name && addr.name !== addr.address
|
||||||
|
? `${addr.name} <${addr.address}>`
|
||||||
|
: addr.address
|
||||||
|
).join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user