mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-06 07:20:29 +03:00
Add backupIframeRef so we can re-add the lobby screen for non-joined calls (for viewing their text channels)
This commit is contained in:
parent
0be5fb9732
commit
a690dbd2ca
1 changed files with 29 additions and 25 deletions
|
|
@ -1,9 +1,10 @@
|
||||||
import { Room } from 'matrix-js-sdk';
|
import { Room } from 'matrix-js-sdk';
|
||||||
import React from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useCallback, useEffect, useRef } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { useOutletContext } from 'react-router-dom';
|
import { useOutletContext } from 'react-router-dom';
|
||||||
import { Box } from 'folds';
|
import { Box } from 'folds';
|
||||||
import { RoomViewHeader } from './RoomViewHeader';
|
import { RoomViewHeader } from './RoomViewHeader';
|
||||||
|
import { useCallState } from '../../pages/client/CallProvider';
|
||||||
|
|
||||||
function debounce<F extends (...args: any[]) => any>(func: F, waitFor: number) {
|
function debounce<F extends (...args: any[]) => any>(func: F, waitFor: number) {
|
||||||
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
@ -28,23 +29,30 @@ type OriginalStyles = {
|
||||||
border?: string;
|
border?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface CallViewOutletContext {
|
||||||
|
iframeRef: React.RefObject<HTMLIFrameElement | null>;
|
||||||
|
backupIframeRef: React.RefObject<HTMLIFrameElement | null>;
|
||||||
|
}
|
||||||
|
|
||||||
export function CallView({ room, eventId }: { room: Room; eventId?: string }) {
|
export function CallView({ room, eventId }: { room: Room; eventId?: string }) {
|
||||||
const { iframeRef } = useOutletContext<{
|
const { iframeRef, backupIframeRef } = useOutletContext<CallViewOutletContext>();
|
||||||
iframeRef: React.RefObject<HTMLIFrameElement | null>;
|
|
||||||
}>();
|
|
||||||
const iframeHostRef = useRef<HTMLDivElement>(null);
|
const iframeHostRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const originalIframeStylesRef = useRef<OriginalStyles | null>(null);
|
const originalIframeStylesRef = useRef<OriginalStyles | null>(null);
|
||||||
|
const { activeCallRoomId, isPrimaryIframe } = useCallState();
|
||||||
|
const isViewingActiveCall = useMemo(
|
||||||
|
() => activeCallRoomId !== null && activeCallRoomId === room.roomId,
|
||||||
|
[activeCallRoomId]
|
||||||
|
);
|
||||||
|
|
||||||
const shouldDisplayCallIFrame =
|
const activeIframeDisplayRef =
|
||||||
room && typeof room.isCallRoom === 'function' && room.isCallRoom();
|
!isPrimaryIframe || isViewingActiveCall ? iframeRef : backupIframeRef;
|
||||||
|
|
||||||
const applyFixedPositioningToIframe = useCallback(() => {
|
const applyFixedPositioningToIframe = useCallback(() => {
|
||||||
const iframeElement = iframeRef?.current;
|
const iframeElement = activeIframeDisplayRef?.current;
|
||||||
const hostElement = iframeHostRef?.current;
|
const hostElement = iframeHostRef?.current;
|
||||||
|
|
||||||
if (iframeElement && hostElement) {
|
if (iframeElement && hostElement) {
|
||||||
// Save original styles only ONCE per "portaling" session
|
|
||||||
if (!originalIframeStylesRef.current) {
|
if (!originalIframeStylesRef.current) {
|
||||||
const computed = window.getComputedStyle(iframeElement);
|
const computed = window.getComputedStyle(iframeElement);
|
||||||
originalIframeStylesRef.current = {
|
originalIframeStylesRef.current = {
|
||||||
|
|
@ -63,29 +71,27 @@ export function CallView({ room, eventId }: { room: Room; eventId?: string }) {
|
||||||
|
|
||||||
const hostRect = hostElement.getBoundingClientRect();
|
const hostRect = hostElement.getBoundingClientRect();
|
||||||
|
|
||||||
// Apply fixed positioning relative to the viewport, but aligned with the host
|
|
||||||
iframeElement.style.position = 'fixed';
|
iframeElement.style.position = 'fixed';
|
||||||
iframeElement.style.top = `${hostRect.top}px`;
|
iframeElement.style.top = `${hostRect.top}px`;
|
||||||
iframeElement.style.left = `${hostRect.left}px`;
|
iframeElement.style.left = `${hostRect.left}px`;
|
||||||
iframeElement.style.width = `${hostRect.width}px`;
|
iframeElement.style.width = `${hostRect.width}px`;
|
||||||
iframeElement.style.height = `${hostRect.height}px`;
|
iframeElement.style.height = `${hostRect.height}px`;
|
||||||
iframeElement.style.border = 'none';
|
iframeElement.style.border = 'none';
|
||||||
iframeElement.style.zIndex = '1000'; // Ensure it's on top
|
iframeElement.style.zIndex = '1000';
|
||||||
iframeElement.style.display = 'block';
|
iframeElement.style.display = 'block';
|
||||||
iframeElement.style.visibility = 'visible';
|
iframeElement.style.visibility = 'visible';
|
||||||
iframeElement.style.pointerEvents = 'auto';
|
iframeElement.style.pointerEvents = 'auto';
|
||||||
}
|
}
|
||||||
}, [iframeRef, iframeHostRef]);
|
}, [activeIframeDisplayRef, iframeHostRef]);
|
||||||
|
|
||||||
const debouncedApplyFixedPositioning = useCallback(debounce(applyFixedPositioningToIframe, 50), [
|
const debouncedApplyFixedPositioning = useCallback(debounce(applyFixedPositioningToIframe, 50), [
|
||||||
applyFixedPositioningToIframe,
|
applyFixedPositioningToIframe,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const iframeElement = iframeRef?.current;
|
const iframeElement = activeIframeDisplayRef?.current;
|
||||||
const hostElement = iframeHostRef?.current;
|
const hostElement = iframeHostRef?.current;
|
||||||
|
|
||||||
if (shouldDisplayCallIFrame && iframeElement && hostElement) {
|
if (isPrimaryIframe || (isViewingActiveCall && iframeElement && hostElement)) {
|
||||||
applyFixedPositioningToIframe();
|
applyFixedPositioningToIframe();
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver(debouncedApplyFixedPositioning);
|
const resizeObserver = new ResizeObserver(debouncedApplyFixedPositioning);
|
||||||
|
|
@ -99,32 +105,30 @@ export function CallView({ room, eventId }: { room: Room; eventId?: string }) {
|
||||||
if (iframeElement && originalIframeStylesRef.current) {
|
if (iframeElement && originalIframeStylesRef.current) {
|
||||||
const originalStyles = originalIframeStylesRef.current;
|
const originalStyles = originalIframeStylesRef.current;
|
||||||
(Object.keys(originalStyles) as Array<keyof OriginalStyles>).forEach((key) => {
|
(Object.keys(originalStyles) as Array<keyof OriginalStyles>).forEach((key) => {
|
||||||
iframeElement.style[key] = originalStyles[key] || '';
|
if (key in iframeElement.style) {
|
||||||
|
iframeElement.style[key as any] = originalStyles[key] || '';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
originalIframeStylesRef.current = null;
|
originalIframeStylesRef.current = null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (iframeElement && originalIframeStylesRef.current) {
|
|
||||||
const originalStyles = originalIframeStylesRef.current;
|
|
||||||
(Object.keys(originalStyles) as Array<keyof OriginalStyles>).forEach((key) => {
|
|
||||||
iframeElement.style[key] = originalStyles[key] || '';
|
|
||||||
});
|
|
||||||
originalIframeStylesRef.current = null;
|
|
||||||
}
|
|
||||||
}, [
|
}, [
|
||||||
shouldDisplayCallIFrame,
|
activeIframeDisplayRef,
|
||||||
iframeRef,
|
|
||||||
applyFixedPositioningToIframe,
|
applyFixedPositioningToIframe,
|
||||||
debouncedApplyFixedPositioning,
|
debouncedApplyFixedPositioning,
|
||||||
|
isPrimaryIframe,
|
||||||
|
isViewingActiveCall,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const isCallViewVisible = room.isCallRoom();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
direction="Column"
|
direction="Column"
|
||||||
style={{
|
style={{
|
||||||
width: '60%',
|
width: '60%',
|
||||||
display: room.isCallRoom() ? 'flex' : 'none',
|
display: isCallViewVisible ? 'flex' : 'none',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RoomViewHeader />
|
<RoomViewHeader />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue