import { useEffect } from 'react'; import { useRouter } from 'expo-router'; import { supabase } from '../lib/supabase'; import { useCallStore, type CallPeer } from '../stores/call'; /** * Lauscht (app-weit, solange eingeloggt) auf den persönlichen Ring-Channel * `call-ring:` und zeigt bei einer eingehenden Einladung den * Call-Screen. Phase 1 = foreground-only (klingelt nur bei offener App; * Wake-when-closed via VoIP-Push ist Phase 2). */ export function useIncomingCalls(myUserId: string | undefined) { const router = useRouter(); useEffect(() => { if (!myUserId) return; console.log('[CALL/recv] subscribing call-ring channel for', myUserId); const chan = supabase.channel(`call-ring:${myUserId}`); chan.on('broadcast', { event: 'ring' }, (msg: any) => { console.log('[CALL/recv] RING received', msg?.payload); const callId = msg?.payload?.callId as string | undefined; const from = msg?.payload?.from as CallPeer | undefined; if (!callId || !from) return; // Schon in einem Call → ignorieren (MVP: kein call-waiting). if (useCallStore.getState().status !== 'idle') return; useCallStore.getState().receiveIncoming(callId, from); router.push('/call'); }); chan.on('broadcast', { event: 'cancel' }, (msg: any) => { const callId = msg?.payload?.callId as string | undefined; const st = useCallStore.getState(); if (st.callId === callId && st.status === 'incoming') { // Caller hat aufgelegt bevor wir annehmen konnten → verpasster Anruf. st.hangup('unanswered'); } }); chan.subscribe((status: string, err?: any) => { console.log('[CALL/recv] call-ring subscribe status:', status, err ?? ''); }); return () => { console.log('[CALL/recv] unsubscribing call-ring for', myUserId); supabase.removeChannel(chan); }; }, [myUserId, router]); }