mail page imap connection 13

This commit is contained in:
alma 2025-04-15 21:52:10 +02:00
parent 47f86057b2
commit f717203e65

View File

@ -41,30 +41,35 @@ interface Email {
category: string; category: string;
} }
// Improve MIME decoding function // Improved MIME decoding function
const decodeMimeContent = (content: string) => { const decodeMimeContent = (content: string) => {
try { try {
// Extract the actual content after headers // First, try to extract the main content
const contentMatch = content.match(/charset="utf-8"\s*([\s\S]*?)(?=\s*(?:\[LINK:|$))/); let cleanContent = content
if (!contentMatch) return content;
let cleanContent = contentMatch[1]
// Remove MIME headers and metadata // Remove MIME headers and metadata
.replace(/^.*?Content-Type:.*?\n\n/s, '') .replace(/^This is a multi-part message.*?utf-8"/s, '')
.replace(/---InfomaniakPhpMail.*?Content-Transfer-Encoding:.*?\n/g, '') .replace(/---InfomaniakPhpMail.*?Content-Transfer-Encoding:.*?\n/g, '')
// Clean up special characters .replace(/Content-Type:.*?\n/g, '')
.replace(/Content-Transfer-Encoding:.*?\n/g, '')
// Clean up special characters and formatting
.replace(/=C2=A0/g, ' ') .replace(/=C2=A0/g, ' ')
.replace(/=\n/g, '') .replace(/=\n/g, '')
.replace(/=([0-9A-F]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16))) .replace(/=([0-9A-F]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
// Remove formatting markers
.replace(/\[IMG:.*?\]/g, '') .replace(/\[IMG:.*?\]/g, '')
.replace(/\*([^*]+)\*/g, '$1') .replace(/\*([^*]+)\*/g, '$1')
// Clean up links .replace(/\[ ?LINK: ([^\]]+) ?\]/g, '$1')
.replace(/\[ LINK: (.*?) \]/g, '$1') // Clean up whitespace
// Normalize whitespace
.replace(/\s+/g, ' ') .replace(/\s+/g, ' ')
.trim(); .trim();
// Extract just the welcome message and first paragraph if it's the welcome email
if (cleanContent.includes('Welcome to your professional mailbox')) {
const welcomeMatch = cleanContent.match(/Welcome to your professional mailbox!(.+?)(?=\*Getting started\*|$)/s);
if (welcomeMatch) {
return welcomeMatch[0].trim();
}
}
return cleanContent; return cleanContent;
} catch (error) { } catch (error) {
console.error('Error decoding MIME content:', error); console.error('Error decoding MIME content:', error);
@ -100,6 +105,9 @@ export default function MailPage() {
const [emails, setEmails] = useState<Email[]>([]); const [emails, setEmails] = useState<Email[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [composeSubject, setComposeSubject] = useState('');
const [composeRecipient, setComposeRecipient] = useState('');
const [composeContent, setComposeContent] = useState('');
// Fetch emails from IMAP API // Fetch emails from IMAP API
useEffect(() => { useEffect(() => {
@ -174,15 +182,15 @@ export default function MailPage() {
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ emailId }) body: JSON.stringify({ emailId })
}); });
const updatedEmails = emails.map(email =>
email.id === emailId ? { ...email, read: true } : email
);
setEmails(updatedEmails);
setSelectedEmail(emailId);
} catch (error) { } catch (error) {
console.error('Error marking email as read:', error); console.error('Error marking email as read:', error);
} }
const updatedEmails = emails.map(email =>
email.id === emailId ? { ...email, read: true } : email
);
setEmails(updatedEmails);
setSelectedEmail(emailId);
}; };
// Toggle starred status // Toggle starred status
@ -284,6 +292,36 @@ export default function MailPage() {
)); ));
}; };
// Handle reply
const handleReply = async (type: 'reply' | 'replyAll' | 'forward') => {
const selectedEmailData = getSelectedEmail();
if (!selectedEmailData) return;
setComposeOpen(true);
const subject = `${type === 'forward' ? 'Fwd: ' : 'Re: '}${selectedEmailData.subject}`;
let to = '';
let content = '';
switch (type) {
case 'reply':
to = selectedEmailData.from;
content = `\n\nOn ${new Date(selectedEmailData.date).toLocaleString()}, ${selectedEmailData.fromName} wrote:\n> ${selectedEmailData.body.split('\n').join('\n> ')}`;
break;
case 'replyAll':
to = selectedEmailData.from; // You would also need to add CC recipients here
content = `\n\nOn ${new Date(selectedEmailData.date).toLocaleString()}, ${selectedEmailData.fromName} wrote:\n> ${selectedEmailData.body.split('\n').join('\n> ')}`;
break;
case 'forward':
content = `\n\n---------- Forwarded message ----------\nFrom: ${selectedEmailData.fromName} <${selectedEmailData.from}>\nDate: ${new Date(selectedEmailData.date).toLocaleString()}\nSubject: ${selectedEmailData.subject}\n\n${selectedEmailData.body}`;
break;
}
// Update compose form state (you'll need to add these state variables)
setComposeSubject(subject);
setComposeRecipient(to);
setComposeContent(content);
};
if (loading) { if (loading) {
return ( return (
<div className="flex h-[calc(100vh-theme(spacing.12))] items-center justify-center bg-gray-100 mt-12"> <div className="flex h-[calc(100vh-theme(spacing.12))] items-center justify-center bg-gray-100 mt-12">
@ -633,6 +671,7 @@ export default function MailPage() {
variant="ghost" variant="ghost"
size="sm" size="sm"
className="text-gray-700 hover:bg-gray-100 hover:text-gray-900" className="text-gray-700 hover:bg-gray-100 hover:text-gray-900"
onClick={() => handleReply('reply')}
> >
<Reply className="h-4 w-4 mr-2" /> <Reply className="h-4 w-4 mr-2" />
Reply Reply
@ -641,6 +680,7 @@ export default function MailPage() {
variant="ghost" variant="ghost"
size="sm" size="sm"
className="text-gray-700 hover:bg-gray-100 hover:text-gray-900" className="text-gray-700 hover:bg-gray-100 hover:text-gray-900"
onClick={() => handleReply('replyAll')}
> >
<ReplyAll className="h-4 w-4 mr-2" /> <ReplyAll className="h-4 w-4 mr-2" />
Reply all Reply all
@ -649,6 +689,7 @@ export default function MailPage() {
variant="ghost" variant="ghost"
size="sm" size="sm"
className="text-gray-700 hover:bg-gray-100 hover:text-gray-900" className="text-gray-700 hover:bg-gray-100 hover:text-gray-900"
onClick={() => handleReply('forward')}
> >
<Forward className="h-4 w-4 mr-2" /> <Forward className="h-4 w-4 mr-2" />
Forward Forward
@ -777,6 +818,8 @@ export default function MailPage() {
<Input <Input
type="email" type="email"
placeholder="email@example.com" placeholder="email@example.com"
value={composeRecipient}
onChange={(e) => setComposeRecipient(e.target.value)}
className="bg-white border-gray-200 py-1.5" className="bg-white border-gray-200 py-1.5"
/> />
</div> </div>
@ -825,6 +868,8 @@ export default function MailPage() {
<Input <Input
type="text" type="text"
placeholder="Subject" placeholder="Subject"
value={composeSubject}
onChange={(e) => setComposeSubject(e.target.value)}
className="bg-white border-gray-200 py-1.5" className="bg-white border-gray-200 py-1.5"
/> />
</div> </div>
@ -835,6 +880,8 @@ export default function MailPage() {
<Textarea <Textarea
className="mt-0.5 h-[calc(100%-1.5rem)] min-h-[200px] bg-white border-gray-200 resize-none" className="mt-0.5 h-[calc(100%-1.5rem)] min-h-[200px] bg-white border-gray-200 resize-none"
placeholder="Write your message here..." placeholder="Write your message here..."
value={composeContent}
onChange={(e) => setComposeContent(e.target.value)}
/> />
</div> </div>