import { chat } from '@chat-app/shared'; import type { ConversationSummary } from '@chat-app/shared/chat'; import { useEffect, useState } from 'react'; import { Modal, Pressable, StyleSheet, Text, View } from 'react-native'; import { Avatar } from './Avatar'; import { useCall } from '../lib/callContext'; import { supabase } from '../lib/supabase'; import { colors } from '../theme/colors'; // Full-screen modal that surfaces over any route when the CallContext // reports an `incoming` state. Resolves the caller's display name from // the conversation membership; falls back to "Anrufer" otherwise. export function IncomingCallModal() { const { state, acceptIncoming, rejectIncoming } = useCall(); const visible = state.kind === 'incoming'; const [conversation, setConversation] = useState(null); useEffect(() => { if (state.kind !== 'incoming') { setConversation(null); return; } let cancelled = false; void (async () => { try { const all = await chat.listConversations(supabase); if (cancelled) return; setConversation(all.find((c) => c.id === state.conversationId) ?? null); } catch { /* swallow */ } })(); return () => { cancelled = true; }; }, [state]); if (state.kind !== 'incoming') return null; const callerName = (() => { if (!conversation) return 'Anrufer'; const m = conversation.members.find((mm) => mm.userId === state.fromUserId); return m?.profile?.displayName ?? m?.profile?.username ?? 'Anrufer'; })(); const conversationTitle = conversation?.type === 'group' ? (conversation.name ?? 'Gruppe') : callerName; return ( Eingehender Anruf {callerName} {conversation?.type === 'group' && ( in {conversationTitle} )} { void rejectIncoming(); }} > Ablehnen { void acceptIncoming(); }} > Annehmen ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.bg, alignItems: 'center', justifyContent: 'center', gap: 20, paddingHorizontal: 32, }, title: { color: colors.text, fontSize: 28, fontWeight: '700' }, subtitle: { color: colors.textMuted, fontSize: 14 }, actions: { flexDirection: 'row', gap: 24, marginTop: 32, }, button: { paddingHorizontal: 28, paddingVertical: 16, borderRadius: 14, minWidth: 140, alignItems: 'center', }, buttonAccept: { backgroundColor: colors.success }, buttonReject: { backgroundColor: colors.danger }, buttonText: { color: colors.text, fontWeight: '700', fontSize: 16 }, });