From cf2fe4b45b046bd7167d58fbbf82229efb3ff56f Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 26 Jan 2026 11:43:09 -0500 Subject: [PATCH 1/2] fix: add fetch lock Signed-off-by: Adam Setch --- src/renderer/hooks/useNotifications.ts | 68 ++++++++++++++------------ 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/renderer/hooks/useNotifications.ts b/src/renderer/hooks/useNotifications.ts index eaae98ddc..e72b601d7 100644 --- a/src/renderer/hooks/useNotifications.ts +++ b/src/renderer/hooks/useNotifications.ts @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useMemo, useRef, useState } from 'react'; import type { Account, @@ -94,44 +94,52 @@ export const useNotifications = (): NotificationsState => { [notifications], ); + const isFetchingRef = useRef(false); const fetchNotifications = useCallback( async (state: GitifyState) => { - setStatus('loading'); - setGlobalError(null); - - const previousNotifications = notifications; - const fetchedNotifications = await getAllNotifications(state); - setNotifications(fetchedNotifications); - - // Set Global Error if all accounts have the same error - const allAccountsHaveErrors = - doesAllAccountsHaveErrors(fetchedNotifications); - const allAccountErrorsAreSame = - areAllAccountErrorsSame(fetchedNotifications); - - if (allAccountsHaveErrors) { - const accountError = fetchedNotifications[0].error; - setStatus('error'); - setGlobalError(allAccountErrorsAreSame ? accountError : null); + if (isFetchingRef.current) { + // Prevent overlapping fetches return; } + isFetchingRef.current = true; + setStatus('loading'); + setGlobalError(null); + try { + const previousNotifications = notifications; + const fetchedNotifications = await getAllNotifications(state); + setNotifications(fetchedNotifications); + + // Set Global Error if all accounts have the same error + const allAccountsHaveErrors = + doesAllAccountsHaveErrors(fetchedNotifications); + const allAccountErrorsAreSame = + areAllAccountErrorsSame(fetchedNotifications); + + if (allAccountsHaveErrors) { + const accountError = fetchedNotifications[0].error; + setStatus('error'); + setGlobalError(allAccountErrorsAreSame ? accountError : null); + return; + } - const diffNotifications = getNewNotifications( - previousNotifications, - fetchedNotifications, - ); + const diffNotifications = getNewNotifications( + previousNotifications, + fetchedNotifications, + ); - if (diffNotifications.length > 0) { - if (state.settings.playSound) { - raiseSoundNotification(state.settings.notificationVolume); - } + if (diffNotifications.length > 0) { + if (state.settings.playSound) { + raiseSoundNotification(state.settings.notificationVolume); + } - if (state.settings.showNotifications) { - raiseNativeNotification(diffNotifications); + if (state.settings.showNotifications) { + raiseNativeNotification(diffNotifications); + } } + } finally { + setStatus('success'); + isFetchingRef.current = false; } - - setStatus('success'); }, [notifications], ); From 01228d45968123458fd59d8291aeb61b44a89547 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 26 Jan 2026 11:54:21 -0500 Subject: [PATCH 2/2] fix: add fetch lock Signed-off-by: Adam Setch --- src/renderer/hooks/useNotifications.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/renderer/hooks/useNotifications.ts b/src/renderer/hooks/useNotifications.ts index e72b601d7..595b140a4 100644 --- a/src/renderer/hooks/useNotifications.ts +++ b/src/renderer/hooks/useNotifications.ts @@ -136,8 +136,9 @@ export const useNotifications = (): NotificationsState => { raiseNativeNotification(diffNotifications); } } - } finally { + setStatus('success'); + } finally { isFetchingRef.current = false; } },