import { useEffect } from "react"; import { supabase } from "../lib/supabase"; import { isRealtimeErrorReal } from "../lib/realtimeStatus"; import type { RealtimeChannel } from "@supabase/supabase-js"; /** * Realtime-Subscription für die Blocker-Page. * Lauscht auf: * - UPDATE auf rebreak.domain_submissions → ruft `onChange()` (refetch) * - INSERT auf rebreak.notifications mit type=domain_accepted für eigene recipient_id → refetch * * Pendant zum Nuxt-Code in apps/rebreak/app/pages/app/blocker/index.vue. */ export function useDomainSubmissionRealtime( onChange: () => void, enabled: boolean = true, ) { useEffect(() => { if (!enabled) return; let channel: RealtimeChannel | null = null; let cancelled = false; let reconnectTimer: ReturnType | null = null; async function subscribe() { const { data } = await supabase.auth.getSession(); const session = data.session; if (!session?.access_token) return; if (cancelled) return; const myId = session.user.id; channel = supabase .channel(`blocker:domains:${myId}:${Date.now()}`) .on( "postgres_changes", { event: "*", schema: "rebreak", table: "domain_submissions", filter: `user_id=eq.${myId}`, }, () => onChange(), ) .on( "postgres_changes", { event: "*", schema: "rebreak", table: "user_custom_domains", filter: `user_id=eq.${myId}`, }, () => onChange(), ) .on( "postgres_changes", { event: "INSERT", schema: "rebreak", table: "notifications", filter: `recipient_id=eq.${myId}`, }, (payload: any) => { const t = payload.new?.type; if (t === "domain_accepted" || t === "domain_rejected") { onChange(); } }, ) .subscribe((status, err) => { if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") { if (isRealtimeErrorReal()) console.warn("[domainRealtime] error:", status, err ?? ""); cleanup(); if (reconnectTimer) clearTimeout(reconnectTimer); reconnectTimer = setTimeout(() => { if (!cancelled) subscribe(); }, 3000); } }); } function cleanup() { if (channel) { supabase.removeChannel(channel); channel = null; } } subscribe(); return () => { cancelled = true; if (reconnectTimer) clearTimeout(reconnectTimer); cleanup(); }; }, [enabled, onChange]); }