courrier multi account restore compose

This commit is contained in:
alma 2025-04-28 13:23:33 +02:00
parent ab6e34c4fa
commit 0f9d84c6a9
4 changed files with 44 additions and 55 deletions

View File

@ -40,13 +40,7 @@ export async function GET(request: Request) {
// Try to get from Redis cache first, but only if it's not a search query // Try to get from Redis cache first, but only if it's not a search query
if (!searchQuery) { if (!searchQuery) {
const cacheKey = accountId ? `${session.user.id}:${accountId}:${folder}` : `${session.user.id}:${folder}`; const cacheKey = accountId ? `${session.user.id}:${accountId}:${folder}` : `${session.user.id}:${folder}`;
const cachedEmails = await getCachedEmailList( const cachedEmails = await getCachedEmailList(session.user.id, folder, page, perPage);
session.user.id,
accountId || 'default',
folder,
page,
perPage
);
if (cachedEmails) { if (cachedEmails) {
console.log(`Using Redis cached emails for ${cacheKey}:${page}:${perPage}`); console.log(`Using Redis cached emails for ${cacheKey}:${page}:${perPage}`);
return NextResponse.json(cachedEmails); return NextResponse.json(cachedEmails);
@ -91,12 +85,12 @@ export async function POST(request: Request) {
// Invalidate Redis cache for the folder // Invalidate Redis cache for the folder
if (folderName) { if (folderName) {
await invalidateFolderCache(session.user.id, 'default', folderName); await invalidateFolderCache(session.user.id, folderName);
} else { } else {
// If no folder specified, invalidate all folders (using a wildcard pattern) // If no folder specified, invalidate all folders (using a wildcard pattern)
const folders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk']; const folders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk'];
for (const folder of folders) { for (const folder of folders) {
await invalidateFolderCache(session.user.id, 'default', folder); await invalidateFolderCache(session.user.id, folder);
} }
} }

View File

@ -312,7 +312,7 @@ export default function CourrierPage() {
folders: accountFolders folders: accountFolders
}; };
console.log(`[DEBUG] Updated loading account to real account: ${account.email} with ID ${account.id}`); console.log(`[DEBUG] Updated loading account to real account: ${account.email} with ID ${account.id}`);
} else if (index > 0) { } else {
// Add additional accounts as new entries // Add additional accounts as new entries
updatedAccounts.push({ updatedAccounts.push({
id: account.id || `account-${index}`, id: account.id || `account-${index}`,
@ -321,31 +321,28 @@ export default function CourrierPage() {
color: account.color || 'bg-blue-500', color: account.color || 'bg-blue-500',
folders: accountFolders folders: accountFolders
}); });
console.log(`[DEBUG] Added additional account: ${account.email} with ID ${account.id}`);
} }
}); });
} else { } else {
// Fallback if accounts array is empty for some reason // Fallback if accounts array is empty for some reason
updatedAccounts.push({ id: 'all-accounts', name: 'All', email: '', color: 'bg-gray-500' }); updatedAccounts.push({ id: 'all-accounts', name: 'All', email: '', color: 'bg-gray-500' });
// Add all accounts from the API response const firstAccount = data.allAccounts[0];
data.allAccounts.forEach((account: any) => { const accountFolders = (firstAccount.folders && Array.isArray(firstAccount.folders))
const accountFolders = (account.folders && Array.isArray(account.folders)) ? firstAccount.folders
? account.folders : (data.mailboxes && Array.isArray(data.mailboxes))
: (data.mailboxes && Array.isArray(data.mailboxes)) ? data.mailboxes
? data.mailboxes : ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk'];
: ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk'];
updatedAccounts.push({
updatedAccounts.push({ id: firstAccount.id,
id: account.id, name: firstAccount.display_name || firstAccount.email,
name: account.display_name || account.email, email: firstAccount.email,
email: account.email, color: firstAccount.color || 'bg-blue-500',
color: account.color || 'bg-blue-500', folders: accountFolders
folders: accountFolders
});
}); });
} }
} else { } else if (data.email) {
// Fallback to single account if allAccounts is not available // Fallback to single account if allAccounts is not available
console.log(`[DEBUG] Fallback to single account: ${data.email}`); console.log(`[DEBUG] Fallback to single account: ${data.email}`);

View File

@ -80,12 +80,6 @@ export const useCourrier = () => {
const loadEmails = useCallback(async (isLoadMore = false, accountId?: string) => { const loadEmails = useCallback(async (isLoadMore = false, accountId?: string) => {
if (!session?.user?.id) return; if (!session?.user?.id) return;
// Skip loading if accountId is 'loading-account'
if (accountId === 'loading-account') {
console.log('Skipping email load for loading account');
return;
}
setIsLoading(true); setIsLoading(true);
setError(null); setError(null);
@ -104,20 +98,13 @@ export const useCourrier = () => {
queryParams.set('search', searchQuery); queryParams.set('search', searchQuery);
} }
// Add accountId if provided and not 'loading-account' // Add accountId if provided
if (accountId && accountId !== 'all-accounts' && accountId !== 'loading-account') { if (accountId) {
queryParams.set('accountId', accountId); queryParams.set('accountId', accountId);
} }
// First try Redis cache with low timeout // First try Redis cache with low timeout
const cachedEmails = await getCachedEmailsWithTimeout( const cachedEmails = await getCachedEmailsWithTimeout(session.user.id, currentFolder, currentRequestPage, perPage, 100);
session.user.id,
currentFolder,
currentRequestPage,
perPage,
100,
accountId && accountId !== 'all-accounts' && accountId !== 'loading-account' ? accountId : undefined
);
if (cachedEmails) { if (cachedEmails) {
// Ensure cached data has emails array property // Ensure cached data has emails array property
if (Array.isArray(cachedEmails.emails)) { if (Array.isArray(cachedEmails.emails)) {

View File

@ -59,27 +59,38 @@ export async function getCachedEmailsWithTimeout(
folder: string, folder: string,
page: number, page: number,
perPage: number, perPage: number,
timeoutMs: number = 100, timeoutMs: number = 100
accountId?: string
): Promise<any | null> { ): Promise<any | null> {
// Skip cache if accountId is 'loading-account'
if (accountId === 'loading-account') {
console.log(`Skipping cache for loading account`);
return null;
}
return new Promise((resolve) => { return new Promise((resolve) => {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
console.log(`Cache access timeout for ${userId}:${folder}:${page}:${perPage}${accountId ? ` for account ${accountId}` : ''}`); console.log(`Cache access timeout for ${userId}:${folder}:${page}:${perPage}`);
resolve(null); resolve(null);
}, timeoutMs); }, timeoutMs);
getCachedEmailList(userId, accountId || 'default', folder, page, perPage) getCachedEmailList(userId, folder, page, perPage)
.then(result => { .then(result => {
clearTimeout(timeoutId); clearTimeout(timeoutId);
if (result) { if (result) {
console.log(`Using cached data for ${userId}:${folder}:${page}:${perPage}${accountId ? ` for account ${accountId}` : ''}`); console.log(`Using cached data for ${userId}:${folder}:${page}:${perPage}`);
resolve(result);
// Validate and normalize the data structure
if (typeof result === 'object') {
// Make sure we have an emails array
if (!result.emails && Array.isArray(result)) {
// If result is an array, convert to proper structure
resolve({ emails: result });
} else if (!result.emails) {
// If no emails property, add empty array
resolve({ ...result, emails: [] });
} else {
// Normal case, return as is
resolve(result);
}
} else {
// Invalid data, return null
console.warn('Invalid cached data format:', result);
resolve(null);
}
} else { } else {
resolve(null); resolve(null);
} }