From abd18591c1fab898d27ca7cbc79b023267dfc401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20David=20Florez=20Salom=C3=B3n?= Date: Sun, 21 Jun 2026 06:21:54 -0500 Subject: [PATCH] Notificaciones nativas: plugin notification + autostart + bandeja MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- src-tauri/Cargo.toml | 4 +- src-tauri/capabilities/default.json | 6 ++- src-tauri/src/lib.rs | 72 +++++++++++++++++++++++++++-- src-tauri/tauri.conf.json | 2 +- 4 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5315537..134eb1a 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -14,7 +14,9 @@ crate-type = ["staticlib", "cdylib", "rlib"] tauri-build = { version = "2", features = [] } [dependencies] -tauri = { version = "2", features = [] } +tauri = { version = "2", features = ["tray-icon"] } tauri-plugin-opener = "2" +tauri-plugin-notification = "2" +tauri-plugin-autostart = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index adc7b23..20433bf 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -3,8 +3,12 @@ "identifier": "default", "description": "Permisos por defecto del envoltorio de escritorio.", "windows": ["main"], + "remote": { + "urls": ["https://os.labstreamsas.com"] + }, "permissions": [ "core:default", - "opener:default" + "opener:default", + "notification:default" ] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 04ba033..1a3a105 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,12 +1,78 @@ // Punto de entrada de la app de escritorio de Labstream OS. -// Es un "envoltorio": la ventana carga directamente el servidor del NAS -// (ver `app.windows[].url` en tauri.conf.json), así que aquí no hay lógica de UI. -// El plugin `opener` permite que los enlaces externos abran el navegador del sistema. +// Es un "envoltorio": la ventana carga directamente el servidor (os.labstreamsas.com), +// así que aquí no hay UI propia. Sí añadimos comportamiento de cliente nativo: +// - plugin `opener`: enlaces externos abren el navegador del sistema. +// - plugin `notification`: la web (vía window.__TAURI__) muestra avisos nativos. +// - plugin `autostart`: la app arranca al iniciar sesión. +// - bandeja (tray) + "cerrar = ocultar": la app sigue corriendo y notificando +// aunque cierres la ventana. + +use tauri::{ + menu::{Menu, MenuItem}, + tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}, + AppHandle, Manager, Runtime, WindowEvent, +}; +use tauri_plugin_autostart::{MacosLauncher, ManagerExt}; + +// Muestra y enfoca la ventana principal (desde el tray o su menú). +fn show_main(app: &AppHandle) { + if let Some(w) = app.get_webview_window("main") { + let _ = w.show(); + let _ = w.unminimize(); + let _ = w.set_focus(); + } +} #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_opener::init()) + .plugin(tauri_plugin_notification::init()) + .plugin(tauri_plugin_autostart::init( + MacosLauncher::LaunchAgent, + None, + )) + .setup(|app| { + // Arranque automático al iniciar sesión (idempotente). + let _ = app.autolaunch().enable(); + + // Icono en la bandeja del sistema con menú Abrir / Salir. + let abrir = MenuItem::with_id(app, "abrir", "Abrir Labstream", true, None::<&str>)?; + let salir = MenuItem::with_id(app, "salir", "Salir", true, None::<&str>)?; + let menu = Menu::with_items(app, &[&abrir, &salir])?; + + TrayIconBuilder::with_id("main-tray") + .icon(app.default_window_icon().unwrap().clone()) + .tooltip("Labstream OS") + .menu(&menu) + .show_menu_on_left_click(false) + .on_menu_event(|app, event| match event.id.as_ref() { + "abrir" => show_main(app), + "salir" => app.exit(0), + _ => {} + }) + .on_tray_icon_event(|tray, event| { + // Clic izquierdo en el icono → mostrar la ventana. + if let TrayIconEvent::Click { + button: MouseButton::Left, + button_state: MouseButtonState::Up, + .. + } = event + { + show_main(tray.app_handle()); + } + }) + .build(app)?; + + Ok(()) + }) + // Cerrar la ventana = ocultarla a la bandeja (la app sigue notificando). + .on_window_event(|window, event| { + if let WindowEvent::CloseRequested { api, .. } = event { + let _ = window.hide(); + api.prevent_close(); + } + }) .run(tauri::generate_context!()) .expect("error al arrancar Labstream OS"); } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 1c7b631..6ff5e0f 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -7,7 +7,7 @@ "frontendDist": "../dist" }, "app": { - "withGlobalTauri": false, + "withGlobalTauri": true, "windows": [ { "label": "main",