diff --git a/src-tauri/src/app.rs b/src-tauri/src/app.rs index 8a8bf3e..caa3ddb 100644 --- a/src-tauri/src/app.rs +++ b/src-tauri/src/app.rs @@ -4,6 +4,7 @@ use tokio::time::{sleep, Instant}; use tracing::{info, warn}; use crate::{ + lock_w, remotes::health::{HealthError, HealthRemote}, services::{ auth::{get_access_token, get_tokens}, @@ -13,11 +14,16 @@ use crate::{ ws::init_ws_client, }, state::init_app_data, - system_tray::init_system_tray, + system_tray::{init_system_tray, update_system_tray}, + FDOLL, }; pub async fn start_fdoll() { - init_system_tray(); + let tray = init_system_tray(); + { + let mut guard = lock_w!(FDOLL); + guard.tray = Some(tray); + } if let Err(err) = init_startup_sequence().await { tracing::error!("startup sequence failed: {err}"); show_health_manager_with_error(Some(err.to_string())); @@ -66,11 +72,13 @@ pub async fn bootstrap() { Some(_tokens) => { info!("Tokens found in keyring - restoring user session"); construct_app().await; + update_system_tray(true); } None => { info!("No active session found - showing welcome first"); open_welcome_window(); close_splash_window(); + update_system_tray(false); } } } diff --git a/src-tauri/src/services/health_manager.rs b/src-tauri/src/services/health_manager.rs index 5475b05..84c848c 100644 --- a/src-tauri/src/services/health_manager.rs +++ b/src-tauri/src/services/health_manager.rs @@ -1,4 +1,5 @@ use crate::get_app_handle; +use crate::{lock_r, state::FDOLL, system_tray::update_system_tray}; use tauri::{Emitter, Manager}; use tauri_plugin_dialog::{DialogExt, MessageDialogBuilder, MessageDialogKind}; use tauri_plugin_positioner::WindowExt; @@ -29,6 +30,8 @@ pub fn show_health_manager_with_error(error_message: Option) { close_window_if_exists(crate::services::scene::SCENE_WINDOW_LABEL); close_window_if_exists(crate::services::app_menu::APP_MENU_WINDOW_LABEL); + update_system_tray(false); + let existing_webview_window = app_handle.get_window(HEALTH_MANAGER_WINDOW_LABEL); if let Some(window) = existing_webview_window { @@ -113,6 +116,10 @@ pub fn close_health_manager_window() { error!("Failed to close health manager window: {}", e); } else { info!("Health manager window closed"); + let guard = lock_r!(FDOLL); + let is_logged_in = guard.app_data.user.is_some(); + drop(guard); + update_system_tray(is_logged_in); } } } diff --git a/src-tauri/src/state.rs b/src-tauri/src/state.rs index 1447bb3..9e23860 100644 --- a/src-tauri/src/state.rs +++ b/src-tauri/src/state.rs @@ -37,6 +37,7 @@ pub struct AppState { pub auth_pass: Option, pub oauth_flow: OAuthFlowTracker, pub tracing_guard: Option, + pub tray: Option, // exposed to the frontend pub app_data: AppData, diff --git a/src-tauri/src/system_tray.rs b/src-tauri/src/system_tray.rs index 4197bf7..c93abdf 100644 --- a/src-tauri/src/system_tray.rs +++ b/src-tauri/src/system_tray.rs @@ -1,12 +1,11 @@ +use crate::{get_app_handle, lock_r, services::app_menu::open_app_menu_window, state::FDOLL}; use tauri::{ menu::{Menu, MenuItem}, tray::TrayIconBuilder, }; use tracing::error; -use crate::{get_app_handle, services::app_menu::open_app_menu_window}; - -pub fn init_system_tray() { +pub fn init_system_tray() -> tauri::tray::TrayIcon { let app = get_app_handle(); let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>).unwrap(); @@ -18,7 +17,7 @@ pub fn init_system_tray() { Err(err) => todo!("Handle error: {}", err), }; - match TrayIconBuilder::new() + TrayIconBuilder::new() .menu(&menu) .on_menu_event(|app, event| match event.id.as_ref() { "quit" => { @@ -33,8 +32,31 @@ pub fn init_system_tray() { }) .icon(app.default_window_icon().unwrap().clone()) .build(app) - { - Ok(it) => it, - Err(err) => todo!("Handle error: {}", err), - }; + .unwrap_or_else(|err| panic!("Failed to build tray: {}", err)) +} + +pub fn update_system_tray(is_logged_in: bool) { + let app = get_app_handle(); + let guard = lock_r!(FDOLL); + if let Some(tray) = &guard.tray { + let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>).unwrap(); + let menu = if is_logged_in { + let open_app_menu_i = + MenuItem::with_id(app, "open-app-menu", "Open App Menu", true, None::<&str>) + .unwrap(); + Menu::with_items(app, &[&open_app_menu_i, &quit_i]) + } else { + Menu::with_items(app, &[&quit_i]) + }; + let menu = match menu { + Ok(it) => it, + Err(err) => { + error!("Failed to create menu: {}", err); + return; + } + }; + if let Err(err) = tray.set_menu(Some(menu)) { + error!("Failed to update tray menu: {}", err); + } + } }