CreaRack-SL

Jitsi: modal flotante dragable con aviso automático al chat

Jitsi: modal flotante dragable con aviso automático al chat

Resumen

Rediseño completo del modal de reunión Jitsi en el workspace interno de CreaRack (PR #59, commit 25e2515). El modal deja de ser una ventana full-screen con backdrop opaco y se convierte en una ventana flotante que coexiste con el resto del workspace, soporta arrastre, redimensionado y minimización.

Adicionalmente, al abrir una reunión se envía un aviso automático al chat del equipo para que los otros miembros (Dani, Txell) sean notificados sin necesidad de invitar manualmente.


Comportamiento del modal flotante

Dimensiones y posición inicial

ParámetroValor
Tamaño por defecto640 × 480 px
Tamaño mínimo360 × 280 px
Altura minimizado56 px (solo header)
Posición inicialCentrada horizontalmente, 1/3 desde arriba
z-index1000 (flota sobre workspace, no bloquea nada que quede al lado)

Funcionalidades de interacción

  • Drag del header: PointerEvents con setPointerCapture / releasePointerCapture. Soporta tanto mouse como touch. La posición se restringe mediante clampPos para que la ventana nunca salga del viewport. No hay drag si está minimizado.
  • Resize desde esquina inferior derecha: handle visual estilo diagonal striped. Mismo mecanismo de pointer capture. Respeta MIN_WIDTH/MIN_HEIGHT y el margen de 16 px al borde de la ventana.
  • Minimizar / Restaurar: oculta el cuerpo del modal (display: none) pero no desmonta el iframe, manteniendo la sesión Jitsi activa. La transición de altura (0.18s ease) solo se aplica al colapsar, evitando lag durante el drag.
  • Botón “Aparte”: abre la sala Jitsi en una pestaña nueva.
  • Cerrar (Esc o botón): desmonta el componente. La prop onClose viene de TeamChat.

Cambios de UX respecto al modal anterior

AspectoAntesAhora
TipoFull-screen con backdrop rgba(0,0,0,0.7) + backdropFilter: blur(4px)Ventana flotante, sin oscurecer
document.body.style.overflowSe bloqueaba ('hidden')Ya no se toca
Interacción con el resto del workspaceImposible (modal bloquea todo)Posible — ventana es movible y no opaca
MinimizaciónNo existíaHeader visible de 56 px, iframe vivo
ResizeNo existíaHandle esquina inferior derecha

Aviso automático al chat del equipo

Flujo

  1. Al montar JitsiMeetingModal, si author está definido y no se está en localhost, se ejecuta un POST /api/chat/messages.
  2. El body del mensaje: 📞 {author} ha iniciado una reunión. Únete: {origin}/?meeting=open o directamente {MEETING_URL}.
  3. announcedRef (un useRef<boolean>) evita reenviar el aviso si el modal se cierra y se reabre en la misma sesión de página.
  4. Errores de red se silencian (.catch(() => {})); la reunión puede continuar aunque falle el anuncio.

Condición de guarda: localhost

if (typeof window === 'undefined' || window.location.hostname === 'localhost') return;

En desarrollo local no se envía el aviso para evitar ruido en el chat real del equipo.

Integración con el polling del chat

Los receptores (Dani, Txell) ven el mensaje en el polling de 15 s del chat de equipo (implementado en TeamChat.tsx). Si tienen el tab oculto, el sistema de notificaciones existente (beep + favicon rojo, ítem 1 s77) actúa sobre este mensaje igual que sobre cualquier otro.

Prop author

TeamChat pasa me (la variable que identifica al usuario actual) como author:

{meetingOpen && <JitsiMeetingModal author={me} onClose={() => setMeetingOpen(false)} />}

Detalles de implementación relevantes

useMemo en winStyle

Los estilos inline del contenedor (position: fixed, left, top, width, height, etc.) se calculan con useMemo dependiendo de pos.x, pos.y, size.w, size.h y collapsed. Esto evita recalcular el objeto en cada render intermedio y es especialmente relevante durante el drag (muchos eventos de pointermove por segundo).

Transición condicional

transition: collapsed ? 'height 0.18s ease' : 'none',

La transición CSS solo está activa cuando se colapsa/expande. Durante el drag no hay transición para que el movimiento sea inmediato y no produzca lag visual.

Sala fija

La sala Jitsi es siempre la misma:

https://meet.jit.si/CrearackSL-Workspace-EduDaniTxell-Sala#config.prejoinPageEnabled=true

Quien entra primero la crea; los demás se unen sin signup. El flag prejoinPageEnabled=true mantiene la pantalla de vista previa antes de entrar.


Archivos afectados

ArchivoTipo de cambio
src/components/widgets/JitsiMeetingModal.tsxReescritura completa (~174 LOC netas añadidas)
src/components/widgets/TeamChat.tsx+1 línea: añade prop author={me} al mount del modal

Véase también

  • [[workspace—que-es-workspace]]