courrier redis
This commit is contained in:
parent
d73442573d
commit
1db445e6c9
@ -209,8 +209,18 @@ export default function CourrierPage() {
|
|||||||
// Handle loading more emails on scroll
|
// Handle loading more emails on scroll
|
||||||
const handleLoadMore = () => {
|
const handleLoadMore = () => {
|
||||||
if (hasMoreEmails && !isLoading) {
|
if (hasMoreEmails && !isLoading) {
|
||||||
// Increment the page and call loadEmails with isLoadMore=true
|
// Increment the page
|
||||||
setPage(page + 1);
|
const nextPage = page + 1;
|
||||||
|
setPage(nextPage);
|
||||||
|
|
||||||
|
// Also prefetch additional pages to make scrolling smoother
|
||||||
|
if (session?.user?.id) {
|
||||||
|
// Prefetch next 2 pages beyond the current next page
|
||||||
|
prefetchFolderEmails(session.user.id, currentFolder, 2, nextPage + 1).catch(err => {
|
||||||
|
console.error(`Error prefetching additional pages for ${currentFolder}:`, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Note: loadEmails will be called automatically due to the page dependency in useEffect
|
// Note: loadEmails will be called automatically due to the page dependency in useEffect
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -275,6 +285,7 @@ export default function CourrierPage() {
|
|||||||
|
|
||||||
// Start prefetching additional pages for this folder
|
// Start prefetching additional pages for this folder
|
||||||
if (session?.user?.id && folder) {
|
if (session?.user?.id && folder) {
|
||||||
|
// First two pages are most important - prefetch immediately
|
||||||
prefetchFolderEmails(session.user.id, folder, 3).catch(err => {
|
prefetchFolderEmails(session.user.id, folder, 3).catch(err => {
|
||||||
console.error(`Error prefetching ${folder}:`, err);
|
console.error(`Error prefetching ${folder}:`, err);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -49,10 +49,16 @@ export default function EmailList({
|
|||||||
const target = event.target as HTMLDivElement;
|
const target = event.target as HTMLDivElement;
|
||||||
const { scrollTop, scrollHeight, clientHeight } = target;
|
const { scrollTop, scrollHeight, clientHeight } = target;
|
||||||
|
|
||||||
|
// Save scroll position for restoration when needed
|
||||||
setScrollPosition(scrollTop);
|
setScrollPosition(scrollTop);
|
||||||
|
|
||||||
// If user scrolls near the bottom and we have more emails, load more
|
// If user scrolls near the bottom and we have more emails, load more
|
||||||
if (scrollHeight - scrollTop - clientHeight < 200 && hasMoreEmails && !isLoading) {
|
if (scrollHeight - scrollTop - clientHeight < 200 && hasMoreEmails && !isLoading) {
|
||||||
|
// Store current scroll data before loading more
|
||||||
|
const currentScrollTop = scrollTop;
|
||||||
|
const currentScrollHeight = scrollHeight;
|
||||||
|
|
||||||
|
// Request more emails
|
||||||
onLoadMore();
|
onLoadMore();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -83,9 +83,12 @@ export const useCourrier = () => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
|
// Keep reference to the current page for this request
|
||||||
|
const currentRequestPage = page;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// First try Redis cache with low timeout
|
// First try Redis cache with low timeout
|
||||||
const cachedEmails = await getCachedEmailsWithTimeout(session.user.id, currentFolder, page, perPage, 100);
|
const cachedEmails = await getCachedEmailsWithTimeout(session.user.id, currentFolder, currentRequestPage, perPage, 100);
|
||||||
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)) {
|
||||||
@ -96,12 +99,26 @@ export const useCourrier = () => {
|
|||||||
const existingIds = new Set(prevEmails.map(email => email.id));
|
const existingIds = new Set(prevEmails.map(email => email.id));
|
||||||
// Filter out any duplicates before appending
|
// Filter out any duplicates before appending
|
||||||
const newEmails = cachedEmails.emails.filter((email: Email) => !existingIds.has(email.id));
|
const newEmails = cachedEmails.emails.filter((email: Email) => !existingIds.has(email.id));
|
||||||
|
|
||||||
|
// Log pagination info
|
||||||
|
console.log(`Added ${newEmails.length} cached emails from page ${currentRequestPage} to existing ${prevEmails.length} emails`);
|
||||||
|
|
||||||
return [...prevEmails, ...newEmails];
|
return [...prevEmails, ...newEmails];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// For initial load, replace emails
|
// For initial load, replace emails
|
||||||
|
console.log(`Setting ${cachedEmails.emails.length} cached emails for page ${currentRequestPage}`);
|
||||||
setEmails(cachedEmails.emails);
|
setEmails(cachedEmails.emails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set pagination info from cache if available
|
||||||
|
if (cachedEmails.totalEmails) setTotalEmails(cachedEmails.totalEmails);
|
||||||
|
if (cachedEmails.totalPages) setTotalPages(cachedEmails.totalPages);
|
||||||
|
|
||||||
|
// Update available mailboxes if provided
|
||||||
|
if (cachedEmails.mailboxes && cachedEmails.mailboxes.length > 0) {
|
||||||
|
setMailboxes(cachedEmails.mailboxes);
|
||||||
|
}
|
||||||
} else if (Array.isArray(cachedEmails)) {
|
} else if (Array.isArray(cachedEmails)) {
|
||||||
// Direct array response
|
// Direct array response
|
||||||
if (isLoadMore) {
|
if (isLoadMore) {
|
||||||
@ -110,10 +127,15 @@ export const useCourrier = () => {
|
|||||||
const existingIds = new Set(prevEmails.map(email => email.id));
|
const existingIds = new Set(prevEmails.map(email => email.id));
|
||||||
// Filter out any duplicates before appending
|
// Filter out any duplicates before appending
|
||||||
const newEmails = cachedEmails.filter((email: Email) => !existingIds.has(email.id));
|
const newEmails = cachedEmails.filter((email: Email) => !existingIds.has(email.id));
|
||||||
|
|
||||||
|
// Log pagination info
|
||||||
|
console.log(`Added ${newEmails.length} cached emails from page ${currentRequestPage} to existing ${prevEmails.length} emails`);
|
||||||
|
|
||||||
return [...prevEmails, ...newEmails];
|
return [...prevEmails, ...newEmails];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// For initial load, replace emails
|
// For initial load, replace emails
|
||||||
|
console.log(`Setting ${cachedEmails.length} cached emails for page ${currentRequestPage}`);
|
||||||
setEmails(cachedEmails);
|
setEmails(cachedEmails);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -123,7 +145,7 @@ export const useCourrier = () => {
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
// Still refresh in background for fresh data
|
// Still refresh in background for fresh data
|
||||||
refreshEmailsInBackground(session.user.id, currentFolder, page, perPage).catch(err => {
|
refreshEmailsInBackground(session.user.id, currentFolder, currentRequestPage, perPage).catch(err => {
|
||||||
console.error('Background refresh error:', err);
|
console.error('Background refresh error:', err);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -132,7 +154,7 @@ export const useCourrier = () => {
|
|||||||
// Build query params
|
// Build query params
|
||||||
const queryParams = new URLSearchParams({
|
const queryParams = new URLSearchParams({
|
||||||
folder: currentFolder,
|
folder: currentFolder,
|
||||||
page: page.toString(),
|
page: currentRequestPage.toString(),
|
||||||
perPage: perPage.toString()
|
perPage: perPage.toString()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -157,10 +179,15 @@ export const useCourrier = () => {
|
|||||||
const existingIds = new Set(prev.map(email => email.id));
|
const existingIds = new Set(prev.map(email => email.id));
|
||||||
// Filter out any duplicates before appending
|
// Filter out any duplicates before appending
|
||||||
const newEmails = data.emails.filter((email: Email) => !existingIds.has(email.id));
|
const newEmails = data.emails.filter((email: Email) => !existingIds.has(email.id));
|
||||||
|
|
||||||
|
// Log pagination info
|
||||||
|
console.log(`Added ${newEmails.length} fetched emails from page ${currentRequestPage} to existing ${prev.length} emails`);
|
||||||
|
|
||||||
return [...prev, ...newEmails];
|
return [...prev, ...newEmails];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Ensure we always set an array even if API returns invalid data
|
// Ensure we always set an array even if API returns invalid data
|
||||||
|
console.log(`Setting ${data.emails?.length || 0} fetched emails for page ${currentRequestPage}`);
|
||||||
setEmails(Array.isArray(data.emails) ? data.emails : []);
|
setEmails(Array.isArray(data.emails) ? data.emails : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +205,7 @@ export const useCourrier = () => {
|
|||||||
setSelectedEmailIds([]);
|
setSelectedEmailIds([]);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading emails:', err);
|
console.error(`Error loading emails for page ${currentRequestPage}:`, err);
|
||||||
// Set emails to empty array on error to prevent runtime issues
|
// Set emails to empty array on error to prevent runtime issues
|
||||||
if (!isLoadMore) {
|
if (!isLoadMore) {
|
||||||
setEmails([]);
|
setEmails([]);
|
||||||
|
|||||||
@ -458,8 +458,9 @@ export async function getEmails(
|
|||||||
mailboxes
|
mailboxes
|
||||||
};
|
};
|
||||||
|
|
||||||
// Cache the result if it's not a search query
|
// Always cache the result if it's not a search query, even for pagination
|
||||||
if (!searchQuery) {
|
if (!searchQuery) {
|
||||||
|
console.log(`Caching email list for ${userId}:${folder}:${page}:${perPage}`);
|
||||||
await cacheEmailList(userId, folder, page, perPage, result);
|
await cacheEmailList(userId, folder, page, perPage, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -169,16 +169,32 @@ export async function prefetchUserEmailData(userId: string): Promise<void> {
|
|||||||
export async function prefetchFolderEmails(
|
export async function prefetchFolderEmails(
|
||||||
userId: string,
|
userId: string,
|
||||||
folder: string,
|
folder: string,
|
||||||
pages: number = 3
|
pages: number = 3,
|
||||||
|
startPage: number = 1
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
console.log(`Prefetching ${pages} pages of emails for folder ${folder}`);
|
console.log(`Prefetching ${pages} pages of emails for folder ${folder} starting from page ${startPage}`);
|
||||||
|
|
||||||
|
// Calculate the range of pages to prefetch
|
||||||
|
const pagesToFetch = Array.from(
|
||||||
|
{ length: pages },
|
||||||
|
(_, i) => startPage + i
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`Will prefetch pages: ${pagesToFetch.join(', ')}`);
|
||||||
|
|
||||||
// Fetch multiple pages in parallel
|
// Fetch multiple pages in parallel
|
||||||
await Promise.allSettled(
|
await Promise.allSettled(
|
||||||
Array.from({ length: pages }, (_, i) => i + 1).map(page =>
|
pagesToFetch.map(page =>
|
||||||
getEmails(userId, folder, page, 20)
|
getEmails(userId, folder, page, 20)
|
||||||
.catch(err => console.error(`Error prefetching page ${page} of ${folder}:`, err))
|
.then(result => {
|
||||||
|
console.log(`Successfully prefetched and cached page ${page} of ${folder} with ${result.emails.length} emails`);
|
||||||
|
return result;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(`Error prefetching page ${page} of ${folder}:`, err);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user