courrier multi account restore compose
This commit is contained in:
parent
21accd5224
commit
d838cb9db9
@ -328,7 +328,6 @@ export const useCourrier = () => {
|
|||||||
// CRITICAL FIX: Clear and precise parameter handling with detailed logging
|
// CRITICAL FIX: Clear and precise parameter handling with detailed logging
|
||||||
let normalizedFolder: string;
|
let normalizedFolder: string;
|
||||||
let effectiveAccountId: string;
|
let effectiveAccountId: string;
|
||||||
let prefixedFolder: string;
|
|
||||||
|
|
||||||
// Parse input folder parameter
|
// Parse input folder parameter
|
||||||
if (folder.includes(':')) {
|
if (folder.includes(':')) {
|
||||||
@ -354,7 +353,7 @@ export const useCourrier = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CRITICAL FIX: Always create a consistently formatted folder name with the EFFECTIVE account prefix
|
// CRITICAL FIX: Always create a consistently formatted folder name with the EFFECTIVE account prefix
|
||||||
prefixedFolder = `${effectiveAccountId}:${normalizedFolder}`;
|
const prefixedFolder = `${effectiveAccountId}:${normalizedFolder}`;
|
||||||
|
|
||||||
console.log(`[changeFolder] Normalized parameters: folder=${normalizedFolder}, accountId=${effectiveAccountId}, prefixedFolder=${prefixedFolder}`);
|
console.log(`[changeFolder] Normalized parameters: folder=${normalizedFolder}, accountId=${effectiveAccountId}, prefixedFolder=${prefixedFolder}`);
|
||||||
|
|
||||||
@ -364,29 +363,29 @@ export const useCourrier = () => {
|
|||||||
// Reset to page 1
|
// Reset to page 1
|
||||||
setPage(1);
|
setPage(1);
|
||||||
|
|
||||||
// CRITICAL FIX: Set currentFolder state and verify it was set correctly
|
// Set currentFolder state
|
||||||
console.log(`[changeFolder] Setting currentFolder to: ${prefixedFolder}`);
|
console.log(`[changeFolder] Setting currentFolder to: ${prefixedFolder}`);
|
||||||
setCurrentFolder(prefixedFolder);
|
setCurrentFolder(prefixedFolder);
|
||||||
|
|
||||||
// CRITICAL FIX: Use a small delay to ensure state updates have propagated
|
// CRITICAL FIX: Wait for state updates to propagate
|
||||||
// This helps prevent race conditions during account switching
|
setTimeout(async () => {
|
||||||
await new Promise(resolve => setTimeout(resolve, 200));
|
try {
|
||||||
|
// CRITICAL FIX: Always pass the effective account ID explicitly to loadEmails
|
||||||
// CRITICAL FIX: Double-check the folder after state update to ensure consistency
|
// This ensures account context is maintained even if currentFolder hasn't updated yet
|
||||||
console.log(`[changeFolder] After state update, currentFolder=${currentFolder}, loading emails with explicit accountId=${effectiveAccountId}`);
|
await loadEmails(false, effectiveAccountId);
|
||||||
|
console.log(`[changeFolder] Finished changing to folder=${prefixedFolder}`);
|
||||||
// CRITICAL FIX: Always pass the effective account ID explicitly to loadEmails
|
} catch (error) {
|
||||||
// This ensures account context is maintained even if currentFolder hasn't updated yet
|
console.error(`[changeFolder] Error in delayed loadEmails:`, error);
|
||||||
await loadEmails(false, effectiveAccountId);
|
setError(error instanceof Error ? error.message : 'Error loading emails');
|
||||||
|
setIsLoading(false);
|
||||||
console.log(`[changeFolder] Finished changing to folder=${prefixedFolder}`);
|
}
|
||||||
|
}, 50);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`[changeFolder] Error changing to folder ${folder}:`, error);
|
console.error(`[changeFolder] Error changing to folder ${folder}:`, error);
|
||||||
setError(error instanceof Error ? error.message : 'Unknown error');
|
setError(error instanceof Error ? error.message : 'Unknown error');
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
}, [loadEmails, currentFolder]);
|
}, [loadEmails, setSearchQuery, setPage, setCurrentFolder, setEmails, setSelectedEmail, setSelectedEmailIds, setIsLoading, setError]);
|
||||||
|
|
||||||
// Load emails when page changes for pagination only
|
// Load emails when page changes for pagination only
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -68,41 +68,57 @@ export async function getCachedEmailsWithTimeout(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract account ID from folder name if present and none was explicitly provided
|
// CRITICAL FIX: Proper folder and account ID normalization
|
||||||
const folderAccountId = folder.includes(':') ? folder.split(':')[0] : accountId;
|
// This is critical for consistent cache keys
|
||||||
|
let effectiveAccountId: string;
|
||||||
// Use the most specific account ID available
|
let normalizedFolder: string;
|
||||||
const effectiveAccountId = folderAccountId || accountId || 'default';
|
|
||||||
|
|
||||||
// Normalize folder name by removing account prefix if present
|
// First, handle the folder format
|
||||||
// This ensures consistent cache key format regardless of how folder name is passed
|
if (folder.includes(':')) {
|
||||||
const normalizedFolder = folder.includes(':') ? folder.split(':')[1] : folder;
|
// Extract parts if folder already has a prefix
|
||||||
|
const parts = folder.split(':');
|
||||||
|
const folderAccountId = parts[0];
|
||||||
|
normalizedFolder = parts[1];
|
||||||
|
|
||||||
|
// CRITICAL FIX: If explicit accountId is provided, it ALWAYS takes precedence
|
||||||
|
// This ensures account switching works correctly
|
||||||
|
if (accountId) {
|
||||||
|
console.log(`[getCachedEmailsWithTimeout] Using provided accountId (${accountId}) over folder prefix (${folderAccountId})`);
|
||||||
|
effectiveAccountId = accountId;
|
||||||
|
} else {
|
||||||
|
effectiveAccountId = folderAccountId;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No folder prefix, use the folder name as is
|
||||||
|
normalizedFolder = folder;
|
||||||
|
effectiveAccountId = accountId || 'default';
|
||||||
|
}
|
||||||
|
|
||||||
// Log the normalization for debugging
|
// Log the normalization for debugging
|
||||||
if (folder !== normalizedFolder) {
|
console.log(`[getCachedEmailsWithTimeout] Normalized: folder=${normalizedFolder}, accountId=${effectiveAccountId} (from ${folder})`);
|
||||||
console.log(`Normalized folder name from ${folder} to ${normalizedFolder} for cache lookup with account ID ${effectiveAccountId}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
console.log(`Cache access timeout for ${userId}:${normalizedFolder}:${page}:${perPage} for account ${effectiveAccountId}`);
|
console.log(`Cache access timeout for ${userId}:${effectiveAccountId}:${normalizedFolder}:${page}:${perPage}`);
|
||||||
resolve(null);
|
resolve(null);
|
||||||
}, timeoutMs);
|
}, timeoutMs);
|
||||||
|
|
||||||
|
// CRITICAL FIX: Use the normalized parameters consistently
|
||||||
|
// This ensures we're looking up the right cache entries
|
||||||
getCachedEmailList(userId, effectiveAccountId, normalizedFolder, page, perPage)
|
getCachedEmailList(userId, effectiveAccountId, normalizedFolder, page, perPage)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
if (result) {
|
if (result) {
|
||||||
console.log(`Using cached data for ${userId}:${normalizedFolder}:${page}:${perPage} for account ${effectiveAccountId}`);
|
console.log(`[getCachedEmailsWithTimeout] Cache hit for ${userId}:${effectiveAccountId}:${normalizedFolder}:${page}:${perPage}`);
|
||||||
resolve(result);
|
resolve(result);
|
||||||
} else {
|
} else {
|
||||||
console.log(`Redis cache miss for ${userId}:${effectiveAccountId}:${normalizedFolder}:${page}:${perPage}, fetching emails from IMAP`);
|
console.log(`[getCachedEmailsWithTimeout] Cache miss for ${userId}:${effectiveAccountId}:${normalizedFolder}:${page}:${perPage}`);
|
||||||
resolve(null);
|
resolve(null);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
console.error('Error accessing cache:', err);
|
console.error('[getCachedEmailsWithTimeout] Error accessing cache:', err);
|
||||||
resolve(null);
|
resolve(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -119,16 +135,35 @@ export async function refreshEmailsInBackground(
|
|||||||
perPage: number = 20,
|
perPage: number = 20,
|
||||||
accountId?: string
|
accountId?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Extract account ID from folder name if present and none was explicitly provided
|
// CRITICAL FIX: Apply consistent account ID and folder name normalization
|
||||||
const folderAccountId = folder.includes(':') ? folder.split(':')[0] : accountId;
|
let effectiveAccountId: string;
|
||||||
|
let normalizedFolder: string;
|
||||||
|
|
||||||
// Use the most specific account ID available
|
// First, handle the folder format
|
||||||
const effectiveAccountId = folderAccountId || accountId || 'default';
|
if (folder.includes(':')) {
|
||||||
|
// Extract parts if folder already has a prefix
|
||||||
|
const parts = folder.split(':');
|
||||||
|
const folderAccountId = parts[0];
|
||||||
|
normalizedFolder = parts[1];
|
||||||
|
|
||||||
|
// CRITICAL FIX: If explicit accountId is provided, it ALWAYS takes precedence
|
||||||
|
if (accountId) {
|
||||||
|
console.log(`[refreshEmailsInBackground] Using provided accountId (${accountId}) over folder prefix (${folderAccountId})`);
|
||||||
|
effectiveAccountId = accountId;
|
||||||
|
} else {
|
||||||
|
effectiveAccountId = folderAccountId;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No folder prefix
|
||||||
|
normalizedFolder = folder;
|
||||||
|
effectiveAccountId = accountId || 'default';
|
||||||
|
}
|
||||||
|
|
||||||
// Normalize folder name by removing account prefix if present
|
console.log(`[refreshEmailsInBackground] Normalized: folder=${normalizedFolder}, accountId=${effectiveAccountId} (from ${folder})`);
|
||||||
const normalizedFolder = folder.includes(':') ? folder.split(':')[1] : folder;
|
|
||||||
|
|
||||||
const prefetchKey = `refresh:${normalizedFolder}:${page}:${effectiveAccountId}`;
|
// CRITICAL FIX: Include accountId in the prefetch key for better tracking
|
||||||
|
// This ensures we don't mix account operations during background refresh
|
||||||
|
const prefetchKey = `refresh:${effectiveAccountId}:${normalizedFolder}:${page}`;
|
||||||
|
|
||||||
// Skip if already in progress or in cooldown
|
// Skip if already in progress or in cooldown
|
||||||
if (!shouldPrefetch(userId, prefetchKey)) {
|
if (!shouldPrefetch(userId, prefetchKey)) {
|
||||||
@ -138,11 +173,14 @@ export async function refreshEmailsInBackground(
|
|||||||
// Use setTimeout to ensure this runs after current execution context
|
// Use setTimeout to ensure this runs after current execution context
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
console.log(`Background refresh for ${userId}:${normalizedFolder}:${page}:${perPage} for account ${effectiveAccountId}`);
|
console.log(`[refreshEmailsInBackground] Starting refresh for ${userId}, account=${effectiveAccountId}, folder=${normalizedFolder}, page=${page}`);
|
||||||
|
|
||||||
|
// CRITICAL FIX: Pass normalized parameters to ensure consistent API calls
|
||||||
const freshData = await getEmails(userId, normalizedFolder, page, perPage, effectiveAccountId);
|
const freshData = await getEmails(userId, normalizedFolder, page, perPage, effectiveAccountId);
|
||||||
console.log(`Background refresh completed for ${userId}:${normalizedFolder} for account ${effectiveAccountId}`);
|
|
||||||
|
console.log(`[refreshEmailsInBackground] Completed for ${userId}, account=${effectiveAccountId}, folder=${normalizedFolder}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Background refresh error:', error);
|
console.error(`[refreshEmailsInBackground] Error: ${error instanceof Error ? error.message : String(error)}`);
|
||||||
} finally {
|
} finally {
|
||||||
markPrefetchCompleted(userId, prefetchKey);
|
markPrefetchCompleted(userId, prefetchKey);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user