From 6601c47abc3dcc666ba30c1c50c44889703c556e Mon Sep 17 00:00:00 2001 From: Gigiaj Date: Sat, 10 May 2025 20:42:21 -0500 Subject: [PATCH] (broken) juggle the iframe states proper... still needs fixing --- .../pages/call/PersistentCallContainer.tsx | 332 ++++++++++-------- 1 file changed, 189 insertions(+), 143 deletions(-) diff --git a/src/app/pages/call/PersistentCallContainer.tsx b/src/app/pages/call/PersistentCallContainer.tsx index 593446ad..6ee0a917 100644 --- a/src/app/pages/call/PersistentCallContainer.tsx +++ b/src/app/pages/call/PersistentCallContainer.tsx @@ -1,8 +1,8 @@ -import React, { createContext, ReactNode, useEffect, useMemo, useRef } from 'react'; +import React, { createContext, ReactNode, useCallback, useEffect, useMemo, useRef } from 'react'; import { logger } from 'matrix-js-sdk/lib/logger'; import { ClientWidgetApi } from 'matrix-widget-api'; import { Box } from 'folds'; -import { Outlet, useParams } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { useCallState } from '../client/CallProvider'; import { createVirtualWidget, @@ -19,27 +19,28 @@ interface PersistentCallContainerProps { children: ReactNode; } -export const RefContext = createContext(null); +export const PrimaryRefContext = createContext(null); +export const BackupRefContext = createContext(null); export function PersistentCallContainer({ children }: PersistentCallContainerProps) { - const iframeRef = useRef(null); - const widgetApiRef = useRef(null); - const smallWidgetRef = useRef(null); + const primaryIframeRef = useRef(null); + const primaryWidgetApiRef = useRef(null); + const primarySmallWidgetRef = useRef(null); const backupIframeRef = useRef(null); const backupWidgetApiRef = useRef(null); const backupSmallWidgetRef = useRef(null); const { activeCallRoomId, + viewedCallRoomId, isChatOpen, isCallActive, isPrimaryIframe, registerActiveClientWidgetApi, + registerViewedClientWidgetApi, } = useCallState(); const mx = useMatrixClient(); - const roomId = useSelectedRoom(); const clientConfig = useClientConfig(); - const room = mx.getRoom(roomId) ?? null; const screenSize = useScreenSizeContext(); const isMobile = screenSize === ScreenSize.Mobile; const { roomIdOrAlias: viewedRoomId } = useParams(); @@ -48,167 +49,212 @@ export function PersistentCallContainer({ children }: PersistentCallContainerPro [activeCallRoomId, viewedRoomId] ); - logger.info(room); + // logger.error('RANDOM LOG RANDOM LOG RANDOM LOG\n\n\n\n\n\n'); + // logger.error(room?.normalizedName); - const setupWidget = (widgetApiRef, smallWidgetRef, iframeRef, skipLobby) => { - const cleanupRoomId = smallWidgetRef.current?.roomId; - logger.debug(`PersistentCallContainer effect running. activeCallRoomId: ${activeCallRoomId}`); + const setupWidget = useCallback( + (widgetApiRef, smallWidgetRef, iframeRef, skipLobby) => { + const cleanupRoomId = smallWidgetRef.current?.roomId; + logger.debug(`PersistentCallContainer effect running. activeCallRoomId: ${activeCallRoomId}`); - /** - * TODO: - * Need proper shutdown handling. Events from the previous widget can still come through it seems. Might need - * to queue the events and then allow the join to actually occur. This will *work* for now as it does handle switching technically. - * Need to look closer at it. - * - * Might also be able to keep the iframe alive and instead navigate to a new "room" to make the transition smoother - */ - const cleanup = () => { - //logger.error(`CallContext: Cleaning up for previous room: ${cleanupRoomId}`); + /** + * TODO: + * Need proper shutdown handling. Events from the previous widget can still come through it seems. Might need + * to queue the events and then allow the join to actually occur. This will *work* for now as it does handle switching technically. + * Need to look closer at it. + * + * Might also be able to keep the iframe alive and instead navigate to a new "room" to make the transition smoother + */ + const cleanup = () => { + // logger.error(`CallContext: Cleaning up for previous room: ${cleanupRoomId}`); - if (smallWidgetRef.current) { - // smallWidgetRef.current.stopMessaging(); - } - // Potentially call widgetApi.stop() or similar if the API instance has it - if (widgetApiRef.current) { - // widgetApiRef.current.stop?.(); - } - //widgetApiRef.current = null; - //smallWidgetRef.current = null; - //if (iframeRef.current) iframeRef.current.src = 'about:blank'; - }; - - if (activeCallRoomId && mx?.getUserId()) { - if (cleanupRoomId !== activeCallRoomId && !isCallActive) { - const newUrl = getWidgetUrl(mx, roomId, clientConfig.elementCallUrl ?? '', { - skipLobby, - returnToLobby: 'true', - perParticipentE2EE: 'true', - }); - if (iframeRef.current && iframeRef.current.src !== newUrl.toString()) { - logger.info( - `PersistentCallContainer: Updating iframe src for ${activeCallRoomId} to ${newUrl.toString()}` - ); - cleanup(); - iframeRef.current.src = newUrl.toString(); - } else if (iframeRef.current && !iframeRef.current.src) { - logger.info( - `PersistentCallContainer: Setting initial iframe src for ${activeCallRoomId} to ${newUrl.toString()}` - ); - iframeRef.current.src = newUrl.toString(); + if (smallWidgetRef.current) { + // smallWidgetRef.current.stopMessaging(); } - - const iframeElement = iframeRef.current; - if (!iframeElement) { - logger.error('PersistentCallContainer: iframeRef is null, cannot setup API.'); - return cleanup; + // Potentially call widgetApi.stop() or similar if the API instance has it + if (widgetApiRef.current) { + // widgetApiRef.current.stop?.(); } + // widgetApiRef.current = null; + // smallWidgetRef.current = null; + // if (iframeRef.current) iframeRef.current.src = 'about:blank'; + }; - const userId = mx.getUserId() ?? ''; - const app = createVirtualWidget( - mx, - `element-call-${activeCallRoomId}-${Date.now()}`, - userId, - 'Element Call', - 'm.call', - newUrl, - false, - getWidgetData(mx, activeCallRoomId, {}, { skipLobby: true }), - activeCallRoomId - ); - - logger.debug( - `PersistentCallContainer: Creating new SmallWidget/API for ${activeCallRoomId}` - ); - const smallWidget = new SmallWidget(app); - smallWidgetRef.current = smallWidget; - - try { - const widgetApiInstance = smallWidget.startMessaging(iframeElement); - widgetApiRef.current = widgetApiInstance; - if (skipLobby) registerActiveClientWidgetApi(activeCallRoomId, widgetApiRef.current); - widgetApiInstance.once('ready', () => { - logger.info(`PersistentCallContainer: Widget for ${activeCallRoomId} is ready.`); + if (mx?.getUserId()) { + if ( + (isCallActive && activeCallRoomId !== viewedCallRoomId) || + // && backupIframeRef.current && primaryIframeRef.current.src + (cleanupRoomId !== activeCallRoomId && !isCallActive) + ) { + //logger.error('PersistentCallContainer Re-render'); + const roomIdToSet = skipLobby ? activeCallRoomId : viewedCallRoomId; + const newUrl = getWidgetUrl(mx, roomIdToSet, clientConfig.elementCallUrl ?? '', { + skipLobby: skipLobby.toString(), + returnToLobby: 'true', + perParticipentE2EE: 'true', }); - } catch (error) { - logger.error( - `PersistentCallContainer: Error initializing widget messaging for ${activeCallRoomId}:`, - error + if (iframeRef.current && iframeRef.current.src !== newUrl.toString()) { + logger.info( + `PersistentCallContainer: Updating iframe src for ${roomIdToSet} to ${newUrl.toString()}` + ); + cleanup(); + iframeRef.current.src = newUrl.toString(); + } else if (iframeRef.current && !iframeRef.current.src) { + logger.info( + `PersistentCallContainer: Setting initial iframe src for ${roomIdToSet} to ${newUrl.toString()}` + ); + iframeRef.current.src = newUrl.toString(); + } + + const iframeElement = iframeRef.current; + if (!iframeElement) { + logger.error('PersistentCallContainer: iframeRef is null, cannot setup API.'); + return cleanup; + } + + const userId = mx.getUserId() ?? ''; + const app = createVirtualWidget( + mx, + `element-call-${roomIdToSet}-${Date.now()}`, + userId, + 'Element Call', + 'm.call', + newUrl, + true, + getWidgetData(mx, roomIdToSet, {}, { skipLobby: true }), + roomIdToSet ); - cleanup(); - } - } else { - /* + + logger.error(`PersistentCallContainer: Creating new SmallWidget/API for ${roomIdToSet}`); + const smallWidget = new SmallWidget(app); + smallWidgetRef.current = smallWidget; + + try { + const widgetApiInstance = smallWidget.startMessaging(iframeElement); + widgetApiRef.current = widgetApiInstance; + logger.error('Pre-register'); + + logger.error(`This is our check: ${skipLobby}`); + if (skipLobby) { + registerActiveClientWidgetApi(activeCallRoomId, widgetApiRef.current); + } else { + registerViewedClientWidgetApi(viewedCallRoomId, widgetApiRef.current); + logger.error('Post view register'); + } + + widgetApiInstance.once('ready', () => { + logger.info(`PersistentCallContainer: Widget for ${roomIdToSet} is ready.`); + }); + } catch (error) { + logger.error( + `PersistentCallContainer: Error initializing widget messaging for ${roomIdToSet}:`, + error + ); + cleanup(); + } + } else { + /* if (iframeRef.current && iframeRef.current.src !== 'about:blank') { logger.info('PersistentCallContainer: No active call, setting src to about:blank'); iframeRef.current.src = 'about:blank'; } */ - cleanup(); + cleanup(); + } } - } - return cleanup; - }; + return cleanup; + }, + [ + activeCallRoomId, + mx, + viewedCallRoomId, + isCallActive, + clientConfig.elementCallUrl, + registerActiveClientWidgetApi, + registerViewedClientWidgetApi, + ] + ); useEffect(() => { - setupWidget(widgetApiRef, smallWidgetRef, iframeRef, true); - setupWidget(backupWidgetApiRef, backupSmallWidgetRef, backupIframeRef, false); - }); + logger.error(`This is our param: ${isPrimaryIframe}`); + setupWidget(primaryWidgetApiRef, primarySmallWidgetRef, primaryIframeRef, isPrimaryIframe); + setupWidget(backupWidgetApiRef, backupSmallWidgetRef, backupIframeRef, !isPrimaryIframe); + }, [ + setupWidget, + primaryWidgetApiRef, + primarySmallWidgetRef, + primaryIframeRef, + backupWidgetApiRef, + backupSmallWidgetRef, + backupIframeRef, + registerActiveClientWidgetApi, + registerViewedClientWidgetApi, + activeCallRoomId, + viewedCallRoomId, + isCallActive, + isPrimaryIframe, + ]); + + const memoizedIframeRef = useMemo(() => primaryIframeRef, [primaryIframeRef]); + const memoizedBackupIframeRef = useMemo(() => backupIframeRef, [backupIframeRef]); return ( - - - + + + -