diff --git a/package.json b/package.json index f6c2c48..773b906 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "iccery", "private": true, - "version": "0.1.11", + "version": "0.1.12", "type": "module", "scripts": { "tauri": "tauri" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b3ecdaf..419ff98 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iccery" -version = "0.1.11" +version = "0.1.12" description = "A Tauri App" authors = ["you"] edition = "2021" diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index cbe2173..1d7fbb3 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -75,6 +75,27 @@ pub fn get_app_info() -> AppInfo { } } +pub fn resolve_safe_cwd(app: &AppHandle, cwd_input: &str) -> Result { + if !cwd_input.trim().is_empty() { + let p = std::path::Path::new(cwd_input.trim()); + if p.is_dir() { + return Ok(p.to_string_lossy().to_string()); + } + } + + app.path() + .document_dir() + .or_else(|_| app.path().home_dir()) + .or_else(|_| app.path().app_data_dir()) + .map(|p| p.to_string_lossy().to_string()) + .map_err(|e| format!("Failed to resolve default working directory: {}", e)) +} + +#[tauri::command] +pub fn get_default_working_dir(app: AppHandle) -> Result { + resolve_safe_cwd(&app, "") +} + #[tauri::command] pub async fn detect_instruments(app: AppHandle, state: State<'_, ProcessManager>) -> Result<(), String> { let binary = resolve_binary(app.clone(), "instlist".to_string()).await?; @@ -197,14 +218,7 @@ pub async fn run_targen( let binary = resolve_binary(app.clone(), "targen".to_string()).await?; let args = build_targen_args(&config); let id = format!("targen_{}", config.basename); - - let cwd = if config.cwd.trim().is_empty() { - None - } else { - Some(config.cwd.clone()) - }; - - println!("DEBUG RUN_TARGEN: binary='{}' args={:?} cwd={:?}", binary, args, cwd); + let cwd = Some(resolve_safe_cwd(&app, &config.cwd)?); state.spawn(app, id, binary, args, cwd).await } @@ -218,12 +232,7 @@ pub async fn run_printtarg( let binary = resolve_binary(app.clone(), "printtarg".to_string()).await?; let args = build_printtarg_args(&config); let id = format!("printtarg_{}", config.basename); - - let cwd = if config.cwd.trim().is_empty() { - None - } else { - Some(config.cwd.clone()) - }; + let cwd = Some(resolve_safe_cwd(&app, &config.cwd)?); state.spawn(app, id, binary, args, cwd).await } @@ -259,12 +268,7 @@ pub async fn run_chartread( let binary = resolve_binary(app.clone(), "chartread".to_string()).await?; let args = build_chartread_args(&config); let id = format!("chartread_{}", config.basename); - - let cwd = if config.cwd.trim().is_empty() { - None - } else { - Some(config.cwd.clone()) - }; + let cwd = Some(resolve_safe_cwd(&app, &config.cwd)?); state.spawn(app, id, binary, args, cwd).await } @@ -323,12 +327,7 @@ pub async fn run_colprof( let binary = resolve_binary(app.clone(), "colprof".to_string()).await?; let args = build_colprof_args(&config); let id = format!("colprof_{}", config.basename); - - let cwd = if config.cwd.trim().is_empty() { - None - } else { - Some(config.cwd.clone()) - }; + let cwd = Some(resolve_safe_cwd(&app, &config.cwd)?); state.spawn(app, id, binary, args, cwd).await } @@ -359,12 +358,7 @@ pub async fn run_profcheck( let binary = resolve_binary(app.clone(), "profcheck".to_string()).await?; let args = build_profcheck_args(&config); let id = format!("profcheck_{}", config.ti3_path); - - let cwd = if config.cwd.trim().is_empty() { - None - } else { - Some(config.cwd.clone()) - }; + let cwd = Some(resolve_safe_cwd(&app, &config.cwd)?); state.spawn(app, id, binary, args, cwd).await } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index e1c3880..282e023 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -13,6 +13,7 @@ pub fn run() { .invoke_handler(tauri::generate_handler![ commands::spawn_process, commands::get_app_info, + commands::get_default_working_dir, commands::send_stdin, commands::kill_process, commands::resolve_binary, diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4da4476..217eb52 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "ICCery", - "version": "0.1.11", + "version": "0.1.12", "identifier": "com.gronod.iccery", "build": { "frontendDist": "../src" diff --git a/src/js/targen.js b/src/js/targen.js index 3618aa5..91b3ed0 100644 --- a/src/js/targen.js +++ b/src/js/targen.js @@ -19,6 +19,25 @@ export function initTargen() { let currentWorkingDir = ""; let currentBasename = ""; + function updateGenerateButton() { + const hasBasename = targetBasename.value.trim().length > 0; + const hasCwd = currentWorkingDir.trim().length > 0; + btnGenerate.disabled = !(hasBasename && hasCwd); + } + + // Load sensible default working directory on startup + invoke("get_default_working_dir") + .then((defaultDir) => { + if (defaultDir && !currentWorkingDir) { + currentWorkingDir = defaultDir; + selectedPathDisplay.textContent = `Directory: ${currentWorkingDir}`; + updateGenerateButton(); + } + }) + .catch((err) => { + console.warn("Could not retrieve default working directory:", err); + }); + // Handle patch count preset changes patchCountPreset.addEventListener("change", (e) => { if (e.target.value === "custom") { @@ -28,13 +47,9 @@ export function initTargen() { } }); - // Enable generate button if text is entered manually + // Enable generate button only when both basename and directory are valid targetBasename.addEventListener("input", () => { - if (targetBasename.value.trim() !== "") { - btnGenerate.disabled = false; - } else { - btnGenerate.disabled = true; - } + updateGenerateButton(); }); // Browse button opens save dialog @@ -65,9 +80,7 @@ export function initTargen() { targetBasename.value = basename; selectedPathDisplay.textContent = `Directory: ${currentWorkingDir}`; - - // Enable generate button - btnGenerate.disabled = false; + updateGenerateButton(); } } catch (err) { console.error("Failed to open save dialog:", err); @@ -76,6 +89,15 @@ export function initTargen() { // Generate button clicks btnGenerate.addEventListener("click", async () => { + const basename = targetBasename.value.trim(); + if (!currentWorkingDir || !basename) { + logPre.textContent = "[ERROR] Please specify both a target basename and a working directory.\n"; + logContainer.open = true; + logContainer.classList.remove("hidden"); + btnGenerate.disabled = false; + return; + } + logPre.textContent = ""; logContainer.open = false; logContainer.classList.remove("hidden");