Gráfico de commits

19 Commits

Autor SHA1 Mensaje Fecha
Munka
29f0b47371 Version 1.7.0
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 10:36:46 -05:00
Munka
b18c155b89 La barra obedece a la app, no a Windows: tema real + acento naranja
El bug de «siempre oscura»: la web decide su modo con su propio botón
(next-themes, defaultTheme claro, sin seguir al sistema), pero la barra
elegía tema con prefers-color-scheme — el del SISTEMA. Con Windows en
oscuro y la app en claro, franja negra sobre app blanca, siempre. La
v1.6.1 pintó bien ambos temas, pero la barra seguía eligiendo el
equivocado.

El arreglo, de punta a punta:

- El script inyectado reporta en ls-title si <html> lleva la clase
  `dark`, con un MutationObserver para que la luna se refleje al
  instante. La guarda de marco y origen queda intacta (OnlyOffice).
- Rust lo guarda (global: todas las pestañas comparten modo), lo
  reenvía en ls-tabs (`dark`) y lo PERSISTE en estado.json: la app
  abre ya del color correcto, sin fogonazo.
- La barra se pone la clase `oscuro`/`claro` al recibirlo; las media
  queries quedan solo como arranque en frío (primer arranque sin
  estado.json). Los tintes de colores de pestaña cuelgan del mismo
  interruptor.
- El acento pasa de índigo #6366f1 (comentado «color de Labstream»,
  que no lo era) al naranja de marca #F47A20: aro de carga, zoom
  activo y hover de la versión.

Verificado en navegador con el CSS y el JS reales, simulando el
payload de Rust: app clara + sistema oscuro → barra clara; app
oscura → negra; sin reporte → cae al sistema. El Rust lo compila el
CI de rama (este equipo no tiene cargo).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 10:22:46 -05:00
Munka
424f401ad6 Versión 1.6.1
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 15:58:00 -05:00
Munka
44898da17c Versión 1.6.0 y README al día
Sube la versión en los cuatro sitios que tienen que coincidir (package.json,
Cargo.toml, Cargo.lock y tauri.conf.json). Así el instalador de prueba se presenta
como v1.6.0 en la barra en vez de repetir v1.5.1, que al probarlo encima de la app
instalada no dejaba saber cuál se está corriendo.

El README describía el comportamiento viejo: decía que en Windows se conserva el
título del sistema con la barra debajo, y que la actualización automática era un
paso futuro cuando lleva funcionando desde la v1.4.0. Ahora cuenta lo que hay: la
barra como fila del título en ambos sistemas, los colores de pestaña, que un commit
sin etiqueta no le llega a nadie, y cómo probar un cambio con el instalador de
prueba del CI sin publicárselo al equipo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 14:19:02 -05:00
Munka
2c872ace7d Pestañas de colores, como los grupos de Chrome
Con la barra ya en la fila del título, teñir es lo que hace que un montón de
pestañas abiertas se lea de un vistazo: todo lo de un cliente en verde, lo que está
en revisión en rojo. Se elige con clic derecho sobre la pestaña ▸ Color, con marca
en el que tiene puesto, y "Sin color" para quitarlo.

Nueve colores, los mismos que usa Chrome para sus grupos. El color se guarda con la
sesión (lista `colors` en estado.json, paralela a `tabs`), así que sobrevive a
cerrar la app. Un estado.json viejo sin colores carga igual: la lista entra por
serde default y todas las pestañas salen sin teñir.

Cómo se pinta: la inactiva lleva el color de fondo translúcido y se le quita el
separador vertical (con fondo propio ya se ve dónde acaba). La ACTIVA no se tiñe
entera —tiene que seguir fundida con el contenido, que es lo que le da el aspecto de
Chrome— sino que lleva el color en una franja de 3 px arriba. En el CSS el color va
en componentes RGB sueltos (`--tc: r, g, b`) para sacar de una sola definición tanto
el tono sólido como el fondo translúcido, en vez de repetir nueve colores por tema.

