From d73442573de6af80179b22482028f423dd6ff0ff Mon Sep 17 00:00:00 2001 From: alma Date: Sun, 27 Apr 2025 14:45:33 +0200 Subject: [PATCH] courrier redis --- app/courrier/page.tsx | 2 ++ hooks/use-courrier.ts | 55 ++++++++++++++++++++++++++++++++++--------- lib/redis.ts | 2 +- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index 23dee7f3..05f59255 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -209,7 +209,9 @@ export default function CourrierPage() { // Handle loading more emails on scroll const handleLoadMore = () => { if (hasMoreEmails && !isLoading) { + // Increment the page and call loadEmails with isLoadMore=true setPage(page + 1); + // Note: loadEmails will be called automatically due to the page dependency in useEffect } }; diff --git a/hooks/use-courrier.ts b/hooks/use-courrier.ts index 926c7d95..ba1e3276 100644 --- a/hooks/use-courrier.ts +++ b/hooks/use-courrier.ts @@ -76,13 +76,6 @@ export const useCourrier = () => { const { data: session } = useSession(); const { toast } = useToast(); - // Load emails when folder or page changes - useEffect(() => { - if (session?.user?.id) { - loadEmails(); - } - }, [currentFolder, page, perPage, session?.user?.id]); - // Load emails from the server const loadEmails = useCallback(async (isLoadMore = false) => { if (!session?.user?.id) return; @@ -96,10 +89,33 @@ export const useCourrier = () => { if (cachedEmails) { // Ensure cached data has emails array property if (Array.isArray(cachedEmails.emails)) { - setEmails(prevEmails => isLoadMore ? [...prevEmails, ...cachedEmails.emails] : cachedEmails.emails); + if (isLoadMore) { + // When loading more, always append to the existing list + setEmails(prevEmails => { + // Create a Set of existing email IDs to avoid duplicates + const existingIds = new Set(prevEmails.map(email => email.id)); + // Filter out any duplicates before appending + const newEmails = cachedEmails.emails.filter((email: Email) => !existingIds.has(email.id)); + return [...prevEmails, ...newEmails]; + }); + } else { + // For initial load, replace emails + setEmails(cachedEmails.emails); + } } else if (Array.isArray(cachedEmails)) { // Direct array response - setEmails(prevEmails => isLoadMore ? [...prevEmails, ...cachedEmails] : cachedEmails); + if (isLoadMore) { + setEmails(prevEmails => { + // Create a Set of existing email IDs to avoid duplicates + const existingIds = new Set(prevEmails.map(email => email.id)); + // Filter out any duplicates before appending + const newEmails = cachedEmails.filter((email: Email) => !existingIds.has(email.id)); + return [...prevEmails, ...newEmails]; + }); + } else { + // For initial load, replace emails + setEmails(cachedEmails); + } } else { console.warn('Invalid cache format:', cachedEmails); } @@ -136,7 +152,13 @@ export const useCourrier = () => { // Update state with the fetched data if (isLoadMore) { - setEmails(prev => [...prev, ...data.emails]); + setEmails(prev => { + // Create a Set of existing email IDs to avoid duplicates + const existingIds = new Set(prev.map(email => email.id)); + // Filter out any duplicates before appending + const newEmails = data.emails.filter((email: Email) => !existingIds.has(email.id)); + return [...prev, ...newEmails]; + }); } else { // Ensure we always set an array even if API returns invalid data setEmails(Array.isArray(data.emails) ? data.emails : []); @@ -158,7 +180,9 @@ export const useCourrier = () => { } catch (err) { console.error('Error loading emails:', err); // Set emails to empty array on error to prevent runtime issues - setEmails([]); + if (!isLoadMore) { + setEmails([]); + } setError(err instanceof Error ? err.message : 'Failed to load emails'); toast({ variant: "destructive", @@ -170,6 +194,15 @@ export const useCourrier = () => { } }, [currentFolder, page, perPage, searchQuery, session?.user?.id, toast]); + // Load emails when folder or page changes + useEffect(() => { + if (session?.user?.id) { + // If page is greater than 1, we're loading more emails + const isLoadingMore = page > 1; + loadEmails(isLoadingMore); + } + }, [currentFolder, page, perPage, session?.user?.id, loadEmails]); + // Fetch a single email's content const fetchEmailContent = useCallback(async (emailId: string) => { try { diff --git a/lib/redis.ts b/lib/redis.ts index c17c469d..166c82d4 100644 --- a/lib/redis.ts +++ b/lib/redis.ts @@ -84,7 +84,7 @@ export const KEYS = { // TTL constants in seconds export const TTL = { CREDENTIALS: 60 * 60 * 24, // 24 hours - SESSION: 60 * 30, // 30 minutes + SESSION: 60 * 60 * 4, // 4 hours (increased from 30 minutes) EMAIL_LIST: 60 * 5, // 5 minutes EMAIL_CONTENT: 60 * 15 // 15 minutes };