From b859b733f641444fe3eb62499159e53c7b58f3cd Mon Sep 17 00:00:00 2001 From: alma Date: Thu, 1 May 2025 21:53:46 +0200 Subject: [PATCH] courrier preview --- hooks/use-email-state.ts | 152 ++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 66 deletions(-) diff --git a/hooks/use-email-state.ts b/hooks/use-email-state.ts index f22b07af..e9a9da72 100644 --- a/hooks/use-email-state.ts +++ b/hooks/use-email-state.ts @@ -560,6 +560,66 @@ export const useEmailState = () => { } }, [state.emails, state.currentFolder, toast, loadEmails, logEmailOp]); + // Function to check for new emails without disrupting the user + const checkForNewEmails = useCallback(async () => { + if (!session?.user?.id) return; + + // Don't check if already loading emails + if (state.isLoading) return; + + try { + // Get normalized parameters using helper function + const accountId = state.selectedAccount ? state.selectedAccount.id : undefined; + const { normalizedFolder, effectiveAccountId, prefixedFolder } = + normalizeFolderAndAccount(state.currentFolder, accountId); + + logEmailOp('CHECK_NEW_EMAILS', `Checking for new emails in ${prefixedFolder}`); + + // Quietly check for new emails with a special parameter + const queryParams = new URLSearchParams({ + folder: normalizedFolder, + page: '1', + perPage: '1', // We only need to check the newest email + accountId: effectiveAccountId, + checkOnly: 'true' // Special parameter to indicate this is just a check + }); + + const response = await fetch(`/api/courrier/emails?${queryParams.toString()}`, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + cache: 'no-cache' + }); + + if (!response.ok) { + throw new Error(`Failed to check for new emails: ${response.status}`); + } + + const data = await response.json(); + + // Store the latest email's ID for easier reference + const lastKnownEmailId = state.emails.length > 0 ? parseInt(state.emails[0].id) : 0; + + // Use newestEmailId from API response (more reliable than checking emails array) + if (data.newestEmailId && data.newestEmailId > lastKnownEmailId) { + logEmailOp('NEW_EMAILS', `Found new emails, newest ID: ${data.newestEmailId} (current: ${lastKnownEmailId})`); + + // Show a toast notification + toast({ + title: "New emails", + description: "You have new emails in your inbox", + duration: 5000 + }); + + // Force refresh the current view to show the new emails + loadEmails(1, state.perPage, false); + } else { + logEmailOp('CHECK_NEW_EMAILS', 'No new emails found'); + } + } catch (error) { + console.error('Error checking for new emails:', error); + } + }, [session?.user?.id, state.currentFolder, state.isLoading, state.emails, state.perPage, toast, loadEmails, logEmailOp]); + // Send email const sendEmail = useCallback(async (emailData: EmailData) => { dispatch({ type: 'SET_LOADING', payload: true }); @@ -586,8 +646,15 @@ export const useEmailState = () => { description: "Your message has been sent successfully" }); - // Refresh emails to show the sent email - loadEmails(state.page, state.perPage, true); + // Wait a moment for the email to be available in the sent folder + // (emails may need time to be stored on IMAP server) + setTimeout(() => { + // Check for new emails and refresh mailbox + checkForNewEmails(); + + // Refresh emails to show the sent email in current view + loadEmails(state.page, state.perPage, false); + }, 1500); return { success: true, ...result }; } catch (error) { @@ -601,7 +668,7 @@ export const useEmailState = () => { } finally { dispatch({ type: 'SET_LOADING', payload: false }); } - }, [toast, loadEmails, logEmailOp]); + }, [toast, loadEmails, logEmailOp, checkForNewEmails]); // Search emails const searchEmails = useCallback(async (query: string) => { @@ -964,68 +1031,6 @@ export const useEmailState = () => { } }, [dispatch, session?.user, state.isLoadingUnreadCounts, logEmailOp]); - // Function to check for new emails without disrupting the user - const checkForNewEmails = useCallback(async () => { - if (!session?.user?.id || !state.selectedAccount) return; - - // Don't check if already loading emails - if (state.isLoading) return; - - try { - // Get normalized parameters using helper function - const accountId = state.selectedAccount ? state.selectedAccount.id : undefined; - const { normalizedFolder, effectiveAccountId, prefixedFolder } = - normalizeFolderAndAccount(state.currentFolder, accountId); - - logEmailOp('CHECK_NEW_EMAILS', `Checking for new emails in ${prefixedFolder}`); - - // Quietly check for new emails with a special parameter - const queryParams = new URLSearchParams({ - folder: normalizedFolder, - page: '1', - perPage: '10', // Just get the top 10 to check if any are new - accountId: effectiveAccountId, - checkOnly: 'true' // Special parameter to indicate this is just a check - }); - - const response = await fetch(`/api/courrier/emails?${queryParams.toString()}`, { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, - cache: 'no-cache' - }); - - if (!response.ok) { - throw new Error(`Failed to check for new emails: ${response.status}`); - } - - const data = await response.json(); - - // If we have emails and the newest one is different from our current newest - if (data.emails && data.emails.length > 0 && state.emails.length > 0) { - const newestEmailId = data.emails[0].id; - const currentNewestEmailId = state.emails[0].id; - - if (newestEmailId !== currentNewestEmailId) { - logEmailOp('NEW_EMAILS', `Found new emails, newest ID: ${newestEmailId}`); - - // Show a toast notification - toast({ - title: "New emails", - description: "You have new emails in your inbox", - duration: 5000 - }); - - // Refresh the current view to show the new emails - loadEmails(state.page, state.perPage, false); - } else { - logEmailOp('CHECK_NEW_EMAILS', 'No new emails found'); - } - } - } catch (error) { - console.error('Error checking for new emails:', error); - } - }, [session?.user?.id, state.selectedAccount, state.currentFolder, state.isLoading, state.emails, state.page, state.perPage, toast, loadEmails, logEmailOp]); - // Calculate and update unread counts const updateUnreadCounts = useCallback(() => { // Skip if no emails or accounts @@ -1133,6 +1138,20 @@ export const useEmailState = () => { } }, [dispatch, fetchUnreadCounts]); + // Set up a function to manually trigger checking for new emails + const forceCheckForNewEmails = useCallback(() => { + // Don't check if we're already loading + if (state.isLoading) return; + + // Log that we're manually checking + logEmailOp('MANUAL_CHECK', 'Manually checking for new emails'); + + // Wait a short moment to allow potential concurrent operations to complete + setTimeout(() => { + checkForNewEmails(); + }, 500); + }, [state.isLoading, checkForNewEmails, logEmailOp]); + // Return all state values and actions return { // State values @@ -1156,6 +1175,7 @@ export const useEmailState = () => { handleLoadMore, fetchUnreadCounts, viewEmail, - checkForNewEmails + checkForNewEmails, + forceCheckForNewEmails }; }; \ No newline at end of file