courrier formatting
This commit is contained in:
parent
f9db3efd39
commit
65b1061088
@ -54,14 +54,24 @@ export default function EmailList({
|
|||||||
// Calculate how close to the bottom we are (in pixels)
|
// Calculate how close to the bottom we are (in pixels)
|
||||||
const distanceToBottom = scrollHeight - scrollTop - clientHeight;
|
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
|
// CRITICAL FIX: Much more aggressive threshold - load more when within 500px of bottom
|
||||||
// Also add double-check with percentage to handle all screen sizes
|
// Also add double-check with percentage to handle all screen sizes
|
||||||
const scrollPercentage = (scrollTop + clientHeight) / scrollHeight;
|
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
|
// Trigger loading when within 500px OR at 80% of the scroll distance
|
||||||
if ((distanceToBottom < 500 || scrollPercentage > 0.8) && hasMoreEmails && !isLoading) {
|
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();
|
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`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -127,12 +127,14 @@ export const useEmailState = () => {
|
|||||||
|
|
||||||
// Fetch emails from API if no cache hit
|
// Fetch emails from API if no cache hit
|
||||||
logEmailOp('API_FETCH', `Fetching emails from API: ${queryParams.toString()}`);
|
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()}`);
|
const response = await fetch(`/api/courrier?${queryParams.toString()}`);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
// CRITICAL FIX: Try to recover from fetch errors by retrying with different pagination
|
// CRITICAL FIX: Try to recover from fetch errors by retrying with different pagination
|
||||||
if (isLoadMore && state.page > 1) {
|
if (isLoadMore && state.page > 1) {
|
||||||
logEmailOp('ERROR_RECOVERY', `Failed to fetch emails for page ${state.page}, attempting to recover by decrementing page`);
|
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
|
// 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: state.page - 1 });
|
||||||
dispatch({ type: 'SET_LOADING', payload: false });
|
dispatch({ type: 'SET_LOADING', payload: false });
|
||||||
@ -146,9 +148,11 @@ export const useEmailState = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
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
|
// CRITICAL FIX: Enhanced empty results handling
|
||||||
if (!data.emails || data.emails.length === 0) {
|
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 we're at a page > 1 and got no results, the paging is off, so try again with page 1
|
||||||
if (state.page > 1) {
|
if (state.page > 1) {
|
||||||
logEmailOp('EMPTY_RESULTS', `No emails returned for page ${state.page}, resetting to 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
|
// Handle loading more emails
|
||||||
const handleLoadMore = useCallback(() => {
|
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) {
|
if (state.isLoading) {
|
||||||
logEmailOp('LOAD_MORE', `Skipping load more request - already loading`);
|
logEmailOp('LOAD_MORE', `Skipping load more request - already loading`);
|
||||||
|
console.log(`[DEBUG-LOAD_MORE] Skipping because isLoading is true`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.page >= state.totalPages && state.totalPages > 0) {
|
if (state.page >= state.totalPages && state.totalPages > 0) {
|
||||||
logEmailOp('LOAD_MORE', `No more emails to load: page ${state.page}/${state.totalPages}`);
|
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
|
// CRITICAL FIX: Re-fetch the last page to force checking for new emails
|
||||||
const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder);
|
const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Re-fetch the last page in a delay to ensure the user can see there are no more emails
|
// 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}`);
|
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);
|
loadEmails(true, effectiveAccountId);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal case - load the next page
|
// 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 || '?'}`);
|
logEmailOp('LOAD_MORE', `Loading more emails: page ${state.page + 1}/${state.totalPages || '?'}`);
|
||||||
dispatch({ type: 'INCREMENT_PAGE' });
|
dispatch({ type: 'INCREMENT_PAGE' });
|
||||||
// The actual loading will be handled by the useEffect that watches page changes
|
// 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
|
// Effect to load more emails when page changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (session?.user?.id && state.page > 1) {
|
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
|
// Extract account ID for consistency
|
||||||
const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder);
|
const { effectiveAccountId } = normalizeFolderAndAccount(state.currentFolder);
|
||||||
|
|
||||||
|
|||||||
@ -224,17 +224,52 @@ export function emailReducer(state: EmailState, action: EmailAction): EmailState
|
|||||||
// Create a set of existing email IDs to avoid duplicates
|
// Create a set of existing email IDs to avoid duplicates
|
||||||
const existingIds = new Set(state.emails.map(email => email.id));
|
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
|
// Filter out any duplicates before appending
|
||||||
const newEmails = action.payload.filter(email => !existingIds.has(email.id));
|
const newEmails = action.payload.filter(email => !existingIds.has(email.id));
|
||||||
|
|
||||||
// Log appending for debugging
|
// 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)
|
// Combine and sort emails by date (newest first)
|
||||||
const combinedEmails = [...state.emails, ...newEmails].sort(
|
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 {
|
return {
|
||||||
...state,
|
...state,
|
||||||
emails: combinedEmails,
|
emails: combinedEmails,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user