diff --git a/src/renderer/src/components/sidebar/sidebar-profile.tsx b/src/renderer/src/components/sidebar/sidebar-profile.tsx index bd1209ec..4fd7ee17 100644 --- a/src/renderer/src/components/sidebar/sidebar-profile.tsx +++ b/src/renderer/src/components/sidebar/sidebar-profile.tsx @@ -1,7 +1,7 @@ import { useNavigate } from "react-router-dom"; import { BellIcon } from "@primer/octicons-react"; import { useAppSelector, useUserDetails } from "@renderer/hooks"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import SteamLogo from "@renderer/assets/steam-logo.svg?react"; import { Avatar } from "../avatar/avatar"; @@ -10,6 +10,8 @@ import { logger } from "@renderer/logger"; import type { NotificationCountResponse } from "@types"; import "./sidebar-profile.scss"; +const NOTIFICATION_POLL_INTERVAL_MS = 5 * 60 * 1000; + export function SidebarProfile() { const navigate = useNavigate(); @@ -20,51 +22,78 @@ export function SidebarProfile() { const { gameRunning } = useAppSelector((state) => state.gameRunning); const [notificationCount, setNotificationCount] = useState(0); + const apiNotificationCountRef = useRef(0); + const userDetailsRef = useRef(userDetails); - const fetchNotificationCount = useCallback(async () => { + // Keep userDetailsRef in sync + useEffect(() => { + userDetailsRef.current = userDetails; + }, [userDetails]); + + const fetchLocalNotificationCount = useCallback(async () => { + try { + const localCount = await window.electron.getLocalNotificationsCount(); + setNotificationCount(localCount + apiNotificationCountRef.current); + } catch (error) { + logger.error("Failed to fetch local notification count", error); + } + }, []); + + const fetchFullNotificationCount = useCallback(async () => { try { - // Always fetch local notification count const localCount = await window.electron.getLocalNotificationsCount(); - // Fetch API notification count only if logged in - let apiCount = 0; - if (userDetails) { + if (userDetailsRef.current) { try { const response = await window.electron.hydraApi.get( "/profile/notifications/count", { needsAuth: true } ); - apiCount = response.count; + apiNotificationCountRef.current = response.count; } catch { // Ignore API errors } + } else { + apiNotificationCountRef.current = 0; } - setNotificationCount(localCount + apiCount); + setNotificationCount(localCount + apiNotificationCountRef.current); } catch (error) { logger.error("Failed to fetch notification count", error); } - }, [userDetails]); + }, []); useEffect(() => { - fetchNotificationCount(); + fetchFullNotificationCount(); - const interval = setInterval(fetchNotificationCount, 60000); + const interval = setInterval( + fetchFullNotificationCount, + NOTIFICATION_POLL_INTERVAL_MS + ); return () => clearInterval(interval); - }, [fetchNotificationCount]); + }, [fetchFullNotificationCount]); + + useEffect(() => { + if (userDetails) { + fetchFullNotificationCount(); + } else { + apiNotificationCountRef.current = 0; + fetchLocalNotificationCount(); + } + }, [userDetails, fetchFullNotificationCount, fetchLocalNotificationCount]); useEffect(() => { const unsubscribe = window.electron.onLocalNotificationCreated(() => { - fetchNotificationCount(); + fetchLocalNotificationCount(); }); return () => unsubscribe(); - }, [fetchNotificationCount]); + }, [fetchLocalNotificationCount]); useEffect(() => { const handleNotificationsChange = () => { - fetchNotificationCount(); + fetchLocalNotificationCount(); }; window.addEventListener("notificationsChanged", handleNotificationsChange); @@ -74,15 +103,18 @@ export function SidebarProfile() { handleNotificationsChange ); }; - }, [fetchNotificationCount]); + }, [fetchLocalNotificationCount]); useEffect(() => { - const unsubscribe = window.electron.onSyncNotificationCount(() => { - fetchNotificationCount(); - }); + const unsubscribe = window.electron.onSyncNotificationCount( + (notification) => { + apiNotificationCountRef.current = notification.notificationCount; + fetchLocalNotificationCount(); + } + ); return () => unsubscribe(); - }, [fetchNotificationCount]); + }, [fetchLocalNotificationCount]); const handleProfileClick = () => { if (userDetails === null) {