use tauri::{ Manager, menu::{MenuBuilder, MenuItemBuilder}, tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}, RunEvent, WindowEvent, }; use tauri_plugin_autostart::MacosLauncher; use tauri_plugin_notification::NotificationExt; use tauri_plugin_store::StoreExt; #[derive(serde::Deserialize)] struct VersionResponse { version: String, } pub fn run() { let app = tauri::Builder::default() .plugin(tauri_plugin_store::Builder::new().build()) .plugin(tauri_plugin_notification::init()) .plugin(tauri_plugin_window_state::Builder::default().build()) .plugin(tauri_plugin_autostart::init(MacosLauncher::LaunchAgent, None)) .setup(|app| { let store = app.store("config.json")?; let server_url = store.get("server_url"); let mut url_for_check: Option = None; if let Some(url_value) = server_url { if let Some(url_str) = url_value.as_str() { if !url_str.is_empty() { url_for_check = Some(url_str.to_string()); if let Some(window) = app.get_webview_window("main") { if let Ok(parsed) = url_str.parse::() { let _ = window.navigate(parsed); } } } } } // Tray menu let open = MenuItemBuilder::with_id("open", "Oeffnen").build(app)?; let quit = MenuItemBuilder::with_id("quit", "Beenden").build(app)?; let menu = MenuBuilder::new(app) .item(&open) .separator() .item(&quit) .build()?; let _tray = TrayIconBuilder::new() .icon(app.default_window_icon().unwrap().clone()) .menu(&menu) .tooltip("Tessera") .show_menu_on_left_click(false) .on_menu_event(|app, event| match event.id().as_ref() { "open" => { if let Some(w) = app.get_webview_window("main") { let _ = w.show(); let _ = w.set_focus(); } } "quit" => { app.exit(0); } _ => {} }) .on_tray_icon_event(|tray, event| { if let TrayIconEvent::Click { button: MouseButton::Left, button_state: MouseButtonState::Up, .. } = event { if let Some(w) = tray.app_handle().get_webview_window("main") { let _ = w.show(); let _ = w.set_focus(); } } }) .build(app)?; // Version check (async, non-blocking) if let Some(server_url) = url_for_check { let app_handle = app.handle().clone(); let app_version = env!("CARGO_PKG_VERSION").to_string(); tauri::async_runtime::spawn(async move { let url = format!("{}/health/version", server_url.trim_end_matches('/')); if let Ok(resp) = reqwest::get(&url).await { if let Ok(info) = resp.json::().await { if info.version != app_version { let _ = app_handle .notification() .builder() .title("Tessera Update") .body("Eine neue Version ist verfuegbar.") .show(); } } } }); } Ok(()) }) .on_window_event(|window, event| { if let WindowEvent::CloseRequested { api, .. } = event { let _ = window.hide(); api.prevent_close(); } }) .build(tauri::generate_context!()) .expect("error while building Tessera desktop application"); app.run(|_app, event| { if let RunEvent::ExitRequested { api, .. } = event { api.prevent_exit(); } }); }