Remoting public alpha (#14541)

Release Notes:

- remoting: An alpha version of remote development is now available to
everyone. For more information on how to use it, and limitations see
https://zed.dev/docs/remote-development.
This commit is contained in:
Conrad Irwin 2024-07-16 12:05:55 -06:00 committed by GitHub
parent 62ab6e1a11
commit cf8bd4a90a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 77 additions and 63 deletions

1
Cargo.lock generated
View file

@ -8525,7 +8525,6 @@ dependencies = [
"client", "client",
"dev_server_projects", "dev_server_projects",
"editor", "editor",
"feature_flags",
"fuzzy", "fuzzy",
"gpui", "gpui",
"language", "language",

View file

@ -16,7 +16,6 @@ doctest = false
anyhow.workspace = true anyhow.workspace = true
client.workspace = true client.workspace = true
editor.workspace = true editor.workspace = true
feature_flags.workspace = true
fuzzy.workspace = true fuzzy.workspace = true
gpui.workspace = true gpui.workspace = true
markdown.workspace = true markdown.workspace = true

View file

@ -2,10 +2,9 @@ use std::time::Duration;
use anyhow::anyhow; use anyhow::anyhow;
use anyhow::Context; use anyhow::Context;
use client::Client;
use dev_server_projects::{DevServer, DevServerId, DevServerProject, DevServerProjectId}; use dev_server_projects::{DevServer, DevServerId, DevServerProject, DevServerProjectId};
use editor::Editor; use editor::Editor;
use feature_flags::FeatureFlagAppExt;
use feature_flags::FeatureFlagViewExt;
use gpui::AsyncWindowContext; use gpui::AsyncWindowContext;
use gpui::Subscription; use gpui::Subscription;
use gpui::Task; use gpui::Task;
@ -33,6 +32,7 @@ use ui::{
}; };
use ui_input::{FieldLabelLayout, TextField}; use ui_input::{FieldLabelLayout, TextField};
use util::ResultExt; use util::ResultExt;
use workspace::notifications::NotifyResultExt;
use workspace::{notifications::DetachAndPromptErr, AppState, ModalView, Workspace, WORKSPACE_DB}; use workspace::{notifications::DetachAndPromptErr, AppState, ModalView, Workspace, WORKSPACE_DB};
use crate::open_dev_server_project; use crate::open_dev_server_project;
@ -70,20 +70,7 @@ enum Mode {
} }
impl DevServerProjects { impl DevServerProjects {
pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) { pub fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
cx.observe_flag::<feature_flags::Remoting, _>(|enabled, workspace, _| {
if enabled {
Self::register_open_remote_action(workspace);
}
})
.detach();
if cx.has_flag::<feature_flags::Remoting>() {
Self::register_open_remote_action(workspace);
}
}
fn register_open_remote_action(workspace: &mut Workspace) {
workspace.register_action(|workspace, _: &OpenRemote, cx| { workspace.register_action(|workspace, _: &OpenRemote, cx| {
let handle = cx.view().downgrade(); let handle = cx.view().downgrade();
workspace.toggle_modal(cx, |cx| Self::new(cx, handle)) workspace.toggle_modal(cx, |cx| Self::new(cx, handle))
@ -969,53 +956,86 @@ impl DevServerProjects {
is_creating = Some(*creating); is_creating = Some(*creating);
creating_dev_server = Some(*dev_server_id); creating_dev_server = Some(*dev_server_id);
}; };
let is_signed_out = Client::global(cx).status().borrow().is_signed_out();
Modal::new("remote-projects", Some(self.scroll_handle.clone())) Modal::new("remote-projects", Some(self.scroll_handle.clone()))
.header( .header(
ModalHeader::new() ModalHeader::new()
.show_dismiss_button(true) .show_dismiss_button(true)
.child(Headline::new("Remote Projects").size(HeadlineSize::Small)), .child(Headline::new("Remote Projects (alpha)").size(HeadlineSize::Small)),
) )
.section( .when(is_signed_out, |modal| {
Section::new().child( modal
div().mb_4().child( .section(Section::new().child(v_flex().mb_4().child(Label::new(
List::new() "You are not currently signed in to Zed. Currently the remote development featuers are only available to signed in users. Please sign in to continue.",
.empty_message("No dev servers registered.") ))))
.header(Some( .footer(
ListHeader::new("Dev Servers").end_slot( ModalFooter::new().end_slot(
Button::new("register-dev-server-button", "New Server") Button::new("sign_in", "Sign in")
.icon(IconName::Plus) .icon(IconName::Github)
.icon_position(IconPosition::Start) .icon_position(IconPosition::Start)
.tooltip(|cx| { .style(ButtonStyle::Filled)
Tooltip::text("Register a new dev server", cx) .full_width()
}) .on_click(cx.listener(|_, _, cx| {
.on_click(cx.listener(|this, _, cx| { let client = Client::global(cx).clone();
this.mode = cx.spawn(|_, mut cx| async move {
Mode::CreateDevServer(CreateDevServer::default()); client
this.dev_server_name_input.update( .authenticate_and_connect(true, &cx)
cx, .await
|text_field, cx| { .notify_async_err(&mut cx);
text_field.editor().update(cx, |editor, cx| { })
editor.set_text("", cx); .detach();
}); cx.emit(gpui::DismissEvent);
}, })),
); ),
cx.notify(); )
})), })
), .when(!is_signed_out, |modal| {
)) modal.section(
.children(dev_servers.iter().map(|dev_server| { Section::new().child(
let creating = if creating_dev_server == Some(dev_server.id) { div().mb_4().child(
is_creating List::new()
} else { .empty_message("No dev servers registered.")
None .header(Some(
}; ListHeader::new("Dev Servers").end_slot(
self.render_dev_server(dev_server, creating, cx) Button::new("register-dev-server-button", "New Server")
.into_any_element() .icon(IconName::Plus)
})), .icon_position(IconPosition::Start)
.tooltip(|cx| {
Tooltip::text("Register a new dev server", cx)
})
.on_click(cx.listener(|this, _, cx| {
this.mode = Mode::CreateDevServer(
CreateDevServer::default(),
);
this.dev_server_name_input.update(
cx,
|text_field, cx| {
text_field.editor().update(
cx,
|editor, cx| {
editor.set_text("", cx);
},
);
},
);
cx.notify();
})),
),
))
.children(dev_servers.iter().map(|dev_server| {
let creating = if creating_dev_server == Some(dev_server.id) {
is_creating
} else {
None
};
self.render_dev_server(dev_server, creating, cx)
.into_any_element()
})),
),
), ),
), )
) })
} }
} }

View file

@ -5,7 +5,6 @@ use client::{DevServerProjectId, ProjectId};
use dev_servers::reconnect_to_dev_server_project; use dev_servers::reconnect_to_dev_server_project;
pub use dev_servers::DevServerProjects; pub use dev_servers::DevServerProjects;
use disconnected_overlay::DisconnectedOverlay; use disconnected_overlay::DisconnectedOverlay;
use feature_flags::FeatureFlagAppExt;
use fuzzy::{StringMatch, StringMatchCandidate}; use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{ use gpui::{
Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView,
@ -518,9 +517,6 @@ impl PickerDelegate for RecentProjectsDelegate {
} }
fn render_footer(&self, cx: &mut ViewContext<Picker<Self>>) -> Option<AnyElement> { fn render_footer(&self, cx: &mut ViewContext<Picker<Self>>) -> Option<AnyElement> {
if !cx.has_flag::<feature_flags::Remoting>() {
return None;
}
Some( Some(
h_flex() h_flex()
.border_t_1() .border_t_1()
@ -534,7 +530,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("New remote project").color(Color::Muted)) .child(Label::new("Open remote folder").color(Color::Muted))
.on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())), .on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())),
) )
.child( .child(