La ventana gastaba DOS filas en cromo (titulo de macOS + barra de pestanas). Ahora es una sola: se recuperan 28 px de alto en cada ventana. - INTEGRADA AL TITULO (macOS): la ventana usa titulo en overlay y sin texto, asi que la barra ocupa esa fila. Deja libres 78 px para el semaforo (que sigue siendo el nativo) y el hueco vacio arrastra la ventana / doble clic la maximiza (data-tauri-drag-region + permiso core🪟allow-start-dragging). En Windows NO cambia nada: titulo del sistema y barra debajo, como hasta ahora (fusionarlas alli obligaria a dibujar a mano minimizar/maximizar/cerrar). Como el area util pasa a ser todo el marco, desaparece la compensacion de v1.4.2: los webviews vuelven a colocarse en 0 / TAB_BAR_H. - NOMBRES QUE SE DISTINGUEN: la web pone el mismo <title> en todas las paginas («(25) Labstream OS»), asi que las tres pestanas se llamaban igual. Ahora el nombre sale de la RUTA (mismas etiquetas que la barra superior de la web) con su emoji: Inicio, Chats, Calendario, Cliente, Proyecto, Operaciones… Si algun dia la web pone titulos por pagina, mandan esos: se limpia el contador de no leidos y el sufijo de la app y, si queda algo propio, se usa. - ANCHO ELASTICO: las pestanas se reparten el sitio y se encogen al abrir mas; por debajo de ~112 px queda solo el icono (y la x solo en la activa), con el nombre completo en el tooltip. Igual que Chrome. - REORDENAR ARRASTRANDO: con eventos de PUNTERO, no drag&drop de HTML5 (en el webview de la barra en macOS los eventos dragstart/dragover no llegan aunque se desactive el manejador nativo). El nodo se mueve en vivo y al soltar se manda el orden a Rust, que valida que sea una permutacion exacta y lo guarda. El clic que cierra el arrastre no activa la pestana. - CLIC DERECHO EN UNA PESTANA: menu NATIVO (la barra mide 40 px; uno dibujado dentro quedaria recortado) con Duplicar, Copiar enlace, Cerrar pestana, Cerrar las demas y Cerrar las de la derecha — estas dos se deshabilitan solas cuando no aplican. «Copiar enlace» usa tauri-plugin-clipboard-manager. - SENAL DE CARGA: el icono de la pestana se vuelve un aro girando mientras la pagina carga (PageLoadEvent Started/Finished), respetando prefers-reduced-motion. Verificado en el Mac con la app real: barra en la fila del titulo con el semaforo intacto, ventana movida arrastrando la barra (15,53 -> 147,243), nombres con emoji, 14 pestanas en modo solo-icono, menu contextual con sus opciones deshabilitadas donde toca, «Cerrar las demas», duplicar, y reordenar (tab-1,tab-2,tab-3 -> tab-3,tab-1,tab-2) persistido entre arranques. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Labstream OS — App de escritorio (Windows + macOS)
Cliente de escritorio para Labstream OS, hecho con Tauri 2.
Desde la v1.1.0 no es un envoltorio de una sola vista: es un shell con pestañas
(multiwebview) sobre el servidor del NAS (https://os.labstreamsas.com).
No contiene la app: el backend, la base de datos, OnlyOffice, etc. siguen en el NAS. Esto le da al equipo un cliente nativo de verdad en Windows y Mac:
- Pestañas como en un navegador: los enlaces internos con
target="_blank"(documentos, entregables, exportaciones, OnlyOffice…) abren pestaña dentro de la app — antes morían en silencio. También ⌘/Ctrl+clic y clic central. Atajos: ⌘/Ctrl+T nueva, ⌘/Ctrl+W cerrar, Ctrl+Tab rotar, ⌘/Ctrl+1…9 ir a la n. La sesión (pestañas abiertas, activa) se restaura al reabrir. - Zoom de interfaz: ⌘/Ctrl
+/−/0y Ctrl+rueda, con indicador en la barra y persistencia entre sesiones (50%–250%). - Documentos dentro de la app: los visores/editores del propio servidor (OnlyOffice, PDFs, reproductor de revisión) abren en pestañas; solo lo de OTRO origen (Drive…) sale al navegador del sistema. El login por Authentik sigue funcionando dentro.
- Notas de voz / cámara: pide permiso de micrófono y cámara (entitlements de macOS).
- Descargas (entregables, exportaciones) con el diálogo nativo de guardado.
- Bandeja del sistema: cerrar la ventana la oculta; la app sigue notificando. En macOS, el clic en el Dock también reabre la ventana, y hay menú nativo en español (Edición/Vista/Archivo) con los atajos.
- Arranque automático al iniciar sesión y sesión persistente (no re-loguea).
- Una sola instancia (release): abrirla de nuevo enfoca la ventana existente.
- Menú de opciones ⋮ (v1.2.0) en la barra — también con clic derecho sobre ella: pestañas, zoom, recargar, abrir la página en el navegador, Iniciar con el sistema (elección recordada) y Buscar actualización… con aviso del resultado. Es un popup nativo del sistema, igual en Windows y macOS, y vive solo en el shell (la web app no se toca).
La barra de pestañas vive en dist/index.html (webview local «chrome»); las
pestañas son webviews hijos tab-*. Shell ↔ Rust se hablan por eventos ls-*.
El servidor objetivo se configura en src-tauri/src/lib.rs → constante SERVER_URL.
Salidas:
- Windows → instalador
.exe(NSIS). - macOS →
.dmguniversal (funciona en Intel y Apple Silicon).
Prerrequisitos (solo para construir)
Quien instala no necesita nada (en Windows, WebView2 ya viene en Win 10/11; en Mac, el WebView del sistema). Para construir hacen falta:
- Node.js 20+
- Rust (incluye
cargo) - En Windows: "Visual Studio Build Tools" con el componente de C++.
- En Mac: Xcode Command Line Tools (
xcode-select --install).
⚠️ Cada sistema se construye en su sistema: el
.exese compila en Windows y el.dmgen Mac. Tauri no compila de forma cruzada de manera fiable. Por eso lo normal es dejar que GitHub Actions construya ambos (ver abajo). Como excepción cómoda: si trabajas en Mac, el.dmgsí lo puedes hacer en local.
Construir los instaladores con GitHub Actions (recomendado)
Genera ambos instaladores sin tener las dos máquinas a mano:
- Sube este proyecto a su propio repositorio (ej.
Labstream2026/labstream-desktop). - Cambia la versión en dos sitios (deben coincidir):
src-tauri/tauri.conf.json→"version"src-tauri/Cargo.toml→version- (opcional)
package.json→"version"
- Crea y publica la etiqueta de versión:
git commit -am "Versión 1.1.0" git tag v1.1.0 git push origin main --tags - GitHub Actions construye el
.exe(Windows) y el.dmg(macOS) en paralelo y los publica juntos en Releases:https://github.com/Labstream2026/labstream-desktop/releases.
También puedes lanzarlo a mano sin etiqueta desde Actions → Build instaladores → Run workflow (los instaladores quedan como artifacts).
Construir en local
En Mac (tu máquina) → genera el .dmg
npm install
npm run icons
npm run tauri build -- --bundles dmg
El .dmg queda en:
src-tauri/target/release/bundle/dmg/Labstream OS_<versión>_<arch>.dmg
Para un
.dmguniversal (Intel + Apple Silicon) en local:rustup target add aarch64-apple-darwin x86_64-apple-darwin npm run tauri build -- --target universal-apple-darwin --bundles dmg
En una PC Windows → genera el .exe
npm install
npm run tauri build -- --bundles nsis
Queda en src-tauri/target/release/bundle/nsis/Labstream OS_<versión>_x64-setup.exe.
Para desarrollo con recarga en caliente (en cualquier sistema): npm run dev.
Versiones (SemVer)
Se usa MAYOR.MENOR.PARCHE:
| Cambio | Ejemplo |
|---|---|
| Corrección / arreglo | 1.0.0 → 1.0.1 |
| Función nueva compatible | 1.0.1 → 1.1.0 |
| Cambio grande / incompatible | 1.1.0 → 2.0.0 |
La versión del envoltorio es independiente de la de la app web
(labstream-os). Una sola etiqueta de versión genera el instalador de Windows y
el de Mac a la vez, así ambas plataformas van siempre sincronizadas.
Actualización automática (opcional, recomendable a futuro)
Hoy, para actualizar, el equipo descarga el nuevo instalador del Release y lo reinstala encima. Para que las apps ya instaladas se actualicen solas, Tauri trae un updater (funciona igual en Windows y Mac). Para activarlo (paso futuro):
- Genera el par de claves de firma:
npm run tauri signer generate -- -w ~/.tauri/labstream.key - Añade el
plugin-updatery la clave pública entauri.conf.json, y guarda la clave privada como secret en GitHub (TAURI_SIGNING_PRIVATE_KEY). - Apunta el updater al
latest.jsonque publica el Release.
Se deja sin activar a propósito para que la primera versión compile sin configuración extra.
Avisos de seguridad del sistema (instalación interna sin firmar)
Como los instaladores no están firmados con certificado de pago, la primera vez cada sistema muestra una advertencia. Es normal para apps internas:
- Windows (SmartScreen): pantalla azul "Windows protegió su PC" → Más información → Ejecutar de todos modos.
- macOS (Gatekeeper): "no se puede abrir porque proviene de un desarrollador
no identificado" → clic derecho sobre la app → Abrir → Abrir. (Si
insiste, ejecutar una vez:
xattr -cr "/Applications/Labstream OS.app".)
Si en el futuro se distribuye a clientes externos, conviene firmar: code signing en Windows (~150–400 USD/año) y un Apple Developer ID + notarizado en Mac (99 USD/año) para quitar estos avisos.
Estructura
labstream-desktop/
├── app-icon.png fuente del ícono (1024×1024)
├── dist/index.html pantalla de respaldo (requerida por Tauri)
├── package.json scripts de build
├── src-tauri/
│ ├── tauri.conf.json nombre, versión, iconos, instaladores, entitlements
│ ├── Cargo.toml dependencias Rust + versión
│ ├── Info.plist textos de permiso (micrófono/cámara) en macOS
│ ├── Entitlements.plist entitlements de macOS (audio-input, cámara, red)
│ ├── build.rs
│ ├── capabilities/default.json
│ ├── icons/ se generan desde app-icon.png
│ └── src/{main.rs,lib.rs} lib.rs crea la ventana + SERVER_URL + tray
└── .github/workflows/build.yml build automático de .exe (Windows) y .dmg (macOS)