diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 182aaf1..5c5dee9 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -309,7 +309,7 @@ pub fn get_domain_usage_stats( // ============================================================================ #[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "camelCase", default)] pub struct AppSettings { pub theme: String, pub auto_start: bool, @@ -317,6 +317,7 @@ pub struct AppSettings { pub polling_interval: u64, // seconds pub idle_threshold: u64, // seconds pub track_urls: bool, + pub hide_dock: bool, } impl Default for AppSettings { @@ -328,6 +329,7 @@ impl Default for AppSettings { polling_interval: 3, idle_threshold: 300, track_urls: false, + hide_dock: false, } } } @@ -556,6 +558,32 @@ pub fn set_autostart(app: tauri::AppHandle, enabled: bool) -> Result<(), String> } } +// ============================================================================ +// Dock Visibility Commands +// ============================================================================ + +/// Set Dock icon visibility (macOS only) +#[tauri::command] +pub fn set_dock_visible(app_handle: tauri::AppHandle, visible: bool) -> Result<(), String> { + #[cfg(target_os = "macos")] + { + use tauri::ActivationPolicy; + let policy = if visible { + ActivationPolicy::Regular + } else { + ActivationPolicy::Accessory + }; + app_handle + .set_activation_policy(policy) + .map_err(|e| e.to_string())?; + } + #[cfg(not(target_os = "macos"))] + { + let _ = (app_handle, visible); + } + Ok(()) +} + // ============================================================================ // System Commands // ============================================================================ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 999547b..3c332dd 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -66,6 +66,20 @@ pub fn run() { tracker, }); + // Restore Dock visibility from saved settings + #[cfg(target_os = "macos")] + { + let settings_db = Database::new(db_path.to_str().unwrap()) + .expect("Failed to open database for settings"); + if let Ok(settings) = settings_db.get_settings() { + if settings.hide_dock { + use tauri::ActivationPolicy; + let _ = app.handle().set_activation_policy(ActivationPolicy::Accessory); + log::info!("Dock icon hidden (restored from settings)"); + } + } + } + log::info!("Timlyzer initialized successfully"); Ok(()) @@ -110,6 +124,8 @@ pub fn run() { commands::export_to_csv, commands::export_to_json, commands::update_tray_menu, + // Dock commands + commands::set_dock_visible, // Autostart commands commands::get_autostart, commands::set_autostart, diff --git a/src/i18n/locales/en-US/settings.json b/src/i18n/locales/en-US/settings.json index a401f6c..7c3d59f 100644 --- a/src/i18n/locales/en-US/settings.json +++ b/src/i18n/locales/en-US/settings.json @@ -13,6 +13,8 @@ "language": "Language", "autostart": "Start on boot", "autostartDesc": "Automatically start Timlyzer when you log in", + "hideDock": "Hide Dock icon", + "hideDockDesc": "Hide the app from Dock and only show in the system tray", "closeAction": "When closing window", "minimize": "Minimize to tray", "ask": "Ask every time", diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index 8b5bf77..5329754 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -13,6 +13,8 @@ "language": "语言", "autostart": "开机自启动", "autostartDesc": "登录时自动启动 Timlyzer", + "hideDock": "隐藏 Dock 图标", + "hideDockDesc": "从 Dock 中隐藏应用,仅在系统托盘中显示", "closeAction": "当关闭窗口时", "minimize": "最小化到托盘", "ask": "每次询问", diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 7a90824..f14b862 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -27,6 +27,7 @@ import { exportApi, trackItemApi, autostartApi, + dockApi, type TrackedApp, type DatabaseInfo, type AppSettings, @@ -49,6 +50,7 @@ export function SettingsPage() { const [isSaving, setIsSaving] = useState(false); const [exportMessage, setExportMessage] = useState(""); const [autostartEnabled, setAutostartEnabled] = useState(false); + const [isMacOS] = useState(() => navigator.userAgent.includes("Macintosh")); // Load settings store for theme const { theme, setTheme } = useSettingsStore(); @@ -288,6 +290,41 @@ export function SettingsPage() { + {/* Hide Dock Icon (macOS only) */} + {isMacOS && ( + + )} + {/* Close Action */}