diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index 7605822..7cb9673 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -1,3 +1,4 @@ +use crate::util::toolbox::open_toolbox_container_in_terminal; use crate::util::toolbox::start_toolbox_container; use crate::util::toolbox::stop_toolbox_container; use gtk::prelude::ButtonExt; @@ -8,6 +9,8 @@ use relm4::factory::{FactoryComponent, FactorySender}; use relm4::gtk; use relm4::gtk::prelude::WidgetExt; use relm4_icons::icon_names; +use std::collections::HashSet; + #[derive(Debug, PartialEq)] pub enum ContainerStatus { Running, @@ -15,11 +18,17 @@ pub enum ContainerStatus { Refreshing, } +#[derive(Debug, PartialEq, Hash, Eq)] +pub enum ContainerOperation { + LaunchingTerminal, +} + #[derive(Debug)] pub struct Container { hash: String, value: String, status: ContainerStatus, + running_operations: HashSet, } #[derive(Debug)] @@ -33,6 +42,7 @@ pub enum ContainerMsg { pub enum CommandMessage { SetStarted, SetStopped, + FinishLaunchTerminal, } pub struct ContainerInit { @@ -103,6 +113,8 @@ impl FactoryComponent for Container { add_suffix = >k::Box{ gtk::AspectFrame{ + #[watch] + set_visible: !self.running_operations.contains(&ContainerOperation::LaunchingTerminal), set_ratio: 1.0, gtk::Button { set_icon_name: icon_names::TERMINAL, @@ -112,6 +124,23 @@ impl FactoryComponent for Container { set_css_classes: &["flat"], connect_clicked => ContainerMsg::OpenTerminal, }, + + }, + gtk::AspectFrame{ + #[watch] + set_visible: self.running_operations.contains(&ContainerOperation::LaunchingTerminal), + set_ratio: 1.0, + gtk::Button { + set_margin_start: 10, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["flat"], + #[wrap(Some)] + set_child = >k::Spinner { + #[watch] + set_spinning: self.running_operations.contains(&ContainerOperation::LaunchingTerminal), + }, + }, }, }, } @@ -122,6 +151,7 @@ impl FactoryComponent for Container { hash: index.clone(), value: value.name.clone(), status: value.status, + running_operations: HashSet::new(), } } @@ -143,7 +173,16 @@ impl FactoryComponent for Container { Err(_) => CommandMessage::SetStarted, }); } - ContainerMsg::OpenTerminal => {} + ContainerMsg::OpenTerminal => { + self.running_operations + .insert(ContainerOperation::LaunchingTerminal); + let hash = (&self.hash).clone(); + sender.spawn_oneshot_command(move || { + match open_toolbox_container_in_terminal(&hash) { + _ => CommandMessage::FinishLaunchTerminal, + } + }); + } } } @@ -151,6 +190,10 @@ impl FactoryComponent for Container { match message { CommandMessage::SetStarted => self.status = ContainerStatus::Running, CommandMessage::SetStopped => self.status = ContainerStatus::NotRunning, + CommandMessage::FinishLaunchTerminal => { + self.running_operations + .remove(&ContainerOperation::LaunchingTerminal); + } }; } } diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs index 78e42c4..1f49500 100644 --- a/src/util/toolbox.rs +++ b/src/util/toolbox.rs @@ -149,6 +149,31 @@ impl ToolbxContainer { } } +pub fn open_toolbox_container_in_terminal(hash: &str) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") + .arg("gnome-terminal") + .arg("--") + .arg("toolbox") + .arg("enter") + .arg(hash) + .output(); + + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + if output.status.code() == Some(0) { + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } +} + pub fn stop_toolbox_container(hash: &str) -> Result<(), ToolbxError> { let output = Command::new("flatpak-spawn") .arg("--host") //Command::new("podman")