/** * Utilitário para gerenciar abertura de CallWindow em nova janela */ export interface CallWindowOptions { width?: number; height?: number; left?: number; top?: number; features?: string; } export interface CallWindowData { chamadaId: string; conversaId: string; tipo: 'audio' | 'video'; roomName: string; ehAnfitriao: boolean; } const DEFAULT_OPTIONS: Required = { width: 1280, height: 720, left: undefined, top: undefined, features: 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes' }; /** * Calcular posição centralizada da janela */ function calcularPosicaoCentralizada(width: number, height: number): { left: number; top: number } { const left = window.screenX + (window.outerWidth - width) / 2; const top = window.screenY + (window.outerHeight - height) / 2; return { left, top }; } /** * Abrir CallWindow em nova janela do navegador */ export function abrirCallWindowEmPopup( data: CallWindowData, options: CallWindowOptions = {} ): Window | null { const opts = { ...DEFAULT_OPTIONS, ...options }; // Calcular posição se não fornecida let left = opts.left; let top = opts.top; if (left === undefined || top === undefined) { const posicao = calcularPosicaoCentralizada(opts.width, opts.height); left = left ?? posicao.left; top = top ?? posicao.top; } // Construir features da janela const features = [ `width=${opts.width}`, `height=${opts.height}`, `left=${left}`, `top=${top}`, opts.features ].join(','); // Criar URL com dados da chamada const url = new URL('/call', window.location.origin); url.searchParams.set('chamadaId', data.chamadaId); url.searchParams.set('conversaId', data.conversaId); url.searchParams.set('tipo', data.tipo); url.searchParams.set('roomName', data.roomName); url.searchParams.set('ehAnfitriao', String(data.ehAnfitriao)); // Abrir janela const popup = window.open(url.toString(), `call-${data.chamadaId}`, features); if (!popup) { console.error('Falha ao abrir popup. Verifique se o bloqueador de popups está desabilitado.'); return null; } // Focar na nova janela popup.focus(); // Configurar comunicação via postMessage configurarComunicacaoPopup(popup, data); return popup; } /** * Configurar comunicação entre janelas usando postMessage */ function configurarComunicacaoPopup(popup: Window, data: CallWindowData): void { // Listener para mensagens da janela popup const messageHandler = (event: MessageEvent) => { // Verificar origem if (event.origin !== window.location.origin) { return; } // Verificar se a mensagem é da janela popup if (event.data?.source === 'call-window-popup') { switch (event.data.type) { case 'ready': console.log('CallWindow popup está pronto'); break; case 'closed': console.log('CallWindow popup foi fechado'); window.removeEventListener('message', messageHandler); break; case 'error': console.error('Erro na CallWindow popup:', event.data.error); break; } } }; window.addEventListener('message', messageHandler); // Detectar quando a janela é fechada const checkClosed = setInterval(() => { if (popup.closed) { clearInterval(checkClosed); window.removeEventListener('message', messageHandler); console.log('CallWindow popup foi fechado pelo usuário'); } }, 1000); } /** * Verificar se popups estão habilitados */ export function verificarSuportePopup(): boolean { if (typeof window === 'undefined') { return false; } // Tentar abrir um popup de teste const testPopup = window.open('about:blank', '_blank', 'width=1,height=1'); if (!testPopup) { return false; } // Fechar popup de teste testPopup.close(); return true; } /** * Obter dados da chamada da URL (para uso na página de popup) */ export function obterDadosChamadaDaUrl(): CallWindowData | null { if (typeof window === 'undefined') { return null; } const params = new URLSearchParams(window.location.search); const chamadaId = params.get('chamadaId'); const conversaId = params.get('conversaId'); const tipo = params.get('tipo'); const roomName = params.get('roomName'); const ehAnfitriao = params.get('ehAnfitriao'); if (!chamadaId || !conversaId || !tipo || !roomName) { return null; } if (tipo !== 'audio' && tipo !== 'video') { return null; } return { chamadaId, conversaId, tipo, roomName, ehAnfitriao: ehAnfitriao === 'true' }; } /** * Notificar janela pai sobre eventos */ export function notificarJanelaPai(type: string, data?: unknown): void { if (typeof window === 'undefined' || !window.opener) { return; } window.opener.postMessage( { source: 'call-window-popup', type, data }, window.location.origin ); }