From 5d7d2148cc593983e1caea90effd63e4a37a4bfe Mon Sep 17 00:00:00 2001 From: /home/neo <158327205+neoapps-dev@users.noreply.github.com> Date: Wed, 24 Jun 2026 19:58:34 +0300 Subject: [PATCH] feat(VersionsMenu): download to custom path (#87) --- src-tauri/src/commands/download.rs | 15 +++++++------- src-tauri/src/commands/game.rs | 5 +++++ src-tauri/src/config.rs | 1 + src-tauri/src/types.rs | 1 + src-tauri/src/util.rs | 5 +++++ src/components/views/VersionsView.tsx | 28 +++++++++++++++++++++++++++ src/hooks/useGameManager.ts | 13 +++++++++++++ src/services/TauriService.ts | 1 + 8 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src-tauri/src/commands/download.rs b/src-tauri/src/commands/download.rs index d863fa3..fc8cb49 100644 --- a/src-tauri/src/commands/download.rs +++ b/src-tauri/src/commands/download.rs @@ -13,8 +13,7 @@ pub async fn download_and_install( url: String, instance_id: String, ) -> Result { - let root = util::get_app_dir(&app); - let instance_dir = root.join("instances").join(&instance_id); + let instance_dir = util::get_instance_working_dir(&app, &instance_id); let token = CancellationToken::new(); let child_token = token.clone(); { @@ -25,21 +24,18 @@ pub async fn download_and_install( *lock = Some(token); } + let root = util::get_app_dir(&app); let zip_path = root.join(format!("temp_{}.zip", instance_id)); let response = reqwest::get(&url).await.map_err(|e| e.to_string())?; if !response.status().is_success() { return Err(format!("Download failed: {}", response.status())); } + let total_size = response.content_length().unwrap_or(0) as f64; let last_modified = response.headers().get(reqwest::header::LAST_MODIFIED) .and_then(|h| h.to_str().ok()) .unwrap_or("") .to_string(); - if !last_modified.is_empty() { - let _ = fs::write(instance_dir.join("update_timestamp.txt"), last_modified); - } - - let total_size = response.content_length().unwrap_or(0) as f64; let mut file = fs::File::create(&zip_path).map_err(|e| e.to_string())?; let mut downloaded = 0.0; let mut stream = response.bytes_stream(); @@ -67,6 +63,7 @@ pub async fn download_and_install( "profile4.dat", "profile5.dat", "profile6.dat", "profile7.dat", "profile8.dat", "profile9.dat", "profile10.dat", "proton_prefix" ].iter().copied().collect(); + if !instance_dir.exists() { fs::create_dir_all(&instance_dir).map_err(|e| e.to_string())?; } else { @@ -98,6 +95,10 @@ pub async fn download_and_install( } } + if !last_modified.is_empty() { + let _ = fs::write(instance_dir.join("update_timestamp.txt"), &last_modified); + } + #[cfg(target_os = "linux")] { let bsdtar_ok = std::process::Command::new("bsdtar") diff --git a/src-tauri/src/commands/game.rs b/src-tauri/src/commands/game.rs index db6df6b..92580c2 100644 --- a/src-tauri/src/commands/game.rs +++ b/src-tauri/src/commands/game.rs @@ -374,6 +374,11 @@ pub fn delete_instance(app: AppHandle, instance_id: String) -> Result<(), String } } } + if let Some(ref custom_paths) = config_val.custom_paths { + if custom_paths.contains_key(&instance_id) { + return Ok(()); + } + } let dir = util::get_app_dir(&app).join("instances").join(&instance_id); if dir.exists() { let _ = fs::remove_dir_all(dir); diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index 2a2511a..0903963 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -22,6 +22,7 @@ pub fn load_config_raw(app: AppHandle) -> AppConfig { apple_silicon_performance_boost: None, custom_editions: None, customizations: None, + custom_paths: None, profile: Some("legacy_evolved".into()), animations_enabled: Some(true), vfx_enabled: Some(true), diff --git a/src-tauri/src/types.rs b/src-tauri/src/types.rs index 5f85a59..04d5eef 100644 --- a/src-tauri/src/types.rs +++ b/src-tauri/src/types.rs @@ -44,6 +44,7 @@ pub struct AppConfig { pub apple_silicon_performance_boost: Option, pub custom_editions: Option>, pub customizations: Option>, + pub custom_paths: Option>, pub profile: Option, pub animations_enabled: Option, pub vfx_enabled: Option, diff --git a/src-tauri/src/util.rs b/src-tauri/src/util.rs index 14daa25..576a70e 100644 --- a/src-tauri/src/util.rs +++ b/src-tauri/src/util.rs @@ -22,6 +22,11 @@ pub fn get_instance_working_dir(app: &AppHandle, instance_id: &str) -> PathBuf { } } } + if let Some(ref custom_paths) = config.custom_paths { + if let Some(path) = custom_paths.get(instance_id) { + return PathBuf::from(path); + } + } root.join("instances").join(instance_id) } diff --git a/src/components/views/VersionsView.tsx b/src/components/views/VersionsView.tsx index b818fe7..ee23ccb 100644 --- a/src/components/views/VersionsView.tsx +++ b/src/components/views/VersionsView.tsx @@ -80,6 +80,7 @@ const VersionsView = memo(function VersionsView() { cycleBranch, customizations, updateCustomization, + saveCustomPath, } = useGame(); const { isDayTime } = useConfig(); const [focusIndex, setFocusIndex] = useState(0); @@ -508,6 +509,33 @@ const VersionsView = memo(function VersionsView() { Update Available! )} + {!isInstalled && ( + + )} {Array.isArray(edition.branches) && edition.branches.length > 0 && (