update to support two iframes - still needs to leverage balancing the two properly but as a PoC it works

This commit is contained in:
Gigiaj 2025-05-02 17:04:50 -05:00
parent 7c6c1f53c0
commit 93fbbecfdd

View file

@ -1,4 +1,4 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useMemo, useRef } from 'react';
import { logger } from 'matrix-js-sdk/lib/logger'; import { logger } from 'matrix-js-sdk/lib/logger';
import { ClientWidgetApi, IWidgetApiRequest } from 'matrix-widget-api'; import { ClientWidgetApi, IWidgetApiRequest } from 'matrix-widget-api';
import { Box } from 'folds'; import { Box } from 'folds';
@ -25,11 +25,17 @@ import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
interface PersistentCallContainerProps { interface PersistentCallContainerProps {
isVisible: boolean; isVisible: boolean;
viewedRoomId: string;
} }
export function PersistentCallContainer({ isVisible }: PersistentCallContainerProps) { export function PersistentCallContainer({ isVisible, viewedRoomId }: PersistentCallContainerProps) {
const { activeCallRoomId, isChatOpen, setActiveCallRoomId, registerActiveClientWidgetApi } = const {
useCallState(); activeCallRoomId,
isChatOpen,
isCallActive,
setActiveCallRoomId,
registerActiveClientWidgetApi,
} = useCallState();
const { eventId } = useParams(); const { eventId } = useParams();
const mx = useMatrixClient(); const mx = useMatrixClient();
const roomId = useSelectedRoom(); const roomId = useSelectedRoom();
@ -37,6 +43,10 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
const room = mx.getRoom(roomId) ?? null; const room = mx.getRoom(roomId) ?? null;
const screenSize = useScreenSizeContext(); const screenSize = useScreenSizeContext();
const isMobile = screenSize === ScreenSize.Mobile; const isMobile = screenSize === ScreenSize.Mobile;
const isViewingActiveCall = useMemo(
() => activeCallRoomId !== null && activeCallRoomId === viewedRoomId,
[activeCallRoomId, viewedRoomId]
);
logger.info(room); logger.info(room);
@ -44,7 +54,11 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
const widgetApiRef = useRef<ClientWidgetApi | null>(null); const widgetApiRef = useRef<ClientWidgetApi | null>(null);
const smallWidgetRef = useRef<SmallWidget | null>(null); const smallWidgetRef = useRef<SmallWidget | null>(null);
useEffect(() => { const backupIframeRef = useRef<HTMLIFrameElement | null>(null);
const backupWidgetApiRef = useRef<ClientWidgetApi | null>(null);
const backupSmallWidgetRef = useRef<SmallWidget | null>(null);
const setupWidget = (widgetApiRef, smallWidgetRef, iframeRef, skipLobby) => {
const cleanupRoomId = smallWidgetRef.current?.roomId; const cleanupRoomId = smallWidgetRef.current?.roomId;
logger.debug(`PersistentCallContainer effect running. activeCallRoomId: ${activeCallRoomId}`); logger.debug(`PersistentCallContainer effect running. activeCallRoomId: ${activeCallRoomId}`);
@ -57,7 +71,7 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
* Might also be able to keep the iframe alive and instead navigate to a new "room" to make the transition smoother * Might also be able to keep the iframe alive and instead navigate to a new "room" to make the transition smoother
*/ */
const cleanup = () => { const cleanup = () => {
logger.error(`CallContext: Cleaning up for previous room: ${cleanupRoomId}`); //logger.error(`CallContext: Cleaning up for previous room: ${cleanupRoomId}`);
if (smallWidgetRef.current) { if (smallWidgetRef.current) {
// smallWidgetRef.current.stopMessaging(); // smallWidgetRef.current.stopMessaging();
@ -66,20 +80,18 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
if (widgetApiRef.current) { if (widgetApiRef.current) {
// widgetApiRef.current.stop?.(); // widgetApiRef.current.stop?.();
} }
widgetApiRef.current = null; //widgetApiRef.current = null;
smallWidgetRef.current = null; //smallWidgetRef.current = null;
//hangUp(); //if (iframeRef.current) iframeRef.current.src = 'about:blank';
if (iframeRef.current) iframeRef.current.src = 'about:blank';
}; };
if (activeCallRoomId && mx?.getUserId()) { if (activeCallRoomId && mx?.getUserId()) {
if (cleanupRoomId !== activeCallRoomId) { if (cleanupRoomId !== activeCallRoomId && !isCallActive) {
const newUrl = getWidgetUrl(mx, roomId, clientConfig.elementCallUrl ?? '', { const newUrl = getWidgetUrl(mx, roomId, clientConfig.elementCallUrl ?? '', {
skipLobby: 'true', skipLobby,
returnToLobby: 'true', returnToLobby: 'true',
perParticipentE2EE: 'true', perParticipentE2EE: 'true',
}); });
if (iframeRef.current && iframeRef.current.src !== newUrl.toString()) { if (iframeRef.current && iframeRef.current.src !== newUrl.toString()) {
logger.info( logger.info(
`PersistentCallContainer: Updating iframe src for ${activeCallRoomId} to ${newUrl.toString()}` `PersistentCallContainer: Updating iframe src for ${activeCallRoomId} to ${newUrl.toString()}`
@ -102,7 +114,7 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
const userId = mx.getUserId() ?? ''; const userId = mx.getUserId() ?? '';
const app = createVirtualWidget( const app = createVirtualWidget(
mx, mx,
`element-call-${activeCallRoomId}`, `element-call-${activeCallRoomId}-${Date.now()}`,
userId, userId,
'Element Call', 'Element Call',
'm.call', 'm.call',
@ -121,7 +133,7 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
try { try {
const widgetApiInstance = smallWidget.startMessaging(iframeElement); const widgetApiInstance = smallWidget.startMessaging(iframeElement);
widgetApiRef.current = widgetApiInstance; widgetApiRef.current = widgetApiInstance;
registerActiveClientWidgetApi(activeCallRoomId, widgetApiRef.current); if (skipLobby) registerActiveClientWidgetApi(activeCallRoomId, widgetApiRef.current);
widgetApiInstance.once('ready', () => { widgetApiInstance.once('ready', () => {
logger.info(`PersistentCallContainer: Widget for ${activeCallRoomId} is ready.`); logger.info(`PersistentCallContainer: Widget for ${activeCallRoomId} is ready.`);
}); });
@ -133,15 +145,22 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
cleanup(); cleanup();
} }
} else { } else {
/*
if (iframeRef.current && iframeRef.current.src !== 'about:blank') { if (iframeRef.current && iframeRef.current.src !== 'about:blank') {
logger.info('PersistentCallContainer: No active call, setting src to about:blank'); logger.info('PersistentCallContainer: No active call, setting src to about:blank');
iframeRef.current.src = 'about:blank'; iframeRef.current.src = 'about:blank';
} }
*/
cleanup(); cleanup();
} }
} }
return cleanup; return cleanup;
}, [activeCallRoomId, mx, setActiveCallRoomId]); };
useEffect(() => {
setupWidget(widgetApiRef, smallWidgetRef, iframeRef, true);
setupWidget(backupWidgetApiRef, backupSmallWidgetRef, backupIframeRef, false);
});
const containerStyle: React.CSSProperties = { const containerStyle: React.CSSProperties = {
width: '100%', width: '100%',
@ -203,7 +222,7 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
position: 'absolute', position: 'absolute',
top: 0, top: 0,
left: 0, left: 0,
// display: isMobile && isChatOpen ? 'none' : 'flex', display: isViewingActiveCall ? 'flex' : 'none',
width: '100%', width: '100%',
height: '100%', height: '100%',
border: 'none', border: 'none',
@ -213,6 +232,23 @@ export function PersistentCallContainer({ isVisible }: PersistentCallContainerPr
allow="microphone; camera; display-capture; autoplay; clipboard-write;" allow="microphone; camera; display-capture; autoplay; clipboard-write;"
src="about:blank" src="about:blank"
/> />
<iframe
ref={backupIframeRef}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
border: 'none',
display: isViewingActiveCall ? 'none' : 'flex',
}}
title={`Persistent Element Call`}
sandbox="allow-forms allow-scripts allow-same-origin allow-popups allow-modals allow-downloads"
allow="microphone; camera; display-capture; autoplay; clipboard-write;"
src="about:blank"
/>
</Box> </Box>
</Box> </Box>
<Box grow="Yes" direction="Column" style={{ position: 'relative' }}> <Box grow="Yes" direction="Column" style={{ position: 'relative' }}>