add roomViewId and related

This commit is contained in:
Gigiaj 2025-05-10 20:41:57 -05:00
parent cde0d5fa64
commit 1b89831c10

View file

@ -27,12 +27,18 @@ const WIDGET_JOIN_ACTION = 'io.element.join';
interface CallContextState { interface CallContextState {
activeCallRoomId: string | null; activeCallRoomId: string | null;
setActiveCallRoomId: (roomId: string | null) => void; setActiveCallRoomId: (roomId: string | null) => void;
viewedCallRoomId: string | null;
setViewedCallRoomId: (roomId: string | null) => void;
hangUp: () => void; hangUp: () => void;
activeClientWidgetApi: ClientWidgetApi | null; activeClientWidgetApi: ClientWidgetApi | null;
registerActiveClientWidgetApi: ( registerActiveClientWidgetApi: (
roomId: string | null, roomId: string | null,
clientWidgetApi: ClientWidgetApi | null clientWidgetApi: ClientWidgetApi | null
) => void; ) => void;
registerViewedClientWidgetApi: (
roomId: string | null,
clientWidgetApi: ClientWidgetApi | null
) => void;
sendWidgetAction: <T = unknown>( sendWidgetAction: <T = unknown>(
action: WidgetApiToWidgetAction | string, action: WidgetApiToWidgetAction | string,
data: T data: T
@ -58,14 +64,23 @@ const DEFAULT_AUDIO_ENABLED = true;
const DEFAULT_VIDEO_ENABLED = false; const DEFAULT_VIDEO_ENABLED = false;
const DEFAULT_CHAT_OPENED = false; const DEFAULT_CHAT_OPENED = false;
const DEFAULT_CALL_ACTIVE = false; const DEFAULT_CALL_ACTIVE = false;
const DEFAULT_PRIMARY_IFRAME = false; const DEFAULT_PRIMARY_IFRAME = true;
export function CallProvider({ children }: CallProviderProps) { export function CallProvider({ children }: CallProviderProps) {
const [activeCallRoomId, setActiveCallRoomIdState] = useState<string | null>(null); const [activeCallRoomId, setActiveCallRoomIdState] = useState<string | null>(null);
const [viewedCallRoomId, setViewedCallRoomIdState] = useState<string | null>(null);
const [activeClientWidgetApi, setActiveClientWidgetApiState] = useState<ClientWidgetApi | null>( const [activeClientWidgetApi, setActiveClientWidgetApiState] = useState<ClientWidgetApi | null>(
null null
); );
const [clientWidgetApiRoomId, setClientWidgetApiRoomId] = useState<string | null>(null); const [activeClientWidgetApiRoomId, setActiveClientWidgetApiRoomId] = useState<string | null>(
null
);
const [viewedClientWidgetApi, setViewedClientWidgetApiState] = useState<ClientWidgetApi | null>(
null
);
const [viewedClientWidgetApiRoomId, setViewedClientWidgetApiRoomId] = useState<string | null>(
null
);
const [isAudioEnabled, setIsAudioEnabledState] = useState<boolean>(DEFAULT_AUDIO_ENABLED); const [isAudioEnabled, setIsAudioEnabledState] = useState<boolean>(DEFAULT_AUDIO_ENABLED);
const [isVideoEnabled, setIsVideoEnabledState] = useState<boolean>(DEFAULT_VIDEO_ENABLED); const [isVideoEnabled, setIsVideoEnabledState] = useState<boolean>(DEFAULT_VIDEO_ENABLED);
@ -95,32 +110,35 @@ export function CallProvider({ children }: CallProviderProps) {
resetMediaState(); resetMediaState();
} }
if (roomId === null || roomId !== clientWidgetApiRoomId) { if (roomId === null || roomId !== activeClientWidgetApiRoomId) {
logger.warn( logger.warn(
`CallContext: Clearing active clientWidgetApi because active room changed to ${roomId} or was cleared.` `CallContext: Clearing active clientWidgetApi because active room changed to ${roomId} or was cleared.`
); );
setActiveClientWidgetApiState(null); //setActiveClientWidgetApiState(null);
setClientWidgetApiRoomId(null); //setActiveClientWidgetApiRoomId(null);
} }
}, },
[clientWidgetApiRoomId, resetMediaState, activeCallRoomId] [activeClientWidgetApiRoomId, resetMediaState, activeCallRoomId]
);
const setViewedCallRoomId = useCallback(
(roomId: string | null) => {
logger.warn(`CallContext: Setting activeCallRoomId to ${roomId}`);
setViewedCallRoomIdState(roomId);
},
[setViewedCallRoomIdState]
); );
const hangUp = useCallback(() => { const hangUp = useCallback(() => {
logger.debug(`CallContext: Hang up called.`); logger.debug(`CallContext: Hang up called.`);
activeClientWidgetApi?.transport.send(`${WIDGET_HANGUP_ACTION}`, {}); activeClientWidgetApi?.transport.send(`${WIDGET_HANGUP_ACTION}`, {});
setIsCallActive(false); setIsCallActive(false);
//setActiveCallRoomId(null); }, [activeClientWidgetApi]);
setActiveCallRoomIdState(null);
//logger.debug(`CallContext: Clearing active clientWidgetApi due to hangup.`);
//setActiveClientWidgetApiState(null);
//setClientWidgetApiRoomId(null);
}, [activeClientWidgetApi?.transport]);
const setActiveClientWidgetApi = useCallback( const setActiveClientWidgetApi = useCallback(
(clientWidgetApi: ClientWidgetApi | null, roomId: string | null) => { (clientWidgetApi: ClientWidgetApi | null, roomId: string | null) => {
setActiveClientWidgetApiState(clientWidgetApi); setActiveClientWidgetApiState(clientWidgetApi);
setClientWidgetApiRoomId(roomId); setActiveClientWidgetApiRoomId(roomId);
}, },
[] []
); );
@ -134,45 +152,79 @@ export function CallProvider({ children }: CallProviderProps) {
if (roomId && clientWidgetApi) { if (roomId && clientWidgetApi) {
logger.debug(`CallContext: Registering active clientWidgetApi for room ${roomId}.`); logger.debug(`CallContext: Registering active clientWidgetApi for room ${roomId}.`);
setActiveClientWidgetApi(clientWidgetApi, roomId); setActiveClientWidgetApi(clientWidgetApi, roomId);
} else if (roomId === clientWidgetApiRoomId || roomId === null) { } else if (roomId === activeClientWidgetApiRoomId || roomId === null) {
logger.debug( logger.debug(
`CallContext: Clearing active clientWidgetApi for room ${clientWidgetApiRoomId}.` `CallContext: Clearing active clientWidgetApi for room ${activeClientWidgetApiRoomId}.`
); );
setActiveClientWidgetApi(null, null); setActiveClientWidgetApi(null, null);
resetMediaState(); resetMediaState();
} else { } else {
logger.debug( logger.debug(
`CallContext: Ignoring clientWidgetApi registration/clear request for room ${roomId}, as current clientWidgetApi belongs to ${clientWidgetApiRoomId}.` `CallContext: Ignoring clientWidgetApi registration/clear request for room ${roomId}, as current clientWidgetApi belongs to ${activeClientWidgetApiRoomId}.`
); );
} }
}, },
[activeClientWidgetApi, clientWidgetApiRoomId, setActiveClientWidgetApi, resetMediaState] [activeClientWidgetApi, activeClientWidgetApiRoomId, setActiveClientWidgetApi, resetMediaState]
);
const setViewedClientWidgetApi = useCallback(
(clientWidgetApi: ClientWidgetApi | null, roomId: string | null) => {
setViewedClientWidgetApiState(clientWidgetApi);
//setViewedClientWidgetApiRoomId(roomId);
},
[]
);
const registerViewedClientWidgetApi = useCallback(
(roomId: string | null, clientWidgetApi: ClientWidgetApi | null) => {
if (viewedClientWidgetApi && viewedClientWidgetApi !== clientWidgetApi) {
logger.error(`CallContext: Cleaning up listeners for previous clientWidgetApi instance.`);
}
if (roomId && clientWidgetApi) {
logger.error(`CallContext: Registering active clientWidgetApi for room ${roomId}.`);
setViewedClientWidgetApi(clientWidgetApi, roomId);
} else if (roomId === viewedClientWidgetApiRoomId || roomId === null) {
logger.error(
`CallContext: Clearing active clientWidgetApi for room ${viewedClientWidgetApiRoomId}.`
);
setViewedClientWidgetApi(null, null);
//resetMediaState();
} else {
logger.debug(
`CallContext: Ignoring clientWidgetApi registration/clear request for room ${roomId}, as current clientWidgetApi belongs to ${viewedClientWidgetApiRoomId}.`
);
}
},
[viewedClientWidgetApi, viewedClientWidgetApiRoomId, setViewedClientWidgetApi]
); );
useEffect(() => { useEffect(() => {
if ( if (
!activeClientWidgetApi || !activeClientWidgetApi ||
!viewedClientWidgetApi ||
!activeCallRoomId || !activeCallRoomId ||
clientWidgetApiRoomId !== activeCallRoomId || !viewedCallRoomId ||
isCallActive isCallActive
) { ) {
return; return;
} }
//logger.error(viewedClientWidgetApi);
const clientWidgetApi = activeClientWidgetApi;
const handleHangup = (ev: CustomEvent) => { const handleHangup = (ev: CustomEvent) => {
ev.preventDefault(); ev.preventDefault();
hangUp();
clientWidgetApi.transport.reply(ev.detail, {}); // if (!isPrimaryIframe) {
activeClientWidgetApi?.transport.reply(ev.detail, {});
// } else {
viewedClientWidgetApi?.transport.reply(ev.detail, {});
// }
logger.warn( logger.warn(
`CallContext: Received hangup action from widget in room ${activeCallRoomId}.`, `CallContext: Received hangup action from widget in room ${activeCallRoomId}.`,
ev ev
); );
setIsPrimaryIframe(true); //setIsPrimaryIframe(!isPrimaryIframe);
setIsCallActive(false); setIsCallActive(false);
setActiveCallRoomIdState(null); //setActiveCallRoomIdState(null);
//hangUp();
}; };
const handleMediaStateUpdate = (ev: CustomEvent<MediaStatePayload>) => { const handleMediaStateUpdate = (ev: CustomEvent<MediaStatePayload>) => {
@ -194,46 +246,54 @@ export function CallProvider({ children }: CallProviderProps) {
const handleOnScreenStateUpdate = (ev: CustomEvent) => { const handleOnScreenStateUpdate = (ev: CustomEvent) => {
ev.preventDefault(); ev.preventDefault();
activeClientWidgetApi.transport.reply(ev.detail, {}); if (isPrimaryIframe) {
activeClientWidgetApi?.transport.reply(ev.detail, {});
} else {
viewedClientWidgetApi?.transport.reply(ev.detail, {});
}
}; };
const handleJoin = (ev: CustomEvent) => { const handleJoin = (ev: CustomEvent) => {
ev.preventDefault(); ev.preventDefault();
if (isCallActive) { if (isCallActive && activeClientWidgetApi) {
setIsPrimaryIframe(false); activeClientWidgetApi?.transport.send(WIDGET_HANGUP_ACTION, {}).then(() => {
setActiveCallRoomIdState(viewedRoomId); setActiveCallRoomIdState(viewedCallRoomId);
} else { setActiveClientWidgetApi(viewedClientWidgetApi, viewedCallRoomId);
setIsPrimaryIframe(true); //setIsPrimaryIframe(!isPrimaryIframe);
} //setViewedClientWidgetApi(null, null);
setIsCallActive(true); setIsCallActive(true);
activeClientWidgetApi?.transport.reply(ev.detail, {});
});
}
}; };
logger.debug( logger.debug(
`CallContext: Setting up listeners for clientWidgetApi in room ${activeCallRoomId}` `CallContext: Setting up listeners for clientWidgetApi in room ${activeCallRoomId}`
); );
clientWidgetApi.on(`action:${WIDGET_HANGUP_ACTION}`, handleHangup); activeClientWidgetApi?.on(`action:${WIDGET_HANGUP_ACTION}`, handleHangup);
clientWidgetApi.on(`action:${WIDGET_MEDIA_STATE_UPDATE_ACTION}`, handleMediaStateUpdate); activeClientWidgetApi?.on(`action:${WIDGET_MEDIA_STATE_UPDATE_ACTION}`, handleMediaStateUpdate);
clientWidgetApi.on(`action:${WIDGET_ON_SCREEN_ACTION}`, handleOnScreenStateUpdate); activeClientWidgetApi?.on(`action:${WIDGET_ON_SCREEN_ACTION}`, handleOnScreenStateUpdate);
clientWidgetApi.on(`action:${WIDGET_JOIN_ACTION}`, handleJoin); activeClientWidgetApi?.on(`action:${WIDGET_JOIN_ACTION}`, handleJoin);
return () => { viewedClientWidgetApi?.on(`action:${WIDGET_JOIN_ACTION}`, handleJoin);
logger.debug( viewedClientWidgetApi?.on(`action:${WIDGET_MEDIA_STATE_UPDATE_ACTION}`, handleMediaStateUpdate);
`CallContext: Cleaning up listeners for clientWidgetApi in room ${activeCallRoomId}` viewedClientWidgetApi?.on(`action:${WIDGET_ON_SCREEN_ACTION}`, handleOnScreenStateUpdate);
); viewedClientWidgetApi?.on(`action:${WIDGET_HANGUP_ACTION}`, handleHangup);
if (clientWidgetApi) {
//clientWidgetApi.off(`action:${WIDGET_HANGUP_ACTION}`, handleHangup);
//clientWidgetApi.off(`action:${WIDGET_MEDIA_STATE_UPDATE_ACTION}`, handleMediaStateUpdate);
}
};
}, [ }, [
activeClientWidgetApi, activeClientWidgetApi,
activeCallRoomId, activeCallRoomId,
clientWidgetApiRoomId, activeClientWidgetApiRoomId,
hangUp, hangUp,
isChatOpen, isChatOpen,
isAudioEnabled, isAudioEnabled,
isVideoEnabled, isVideoEnabled,
isCallActive, isCallActive,
viewedRoomId,
viewedClientWidgetApi,
isPrimaryIframe,
viewedCallRoomId,
setViewedClientWidgetApi,
setActiveClientWidgetApi,
]); ]);
const sendWidgetAction = useCallback( const sendWidgetAction = useCallback(
@ -244,15 +304,15 @@ export function CallProvider({ children }: CallProviderProps) {
); );
return Promise.reject(new Error('No active call clientWidgetApi')); return Promise.reject(new Error('No active call clientWidgetApi'));
} }
if (!clientWidgetApiRoomId || clientWidgetApiRoomId !== activeCallRoomId) { if (!activeClientWidgetApiRoomId || activeClientWidgetApiRoomId !== activeCallRoomId) {
logger.debug( logger.debug(
`CallContext: Cannot send action '${action}', clientWidgetApi room (${clientWidgetApiRoomId}) does not match active call room (${activeCallRoomId}). Stale clientWidgetApi?` `CallContext: Cannot send action '${action}', clientWidgetApi room (${activeClientWidgetApiRoomId}) does not match active call room (${activeCallRoomId}). Stale clientWidgetApi?`
); );
return Promise.reject(new Error('Mismatched active call clientWidgetApi')); return Promise.reject(new Error('Mismatched active call clientWidgetApi'));
} }
try { try {
logger.debug( logger.debug(
`CallContext: Sending action '${action}' via active clientWidgetApi (room: ${clientWidgetApiRoomId}) with data:`, `CallContext: Sending action '${action}' via active clientWidgetApi (room: ${activeClientWidgetApiRoomId}) with data:`,
data data
); );
await activeClientWidgetApi.transport.send(action as WidgetApiAction, data); await activeClientWidgetApi.transport.send(action as WidgetApiAction, data);
@ -261,7 +321,7 @@ export function CallProvider({ children }: CallProviderProps) {
throw error; throw error;
} }
}, },
[activeClientWidgetApi, activeCallRoomId, clientWidgetApiRoomId] [activeClientWidgetApi, activeCallRoomId, activeClientWidgetApiRoomId]
); );
const toggleAudio = useCallback(async () => { const toggleAudio = useCallback(async () => {
@ -312,9 +372,12 @@ export function CallProvider({ children }: CallProviderProps) {
() => ({ () => ({
activeCallRoomId, activeCallRoomId,
setActiveCallRoomId, setActiveCallRoomId,
viewedCallRoomId,
setViewedCallRoomId,
hangUp, hangUp,
activeClientWidgetApi, activeClientWidgetApi,
registerActiveClientWidgetApi, registerActiveClientWidgetApi,
registerViewedClientWidgetApi,
sendWidgetAction, sendWidgetAction,
isChatOpen, isChatOpen,
isAudioEnabled, isAudioEnabled,
@ -329,9 +392,12 @@ export function CallProvider({ children }: CallProviderProps) {
[ [
activeCallRoomId, activeCallRoomId,
setActiveCallRoomId, setActiveCallRoomId,
viewedCallRoomId,
setViewedCallRoomId,
hangUp, hangUp,
activeClientWidgetApi, activeClientWidgetApi,
registerActiveClientWidgetApi, registerActiveClientWidgetApi,
registerViewedClientWidgetApi,
sendWidgetAction, sendWidgetAction,
isChatOpen, isChatOpen,
isAudioEnabled, isAudioEnabled,