Al restaurar la sesión, el color se empareja con su URL ANTES de filtrar por origen:
el filtro puede descartar entradas y entonces los índices de las dos listas dejarían
de casar, y las pestañas saldrían con el color de otra.

El id que llega del menú se valida contra la paleta antes de guardarlo; uno
desconocido deja la pestaña sin color en vez de escribir cualquier cosa en el disco.

Verificado: sintaxis del script con node --check, y en el navegador que la inactiva
se tiñe, que la activa conserva su fondo de tarjeta con la franja del color encima,
y que el separador desaparece en las teñidas. La compilación la verifica el CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 13:39:10 -05:00
Munka
9489d6cc58 Las pestañas ocupan la fila del título también en Windows
En Windows la ventana conservaba la barra de título del sistema y la barra de
pestañas iba DEBAJO: una fila entera gastada en repetir el nombre de la app. En
macOS ya no pasaba (TitleBarStyle::Overlay desde la v1.4.2). Ahora las dos se
comportan igual, y como Chrome: la barra de pestañas ES la fila del título.

- Ventana sin decoración en Windows (decorations(false)). resizable(true) conserva
  WS_THICKFRAME, así que los bordes siguen redimensionando y Aero Snap (arrastrar a
  un borde, Win+flechas) sigue vivo.
- La barra dibuja sus propios botones minimizar/maximizar/cerrar con las medidas y
  colores del sistema (46 px de ancho, alto completo de la barra, esquinas rectas,
  rojo #c42b1c al posarse en el aspa) y los glifos de Segoe Fluent Icons. Actúan
  por el evento nuevo ls-window; cerrar sigue pasando por CloseRequested, o sea que
  oculta a la bandeja igual que antes.
- El icono del medio alterna maximizar/restaurar según el estado. El repintado se
  dispara solo cuando ese estado CAMBIA, no en cada píxel del redimensionado.
- La geometría maximizada ya no se guarda entre sesiones: sin decoración, al
  reabrir volvería como ventana normal del tamaño de la pantalla y taparía la barra
  de tareas. Se conserva la última geometría restaurada.
- Doble clic en el hueco libre de la barra ahora maximiza/restaura (lo gobierna
  data-tauri-drag-region), como la barra de título del sistema y como Chrome. Antes
  abría una pestaña nueva; para eso quedan el botón + y Cmd/Ctrl+T.

NO incluye los Snap Layouts de Windows 11 (el menú que asoma al posar el cursor
sobre maximizar). Requieren que la ventana conteste WM_NCHITTEST con HTMAXBUTTON, y
aquí ese botón lo tapa el webview hijo de la barra, que se queda con los mensajes
del ratón: la ventana principal nunca los ve. Es la misma razón por la que Electron
necesita botones NATIVOS (titleBarOverlay) para poder ofrecerlo. El resto de Aero
Snap no se ve afectado.

Se añade .github/workflows/check.yml: cargo check en Windows y macOS al empujar una
rama, sin publicar nada. Hasta ahora solo existía el workflow de publicar (etiquetas
v*), así que no había forma de comprobar que algo compilaba sin sacar un release.

Verificado: sintaxis del script de la barra con node --check; medidas, clases y
estados de los botones comprobados en el navegador (46 px, pegados al borde, ocultos
en macOS, icono y rótulo correctos al maximizar, y el arrastre solo en el hueco
libre, nunca en los botones). La compilación la verifica el workflow nuevo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 12:35:10 -05:00
Jonathan David Florez Salomón
d302591c25 v1.5.1: el shell dejaba de meterse dentro del editor de OnlyOffice en Windows
OnlyOffice fallaba al editar y al descargar SOLO en la app de escritorio de
Windows. En el navegador y en la app de macOS iba bien. La causa estaba en el
propio shell, no en el servidor de documentos.

En Windows, wry inyecta los scripts de inicio en TODOS los marcos e ignora
for_main_frame_only (wry-0.55.1/src/webview2/mod.rs:492-495, documentado en su
lib.rs:990); macOS si respeta la bandera (wkwebview/mod.rs:643-645). Y __TAURI__
viaja con ellos, asi que la guarda «if (!T || !T.event) return» no frenaba nada.
Resultado: INIT_JS_TPL corria DENTRO del iframe del Document Server con ORIGIN
apuntando todavia a la app; como alli location.href es el de docs.*, cada enlace
del editor se resolvia contra ese origen, daba isExt() = true y se desviaba al
navegador del sistema —que no tiene la sesion: «no se puede acceder»—, y
window.open devolvia null.

Cambios:

1. Guarda de marco y origen al principio del script inyectado: solo actua en el
   documento PRINCIPAL y solo en el origen de la app. En macOS es un no-op (alli
   nunca corrio en subframes). De paso arregla que en Windows el shell tambien
   secuestrara los enlaces de las paginas de SSO.

2. El manejador de atajos ignora e.altKey. AltGr enciende ctrlKey en Windows, asi
   que escribir [ o ] con teclado espanol disparaba history.back()/forward() en
   vez de escribir el caracter — en el editor y en cualquier campo de la app.

3. Aviso nativo al terminar una descarga. No es un adorno: wry trae un manejador
   de descargas por defecto (wry-0.55.1/src/lib.rs:830), de modo que en WebView2
   siempre se registra DownloadStarting y siempre responde SetHandled(true)
   (webview2/mod.rs:858-861), lo que apaga la interfaz de descargas de Windows.
   El archivo bajaba a Descargas pero nada lo decia y parecia roto. Quitar el
   manejador NO devuelve la interfaz nativa: el de wry sigue puesto.

4. Feature «devtools» de tauri: el inspector queda disponible tambien en release.
   Sin el, un fallo que solo aparece en la app instalada no se puede mirar por
   dentro.

Descartado a proposito: registrar on_new_window. En macOS el delegado ejecuta
webview.window().unwrap() y current_window.screen().unwrap() ANTES del match
(wry-0.55.1/src/wkwebview/class/wry_web_view_ui_delegate.rs:150-154), tambien en
la rama Deny; y este shell oculta la ventana al cerrar, con lo que NSWindow.screen
puede ser nil y la app entera abortaria. Cambiar un fallo de Windows por un crash
en macOS no compensa.

Verificado: cargo check limpio; sintaxis del script inyectado validada con node;
y simulacion de la guarda — marco principal + origen propio interviene, iframe de
OnlyOffice no interviene, origen ajeno no interviene.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 07:12:22 -05:00
Jonathan David Florez Salomón
e7c69fe0ea Barra al estilo Notion: una sola fila, pestanas con nombre y reordenables
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>
2026-07-25 10:01:24 -05:00
Jonathan David Florez Salomón
bfc4e1172c La barra de pestanas ya no queda debajo del titulo nativo (macOS)
La barra existia pero estaba DIBUJADA DETRAS de la barra de titulo de macOS:
solo asomaban ~12 px por debajo, y como el titulo nativo es translucido hasta
se tenia del color de la barra. Con el rediseno estilo Chrome el sintoma se
volvio evidente (no se veian ni las pestanas ni los controles), pero el fallo
venia de antes: no lo causo el CSS.

Causa (medida en vivo con instrumentacion): en macOS las coordenadas de los
webviews HIJOS son relativas al MARCO de la ventana (incluye el titulo) y
ademas `inner_size()` devuelve el marco, no el area de contenido
(inner_size == outer_size e inner_position == outer_position). Al colocar la
barra en y=0 quedaba bajo el titulo, y el contenido en y=40 arrancaba 12 px
por debajo, tapando el resto.

Arreglo: `top_offset()` compensa el alto del titulo (28 pt) SOLO cuando hace
falta. La deteccion es en caliente -- si el marco y el interior miden lo mismo
hay que compensar; el dia que Tauri lo corrija la resta dejara de ser 0 y no se
compensara nada -- y en Windows/Linux devuelve 0 (ahi las coordenadas ya son
del area de cliente). Se aplica en los tres sitios que colocan webviews:
layout_all, la creacion de la barra y la creacion de cada pestana.

Verificado en el Mac con la app real: barra completa y alineada bajo el
titulo, redimensionado, pestana nueva, cierre de pestana y cambio de pestana.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 08:55:56 -05:00
Jonathan David Florez Salomón
5108b06ae1 v1.4.1: barra de pestanas al estilo Chrome
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 07:18:19 -05:00
Jonathan David Florez Salomón
d8a35f5bae Atrás/adelante en la barra + reabrir pestaña + globo de no-leídos en el icono
- ATRÁS/ADELANTE por fin: botones ← → en la barra de pestañas, ⌘[ / ⌘] en
  ambas plataformas, Alt+←/→ en Windows (fuera de campos de texto) y menú
  «Historial» en macOS. Cierra el callejón sin salida: una página sin menú
  propio (p. ej. el portal de revisión) dejaba al usuario atrapado sin forma
  de volver.
- «Reabrir pestaña cerrada» (⌘/Ctrl+Shift+T, tope de 20): en la barra ⌘⇧T
  antes caía en «nueva pestaña» por no mirar el Shift.
- Globo de NO-LEÍDOS en el icono: la web app emite `ls-badge {count}` (mismo
  conteo del «(N)» del título) y el shell pinta el número en el Dock (macOS),
  un punto rojo dibujado a mano sobre el icono de la barra de tareas (Windows,
  sin assets) y el tooltip de la bandeja («— N sin leer»).

Verificado: cargo check limpio (macOS) y firmas de las APIs solo-Windows
(set_overlay_icon, set_badge_count, Image::new_owned) cotejadas contra el
código fuente de tauri 2.11.3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 07:11:37 -05:00
Jonathan David Florez Salomón
d682b06ab9 Versión visible en la barra de la app (clic = buscar actualización)
La barra muestra la versión real del paquete (viene de Rust en el payload
ls-tabs, no quemada en el HTML) junto al menú ⋮. Clic en la etiqueta →
"Buscar actualización…" con aviso del resultado (evento ls-check-update).
Versión 1.3.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 20:02:30 -05:00
Jonathan David Florez Salomón
329ea1195e Menú de opciones ⋮ de la app (popup nativo) + preferencia de autostart
Botón ⋮ en la barra de pestañas (y clic derecho sobre ella) → menú NATIVO del
sistema, idéntico en Windows y macOS, solo del shell (la web app no se toca):

- Nueva/cerrar pestaña, recargar, acercar/alejar/tamaño real.
- "Abrir esta página en el navegador" (la pestaña activa, vía opener).
- "Iniciar con el sistema" con check: ahora la elección SE RECUERDA
  (antes el arranque re-activaba el autostart en cada apertura).
- "Buscar actualización…" manual con aviso del resultado (instalando /
  ya estás al día / sin red), además del chequeo silencioso de siempre.
- Versión visible y "Salir de Labstream OS".

El manejador de menús pasa a ser global (antes solo existía dentro del cfg de
macOS): lo comparten el menú de macOS y el popup ⋮ de ambas plataformas. El
menú de macOS gana "Buscar actualización…" y "Abrir en el navegador".

Versión 1.2.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 19:50:46 -05:00
Jonathan David Florez Salomón
2d9f14f026 Shell de pestañas: multiwebview, zoom persistente y documentos dentro de la app
La app deja de ser un envoltorio de una sola vista y pasa a ser un shell con
pestañas (multiwebview de Tauri 2, ventana "main" = barra local "chrome" +
webviews "tab-*" del servidor):

- Los enlaces internos target=_blank (documentos, entregables, OnlyOffice,
  exportaciones) abrían nada: ahora abren pestaña dentro de la app. También
  Cmd/Ctrl+clic, clic central y window.open del propio origen.
- Zoom de interfaz: Cmd/Ctrl +/−/0 y Ctrl+rueda (50%–250%), con indicador en
  la barra y persistencia entre sesiones.
- Sesión restaurada: pestañas abiertas, activa, zoom y tamaño/posición de la
  ventana vuelven al reabrir (estado.json en app_config_dir).
- Atajos: Cmd/Ctrl+T/W/R, Ctrl+Tab rota, Cmd/Ctrl+1..9; en macOS van por el
  menú nativo nuevo en español (Archivo/Edición/Vista/Ventana); en Windows
  por JS (sin barra de menú).
- macOS: clic en el Dock reabre la ventana oculta (RunEvent::Reopen).
- Una sola instancia en release (single-instance): reabrir enfoca la existente.
- Updater: avisa con notificación nativa antes de reiniciar por actualización.
- Los enlaces a OTRO origen siguen yendo al navegador del sistema y el login
  por Authentik sigue intacto (el init script se desactiva fuera del origen).

Shell ↔ Rust por eventos ls-* (core:default cubre el origen remoto; sin ACL
de comandos propios). Versión 1.1.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 15:50:04 -05:00
Jonathan David Florez Salomón
c18438fd9f Auto-actualización: plugin updater + firma + CI con tauri-action
Al abrir, la app busca en segundo plano una versión nueva en los Releases de GitHub
(latest.json), y si la hay —firmada con nuestra clave— la instala sola y reinicia.

- Cargo/lib.rs: tauri-plugin-updater + check_update() en el arranque (no bloquea).
- tauri.conf.json: bundle.createUpdaterArtifacts=true y plugins.updater con el endpoint
  (releases/latest/download/latest.json) y la clave PÚBLICA de verificación.
- CI: build.yml pasa a tauri-apps/tauri-action, que construye el .exe (Windows) y el
  .dmg universal (macOS), firma los artefactos del updater y publica todo —incluido
  latest.json— en un Release. Requiere los secrets TAURI_SIGNING_PRIVATE_KEY y
  TAURI_SIGNING_PRIVATE_KEY_PASSWORD (la clave privada NO va en el repo).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 17:29:12 -05:00
Jonathan David Florez Salomón
8e48d888e2 Cliente nativo: enlaces externos al navegador, micrófono para notas de voz, descargas
La ventana se crea ahora en Rust (lib.rs) para poder:
- Inyectar un script que manda los enlaces EXTERNOS (Drive, docs ajenos, target=_blank,
  window.open) al navegador del sistema, dejando dentro la navegación del propio
  servidor y el login por Authentik (que redirige a otro dominio y vuelve).
- Permitir descargas (entregables/exportaciones) con el diálogo nativo de guardado.
- SERVER_URL centralizado (antes en tauri.conf.json app.windows[0].url).

macOS: Info.plist con NSMicrophoneUsageDescription/NSCameraUsageDescription y
Entitlements.plist (audio-input, cámara, red, allow-jit) → las notas de voz y los
adjuntos de foto/video piden permiso y funcionan. Referenciados en bundle.macOS.

Se conserva el tray, cerrar=ocultar y el autostart. Verificado: build de macOS OK
(.app + .dmg de 3,8 MB, icono del logo, textos de permiso fusionados en Info.plist).
Los instaladores de Windows (.exe) y macOS (.dmg universal) los sigue produciendo
GitHub Actions (.github/workflows/build.yml) en cada tag de versión.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 17:19:27 -05:00
Jonathan David Florez Salomón
abd18591c1 Notificaciones nativas: plugin notification + autostart + bandeja
- tauri-plugin-notification (la web lo invoca vía window.__TAURI__ con withGlobalTauri).
- tauri-plugin-autostart: arranca al iniciar sesión.
- Bandeja del sistema (Abrir/Salir) y cerrar la ventana = ocultar a la bandeja,
  para que la app siga notificando en segundo plano.
- capabilities: notification:default + remote acotado a os.labstreamsas.com.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:21:54 -05:00
Labstream
7bb1ea092b Añadir build de macOS (.dmg universal) además de Windows
Workflow en matriz que genera .exe (NSIS) y .dmg (Intel+Apple Silicon)
en cada versión. targets=all en la config y selección por --bundles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 14:19:26 -05:00
Labstream
922299e2a5 Envoltorio de escritorio Windows (Tauri 2) para Labstream OS
Cliente delgado que abre os.labstreamsas.com en su propia ventana.
Incluye build por GitHub Actions y guía de versionado.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 14:14:03 -05:00