200 lines
4.7 KiB
TypeScript
200 lines
4.7 KiB
TypeScript
/**
|
|
* 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<CallWindowOptions> = {
|
|
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
|
|
);
|
|
}
|