diff --git a/src-tauri/src/commands/container.rs b/src-tauri/src/commands/container.rs index 292a578..32c9fda 100644 --- a/src-tauri/src/commands/container.rs +++ b/src-tauri/src/commands/container.rs @@ -104,7 +104,6 @@ pub async fn container_operation( op_type: String, ) -> Result { let docker = state.docker.clone(); - let terminal = get_terminal(&app_handle).await?; let mut list_container_filters = std::collections::HashMap::new(); list_container_filters.insert(String::from("name"), vec![container_name.clone()]); @@ -144,10 +143,21 @@ pub async fn container_operation( Err(e) => Err(format!("Failed to restart container: {}", e.to_string())), }, "web" => open_container_url(container), - "exec" => match open_terminal(&terminal, Some("exec"), Some(&container_name)) { - Ok(_) => Ok("Opening terminal".to_string()), - Err(e) => Err(format!("Failed to open terminal: {}", e.to_string())), - }, + "exec" => { + let terminal = get_terminal(&app_handle).await.map_err(|e| e.to_string())?; + match open_terminal(&terminal, Some("exec"), Some(&container_name)) { + Ok(_) => Ok("Opening terminal".to_string()), + Err(e) => { + let error_msg = e.to_string(); + + if error_msg.contains("deprecated") { + Ok("Terminal opened".to_string()) + } else { + Err(format!("Failed to open terminal: {}", error_msg)) + } + } + } + } _ => Err("Invalid operation type".to_string()), }; diff --git a/src-tauri/src/utils/terminal.rs b/src-tauri/src/utils/terminal.rs index 247af22..82ff28b 100644 --- a/src-tauri/src/utils/terminal.rs +++ b/src-tauri/src/utils/terminal.rs @@ -2,6 +2,7 @@ use crate::constants::DOCKER_TERMINAL; use crate::constants::{LINUX_COMMAND_TEMPLATE, MACOS_COMMAND_TEMPLATE, WINDOWS_COMMAND_TEMPLATE}; use crate::utils::storage::get_storage_path; use std::process::Command; +use serde_json::{json, Value}; use tauri::Manager; use tauri::{AppHandle, Wry}; use tauri_plugin_store::with_store; @@ -64,6 +65,18 @@ define_terminals!( WezTerm => "WezTerm", MACOS_COMMAND_TEMPLATE, "macos" ); + +// A fallback mechanism to figure out the default installed terminal on the system +pub fn find_default_terminal() -> Option { + for terminal in Terminal::variants() { + let app_name = terminal.app_name(); + if Command::new("which").arg(app_name).output().is_ok() { + return Some(*terminal); + } + } + None +} + pub async fn get_terminal(app: &AppHandle) -> Result { let stores = app.state::>(); let path = get_storage_path(); @@ -71,10 +84,22 @@ pub async fn get_terminal(app: &AppHandle) -> Result { let terminal_str = with_store(app.clone(), stores, path.clone(), |store| { match store.get(DOCKER_TERMINAL) { Some(value) => Ok(value.clone()), - None => Err(Error::NotFound(path.clone())), + None => { + // Find the terminal if not found in storage + if let Some(terminal) = find_default_terminal() { + let terminal_app_name = terminal.app_name().to_string(); + store.insert(DOCKER_TERMINAL.parse().unwrap(), terminal_app_name.clone().into()) + .map_err(|e| format!("Failed to store terminal: {}", e)).unwrap(); + + // Return the found terminal app name + Ok(terminal_app_name.into()) + } else { + Err(Error::NotFound(path.clone())) + } + } } }) - .map_err(|e| format!("Failed to retrieve terminal from storage: {}", e))?; + .map_err(|e| format!("Failed to retrieve terminal from storage: {}", e))?; let terminal_str = terminal_str.as_str().unwrap_or_default().to_string();