import React, { ReactNode, useCallback, useEffect, useRef } from 'react'; import { useAtomValue, useSetAtom, useStore } from 'jotai'; import { CallEmbedContextProvider, CallEmbedRefContextProvider, useCallHangupEvent, useCallJoined, useCallThemeSync, useCallMemberSoundSync, } from '../hooks/useCallEmbed'; import { callChatAtom, callEmbedAtom } from '../state/callEmbed'; import { CallEmbed } from '../plugins/call'; import { useSelectedRoom } from '../hooks/router/useSelectedRoom'; import { ScreenSize, useScreenSizeContext } from '../hooks/useScreenSize'; import { useAndroidCallForegroundSync } from '../hooks/useAndroidCallForegroundSync'; function CallUtils({ embed }: { embed: CallEmbed }) { const setCallEmbed = useSetAtom(callEmbedAtom); const store = useStore(); useCallMemberSoundSync(embed); useCallThemeSync(embed); useCallHangupEvent( embed, useCallback(() => { if (store.get(callEmbedAtom) !== embed) return; setCallEmbed(undefined); }, [store, embed, setCallEmbed]) ); // Widget failed to prepare (bad network, iframe load error). Without this, // the embed lingers with joined=false forever, and the Android FGS (keyed // to callEmbedAtom presence) stays up as a ghost ongoing notification. useEffect(() => { const unsubscribe = embed.onPreparingError(() => { if (store.get(callEmbedAtom) !== embed) return; setCallEmbed(undefined); }); return unsubscribe; }, [embed, store, setCallEmbed]); return null; } type CallEmbedProviderProps = { children?: ReactNode; }; export function CallEmbedProvider({ children }: CallEmbedProviderProps) { const callEmbed = useAtomValue(callEmbedAtom); const callEmbedRef = useRef(null); const joined = useCallJoined(callEmbed); useAndroidCallForegroundSync(); const selectedRoom = useSelectedRoom(); const chat = useAtomValue(callChatAtom); const screenSize = useScreenSizeContext(); const chatOnlyView = chat && screenSize !== ScreenSize.Desktop; const callVisible = callEmbed && !callEmbed.voiceOnly && selectedRoom === callEmbed.roomId && joined && !chatOnlyView; return ( {callEmbed && } {children}
); }