Volver a la wiki

ADR: MeetingRoom pasa de modal flotante a popup window (2026-05-22)

ADR 2026-05-22: MeetingRoom pasa de modal flotante embebido a popup window

Estado

Aceptada — implementada en s80 (22-05-2026).


Contexto

El componente MeetingRoom (introducido en s79 como reemplazo de Jitsi — ver [[decision—20260522—webrtc-reemplaza-jitsi]]) vivía como modal flotante dentro del workspace: createPortal(..., document.body) + position: fixed, draggable, redimensionable, con modo colapsado. Visualmente flotante, pero lógicamente hijo del componente TeamChat que se monta en el home /.

Problema reportado por Edu (22-05-2026)

“El modal de videollamada se pierde cuando cambias de página en el WS. Debería ser un proceso flotante independientemente de la página del navegador, así podremos abrir y trabajar en el WS sin que se pierda el modal de videollamada, incluso esto permitiría desplazarlo al segundo monitor seguramente.”

Causa raíz: el workspace es un sitio Astro output: 'static' sin ClientRouter/View Transitions. Cada navegación entre páginas (home → wiki → /tools → home) hace un full page reload del navegador. El island React que aloja TeamChat se desmonta, y con él el MeetingRoom: tracks de cámara parados, RTCPeerConnection cerradas, mensaje peer_left enviado al signaling. La sesión muere y los otros peers (Dani, Txell) ven al usuario desconectarse aunque sólo estuviera cambiando de pestaña dentro del propio WS.

Opciones evaluadas

OpciónSobrevive a nav WSSegundo monitorCoste implementaciónCompatibilidad
Popup window (window.open(..., 'popup=yes,...'))✅ ventana SO independiente✅ arrastrableBaja (nueva ruta /reunion, refactor componente)Universal (con popup blocker opt-in)
Document Picture-in-Picture API⚠️ muere si pestaña padre navega⚠️ solo en stacking propioMediaSolo Chromium (no Firefox/Safari)
Astro ClientRouter + transition:persist✅ dentro del WS❌ noAlta (refactor layout invasivo)Universal pero F5/URL externa lo mata igualmente

Decisión

Popup window dedicado. Se crea la ruta /reunion (página Astro standalone con AppLayout minimal, sin Sidebar/BottomNav del WS) y TeamChat reemplaza el render inline del modal por window.open('/reunion?author=...&target=...', 'crearack-meeting', 'popup=yes,width=1100,height=720,left=...,top=...').

El popup vive como una ventana del sistema operativo independiente del WS:


Consecuencias

Positivas

Negativas / riesgos


Implementación

Archivos nuevos

ArchivoPropósito
src/pages/reunion.astroRuta standalone, AppLayout sin chrome, html/body 100vh + overflow:hidden
src/components/widgets/MeetingRoomShell.tsxLee query params (author, target, silent), monta MeetingRoom, onClose → window.close()

Archivos modificados

ArchivoCambio
src/components/widgets/MeetingRoom.tsxQuitado createPortal, drag/resize, collapsed, clampPos, refs de posición/tamaño. Añadido listener beforeunload/pagehide con sendBeacon. Ocupa 100% del viewport del popup vía position: fixed; inset: 0.
src/components/widgets/TeamChat.tsxHelper openMeetingPopup(author, target, silent) usa window.open(...) con name 'crearack-meeting'. Eliminados estados meetingOpen/Target/Silent y el render inline <MeetingRoom>. Handler de URL ?meeting=open ahora abre popup en vez de set state.

Trabajo futuro pendiente


Véase también

Subir