mail page connected with folders 6

This commit is contained in:
alma 2025-04-16 17:00:07 +02:00
parent 7cf49d8cf3
commit fd2a4f1483
2 changed files with 91 additions and 112 deletions

View File

@ -91,7 +91,7 @@ function getStoredCredentials(): StoredCredentials | null {
} }
} }
export async function GET() { export async function GET(request: Request) {
try { try {
const credentials = getStoredCredentials(); const credentials = getStoredCredentials();
if (!credentials) { if (!credentials) {
@ -101,8 +101,10 @@ export async function GET() {
); );
} }
const availableMailboxes: string[] = []; // Get the current folder from the URL
const emailsByFolder: { [key: string]: any[] } = {}; const url = new URL(request.url);
const folder = url.searchParams.get('folder') || 'INBOX';
const limit = 50; // Limit number of emails per folder
return new Promise((resolve) => { return new Promise((resolve) => {
const imap = new Imap({ const imap = new Imap({
@ -116,7 +118,6 @@ export async function GET() {
connTimeout: 30000 connTimeout: 30000
}); });
// Add a timeout to prevent hanging
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
console.error('IMAP connection timeout'); console.error('IMAP connection timeout');
imap.end(); imap.end();
@ -124,7 +125,7 @@ export async function GET() {
emails: [], emails: [],
error: 'Connection timeout' error: 'Connection timeout'
})); }));
}, 60000); }, 30000);
imap.once('error', (err: Error) => { imap.once('error', (err: Error) => {
console.error('IMAP error:', err); console.error('IMAP error:', err);
@ -145,71 +146,45 @@ export async function GET() {
return; return;
} }
// Process mailboxes const availableMailboxes = Object.keys(boxes);
Object.keys(boxes).forEach((box) => {
availableMailboxes.push(box);
});
console.log('Available mailboxes:', availableMailboxes); console.log('Available mailboxes:', availableMailboxes);
// Process each mailbox // Only process the requested folder
const foldersToProcess = availableMailboxes; imap.openBox(folder, false, (err, box) => {
let processedFolders = 0;
let activeFetches = 0;
function checkCompletion() {
processedFolders++;
if (processedFolders === foldersToProcess.length && activeFetches === 0) {
clearTimeout(timeout);
finishProcessing();
}
}
function finishProcessing() {
// Combine all emails from all folders
const allEmails = Object.entries(emailsByFolder).flatMap(([folder, emails]) => emails);
console.log('Emails by folder:', Object.fromEntries(
Object.entries(emailsByFolder).map(([folder, emails]) => [folder, emails.length])
));
console.log('All folders processed, total emails:', allEmails.length);
const response = {
emails: allEmails,
folders: availableMailboxes,
mailUrl: process.env.NEXTCLOUD_URL ? `${process.env.NEXTCLOUD_URL}/apps/mail/` : null
};
imap.end();
resolve(NextResponse.json(response));
}
foldersToProcess.forEach((folderName) => {
// Initialize array for this folder
emailsByFolder[folderName] = [];
imap.openBox(folderName, false, (err, box) => {
if (err) { if (err) {
console.error(`Error opening box ${folderName}:`, err); console.error(`Error opening box ${folder}:`, err);
checkCompletion(); clearTimeout(timeout);
imap.end();
resolve(NextResponse.json({ emails: [], error: `Failed to open folder ${folder}` }));
return; return;
} }
// Search for all emails in this folder // Search for emails in this folder, limited to the most recent ones
imap.search(['ALL'], (err, results) => { imap.search(['ALL'], (err, results) => {
if (err) { if (err) {
console.error(`Error searching in ${folderName}:`, err); console.error(`Error searching in ${folder}:`, err);
checkCompletion(); clearTimeout(timeout);
imap.end();
resolve(NextResponse.json({ emails: [], error: `Failed to search in ${folder}` }));
return; return;
} }
if (!results || results.length === 0) { if (!results || results.length === 0) {
checkCompletion(); clearTimeout(timeout);
imap.end();
resolve(NextResponse.json({
emails: [],
folders: availableMailboxes,
mailUrl: process.env.NEXTCLOUD_URL ? `${process.env.NEXTCLOUD_URL}/apps/mail/` : null
}));
return; return;
} }
activeFetches++; // Take only the most recent emails up to the limit
// Fetch emails const recentResults = results.slice(-limit);
const fetch = imap.fetch(results, { const emails: any[] = [];
const fetch = imap.fetch(recentResults, {
bodies: ['HEADER', 'TEXT'], bodies: ['HEADER', 'TEXT'],
struct: true struct: true
}); });
@ -220,7 +195,6 @@ export async function GET() {
let messageId: number | null = null; let messageId: number | null = null;
let messageFlags: string[] = []; let messageFlags: string[] = [];
// Handle attributes first
msg.once('attributes', (attrs) => { msg.once('attributes', (attrs) => {
messageId = attrs.uid; messageId = attrs.uid;
messageFlags = attrs.flags || []; messageFlags = attrs.flags || [];
@ -254,23 +228,28 @@ export async function GET() {
subject: parsedHeader.subject?.[0] || '(No subject)', subject: parsedHeader.subject?.[0] || '(No subject)',
date: parsedHeader.date?.[0] || new Date().toISOString(), date: parsedHeader.date?.[0] || new Date().toISOString(),
body: text, body: text,
folder: folderName, folder: folder,
flags: messageFlags flags: messageFlags
}; };
emailsByFolder[folderName].push(email); emails.push(email);
}); });
}); });
fetch.on('error', (err) => { fetch.on('error', (err) => {
console.error(`Error fetching emails from ${folderName}:`, err); console.error(`Error fetching emails from ${folder}:`, err);
activeFetches--; clearTimeout(timeout);
checkCompletion(); imap.end();
resolve(NextResponse.json({ emails: [], error: `Failed to fetch emails from ${folder}` }));
}); });
fetch.on('end', () => { fetch.on('end', () => {
activeFetches--; clearTimeout(timeout);
checkCompletion(); imap.end();
}); resolve(NextResponse.json({
emails: emails,
folders: availableMailboxes,
mailUrl: process.env.NEXTCLOUD_URL ? `${process.env.NEXTCLOUD_URL}/apps/mail/` : null
}));
}); });
}); });
}); });

View File

@ -540,7 +540,7 @@ export default function MailPage() {
setLoading(true); setLoading(true);
setError(null); setError(null);
const response = await fetch('/api/mail'); const response = await fetch(`/api/mail?folder=${currentView}`);
if (!response.ok) { if (!response.ok) {
throw new Error('Failed to load emails'); throw new Error('Failed to load emails');
} }