diff --git a/src/hooks/useNotifications.js b/src/hooks/useNotifications.js index 8ae7f67..f936d8d 100644 --- a/src/hooks/useNotifications.js +++ b/src/hooks/useNotifications.js @@ -31,50 +31,19 @@ export function useNotifications(userId) { fetchNotifications(); }, [fetchNotifications]); - // Realtime subscription + // NOTE: realtime (WebSocket) subscription intentionally removed (2026-08). + // The supabase realtime container kept dying and the client hung in WS retry + // loops (30-40s stalls on open). Notifications now update via REST fetch on + // page load / focus only — see handleFocus below for refresh on tab focus. + + // Refresh notifications when the tab regains focus so the unread badge stays + // reasonably fresh without a live WebSocket connection. React.useEffect(() => { if (!hasSupabaseConfig || !userId) return; - - const channel = supabase - .channel(`notifications:${userId}`) - .on( - "postgres_changes", - { - event: "INSERT", - schema: "public", - table: "notifications", - filter: `user_id=eq.${userId}`, - }, - (payload) => { - const newNotif = payload.new; - setNotifications((prev) => [newNotif, ...prev].slice(0, 50)); - setUnreadCount((prev) => prev + 1); - } - ) - .on( - "postgres_changes", - { - event: "UPDATE", - schema: "public", - table: "notifications", - filter: `user_id=eq.${userId}`, - }, - (payload) => { - const updated = payload.new; - setNotifications((prev) => - prev.map((n) => (n.id === updated.id ? updated : n)) - ); - setUnreadCount((prev) => - Math.max(0, prev + (updated.read ? -1 : 0) + (prev === 0 && !updated.read ? 1 : 0)) - ); - } - ) - .subscribe(); - - return () => { - supabase.removeChannel(channel); - }; - }, [userId]); + const handleFocus = () => fetchNotifications(); + window.addEventListener("focus", handleFocus); + return () => window.removeEventListener("focus", handleFocus); + }, [fetchNotifications, userId]); // Fix unread count: always recalculate from notifications React.useEffect(() => {