ssh remote: Handle disconnect on project and show overlay (#19014)
Demo: https://github.com/user-attachments/assets/e5edf8f3-8c15-482e-a792-6eb619f83de4 Release Notes: - N/A --------- Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
parent
e3ff2ced79
commit
b75532fad7
16 changed files with 264 additions and 78 deletions
|
@ -58,7 +58,7 @@ use node_runtime::NodeRuntime;
|
|||
use parking_lot::{Mutex, RwLock};
|
||||
pub use prettier_store::PrettierStore;
|
||||
use project_settings::{ProjectSettings, SettingsObserver, SettingsObserverEvent};
|
||||
use remote::SshRemoteClient;
|
||||
use remote::{SshConnectionOptions, SshRemoteClient};
|
||||
use rpc::{proto::SSH_PROJECT_ID, AnyProtoClient, ErrorCode};
|
||||
use search::{SearchInputKind, SearchQuery, SearchResult};
|
||||
use search_history::SearchHistory;
|
||||
|
@ -245,6 +245,7 @@ pub enum Event {
|
|||
},
|
||||
RemoteIdChanged(Option<u64>),
|
||||
DisconnectedFromHost,
|
||||
DisconnectedFromSshRemote,
|
||||
Closed,
|
||||
DeletedEntry(ProjectEntryId),
|
||||
CollaboratorUpdated {
|
||||
|
@ -755,6 +756,8 @@ impl Project {
|
|||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
cx.subscribe(&ssh, Self::on_ssh_event).detach();
|
||||
cx.observe(&ssh, |_, _, cx| cx.notify()).detach();
|
||||
|
||||
let this = Self {
|
||||
|
@ -1313,6 +1316,12 @@ impl Project {
|
|||
.map(|ssh| ssh.read(cx).connection_state())
|
||||
}
|
||||
|
||||
pub fn ssh_connection_options(&self, cx: &AppContext) -> Option<SshConnectionOptions> {
|
||||
self.ssh_client
|
||||
.as_ref()
|
||||
.map(|ssh| ssh.read(cx).connection_options())
|
||||
}
|
||||
|
||||
pub fn replica_id(&self) -> ReplicaId {
|
||||
match self.client_state {
|
||||
ProjectClientState::Remote { replica_id, .. } => replica_id,
|
||||
|
@ -1658,7 +1667,7 @@ impl Project {
|
|||
}
|
||||
|
||||
pub fn disconnected_from_host(&mut self, cx: &mut ModelContext<Self>) {
|
||||
if self.is_disconnected() {
|
||||
if self.is_disconnected(cx) {
|
||||
return;
|
||||
}
|
||||
self.disconnected_from_host_internal(cx);
|
||||
|
@ -1708,16 +1717,24 @@ impl Project {
|
|||
cx.emit(Event::Closed);
|
||||
}
|
||||
|
||||
pub fn is_disconnected(&self) -> bool {
|
||||
pub fn is_disconnected(&self, cx: &AppContext) -> bool {
|
||||
match &self.client_state {
|
||||
ProjectClientState::Remote {
|
||||
sharing_has_stopped,
|
||||
..
|
||||
} => *sharing_has_stopped,
|
||||
ProjectClientState::Local if self.is_via_ssh() => self.ssh_is_disconnected(cx),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn ssh_is_disconnected(&self, cx: &AppContext) -> bool {
|
||||
self.ssh_client
|
||||
.as_ref()
|
||||
.map(|ssh| ssh.read(cx).is_disconnected())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn capability(&self) -> Capability {
|
||||
match &self.client_state {
|
||||
ProjectClientState::Remote { capability, .. } => *capability,
|
||||
|
@ -1725,8 +1742,8 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_read_only(&self) -> bool {
|
||||
self.is_disconnected() || self.capability() == Capability::ReadOnly
|
||||
pub fn is_read_only(&self, cx: &AppContext) -> bool {
|
||||
self.is_disconnected(cx) || self.capability() == Capability::ReadOnly
|
||||
}
|
||||
|
||||
pub fn is_local(&self) -> bool {
|
||||
|
@ -1807,7 +1824,7 @@ impl Project {
|
|||
path: impl Into<ProjectPath>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
if self.is_via_collab() && self.is_disconnected() {
|
||||
if (self.is_via_collab() || self.is_via_ssh()) && self.is_disconnected(cx) {
|
||||
return Task::ready(Err(anyhow!(ErrorCode::Disconnected)));
|
||||
}
|
||||
|
||||
|
@ -2114,6 +2131,30 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_ssh_event(
|
||||
&mut self,
|
||||
_: Model<SshRemoteClient>,
|
||||
event: &remote::SshRemoteEvent,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
remote::SshRemoteEvent::Disconnected => {
|
||||
// if self.is_via_ssh() {
|
||||
// self.collaborators.clear();
|
||||
self.worktree_store.update(cx, |store, cx| {
|
||||
store.disconnected_from_host(cx);
|
||||
});
|
||||
self.buffer_store.update(cx, |buffer_store, cx| {
|
||||
buffer_store.disconnected_from_host(cx)
|
||||
});
|
||||
self.lsp_store.update(cx, |lsp_store, _cx| {
|
||||
lsp_store.disconnected_from_ssh_remote()
|
||||
});
|
||||
cx.emit(Event::DisconnectedFromSshRemote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_settings_observer_event(
|
||||
&mut self,
|
||||
_: Model<SettingsObserver>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue