From 4e27406e250a7e0f8e69fca060dd92dad85dda9a Mon Sep 17 00:00:00 2001 From: Munka Date: Wed, 14 Oct 2026 22:05:19 -0500 Subject: [PATCH] =?UTF-8?q?1.24.0:=20la=20versi=C3=B3n=20nueva=20tambi?= =?UTF-8?q?=C3=A9n=20llega=20con=20la=20app=20abierta=20todo=20el=20d?= =?UTF-8?q?=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La app solo buscaba versión nueva al abrir: un equipo que la deja abierta de la mañana a la noche se quedaba en la de la mañana (este PC seguía en la 1.20 con la 1.23 publicada, y Rellenar con IA no le llegaba). Ahora, cada hora, mira si hay una nueva sin instalarla: la versión de la barra pasa a «Actualizar a vX» (en el color de la marca) y avisa una vez por versión. Al pulsarlo instala, se reinicia y vuelve a abrir las pestañas. No se reinicia sola en medio del trabajo. Co-Authored-By: Claude Opus 5.5 --- README.md | 6 +++++ dist/index.html | 16 +++++++++++- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/src/lib.rs | 52 +++++++++++++++++++++++++++++++++++++++ src-tauri/tauri.conf.json | 2 +- 7 files changed, 77 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ae20419..404f103 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,12 @@ guardada como secret del repo (`TAURI_SIGNING_PRIVATE_KEY`). También se puede f la comprobación con clic en la versión de la barra, o desde el menú ⋮ ▸ *Buscar actualización…*. +Al **abrir**, la app busca versión nueva y, si la hay, la instala y se reinicia sola. Con la +app **abierta** (desde la 1.24) mira cada hora sin instalar nada: si hay una nueva, la versión +de la barra pasa a **«Actualizar a vX»** (en el color de la marca) y avisa una vez. Al pulsarlo +instala, se reinicia y vuelve a abrir las pestañas. No se reinicia sola en medio del trabajo: +se perdería lo que una página no hubiera guardado. + > ⚠️ De ahí se sigue algo que conviene tener presente: **un commit en `main` no le > llega a nadie**. Mientras no exista la etiqueta `vX.Y.Z`, el CI no construye nada y > el updater no ve versión nueva. Y al revés: publicar una etiqueta **actualiza la app diff --git a/dist/index.html b/dist/index.html index a636926..e1f27c1 100644 --- a/dist/index.html +++ b/dist/index.html @@ -333,6 +333,14 @@ border-radius: 13px; } #version:hover { color: var(--accent); } + /* Hay una versión nueva publicada: el botón la ofrece (clic: instala y reinicia). */ + #version.nueva { + color: #fff; + background: var(--accent); + font-weight: 600; + padding: 0 10px; + } + #version.nueva:hover { color: #fff; filter: brightness(1.1); } /* ── Botones de ventana ────────────────────────────────────────────────────────── Solo en Windows: allí la ventana va SIN decoración, así que esta barra es la fila del título (como Chrome) y el aspa del sistema no existe. Medidas y colores del @@ -595,7 +603,13 @@ $pct.textContent = estado.zoom + "%"; $pct.classList.toggle("activo", estado.zoom !== 100); - $ver.textContent = estado.version ? "v" + estado.version : ""; + // Con una versión nueva esperando, el botón la ofrece; si no, la versión de ahora. + const nueva = estado.actualizacion || null; + $ver.textContent = nueva ? "Actualizar a v" + nueva : estado.version ? "v" + estado.version : ""; + $ver.classList.toggle("nueva", !!nueva); + $ver.title = nueva + ? "Hay una versión nueva (" + nueva + "): clic para instalarla. La app se reinicia y vuelve a abrir tus pestañas." + : "Versión de la app · clic: buscar actualización"; // Tema: manda el de la APP (payload `dark`). Mientras Rust no sepa nada (null), // no se pone clase y siguen las media queries del sistema como arranque en frío. if (typeof estado.dark === "boolean") { diff --git a/package.json b/package.json index b46a793..9e0caae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "labstream-desktop", - "version": "1.23.0", + "version": "1.24.0", "private": true, "description": "App de escritorio (Windows) que envuelve Labstream OS — cliente del servidor del NAS.", "scripts": { diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 5fe58c4..54ec9be 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2367,7 +2367,7 @@ dependencies = [ [[package]] name = "labstream-desktop" -version = "1.23.0" +version = "1.24.0" dependencies = [ "active-win-pos-rs", "device_query", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 734696e..185081c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "labstream-desktop" -version = "1.23.0" +version = "1.24.0" description = "Cliente de escritorio de Labstream OS" authors = ["Labstream SAS"] edition = "2021" diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 20f1544..7c66c7e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -704,6 +704,8 @@ fn broadcast(app: &AppHandle) { "tabs": tabs, "zoom": (ZOOM_STEPS[s.zoom_idx.min(ZOOM_STEPS.len()-1)] * 100.0).round() as u32, "version": app.package_info().version.to_string(), + // La versión nueva que ya está publicada y espera a que se pulse «Actualizar» (o null). + "actualizacion": version_pendiente(), // En macOS la barra ocupa la fila del título (ventana con título en overlay) y // debe dejar libre el hueco del semáforo, que lo pinta el sistema. "mac": cfg!(target_os = "macos"), @@ -1557,6 +1559,47 @@ fn show_main(app: &AppHandle) { } } +// ── La versión nueva, también con la app abierta todo el día (1.24, 14-oct-2026) ── +// Al abrir, la app busca versión nueva y, si hay, la instala y se reinicia (antes de que nadie +// trabaje). Pero solo al abrir: un equipo que deja la app abierta de la mañana a la noche se +// quedaba en la versión de la mañana (este PC seguía en la 1.20 con la 1.23 publicada, y Rellenar +// con IA no le llegaba). Ahora, cada hora, mira si hay una nueva SIN instalarla —reiniciar en +// medio del trabajo perdería lo que no se guardó en una página—: la barra cambia la versión por +// «Actualizar a vX» (el mismo botón de siempre: instala y reinicia, y las pestañas vuelven) y +// avisa una vez por versión. +const BUSCAR_CADA: Duration = Duration::from_secs(60 * 60); +static PENDIENTE: Mutex> = Mutex::new(None); + +fn version_pendiente() -> Option { + PENDIENTE.lock().ok().and_then(|p| p.clone()) +} + +#[cfg(desktop)] +async fn buscar_sin_instalar(handle: tauri::AppHandle) { + use tauri_plugin_updater::UpdaterExt; + let Ok(updater) = handle.updater() else { return }; + let nueva = match updater.check().await { + Ok(Some(u)) => u.version, + Ok(None) => return, + Err(e) => { + salud::anotar("AVISO", "actualizacion", &format!("no se pudo comprobar: {e}")); + return; + } + }; + let ya = PENDIENTE.lock().map(|mut p| p.replace(nueva.clone())).unwrap_or(None); + if ya.as_deref() == Some(nueva.as_str()) { + return; + } + salud::anotar("INFO", "actualizacion", &format!("hay versión nueva ({nueva}): espera a que se pulse «Actualizar»")); + broadcast(&handle); + let _ = handle + .notification() + .builder() + .title("Labstream OS") + .body(format!("Hay una versión nueva ({nueva}). Pulsa «Actualizar» en la barra de pestañas: la app se reinicia y vuelve a abrir tus pestañas.")) + .show(); +} + // Busca e instala una actualización en segundo plano. Si instala, avisa y reinicia. #[cfg(desktop)] async fn check_update(handle: tauri::AppHandle) { @@ -1725,6 +1768,15 @@ pub fn run() { let handle = app.handle().clone(); tauri::async_runtime::spawn(check_update(handle)); } + // Y después, cada hora, sin instalarla: la barra ofrece «Actualizar» (ver PENDIENTE). + #[cfg(desktop)] + { + let handle = app.handle().clone(); + std::thread::spawn(move || loop { + std::thread::sleep(BUSCAR_CADA); + tauri::async_runtime::block_on(buscar_sin_instalar(handle.clone())); + }); + } { let shell = handle.state::(); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f8fdc5e..9c5fa31 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Labstream OS", - "version": "1.23.0", + "version": "1.24.0", "identifier": "co.labstream.os", "build": { "frontendDist": "../dist"