diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index e513433..62006dd 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -30,6 +30,47 @@ fn api_url(server: &str, path: &str) -> String { format!("{}/api-proxy{}", server.trim_end_matches('/'), path) } +/// Haengt das Query-Paar `desktop=1` an einen Klon der Adresse an und gibt +/// den Klon zurueck -- das Original bleibt unveraendert. Der Parameter geht +/// NUR in die Navigation, niemals in den gespeicherten Server-Wert +/// (`server_url` im Store bleibt die reine Adresse); daraus liest die +/// Next.js-Middleware (apps/web/src/middleware.ts) das Cookie +/// `tessera_desktop`, an dem der Web-Client den Desktop-Client erkennt. Die +/// Tray-URL "Update herunterladen" bekommt den Parameter bewusst NICHT -- +/// sie oeffnet im System-Browser, dort muessen die Download-Links sichtbar +/// bleiben. +fn with_desktop_marker(url: &tauri::Url) -> tauri::Url { + let mut marked = url.clone(); + marked.query_pairs_mut().append_pair("desktop", "1"); + marked +} + +/// Liefert (Menuetext, Benachrichtigungstext) fuer den Update-Hinweis. Der +/// Beta-Kanal (main) vergibt jedem Commit dieselbe X.Y.Z-Version (D-07, +/// desktop-collect.sh) -- hat sich nur der Commit geaendert, waere der reine +/// Versionstext ("Version 1.1.0 herunterladen") verwirrend, weil der Client +/// bereits genau diese Version hat. Der zweite Zweig nennt darum den +/// Commit-Stempel statt der unveraenderten Version. +fn update_labels(version_changed: bool, version: &str, commit: &str) -> (String, String) { + if version_changed { + ( + format!("Version {} herunterladen", version), + format!( + "Neue Version {} verfügbar – Download über das Symbol im Infobereich.", + version + ), + ) + } else { + ( + "Neuen Beta-Stand herunterladen".to_string(), + format!( + "Neuer Beta-Stand {} verfügbar – Download über das Symbol im Infobereich.", + commit + ), + ) + } +} + #[tauri::command] async fn check_server(url: String) -> Result { let parsed = tauri::Url::parse(&url).map_err(|_| "Diese Adresse ist ungültig.".to_string())?; @@ -73,7 +114,7 @@ fn save_server_url(app: AppHandle, url: String) -> Result<(), String> { store.save().map_err(|e| e.to_string())?; if let Some(window) = app.get_webview_window("main") { - let _ = window.navigate(parsed); + let _ = window.navigate(with_desktop_marker(&parsed)); } Ok(()) @@ -84,7 +125,10 @@ pub fn run() { .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)) + .plugin(tauri_plugin_autostart::init( + MacosLauncher::LaunchAgent, + None, + )) .plugin(tauri_plugin_opener::init()) .invoke_handler(tauri::generate_handler![check_server, save_server_url]) .setup(|app| { @@ -99,7 +143,7 @@ pub fn run() { 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); + let _ = window.navigate(with_desktop_marker(&parsed)); } } } @@ -151,8 +195,10 @@ pub fn run() { } "update" => { if let Some(server) = &server_for_menu { - let target = - format!("{}/settings/general/desktop", server.trim_end_matches('/')); + let target = format!( + "{}/settings/general/desktop", + server.trim_end_matches('/') + ); let _ = app.opener().open_url(target, None::<&str>); } } @@ -208,21 +254,21 @@ pub fn run() { // (D-07, desktop-collect.sh) -- ohne den Commit-Vergleich saehe // ein Beta-Client zwischen zwei Freigabe-Tags nie einen neueren // Bau (WR-02, Code-Review Phase 18). Fuer den Live-Kanal bleibt - // es beim reinen Versionsvergleich. - let is_newer = info.version != app_version + // es beim reinen Versionsvergleich. Die Texte fuer Menue und + // Benachrichtigung liefert `update_labels`. + let version_changed = info.version != app_version; + let is_newer = version_changed || (info.channel == "beta" && info.commit != app_commit); if is_newer { + let (menu_text, body) = + update_labels(version_changed, &info.version, &info.commit); let _ = app_handle .notification() .builder() .title("Tessera-Update") - .body(format!( - "Neue Version {} verfügbar – Download über das Symbol im Infobereich.", - info.version - )) + .body(body) .show(); - let _ = update_item - .set_text(format!("Version {} herunterladen", info.version)); + let _ = update_item.set_text(menu_text); let _ = update_item.set_enabled(true); } } @@ -255,3 +301,49 @@ pub fn run() { } }); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn with_desktop_marker_ohne_pfad_haengt_query_an() { + let url = tauri::Url::parse("https://tessera.example.com").unwrap(); + let marked = with_desktop_marker(&url); + assert_eq!(marked.as_str(), "https://tessera.example.com/?desktop=1"); + } + + #[test] + fn with_desktop_marker_mit_vorhandenem_query_haengt_an() { + let url = tauri::Url::parse("https://host/app?x=1").unwrap(); + let marked = with_desktop_marker(&url); + assert_eq!(marked.as_str(), "https://host/app?x=1&desktop=1"); + } + + #[test] + fn with_desktop_marker_laesst_original_unveraendert() { + let url = tauri::Url::parse("https://host/app").unwrap(); + let _ = with_desktop_marker(&url); + assert_eq!(url.query(), None); + } + + #[test] + fn update_labels_bei_versionswechsel() { + let (menu_text, body) = update_labels(true, "1.2.0", "abc1234"); + assert_eq!(menu_text, "Version 1.2.0 herunterladen"); + assert_eq!( + body, + "Neue Version 1.2.0 verfügbar – Download über das Symbol im Infobereich." + ); + } + + #[test] + fn update_labels_bei_gleicher_version_beta_commit() { + let (menu_text, body) = update_labels(false, "1.1.0", "abc1234"); + assert_eq!(menu_text, "Neuen Beta-Stand herunterladen"); + assert_eq!( + body, + "Neuer Beta-Stand abc1234 verfügbar – Download über das Symbol im Infobereich." + ); + } +}