feat(notifications): disable realtime/WebSocket entirely — REST fetch + focus refresh only

- remove postgres_changes .channel().subscribe() from useNotifications
- notifications now load via REST on mount and refresh on tab focus
- eliminates WS retry hangs (30-40s stalls) from dead realtime container;
  web-push (Push API) is unaffected and works independently
This commit is contained in:
Hermes 2026-08-18 10:58:39 +02:00
parent cd72507766
commit 7a76c0a6c0
1 changed files with 11 additions and 42 deletions

View File

@ -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(() => {