remote config fixes (#12178)

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin 2024-05-22 22:28:00 -06:00 committed by GitHub
parent af8641ce5b
commit 8b57d6d4c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 106 additions and 85 deletions

View file

@ -49,9 +49,9 @@ pub struct DevServerProjects {
_dev_server_subscription: Subscription, _dev_server_subscription: Subscription,
} }
#[derive(Default, Clone)] #[derive(Default)]
struct CreateDevServer { struct CreateDevServer {
creating: bool, creating: Option<Task<()>>,
dev_server_id: Option<DevServerId>, dev_server_id: Option<DevServerId>,
access_token: Option<String>, access_token: Option<String>,
manual_setup: bool, manual_setup: bool,
@ -316,60 +316,75 @@ impl DevServerProjects {
let workspace = self.workspace.clone(); let workspace = self.workspace.clone();
let store = dev_server_projects::Store::global(cx); let store = dev_server_projects::Store::global(cx);
cx.spawn({ let task = cx
|this, mut cx| async move { .spawn({
let result = dev_server.await; |this, mut cx| async move {
let result = dev_server.await;
match result { match result {
Ok(dev_server) => { Ok(dev_server) => {
if let Some(ssh_connection_string) = ssh_connection_string { if let Some(ssh_connection_string) = ssh_connection_string {
spawn_ssh_task( this.update(&mut cx, |this, cx| {
workspace if let Mode::CreateDevServer(CreateDevServer {
.upgrade() access_token,
.ok_or_else(|| anyhow!("workspace dropped"))?, dev_server_id,
store, ..
DevServerId(dev_server.dev_server_id), }) = &mut this.mode
ssh_connection_string, {
dev_server.access_token.clone(), access_token.replace(dev_server.access_token.clone());
&mut cx, dev_server_id
) .replace(DevServerId(dev_server.dev_server_id));
.await }
.log_err(); cx.notify();
})?;
spawn_ssh_task(
workspace
.upgrade()
.ok_or_else(|| anyhow!("workspace dropped"))?,
store,
DevServerId(dev_server.dev_server_id),
ssh_connection_string,
dev_server.access_token.clone(),
&mut cx,
)
.await
.log_err();
}
this.update(&mut cx, |this, cx| {
this.focus_handle.focus(cx);
this.mode = Mode::CreateDevServer(CreateDevServer {
creating: None,
dev_server_id: Some(DevServerId(dev_server.dev_server_id)),
access_token: Some(dev_server.access_token),
manual_setup,
});
cx.notify();
})?;
Ok(())
} }
Err(e) => {
this.update(&mut cx, |this, cx| {
this.mode = Mode::CreateDevServer(CreateDevServer {
creating: None,
dev_server_id: existing_id,
access_token: None,
manual_setup,
});
cx.notify()
})
.log_err();
this.update(&mut cx, |this, cx| { return Err(e);
this.focus_handle.focus(cx); }
this.mode = Mode::CreateDevServer(CreateDevServer {
creating: false,
dev_server_id: Some(DevServerId(dev_server.dev_server_id)),
access_token: Some(dev_server.access_token),
manual_setup,
});
cx.notify();
})?;
Ok(())
}
Err(e) => {
this.update(&mut cx, |this, cx| {
this.mode = Mode::CreateDevServer(CreateDevServer {
creating: false,
dev_server_id: existing_id,
access_token: None,
manual_setup,
});
cx.notify()
})
.log_err();
return Err(e);
} }
} }
} })
}) .prompt_err("Failed to create server", cx, |_, _| None);
.detach_and_prompt_err("Failed to create server", cx, |_, _| None);
self.mode = Mode::CreateDevServer(CreateDevServer { self.mode = Mode::CreateDevServer(CreateDevServer {
creating: true, creating: Some(task),
dev_server_id: existing_id, dev_server_id: existing_id,
access_token, access_token,
manual_setup, manual_setup,
@ -471,7 +486,7 @@ impl DevServerProjects {
self.create_dev_server_project(create_project.dev_server_id, cx); self.create_dev_server_project(create_project.dev_server_id, cx);
} }
Mode::CreateDevServer(state) => { Mode::CreateDevServer(state) => {
if !state.creating { if state.creating.is_none() || state.dev_server_id.is_some() {
self.create_or_update_dev_server( self.create_or_update_dev_server(
state.manual_setup, state.manual_setup,
state.dev_server_id, state.dev_server_id,
@ -548,7 +563,7 @@ impl DevServerProjects {
.on_click(cx.listener(move |this, _, cx| { .on_click(cx.listener(move |this, _, cx| {
this.mode = Mode::CreateDevServer(CreateDevServer { this.mode = Mode::CreateDevServer(CreateDevServer {
dev_server_id: Some(dev_server_id), dev_server_id: Some(dev_server_id),
creating: false, creating: None,
access_token: None, access_token: None,
manual_setup, manual_setup,
}); });
@ -683,16 +698,14 @@ impl DevServerProjects {
} }
fn render_create_dev_server( fn render_create_dev_server(
&mut self, &self,
state: CreateDevServer, state: &CreateDevServer,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> impl IntoElement { ) -> impl IntoElement {
let CreateDevServer { let creating = state.creating.is_some();
creating, let dev_server_id = state.dev_server_id;
dev_server_id, let access_token = state.access_token.clone();
access_token, let manual_setup = state.manual_setup;
manual_setup,
} = state.clone();
let status = dev_server_id let status = dev_server_id
.map(|id| self.dev_server_store.read(cx).dev_server_status(id)) .map(|id| self.dev_server_store.read(cx).dev_server_status(id))
@ -738,13 +751,11 @@ impl DevServerProjects {
Label::new("Connect via SSH (default)"), Label::new("Connect via SSH (default)"),
!manual_setup, !manual_setup,
cx.listener({ cx.listener({
let state = state.clone();
move |this, _, cx| { move |this, _, cx| {
this.mode = Mode::CreateDevServer(CreateDevServer { if let Mode::CreateDevServer(CreateDevServer{ manual_setup, .. }) = &mut this.mode {
manual_setup: false, *manual_setup = false;
..state.clone() }
}); cx.notify()
cx.notify()
} }
}), }),
)) ))
@ -753,13 +764,11 @@ impl DevServerProjects {
Label::new("Manual Setup"), Label::new("Manual Setup"),
manual_setup, manual_setup,
cx.listener({ cx.listener({
let state = state.clone();
move |this, _, cx| { move |this, _, cx| {
this.mode = Mode::CreateDevServer(CreateDevServer { if let Mode::CreateDevServer(CreateDevServer{ manual_setup, .. }) = &mut this.mode {
manual_setup: true, *manual_setup = true;
..state.clone() }
}); cx.notify()
cx.notify()
}}), }}),
))) )))
.when(dev_server_id.is_none(), |el| { .when(dev_server_id.is_none(), |el| {
@ -807,10 +816,10 @@ impl DevServerProjects {
cx.notify(); cx.notify();
})) }))
} else { } else {
Button::new("create-dev-server", if manual_setup { "Create"} else { "Connect"}) Button::new("create-dev-server", if manual_setup { if dev_server_id.is_some() { "Update" } else { "Create"} } else { if dev_server_id.is_some() { "Reconnect" } else { "Connect"} })
.style(ButtonStyle::Filled) .style(ButtonStyle::Filled)
.layer(ElevationIndex::ModalSurface) .layer(ElevationIndex::ModalSurface)
.disabled(creating) .disabled(creating && dev_server_id.is_none())
.on_click(cx.listener({ .on_click(cx.listener({
let access_token = access_token.clone(); let access_token = access_token.clone();
move |this, _, cx| { move |this, _, cx| {
@ -975,18 +984,15 @@ impl Render for DevServerProjects {
.on_mouse_down_out(cx.listener(|this, _, cx| { .on_mouse_down_out(cx.listener(|this, _, cx| {
if matches!(this.mode, Mode::Default(None)) { if matches!(this.mode, Mode::Default(None)) {
cx.emit(DismissEvent) cx.emit(DismissEvent)
} else {
this.focus_handle(cx).focus(cx);
cx.stop_propagation()
} }
})) }))
.w(rems(34.)) .w(rems(34.))
.max_h(rems(40.)) .max_h(rems(40.))
.child(match &self.mode { .child(match &self.mode {
Mode::Default(_) => self.render_default(cx).into_any_element(), Mode::Default(_) => self.render_default(cx).into_any_element(),
Mode::CreateDevServer(state) => self Mode::CreateDevServer(state) => {
.render_create_dev_server(state.clone(), cx) self.render_create_dev_server(state, cx).into_any_element()
.into_any_element(), }
}) })
} }
} }

View file

@ -535,7 +535,7 @@ impl PickerDelegate for RecentProjectsDelegate {
.when_some(KeyBinding::for_action(&OpenRemote, cx), |button, key| { .when_some(KeyBinding::for_action(&OpenRemote, cx), |button, key| {
button.child(key) button.child(key)
}) })
.child(Label::new("Connect…").color(Color::Muted)) .child(Label::new("New remote project…").color(Color::Muted))
.on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())), .on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())),
) )
.child( .child(
@ -544,7 +544,7 @@ impl PickerDelegate for RecentProjectsDelegate {
KeyBinding::for_action(&workspace::Open, cx), KeyBinding::for_action(&workspace::Open, cx),
|button, key| button.child(key), |button, key| button.child(key),
) )
.child(Label::new("Open folder…").color(Color::Muted)) .child(Label::new("Open local folder…").color(Color::Muted))
.on_click(|_, cx| cx.dispatch_action(workspace::Open.boxed_clone())), .on_click(|_, cx| cx.dispatch_action(workspace::Open.boxed_clone())),
) )
.into_any(), .into_any(),

View file

@ -283,7 +283,7 @@ impl TerminalView {
cx.spawn(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
Timer::after(CURSOR_BLINK_INTERVAL).await; Timer::after(CURSOR_BLINK_INTERVAL).await;
this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx)) this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx))
.log_err(); .ok();
}) })
.detach(); .detach();
} }

View file

@ -512,6 +512,13 @@ where
} }
pub trait DetachAndPromptErr { pub trait DetachAndPromptErr {
fn prompt_err(
self,
msg: &str,
cx: &mut WindowContext,
f: impl FnOnce(&anyhow::Error, &mut WindowContext) -> Option<String> + 'static,
) -> Task<()>;
fn detach_and_prompt_err( fn detach_and_prompt_err(
self, self,
msg: &str, msg: &str,
@ -524,12 +531,12 @@ impl<R> DetachAndPromptErr for Task<anyhow::Result<R>>
where where
R: 'static, R: 'static,
{ {
fn detach_and_prompt_err( fn prompt_err(
self, self,
msg: &str, msg: &str,
cx: &mut WindowContext, cx: &mut WindowContext,
f: impl FnOnce(&anyhow::Error, &mut WindowContext) -> Option<String> + 'static, f: impl FnOnce(&anyhow::Error, &mut WindowContext) -> Option<String> + 'static,
) { ) -> Task<()> {
let msg = msg.to_owned(); let msg = msg.to_owned();
cx.spawn(|mut cx| async move { cx.spawn(|mut cx| async move {
if let Err(err) = self.await { if let Err(err) = self.await {
@ -543,6 +550,14 @@ where
} }
} }
}) })
.detach(); }
fn detach_and_prompt_err(
self,
msg: &str,
cx: &mut WindowContext,
f: impl FnOnce(&anyhow::Error, &mut WindowContext) -> Option<String> + 'static,
) {
self.prompt_err(msg, cx, f).detach();
} }
} }