diff --git a/src/renderer/__mocks__/state-mocks.ts b/src/renderer/__mocks__/state-mocks.ts index 65acbd6ae..a9321221b 100644 --- a/src/renderer/__mocks__/state-mocks.ts +++ b/src/renderer/__mocks__/state-mocks.ts @@ -3,7 +3,6 @@ import { Constants } from '../constants'; import { type Account, type AppearanceSettingsState, - FetchType, GroupBy, type KeyboardAcceleratorShortcut, type NotificationSettingsState, @@ -34,7 +33,6 @@ const mockAppearanceSettings: AppearanceSettingsState = { const mockNotificationSettings: NotificationSettingsState = { groupBy: GroupBy.REPOSITORY, - fetchType: FetchType.INTERVAL, fetchInterval: Constants.DEFAULT_FETCH_NOTIFICATIONS_INTERVAL_MS, fetchAllNotifications: true, detailedNotifications: true, diff --git a/src/renderer/components/settings/NotificationSettings.test.tsx b/src/renderer/components/settings/NotificationSettings.test.tsx index cff5e8c57..9f63423db 100644 --- a/src/renderer/components/settings/NotificationSettings.test.tsx +++ b/src/renderer/components/settings/NotificationSettings.test.tsx @@ -31,17 +31,6 @@ describe('renderer/components/settings/NotificationSettings.tsx', () => { expect(updateSettingSpy).toHaveBeenCalledWith('groupBy', 'DATE'); }); - it('should change the fetchType radio group', async () => { - await act(async () => { - renderWithProviders(); - }); - - await userEvent.click(screen.getByTestId('radio-fetchType-inactivity')); - - expect(updateSettingSpy).toHaveBeenCalledTimes(1); - expect(updateSettingSpy).toHaveBeenCalledWith('fetchType', 'INACTIVITY'); - }); - describe('fetch interval settings', () => { it('should update the fetch interval values when using the buttons', async () => { await act(async () => { diff --git a/src/renderer/components/settings/NotificationSettings.tsx b/src/renderer/components/settings/NotificationSettings.tsx index 92aa5ccfd..7c3f0ebea 100644 --- a/src/renderer/components/settings/NotificationSettings.tsx +++ b/src/renderer/components/settings/NotificationSettings.tsx @@ -31,7 +31,7 @@ import { FieldLabel } from '../fields/FieldLabel'; import { RadioGroup } from '../fields/RadioGroup'; import { Title } from '../primitives/Title'; -import { FetchType, GroupBy, Size } from '../../types'; +import { GroupBy, Size } from '../../types'; import { hasAlternateScopes, hasRecommendedScopes } from '../../utils/auth/scopes'; import { openGitHubParticipatingDocs } from '../../utils/system/links'; @@ -48,7 +48,6 @@ export const NotificationSettings: FC = () => { // Setting store values const groupBy = useSettingsStore((s) => s.groupBy); - const fetchType = useSettingsStore((s) => s.fetchType); const fetchInterval = useSettingsStore((s) => s.fetchInterval); const fetchAllNotifications = useSettingsStore((s) => s.fetchAllNotifications); const detailedNotifications = useSettingsStore((s) => s.detailedNotifications); @@ -90,32 +89,6 @@ export const NotificationSettings: FC = () => { value={groupBy} /> - { - updateSetting('fetchType', evt.target.value as FetchType); - }} - options={[ - { label: 'Interval', value: FetchType.INTERVAL }, - { label: 'Inactivity', value: FetchType.INACTIVITY }, - ]} - tooltip={ - - Controls how new notifications are fetched. - - Interval will check for new notifications on a regular - scheduled interval. - - - Inactivity will check for new notifications only when there - has been no user activity within {APPLICATION.NAME} for a specified period of time. - - - } - value={fetchType} - /> - diff --git a/src/renderer/hooks/timers/useInactivityTimer.ts b/src/renderer/hooks/timers/useInactivityTimer.ts deleted file mode 100644 index cc70a26ec..000000000 --- a/src/renderer/hooks/timers/useInactivityTimer.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { useCallback, useEffect, useRef } from 'react'; - -import { isOnline } from '../../utils/system/network'; - -const events = ['mousedown', 'keypress', 'click']; - -/** - * Hook that triggers a callback after a specified period of user inactivity. - * User activity (mousedown, keypress, click) resets the timer. - * - * @param callback - The function to call once inactivity exceeds `delay`. - * @param delay - Inactivity timeout in milliseconds. - */ -export const useInactivityTimer = (callback: () => void, delay: number | null) => { - const savedCallback = useRef<(() => void) | null>(null); - const timeoutRef = useRef | null>(null); - - // Remember the latest callback - useEffect(() => { - savedCallback.current = callback; - }, [callback]); - - // Reset the inactivity timer - const resetTimer = useCallback(() => { - if (timeoutRef.current) { - clearTimeout(timeoutRef.current); - } - - if (delay !== null && savedCallback.current) { - timeoutRef.current = setTimeout(() => { - // Fire callback once inactivity threshold reached if online - if (savedCallback.current && isOnline()) { - savedCallback.current(); - } - - // Schedule next run while still inactive - resetTimer(); - }, delay); - } - }, [delay]); - - // Set up event listeners for user activity - useEffect(() => { - if (delay === null) { - return; - } - - // Add event listeners to track activity - for (const event of events) { - document.addEventListener(event, resetTimer, { passive: true }); - } - - // Start initial timer - resetTimer(); - - // Cleanup function - return () => { - if (timeoutRef.current) { - clearTimeout(timeoutRef.current); - } - - for (const event of events) { - document.removeEventListener(event, resetTimer); - } - }; - }, [delay, resetTimer]); -}; diff --git a/src/renderer/hooks/useNotifications.test.tsx b/src/renderer/hooks/useNotifications.test.tsx index a8baf72f6..022e1272f 100644 --- a/src/renderer/hooks/useNotifications.test.tsx +++ b/src/renderer/hooks/useNotifications.test.tsx @@ -16,7 +16,6 @@ import { import { useAccountsStore, useFiltersStore, useSettingsStore } from '../stores'; import type { AccountNotifications, Percentage } from '../types'; -import { FetchType } from '../types'; import { Errors } from '../utils/core/errors'; import * as logger from '../utils/core/logger'; @@ -182,7 +181,6 @@ describe('renderer/hooks/useNotifications.ts', () => { getAllNotificationsMock.mockResolvedValue(mockSingleAccountNotifications); useSettingsStore.setState({ - fetchType: FetchType.INTERVAL, fetchInterval: 1000, }); @@ -222,7 +220,6 @@ describe('renderer/hooks/useNotifications.ts', () => { getAllNotificationsMock.mockResolvedValue(mockSingleAccountNotifications); useSettingsStore.setState({ - fetchType: FetchType.INTERVAL, fetchInterval: 1000, }); diff --git a/src/renderer/hooks/useNotifications.ts b/src/renderer/hooks/useNotifications.ts index 83aa849f9..72ec490f4 100644 --- a/src/renderer/hooks/useNotifications.ts +++ b/src/renderer/hooks/useNotifications.ts @@ -7,7 +7,6 @@ import { useAccountsStore, useFiltersStore, useSettingsStore } from '../stores'; import { type Account, type AccountNotifications, - FetchType, type GitifyError, type GitifyNotification, type Status, @@ -32,7 +31,6 @@ import { removeNotificationsForAccount } from '../utils/notifications/remove'; import { getNewNotifications } from '../utils/notifications/utils'; import { raiseSoundNotification } from '../utils/system/audio'; import { raiseNativeNotification } from '../utils/system/native'; -import { useInactivityTimer } from './timers/useInactivityTimer'; interface NotificationsState { status: Status; @@ -54,10 +52,10 @@ interface NotificationsState { interface UseNotificationsOptions { /** - * Run the singleton side effects (sound/native alerts for new notifications, - * inactivity-based refetching, and interval/focus/reconnect polling). Only - * the app-level effects host should enable this; all other consumers share - * the query cache without them. + * Run the singleton side effects (sound/native alerts for new notifications + * and interval/focus/reconnect polling). Only the app-level effects host + * should enable this; all other consumers share the query cache without + * them. * * Polling is owned by the singleton host because TanStack Query schedules * `refetchInterval` per mounted observer, not per query. Every consumer @@ -98,7 +96,6 @@ export const useNotifications = ({ // Setting store values const fetchReadNotifications = useSettingsStore((s) => s.fetchReadNotifications); const fetchParticipatingNotifications = useSettingsStore((s) => s.participating); - const fetchType = useSettingsStore((s) => s.fetchType); const fetchIntervalMs = useSettingsStore((s) => s.fetchInterval); const markAsDoneOnUnsubscribe = useSettingsStore((s) => s.markAsDoneOnUnsubscribe); const playSoundNewNotifications = useSettingsStore((s) => s.playSound); @@ -162,21 +159,12 @@ export const useNotifications = ({ // Only the singleton side-effects host polls. Other consumers share the // cached data and would otherwise each schedule their own refetch timer. - refetchInterval: withSideEffects && fetchType === FetchType.INTERVAL ? fetchIntervalMs : false, + refetchInterval: withSideEffects ? fetchIntervalMs : false, refetchOnMount: withSideEffects, refetchOnReconnect: withSideEffects, refetchOnWindowFocus: withSideEffects, }); - // Inactivity-based fetching re-fetches once the user has been idle for the - // configured interval, instead of polling on a fixed schedule. - useInactivityTimer( - () => { - refetch(); - }, - withSideEffects && fetchType === FetchType.INACTIVITY ? fetchIntervalMs : null, - ); - const notificationCount = getNotificationCount(notifications); const unreadNotificationCount = getUnreadNotificationCount(notifications); diff --git a/src/renderer/routes/__snapshots__/Settings.test.tsx.snap b/src/renderer/routes/__snapshots__/Settings.test.tsx.snap index dcb7a8dc1..d1bbc7900 100644 --- a/src/renderer/routes/__snapshots__/Settings.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/Settings.test.tsx.snap @@ -717,101 +717,6 @@ exports[`renderer/routes/Settings.tsx > should render itself & its children 1`] -
- -
- - -
-
- - -
- -
should render itself & its children 1`] data-wrap="nowrap" >