courrier formatting

This commit is contained in:
alma 2025-04-30 17:56:39 +02:00
parent 9d23eb3297
commit e61b0855bd

View File

@ -62,47 +62,48 @@ export const useEmailState = () => {
}, []);
// Load emails from the server
const loadEmails = useCallback(async (isLoadMore = false, accountId?: string) => {
const loadEmails = useCallback(async (page: number, perPage: number, isLoadMore: boolean = false) => {
if (!session?.user?.id) return;
// CRITICAL FIX: Always log the isLoadMore parameter
console.log(`[DEBUG-LOAD_EMAILS] Called with isLoadMore=${isLoadMore}, page=${state.page}, currentEmails=${state.emails.length}`);
console.log(`[DEBUG-LOAD_EMAILS] Called with isLoadMore=${isLoadMore}, page=${page}, currentEmails=${state.emails.length}`);
dispatch({ type: 'SET_LOADING', payload: true });
try {
// Get normalized parameters using helper function
// Get normalized parameters using helper function with proper account ID handling
const accountId = state.selectedAccount ? state.selectedAccount.id : undefined;
const { normalizedFolder, effectiveAccountId, prefixedFolder } =
normalizeFolderAndAccount(state.currentFolder, accountId);
logEmailOp('LOAD_EMAILS', `Loading emails for ${prefixedFolder} (account: ${effectiveAccountId}, isLoadMore: ${isLoadMore}, page: ${state.page})`);
logEmailOp('LOAD_EMAILS', `Loading emails for ${prefixedFolder} (account: ${effectiveAccountId}, isLoadMore: ${isLoadMore}, page: ${page})`);
// Construct query parameters
const queryParams = new URLSearchParams({
folder: normalizedFolder,
page: state.page.toString(),
perPage: state.perPage.toString(),
page: page.toString(),
perPage: perPage.toString(),
accountId: effectiveAccountId
});
// Debug log existing emails count
if (isLoadMore) {
console.log(`[DEBUG-PAGINATION] Loading more emails. Current page: ${state.page}, existing emails: ${state.emails.length}`);
console.log(`[DEBUG-PAGINATION] Loading more emails. Current page: ${page}, existing emails: ${state.emails.length}`);
}
// Try to get cached emails first
logEmailOp('CACHE_CHECK', `Checking cache for ${prefixedFolder}, page: ${state.page}`);
logEmailOp('CACHE_CHECK', `Checking cache for ${prefixedFolder}, page: ${page}`);
const cachedEmails = await getCachedEmailsWithTimeout(
session.user.id,
prefixedFolder,
state.page,
state.perPage,
page,
perPage,
100,
effectiveAccountId
);
if (cachedEmails) {
logEmailOp('CACHE_HIT', `Using cached data for ${prefixedFolder}, page: ${state.page}, emails: ${cachedEmails.emails?.length || 0}, isLoadMore: ${isLoadMore}`);
logEmailOp('CACHE_HIT', `Using cached data for ${prefixedFolder}, page: ${page}, emails: ${cachedEmails.emails?.length || 0}, isLoadMore: ${isLoadMore}`);
// Ensure cached data has emails array property
if (Array.isArray(cachedEmails.emails)) {
@ -147,14 +148,14 @@ export const useEmailState = () => {
if (!response.ok) {
// CRITICAL FIX: Try to recover from fetch errors by retrying with different pagination
if (isLoadMore && state.page > 1) {
logEmailOp('ERROR_RECOVERY', `Failed to fetch emails for page ${state.page}, attempting to recover by decrementing page`);
console.log(`[DEBUG-ERROR] API returned ${response.status} for page ${state.page}`);
if (isLoadMore && page > 1) {
logEmailOp('ERROR_RECOVERY', `Failed to fetch emails for page ${page}, attempting to recover by decrementing page`);
console.log(`[DEBUG-ERROR] API returned ${response.status} for page ${page}`);
// If we're loading more and there's an error, just decrement the page to avoid getting stuck
dispatch({ type: 'SET_PAGE', payload: state.page - 1 });
dispatch({ type: 'SET_PAGE', payload: page - 1 });
dispatch({ type: 'SET_LOADING', payload: false });
// Also reset total pages to try again
dispatch({ type: 'SET_TOTAL_PAGES', payload: state.page });
dispatch({ type: 'SET_TOTAL_PAGES', payload: page });
return;
}
@ -167,10 +168,10 @@ export const useEmailState = () => {
// CRITICAL FIX: Enhanced empty results handling
if (!data.emails || data.emails.length === 0) {
console.log(`[DEBUG-EMPTY] No emails in response for page ${state.page}`);
console.log(`[DEBUG-EMPTY] No emails in response for page ${page}`);
// If we're at a page > 1 and got no results, the paging is off, so try again with page 1
if (state.page > 1 && !isLoadMore) {
logEmailOp('EMPTY_RESULTS', `No emails returned for page ${state.page}, resetting to page 1`);
if (page > 1 && !isLoadMore) {
logEmailOp('EMPTY_RESULTS', `No emails returned for page ${page}, resetting to page 1`);
dispatch({ type: 'SET_PAGE', payload: 1 });
dispatch({ type: 'SET_LOADING', payload: false });
return;
@ -271,7 +272,7 @@ export const useEmailState = () => {
description: err instanceof Error ? err.message : 'Failed to load emails'
});
}
}, [session?.user?.id, state.currentFolder, state.page, state.perPage, state.emails.length, toast, logEmailOp]);
}, [session?.user?.id, state.currentFolder, state.selectedAccount, state.page, state.perPage, state.emails.length, toast, logEmailOp]);
// Change folder
const changeFolder = useCallback(async (folder: string, accountId?: string) => {
@ -459,7 +460,7 @@ export const useEmailState = () => {
}
// Reload emails to get updated state
loadEmails();
loadEmails(state.page, state.perPage, true);
return true;
} catch (error) {
@ -507,7 +508,7 @@ export const useEmailState = () => {
dispatch({ type: 'CLEAR_SELECTED_EMAILS' });
// Reload emails to get updated list
loadEmails();
loadEmails(state.page, state.perPage, true);
toast({
title: "Emails Deleted",
@ -555,7 +556,7 @@ export const useEmailState = () => {
});
// Refresh emails to show the sent email
loadEmails();
loadEmails(state.page, state.perPage, true);
return { success: true, ...result };
} catch (error) {
@ -644,55 +645,38 @@ export const useEmailState = () => {
// Handle loading more emails
const handleLoadMore = useCallback(() => {
logEmailOp('LOAD_MORE', `Current state - page: ${state.page}, totalPages: ${state.totalPages}, isLoading: ${state.isLoading}, current emails: ${state.emails.length}`);
// Skip if we're already at the last page
if (state.page >= state.totalPages) {
logEmailOp('LOAD_MORE', 'Already at the last page, skipping load more');
return;
}
// Skip if we're already loading
if (state.isLoading) {
logEmailOp('LOAD_MORE', 'Already loading, skipping load more request');
return;
}
// Debounce: prevent multiple triggers within 1 second
const now = Date.now();
if (now - loadMoreTriggerTimeRef.current < 1000) {
logEmailOp('LOAD_MORE', 'Debouncing load more request');
// Don't load more if already loading or if there are no more pages
if (state.isLoading || state.page >= state.totalPages) {
console.log(`[LOAD_MORE] Skipping load more - already loading: ${state.isLoading}, page: ${state.page}, totalPages: ${state.totalPages}`);
return;
}
// Update the trigger time
loadMoreTriggerTimeRef.current = now;
// Log the current state
console.log(`[LOAD_MORE] Loading more emails for ${state.currentFolder}, currentPage: ${state.page}, totalPages: ${state.totalPages}, current email count: ${state.emails.length}`);
// CRITICAL FIX: Set nextPage value and log for debugging
// Set loading state immediately to prevent double-loading
dispatch({
type: 'SET_LOADING',
payload: true
});
// Calculate next page
const nextPage = state.page + 1;
console.log(`[DEBUG-LOAD_MORE] Incrementing page from ${state.page} to ${nextPage}, current emails count: ${state.emails.length}`);
// CRITICAL FIX: First set loading state to true to prevent other effects from firing
dispatch({ type: 'SET_LOADING', payload: true });
// Update the page state - fix type issue
dispatch({
type: 'SET_PAGE',
payload: nextPage
});
// CRITICAL FIX: Get folder info for consistency
const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder);
// CRITICAL FIX: Directly call loadEmails with isLoadMore=true instead of relying on the useEffect
// This bypasses the issues with the folder change effect interfering
console.log(`[DEBUG-LOAD_MORE] Directly calling loadEmails with isLoadMore=true, page=${nextPage}`);
// We need to set the page number first, so loadEmails uses the right page
dispatch({ type: 'SET_PAGE', payload: nextPage });
// CRITICAL FIX: Update the lastPageLoaded ref to prevent duplicate loading
// CRITICAL FIX: Update the lastLoadedPage ref to track pagination state
lastPageLoadedRef.current = nextPage;
// Now load the emails with the new page number
setTimeout(() => {
loadEmails(true, effectiveAccountId);
}, 0);
}, [state.page, state.totalPages, state.isLoading, state.emails.length, state.currentFolder, logEmailOp, dispatch, loadEmails]);
// Load the next page
loadEmails(nextPage, state.perPage, true).then(() => {
console.log(`[LOAD_MORE] Completed loading more emails for page ${nextPage}`);
});
}, [state.isLoading, state.page, state.totalPages, state.currentFolder, state.emails.length, state.perPage, dispatch, loadEmails]);
// Effect to load emails when folder changes
useEffect(() => {
@ -727,18 +711,22 @@ export const useEmailState = () => {
// CRITICAL FIX: Only load initial emails if we're on page 1 or the folder changed
if (state.page === 1 || folderChanged) {
// Load emails with the correct account ID (not appending since this is a folder change)
loadEmails(false, effectiveAccountId);
loadEmails(state.page, state.perPage, false);
}
}
}, [session?.user?.id, state.currentFolder, state.page, loadEmails, logEmailOp, dispatch]);
}, [session?.user?.id, state.currentFolder, state.page, state.perPage, loadEmails, logEmailOp, dispatch]);
// Effect to load more emails when page changes
useEffect(() => {
// Skip if no user ID
if (!session?.user?.id) return;
if (!session?.user?.id || !state.currentFolder) return;
// Skip if still on page 1 or the current folder is empty
if (state.page <= 1 || !state.currentFolder) return;
// Make sure we're on at least page 1
if (state.page < 1) {
dispatch({ type: 'SET_PAGE', payload: 1 });
return;
}
console.log(`[DEBUG-PAGE_EFFECT] Page changed to ${state.page}`);
// CRITICAL FIX: Don't run this effect at all if we're already loading
if (state.isLoading) {
@ -746,36 +734,33 @@ export const useEmailState = () => {
return;
}
// CRITICAL FIX: Get current folder data
const { effectiveAccountId, prefixedFolder } = normalizeFolderAndAccount(state.currentFolder);
// Normalize folder and get account ID
const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder);
// Debug log
console.log(`[DEBUG-PAGE_EFFECT] Page changed to ${state.page}, lastLoaded=${lastPageLoadedRef.current}, folder=${prefixedFolder}, emails=${state.emails.length}`);
// Skip if this page was already loaded for this folder
if (lastPageLoadedRef.current === state.page && prevFolderRef.current === state.currentFolder) {
console.log(`[DEBUG-PAGE_EFFECT] Skipping reload of already loaded page ${state.page} for folder ${prefixedFolder}`);
// Check if this is a duplicate page load
if (state.page === lastPageLoadedRef.current) {
console.log(`[DEBUG-PAGE_EFFECT] Skipping - already loaded page ${state.page}`);
return;
}
// CRITICAL FIX: Set the ref immediately to prevent further executions
// Skip loads for zero-based pages
if (state.page === 0) {
console.log(`[DEBUG-PAGE_EFFECT] Skipping load for invalid page ${state.page}`);
return;
}
// Update our reference to prevent duplicate loads
lastPageLoadedRef.current = state.page;
// Make sure we also track the current folder
prevFolderRef.current = state.currentFolder;
logEmailOp('PAGINATION', `Loading MORE emails for page ${state.page} for folder ${prefixedFolder} (total emails so far: ${state.emails.length})`);
// CRITICAL FIX: Always use isLoadMore=true when page > 1
console.log(`[DEBUG-PAGE_EFFECT] Calling loadEmails with isLoadMore=true for page ${state.page}`);
loadEmails(true, effectiveAccountId);
loadEmails(state.page, state.perPage, true);
// Do NOT include state.emails.length here to prevent infinite loops
}, [session?.user?.id, state.page, state.currentFolder, state.isLoading, loadEmails, logEmailOp]);
}, [session?.user?.id, state.page, state.currentFolder, state.isLoading, state.perPage, loadEmails, logEmailOp]);
// Fetch unread counts from API
const fetchUnreadCounts = useCallback(async () => {
// Don't fetch if user is not logged in
if (!session?.user) return;
// Don't fetch if we're already fetching
@ -783,8 +768,14 @@ export const useEmailState = () => {
// Skip fetching if an email was viewed recently (within last 5 seconds)
const now = Date.now();
const lastViewedTimestamp = (window as any).__lastViewedEmailTimestamp || 0;
if (lastViewedTimestamp && now - lastViewedTimestamp < 5000) {
// Initialize the ref to the current time if it's null
if (lastEmailViewedRef.current === null) {
lastEmailViewedRef.current = now;
}
// Now we can safely use it since we've initialized it
if (now - lastEmailViewedRef.current < 5000) {
console.log('Skipping unread count update - email viewed recently');
return;
}