From f162f5ae09b41448a792ae40f1f03e2f42bad0ba Mon Sep 17 00:00:00 2001 From: Munka Date: Fri, 14 Aug 2026 14:19:03 -0500 Subject: [PATCH] El sensor acusa recibo del token y dice como esta Antes la pagina emitia el token a ciegas: en una app SIN sensor (anterior a la 1.8.0) nadie lo recogia y la pantalla cantaba "equipo vinculado" igual, dejando un equipo registrado que jamas reporta. - ls-tracker-token -> responde ls-tracker-listo (acuse). Sin acuse, la web deshace el equipo que acaba de crear y avisa que hay que actualizar. - ls-tracker-consulta -> responde ls-tracker-estado {vinculado, pausado, version}, para no ofrecer vincular lo que ya esta vinculado y para poder avisar de un clic a quien le falta. Los dos emit salen en un hilo aparte, por el mismo motivo que los repintados del menu: un listener puede correr en el hilo principal. Co-Authored-By: Claude Opus 5 --- src-tauri/src/tracker.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/tracker.rs b/src-tauri/src/tracker.rs index aa7b772..52a8def 100644 --- a/src-tauri/src/tracker.rs +++ b/src-tauri/src/tracker.rs @@ -25,7 +25,7 @@ use std::{ use serde::{Deserialize, Serialize}; use serde_json::json; -use tauri::{menu::MenuItem, AppHandle, Listener, Manager, Runtime}; +use tauri::{menu::MenuItem, AppHandle, Emitter, Listener, Manager, Runtime}; const API: &str = "https://os.labstreamsas.com/api/tracker"; const TICK_SEG: u64 = 5; @@ -243,6 +243,16 @@ fn enviar(app: &AppHandle) { guardar_cola(app, &cola); } +/// Manda un evento a la página SIN bloquear el hilo del que sale. Mismo motivo que +/// `pintar_en_hilo`: un listener puede correr en el hilo principal, y cualquier cosa que +/// espere a ese hilo desde ahí cuelga la app. +fn avisar(app: &AppHandle, evento: &'static str, payload: serde_json::Value) { + let h = app.clone(); + thread::spawn(move || { + let _ = h.emit(evento, payload); + }); +} + // ── Arranque: listener de vinculación + hilo del sensor ── pub fn iniciar(app: &AppHandle) { let cfg = cargar_cfg(app); @@ -270,10 +280,31 @@ pub fn iniciar(app: &AppHandle) { n.cfg.clone() }; guardar_cfg(&h, &cfg); + // ACUSE de recibo. Sin esto la página no puede distinguir «el sensor lo guardó» de + // «esta app es vieja y no había nadie escuchando», y cantaba éxito en falso dejando + // un equipo registrado que jamás reporta. Si no llega este evento, la página revoca. + avisar(&h, "ls-tracker-listo", json!({ "ok": true })); // Sin repintar aquí: el evento puede llegar en el hilo principal. El sensor ve el // token en su próximo tic (≤5 s) y actualiza la bandeja solo. }); + // La página pregunta cómo está ESTE equipo (¿ya vinculado? ¿en pausa?) para no ofrecer + // vincular lo que ya está vinculado y para poder avisar cuando falta hacerlo. + let h = app.clone(); + app.listen_any("ls-tracker-consulta", move |_| { + let nucleo = h.state::(); + let cfg = nucleo.0.lock().unwrap().cfg.clone(); + avisar( + &h, + "ls-tracker-estado", + json!({ + "vinculado": cfg.token.is_some(), + "pausado": esta_pausado(&cfg), + "version": env!("CARGO_PKG_VERSION"), + }), + ); + }); + // El sensor: un hilo con tic de 5 s. Nada de esto toca la interfaz salvo el menú del tray. let h = app.clone(); thread::spawn(move || {