/** * Voice Call Context * * Global state for voice calls that persists across screens. * Enables floating bubble when call is active and user navigates away. */ import React, { createContext, useContext, useState, useCallback, ReactNode } from 'react'; interface VoiceCallState { // Whether a voice call is currently active isActive: boolean; // Whether the call UI is minimized (showing bubble instead of full screen) isMinimized: boolean; // Voice service connection details token: string | undefined; wsUrl: string | undefined; // Call metadata beneficiaryName: string | undefined; beneficiaryId: string | undefined; // Call duration in seconds callDuration: number; } interface VoiceCallContextValue { // Current call state callState: VoiceCallState; // Start a new voice call startCall: (params: { token: string; wsUrl: string; beneficiaryName?: string; beneficiaryId?: string; }) => void; // End the current call endCall: () => void; // Minimize call (show floating bubble) minimizeCall: () => void; // Maximize call (show full screen) maximizeCall: () => void; // Update call duration updateDuration: (seconds: number) => void; // Check if call is active isCallActive: boolean; } const initialState: VoiceCallState = { isActive: false, isMinimized: false, token: undefined, wsUrl: undefined, beneficiaryName: undefined, beneficiaryId: undefined, callDuration: 0, }; const VoiceCallContext = createContext(undefined); export function VoiceCallProvider({ children }: { children: ReactNode }) { const [callState, setCallState] = useState(initialState); const startCall = useCallback((params: { token: string; wsUrl: string; beneficiaryName?: string; beneficiaryId?: string; }) => { console.log('[VoiceCallContext] Starting call'); setCallState({ isActive: true, isMinimized: false, token: params.token, wsUrl: params.wsUrl, beneficiaryName: params.beneficiaryName, beneficiaryId: params.beneficiaryId, callDuration: 0, }); }, []); const endCall = useCallback(() => { console.log('[VoiceCallContext] Ending call'); setCallState(initialState); }, []); const minimizeCall = useCallback(() => { console.log('[VoiceCallContext] Minimizing call'); setCallState(prev => ({ ...prev, isMinimized: true, })); }, []); const maximizeCall = useCallback(() => { console.log('[VoiceCallContext] Maximizing call'); setCallState(prev => ({ ...prev, isMinimized: false, })); }, []); const updateDuration = useCallback((seconds: number) => { setCallState(prev => ({ ...prev, callDuration: seconds, })); }, []); return ( {children} ); } export function useVoiceCall() { const context = useContext(VoiceCallContext); if (!context) { throw new Error('useVoiceCall must be used within VoiceCallProvider'); } return context; }