diff --git a/Cargo.lock b/Cargo.lock index 40b123df9..3a2c0162b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1128,6 +1128,7 @@ dependencies = [ "criterion", "dark-light", "deelevate", + "dirs 6.0.0", "dunce", "flate2", "flexi_logger", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9bb4be725..b7837bf99 100755 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -61,6 +61,7 @@ socket2 = { workspace = true } warp = { version = "0.4.3", features = ["server"] } open = "5.4.1" rfd = { version = "0.16.0", default-features = false, features = ["common-controls-v6"] } +dirs = "6" dunce = "1.0.5" nanoid = "0.5" chrono = { workspace = true } diff --git a/src-tauri/src/core/updater.rs b/src-tauri/src/core/updater.rs index b33a8438f..4f53a3221 100644 --- a/src-tauri/src/core/updater.rs +++ b/src-tauri/src/core/updater.rs @@ -395,12 +395,6 @@ impl SilentUpdater { impl SilentUpdater { async fn check_and_download(&self, app_handle: &tauri::AppHandle) -> Result<()> { - let is_portable = *dirs::PORTABLE_FLAG.get().unwrap_or(&false); - if is_portable { - logging!(debug, Type::System, "Silent update skipped: portable build"); - return Ok(()); - } - let auto_check = Config::verge().await.latest_arc().auto_check_update.unwrap_or(true); if !auto_check { logging!(debug, Type::System, "Silent update skipped: auto_check_update is false"); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 6b55f24df..48f917b76 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -231,8 +231,6 @@ pub fn run() -> std::process::ExitCode { return std::process::ExitCode::SUCCESS; } - let _ = utils::dirs::init_portable_flag(); - // Runs before the singleton check, which is the first thing to open a file in that directory. #[cfg(windows)] if let Err(error) = diff --git a/src-tauri/src/utils/dirs.rs b/src-tauri/src/utils/dirs.rs index c0a6021e8..c76e780a5 100644 --- a/src-tauri/src/utils/dirs.rs +++ b/src-tauri/src/utils/dirs.rs @@ -2,7 +2,6 @@ use crate::core::{CoreManager, handle, manager::RunningMode}; use anyhow::Result; use async_trait::async_trait; use clash_verge_logging::{Type, logging}; -use once_cell::sync::OnceCell; use std::{ fs, path::{Path, PathBuf}, @@ -19,74 +18,21 @@ pub static APP_ID: &str = "io.github.clash-verge-rev.clash-verge-rev.dev"; #[cfg(feature = "verge-dev")] pub static BACKUP_DIR: &str = "clash-verge-rev-backup-dev"; -pub static PORTABLE_FLAG: OnceCell = OnceCell::new(); - pub static CLASH_CONFIG: &str = "config.yaml"; pub static VERGE_CONFIG: &str = "verge.yaml"; pub static PROFILE_YAML: &str = "profiles.yaml"; /// Marks that the one-shot raise of too-short auto-update intervals has already run. pub static UPDATE_INTERVAL_MIGRATED: &str = ".update-interval-migrated"; -pub fn init_portable_flag() -> Result<()> { - use tauri::utils::platform::current_exe; - - let app_exe = current_exe()?; - if let Some(dir) = app_exe.parent() { - let dir = PathBuf::from(dir).join(".config/PORTABLE"); - - if dir.exists() { - PORTABLE_FLAG.get_or_init(|| true); - } - } - PORTABLE_FLAG.get_or_init(|| false); - Ok(()) -} - +/// Uses the same platform data resolver as Tauri, including before its handle exists. pub fn app_home_dir() -> Result { - use tauri::utils::platform::current_exe; - - let flag = PORTABLE_FLAG.get().unwrap_or(&false); - if *flag { - let app_exe = current_exe()?; - let app_exe = dunce::canonicalize(app_exe)?; - let app_dir = app_exe - .parent() - .ok_or_else(|| anyhow::anyhow!("failed to get the portable app dir"))?; - return Ok(PathBuf::from(app_dir).join(".config").join(APP_ID)); - } - - // Directory helpers can run before the Tauri handle is initialized. - let app_handle = handle::Handle::app_handle(); - - match app_handle.path().data_dir() { - Ok(dir) => Ok(dir.join(APP_ID)), - Err(e) => { - logging!(error, Type::File, "Failed to get the app home directory: {e}"); - Err(anyhow::anyhow!("Failed to get the app homedirectory")) - } - } + ::dirs::data_dir() + .map(|root| root.join(APP_ID)) + .ok_or_else(|| anyhow::anyhow!("Failed to get the app home directory")) } pub fn preinit_app_data_dir() -> Result { - if PORTABLE_FLAG.get().copied().unwrap_or(false) { - let executable = std::env::current_exe()?; - let parent = executable - .parent() - .ok_or_else(|| anyhow::anyhow!("portable executable has no parent directory"))?; - return Ok(parent.join(".config").join(APP_ID)); - } - - #[cfg(target_os = "macos")] - let root = PathBuf::from(std::env::var_os("HOME").ok_or_else(|| anyhow::anyhow!("HOME is unavailable"))?) - .join("Library/Application Support"); - #[cfg(target_os = "linux")] - let root = std::env::var_os("XDG_DATA_HOME") - .map(PathBuf::from) - .unwrap_or_else(|| PathBuf::from(std::env::var_os("HOME").unwrap_or_default()).join(".local/share")); - #[cfg(windows)] - let root = PathBuf::from(std::env::var_os("APPDATA").ok_or_else(|| anyhow::anyhow!("APPDATA is unavailable"))?); - - Ok(root.join(APP_ID)) + app_home_dir() } pub fn app_resources_dir() -> Result {