use super::CmdResult; use crate::core::{autostart, handle}; use crate::utils::resolve::ui::{self, UiReadyStage}; use crate::{cmd::StringifyErr as _, feat, utils::dirs}; use clash_verge_logging::{Type, logging}; use smartstring::alias::String; use tauri::{AppHandle, Manager as _}; /// 打开应用程序所在目录 #[tauri::command] pub async fn open_app_dir() -> CmdResult<()> { let app_dir = dirs::app_home_dir().stringify_err()?; open::that(app_dir).stringify_err() } /// 打开核心所在目录 #[tauri::command] pub async fn open_core_dir() -> CmdResult<()> { let core_dir = tauri::utils::platform::current_exe().stringify_err()?; let core_dir = core_dir.parent().ok_or("failed to get core dir")?; open::that(core_dir).stringify_err() } /// 打开日志目录 #[tauri::command] pub async fn open_logs_dir() -> CmdResult<()> { let log_dir = dirs::app_logs_dir().stringify_err()?; open::that(log_dir).stringify_err() } /// 打开网页链接 #[tauri::command] pub fn open_web_url(url: String) -> CmdResult<()> { open::that(url.as_str()).stringify_err() } // TODO 后续可以为前端提供接口,当前作为托盘菜单使用 /// 打开 Verge 最新日志 #[tauri::command] pub async fn open_app_log() -> CmdResult<()> { let log_path = dirs::app_latest_log().stringify_err()?; #[cfg(target_os = "windows")] let log_path = crate::utils::help::snapshot_path(&log_path).stringify_err()?; open::that(log_path).stringify_err() } // TODO 后续可以为前端提供接口,当前作为托盘菜单使用 /// 打开 Clash 最新日志 #[tauri::command] pub async fn open_core_log() -> CmdResult<()> { let log_path = dirs::clash_latest_log().stringify_err()?; #[cfg(target_os = "windows")] let log_path = crate::utils::help::snapshot_path(&log_path).stringify_err()?; open::that(log_path).stringify_err() } /// 打开/关闭开发者工具 #[tauri::command] pub fn open_devtools(app_handle: AppHandle) { if let Some(window) = app_handle.get_webview_window("main") { if !window.is_devtools_open() { window.open_devtools(); } else { window.close_devtools(); } } } /// 退出应用 #[tauri::command] pub async fn exit_app() { feat::quit().await; } /// 重启应用 #[tauri::command] pub async fn restart_app() -> CmdResult<()> { feat::restart_app().await; Ok(()) } /// 获取便携版标识 #[tauri::command] pub fn get_portable_flag() -> bool { *dirs::PORTABLE_FLAG.get().unwrap_or(&false) } /// 获取应用目录 #[tauri::command] pub fn get_app_dir() -> CmdResult { let app_home_dir = dirs::app_home_dir().stringify_err()?.to_string_lossy().into(); Ok(app_home_dir) } /// 获取当前自启动状态 #[tauri::command] pub fn get_auto_launch_status() -> CmdResult { autostart::get_launch_status().stringify_err() } /// 下载图标缓存 #[tauri::command] pub async fn download_icon_cache(url: String, name: String) -> CmdResult { feat::download_icon_cache(url, name).await } /// 复制图标文件 #[tauri::command] pub async fn copy_icon_file(path: String, icon_info: feat::IconInfo) -> CmdResult { feat::copy_icon_file(path, icon_info).await } /// 通知UI已准备就绪 #[tauri::command] pub async fn notify_ui_ready() { logging!(info, Type::Cmd, "前端UI已准备就绪"); ui::mark_ui_ready(); handle::Handle::refresh_clash(); let delayed_refresh_delay = std::time::Duration::from_millis(1500); tokio::time::sleep(delayed_refresh_delay).await; handle::Handle::refresh_clash(); } /// UI加载阶段 #[tauri::command] pub fn update_ui_stage(stage: UiReadyStage) { logging!(info, Type::Cmd, "UI加载阶段更新: {:?}", &stage); ui::update_ui_ready_stage(stage); }