import { useEffect } from "react"; import { supabase } from "../lib/supabase"; import { useDeviceApprovalStore } from "../stores/deviceApproval"; import type { RealtimeChannel } from "@supabase/supabase-js"; /** * Realtime-Subscription für Device-Approval-Requests. * * Lauscht auf INSERT/UPDATE auf rebreak.device_approval_requests gefiltert * nach user_id. Wenn eine pending Row hereinkommt → triggert * refreshIncomingFromServer() (holt die newest pending Row und zeigt das * Approval-Sheet auf diesem existierenden Gerät). * * Wird global im _layout.tsx aufgerufen — IMMER aktiv für eingeloggte User. */ export function useDeviceApprovalRealtime(enabled: boolean = true) { const refreshIncoming = useDeviceApprovalStore( (s) => s.refreshIncomingFromServer, ); 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; // Initial pull (in case we missed something while offline) refreshIncoming(); channel = supabase .channel(`device_approvals:${myId}:${Date.now()}`) .on( "postgres_changes", { event: "INSERT", schema: "rebreak", table: "device_approval_requests", filter: `user_id=eq.${myId}`, }, () => refreshIncoming(), ) .on( "postgres_changes", { event: "UPDATE", schema: "rebreak", table: "device_approval_requests", filter: `user_id=eq.${myId}`, }, () => refreshIncoming(), ) .subscribe((status, err) => { if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") { console.warn("[approvalRealtime] error:", status, err ?? ""); cleanup(); if (reconnectTimer) clearTimeout(reconnectTimer); reconnectTimer = setTimeout(() => { if (!cancelled) subscribe(); }, 3000); } }); } function cleanup() { if (channel) { supabase.removeChannel(channel).catch(() => {}); channel = null; } } subscribe(); return () => { cancelled = true; if (reconnectTimer) clearTimeout(reconnectTimer); cleanup(); }; }, [enabled, refreshIncoming]); }