From 65b1061088d08567f316b05881e9d52b7d42e89b Mon Sep 17 00:00:00 2001 From: alma Date: Wed, 30 Apr 2025 17:02:49 +0200 Subject: [PATCH] courrier formatting --- components/email/EmailList.tsx | 12 ++++++++++- hooks/use-email-state.ts | 14 ++++++++++++ lib/reducers/emailReducer.ts | 39 ++++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/components/email/EmailList.tsx b/components/email/EmailList.tsx index 90985c2a..da97309b 100644 --- a/components/email/EmailList.tsx +++ b/components/email/EmailList.tsx @@ -54,14 +54,24 @@ export default function EmailList({ // Calculate how close to the bottom we are (in pixels) const distanceToBottom = scrollHeight - scrollTop - clientHeight; + // DEBUG: Log scroll positions + console.log(`[DEBUG] Scroll metrics - Distance to bottom: ${distanceToBottom}px, scrollHeight: ${scrollHeight}, scrollTop: ${scrollTop}, clientHeight: ${clientHeight}`); + // CRITICAL FIX: Much more aggressive threshold - load more when within 500px of bottom // Also add double-check with percentage to handle all screen sizes const scrollPercentage = (scrollTop + clientHeight) / scrollHeight; + // DEBUG: Log scroll percentage and conditions + console.log(`[DEBUG] Scroll percentage: ${Math.round(scrollPercentage * 100)}%, hasMoreEmails: ${hasMoreEmails}, isLoading: ${isLoading}`); + // Trigger loading when within 500px OR at 80% of the scroll distance if ((distanceToBottom < 500 || scrollPercentage > 0.8) && hasMoreEmails && !isLoading) { - console.log(`[EMAIL_LIST] Near bottom (${distanceToBottom}px, ${Math.round(scrollPercentage * 100)}%), loading more emails`); + console.log(`[DEBUG-TRIGGER] Loading more emails - distance: ${distanceToBottom}px, percentage: ${Math.round(scrollPercentage * 100)}%`); onLoadMore(); + } else if ((distanceToBottom < 500 || scrollPercentage > 0.8) && hasMoreEmails && isLoading) { + console.log(`[DEBUG-BLOCKED] Not loading more emails because isLoading is true`); + } else if ((distanceToBottom < 500 || scrollPercentage > 0.8) && !hasMoreEmails) { + console.log(`[DEBUG-BLOCKED] Not loading more emails because hasMoreEmails is false`); } }; diff --git a/hooks/use-email-state.ts b/hooks/use-email-state.ts index 615e3a0d..3a7fe00a 100644 --- a/hooks/use-email-state.ts +++ b/hooks/use-email-state.ts @@ -127,12 +127,14 @@ export const useEmailState = () => { // Fetch emails from API if no cache hit logEmailOp('API_FETCH', `Fetching emails from API: ${queryParams.toString()}`); + console.log(`[DEBUG-API_FETCH] Fetching from /api/courrier?${queryParams.toString()}`); const response = await fetch(`/api/courrier?${queryParams.toString()}`); 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 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_LOADING', payload: false }); @@ -146,9 +148,11 @@ export const useEmailState = () => { } const data = await response.json(); + console.log(`[DEBUG-API_RESPONSE] Got response with ${data.emails?.length || 0} emails, totalPages: ${data.totalPages}, totalEmails: ${data.totalEmails}`); // 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}`); // 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) { logEmailOp('EMPTY_RESULTS', `No emails returned for page ${state.page}, resetting to page 1`); @@ -612,24 +616,31 @@ export const useEmailState = () => { // Handle loading more emails const handleLoadMore = useCallback(() => { + // DEBUG: Log current state + console.log(`[DEBUG-LOAD_MORE] Current state - page: ${state.page}, totalPages: ${state.totalPages}, isLoading: ${state.isLoading}`); + if (state.isLoading) { logEmailOp('LOAD_MORE', `Skipping load more request - already loading`); + console.log(`[DEBUG-LOAD_MORE] Skipping because isLoading is true`); return; } if (state.page >= state.totalPages && state.totalPages > 0) { logEmailOp('LOAD_MORE', `No more emails to load: page ${state.page}/${state.totalPages}`); + console.log(`[DEBUG-LOAD_MORE] At last page - page: ${state.page}, totalPages: ${state.totalPages}`); // CRITICAL FIX: Re-fetch the last page to force checking for new emails const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder); setTimeout(() => { // Re-fetch the last page in a delay to ensure the user can see there are no more emails logEmailOp('LOAD_MORE', `Re-checking for emails at page ${state.page}`); + console.log(`[DEBUG-LOAD_MORE] Re-checking emails at page ${state.page}`); loadEmails(true, effectiveAccountId); }, 2000); return; } // Normal case - load the next page + console.log(`[DEBUG-LOAD_MORE] Incrementing page from ${state.page} to ${state.page + 1}`); logEmailOp('LOAD_MORE', `Loading more emails: page ${state.page + 1}/${state.totalPages || '?'}`); dispatch({ type: 'INCREMENT_PAGE' }); // The actual loading will be handled by the useEffect that watches page changes @@ -651,6 +662,9 @@ export const useEmailState = () => { // Effect to load more emails when page changes useEffect(() => { if (session?.user?.id && state.page > 1) { + // Debug log + console.log(`[DEBUG-PAGE_EFFECT] Page changed to ${state.page}, calling loadEmails`); + // Extract account ID for consistency const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder); diff --git a/lib/reducers/emailReducer.ts b/lib/reducers/emailReducer.ts index 2466e7dc..6224c825 100644 --- a/lib/reducers/emailReducer.ts +++ b/lib/reducers/emailReducer.ts @@ -224,17 +224,52 @@ export function emailReducer(state: EmailState, action: EmailAction): EmailState // Create a set of existing email IDs to avoid duplicates const existingIds = new Set(state.emails.map(email => email.id)); + console.log(`[DEBUG-REDUCER] APPEND_EMAILS - Got ${action.payload.length} emails to append, current list has ${state.emails.length}`); + // Filter out any duplicates before appending const newEmails = action.payload.filter(email => !existingIds.has(email.id)); // Log appending for debugging - console.log(`[EMAIL_REDUCER] Appending ${newEmails.length} new emails to existing ${state.emails.length} emails`); + console.log(`[DEBUG-REDUCER] Filtered to ${newEmails.length} new non-duplicate emails`); + + // CRITICAL FIX: If no new emails were found, set isLoading to false but don't change the email list + if (newEmails.length === 0) { + console.log('[DEBUG-REDUCER] No new emails to append, returning current state with isLoading=false'); + return { + ...state, + isLoading: false + }; + } + + // Debug the dates to check sorting + if (newEmails.length > 0) { + console.log('[DEBUG-REDUCER] Sample new emails before combining:', + newEmails.slice(0, 3).map(e => ({ + id: e.id.substring(0, 8), + subject: e.subject?.substring(0, 20), + date: e.date, + timestamp: new Date(e.date).getTime() + })) + ); + } // Combine and sort emails by date (newest first) const combinedEmails = [...state.emails, ...newEmails].sort( - (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() + (a, b) => { + const dateA = new Date(a.date).getTime(); + const dateB = new Date(b.date).getTime(); + + // Handle invalid dates + if (isNaN(dateA) && isNaN(dateB)) return 0; + if (isNaN(dateA)) return 1; // Put invalid dates at the end + if (isNaN(dateB)) return -1; + + return dateB - dateA; // Newest first + } ); + console.log(`[DEBUG-REDUCER] Final combined list has ${combinedEmails.length} emails`); + return { ...state, emails: combinedEmails,