diff --git a/src/app/mod.rs b/src/app/mod.rs index e41ee14..cfd32e2 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -915,6 +915,11 @@ impl Ashell { format!("{}@{}:{}", session.user, session.host, session.port) }); } + let is_sftp = self.tab_groups.iter().any(|g| g.id == tab_id); + if is_sftp { + tab_title = self.tab_groups.iter().find(|g| g.id == tab_id).map(|g| g.title.clone()); + session_label = Some("sftp".to_string()); + } if self.system_tab_id.as_deref() == Some(tab_id.as_str()) { self.system_status = Some(reason.clone().into()); } diff --git a/src/session/mod.rs b/src/session/mod.rs index 47028bc..6036011 100644 --- a/src/session/mod.rs +++ b/src/session/mod.rs @@ -558,6 +558,9 @@ impl Ashell { }; self.connection_progress = None; let mut groups_to_restart_sftp = std::collections::HashSet::new(); + if self.tab_groups.iter().any(|g| g.id == progress.tab_id) { + groups_to_restart_sftp.insert(progress.tab_id.clone()); + } let mut retry_tabs = Vec::new(); for (ix, tab) in self.tabs.iter().enumerate() { @@ -566,7 +569,7 @@ impl Ashell { } } - if retry_tabs.is_empty() { + if retry_tabs.is_empty() && groups_to_restart_sftp.is_empty() { cx.notify(); return; } @@ -639,10 +642,20 @@ impl Ashell { } pub(crate) fn cancel_connection_progress(&mut self, cx: &mut Context) { - if self.connection_progress.is_none() { + let Some(progress) = self.connection_progress.clone() else { + return; + }; + self.connection_progress = None; + + if self.tab_groups.iter().any(|g| g.id == progress.tab_id) { + if let Some(group) = self.tab_groups.iter_mut().find(|g| g.id == progress.tab_id) { + group.sftp = None; + } + self.sftp_handles.remove(&progress.tab_id); + cx.notify(); return; } - self.connection_progress = None; + let tabs_to_close: Vec<_> = self .tabs .iter() diff --git a/src/sftp/mod.rs b/src/sftp/mod.rs index 8e33961..77974f7 100644 --- a/src/sftp/mod.rs +++ b/src/sftp/mod.rs @@ -218,9 +218,13 @@ pub fn spawn_sftp( .await { let _ = events.send(BackendEvent::SftpStatus { - tab_id, + tab_id: tab_id.clone(), text: format!("sftp error: {err:#}"), }); + let _ = events.send(BackendEvent::Closed { + tab_id, + reason: format!("sftp error: {err:#}"), + }); } }); SftpHandle { @@ -824,6 +828,8 @@ async fn connect_and_authenticate( ) -> Result>> { let config = Arc::new(client::Config { inactivity_timeout: Some(std::time::Duration::from_secs(600)), + keepalive_interval: Some(std::time::Duration::from_secs(10)), + keepalive_max: 3, ..Default::default() }); let addr = format!("{}:{}", session.host, session.port);