Rename dev servers to remote projects in UI (#19527)

Conrad Irwin and Mikayla created

Release Notes:

- N/A

Co-authored-by: Mikayla <mikayla@zed.dev>

Change summary

crates/recent_projects/src/disconnected_overlay.rs |  6 
crates/recent_projects/src/recent_projects.rs      | 11 +
crates/recent_projects/src/remote_servers.rs       | 81 ++++++++-------
crates/recent_projects/src/ssh_connections.rs      |  9 +
crates/remote/src/ssh_session.rs                   |  2 
crates/title_bar/src/title_bar.rs                  |  2 
6 files changed, 62 insertions(+), 49 deletions(-)

Detailed changes

crates/recent_projects/src/disconnected_overlay.rs 🔗

@@ -11,8 +11,8 @@ use ui::{
 use workspace::{notifications::DetachAndPromptErr, ModalView, OpenOptions, Workspace};
 
 use crate::{
-    dev_servers::reconnect_to_dev_server_project, open_dev_server_project, open_ssh_project,
-    DevServerProjects,
+    open_dev_server_project, open_ssh_project, remote_servers::reconnect_to_dev_server_project,
+    RemoteServerProjects,
 };
 
 enum Host {
@@ -130,7 +130,7 @@ impl DisconnectedOverlay {
         } else {
             return workspace.update(cx, |workspace, cx| {
                 let handle = cx.view().downgrade();
-                workspace.toggle_modal(cx, |cx| DevServerProjects::new(cx, handle))
+                workspace.toggle_modal(cx, |cx| RemoteServerProjects::new(cx, handle))
             });
         }
     }

crates/recent_projects/src/recent_projects.rs 🔗

@@ -1,12 +1,10 @@
-mod dev_servers;
 pub mod disconnected_overlay;
+mod remote_servers;
 mod ssh_connections;
 use remote::SshConnectionOptions;
 pub use ssh_connections::open_ssh_project;
 
 use client::{DevServerProjectId, ProjectId};
-use dev_servers::reconnect_to_dev_server_project;
-pub use dev_servers::DevServerProjects;
 use disconnected_overlay::DisconnectedOverlay;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
@@ -19,6 +17,8 @@ use picker::{
     highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText},
     Picker, PickerDelegate,
 };
+use remote_servers::reconnect_to_dev_server_project;
+pub use remote_servers::RemoteServerProjects;
 use rpc::proto::DevServerStatus;
 use serde::Deserialize;
 use settings::Settings;
@@ -53,7 +53,8 @@ gpui::actions!(projects, [OpenRemote]);
 pub fn init(cx: &mut AppContext) {
     SshSettings::register(cx);
     cx.observe_new_views(RecentProjects::register).detach();
-    cx.observe_new_views(DevServerProjects::register).detach();
+    cx.observe_new_views(RemoteServerProjects::register)
+        .detach();
     cx.observe_new_views(DisconnectedOverlay::register).detach();
 }
 
@@ -359,7 +360,7 @@ impl PickerDelegate for RecentProjectsDelegate {
                                             if response == 1 {
                                                 workspace.update(&mut cx, |workspace, cx| {
                                                     let handle = cx.view().downgrade();
-                                                    workspace.toggle_modal(cx, |cx| DevServerProjects::new(cx, handle))
+                                                    workspace.toggle_modal(cx, |cx| RemoteServerProjects::new(cx, handle))
                                                 })?;
                                             } else {
                                                 workspace.update(&mut cx, |workspace, cx| {

crates/recent_projects/src/dev_servers.rs → crates/recent_projects/src/remote_servers.rs 🔗

@@ -55,7 +55,7 @@ use crate::ssh_connections::SshPrompt;
 use crate::ssh_connections::SshSettings;
 use crate::OpenRemote;
 
-pub struct DevServerProjects {
+pub struct RemoteServerProjects {
     mode: Mode,
     focus_handle: FocusHandle,
     scroll_handle: ScrollHandle,
@@ -63,14 +63,14 @@ pub struct DevServerProjects {
     selectable_items: SelectableItemList,
 }
 
-struct CreateDevServer {
+struct CreateRemoteServer {
     address_editor: View<Editor>,
     address_error: Option<SharedString>,
     ssh_prompt: Option<View<SshPrompt>>,
     _creating: Option<Task<Option<()>>>,
 }
 
-impl CreateDevServer {
+impl CreateRemoteServer {
     fn new(cx: &mut WindowContext<'_>) -> Self {
         let address_editor = cx.new_view(Editor::single_line);
         address_editor.update(cx, |this, cx| {
@@ -92,7 +92,7 @@ struct ProjectPicker {
 }
 
 type SelectedItemCallback =
-    Box<dyn Fn(&mut DevServerProjects, &mut ViewContext<DevServerProjects>) + 'static>;
+    Box<dyn Fn(&mut RemoteServerProjects, &mut ViewContext<RemoteServerProjects>) + 'static>;
 
 /// Used to implement keyboard navigation for SSH modal.
 #[derive(Default)]
@@ -171,9 +171,13 @@ impl SelectableItemList {
         self.active_item == self.items.len().checked_sub(1)
     }
 
-    fn confirm(&self, dev_modal: &mut DevServerProjects, cx: &mut ViewContext<DevServerProjects>) {
+    fn confirm(
+        &self,
+        remote_modal: &mut RemoteServerProjects,
+        cx: &mut ViewContext<RemoteServerProjects>,
+    ) {
         if let Some(active_item) = self.active_item.and_then(|ix| self.items.get(ix)) {
-            active_item(dev_modal, cx);
+            active_item(remote_modal, cx);
         }
     }
 }
@@ -184,7 +188,7 @@ impl ProjectPicker {
         connection_string: SharedString,
         project: Model<Project>,
         workspace: WeakView<Workspace>,
-        cx: &mut ViewContext<DevServerProjects>,
+        cx: &mut ViewContext<RemoteServerProjects>,
     ) -> View<Self> {
         let (tx, rx) = oneshot::channel();
         let lister = project::DirectoryLister::Project(project.clone());
@@ -208,7 +212,7 @@ impl ProjectPicker {
                                 .update(&mut cx, |workspace, cx| {
                                     let weak = cx.view().downgrade();
                                     workspace
-                                        .toggle_modal(cx, |cx| DevServerProjects::new(cx, weak));
+                                        .toggle_modal(cx, |cx| RemoteServerProjects::new(cx, weak));
                                 })
                                 .log_err()?;
                             return None;
@@ -306,7 +310,7 @@ enum Mode {
     ViewServerOptions(usize, SshConnection),
     EditNickname(EditNicknameState),
     ProjectPicker(View<ProjectPicker>),
-    CreateDevServer(CreateDevServer),
+    CreateRemoteServer(CreateRemoteServer),
 }
 
 impl Mode {
@@ -315,7 +319,7 @@ impl Mode {
         Self::Default(ScrollbarState::new(handle))
     }
 }
-impl DevServerProjects {
+impl RemoteServerProjects {
     pub fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
         workspace.register_action(|workspace, _: &OpenRemote, cx| {
             let handle = cx.view().downgrade();
@@ -388,7 +392,7 @@ impl DevServerProjects {
         let connection_options = match SshConnectionOptions::parse_command_line(&input) {
             Ok(c) => c,
             Err(e) => {
-                self.mode = Mode::CreateDevServer(CreateDevServer {
+                self.mode = Mode::CreateRemoteServer(CreateRemoteServer {
                     address_editor: editor,
                     address_error: Some(format!("could not parse: {:?}", e).into()),
                     ssh_prompt: None,
@@ -400,7 +404,7 @@ impl DevServerProjects {
         let ssh_prompt = cx.new_view(|cx| SshPrompt::new(&connection_options, cx));
 
         let connection = connect_over_ssh(
-            connection_options.dev_server_identifier(),
+            connection_options.remote_server_identifier(),
             connection_options.clone(),
             ssh_prompt.clone(),
             cx,
@@ -430,7 +434,7 @@ impl DevServerProjects {
                         address_editor.update(cx, |this, _| {
                             this.set_read_only(false);
                         });
-                        this.mode = Mode::CreateDevServer(CreateDevServer {
+                        this.mode = Mode::CreateRemoteServer(CreateRemoteServer {
                             address_editor,
                             address_error: None,
                             ssh_prompt: None,
@@ -446,7 +450,7 @@ impl DevServerProjects {
         editor.update(cx, |this, _| {
             this.set_read_only(true);
         });
-        self.mode = Mode::CreateDevServer(CreateDevServer {
+        self.mode = Mode::CreateRemoteServer(CreateRemoteServer {
             address_editor: editor,
             address_error: None,
             ssh_prompt: Some(ssh_prompt.clone()),
@@ -488,7 +492,7 @@ impl DevServerProjects {
                     .clone();
 
                 let connect = connect_over_ssh(
-                    connection_options.dev_server_identifier(),
+                    connection_options.remote_server_identifier(),
                     connection_options.clone(),
                     prompt,
                     cx,
@@ -499,7 +503,8 @@ impl DevServerProjects {
                         workspace
                             .update(&mut cx, |workspace, cx| {
                                 let weak = cx.view().downgrade();
-                                workspace.toggle_modal(cx, |cx| DevServerProjects::new(cx, weak));
+                                workspace
+                                    .toggle_modal(cx, |cx| RemoteServerProjects::new(cx, weak));
                             })
                             .log_err();
                         return;
@@ -519,7 +524,7 @@ impl DevServerProjects {
                                 cx,
                             );
                             workspace.toggle_modal(cx, |cx| {
-                                DevServerProjects::project_picker(
+                                RemoteServerProjects::project_picker(
                                     ix,
                                     connection_options,
                                     project,
@@ -543,7 +548,7 @@ impl DevServerProjects {
                 self.selectable_items = items;
             }
             Mode::ProjectPicker(_) => {}
-            Mode::CreateDevServer(state) => {
+            Mode::CreateRemoteServer(state) => {
                 if let Some(prompt) = state.ssh_prompt.as_ref() {
                     prompt.update(cx, |prompt, cx| {
                         prompt.confirm(cx);
@@ -575,8 +580,8 @@ impl DevServerProjects {
     fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
         match &self.mode {
             Mode::Default(_) => cx.emit(DismissEvent),
-            Mode::CreateDevServer(state) if state.ssh_prompt.is_some() => {
-                self.mode = Mode::CreateDevServer(CreateDevServer::new(cx));
+            Mode::CreateRemoteServer(state) if state.ssh_prompt.is_some() => {
+                self.mode = Mode::CreateRemoteServer(CreateRemoteServer::new(cx));
                 self.selectable_items.reset_selection();
                 cx.notify();
             }
@@ -818,9 +823,9 @@ impl DevServerProjects {
         });
     }
 
-    fn render_create_dev_server(
+    fn render_create_remote_server(
         &self,
-        state: &CreateDevServer,
+        state: &CreateRemoteServer,
         cx: &mut ViewContext<Self>,
     ) -> impl IntoElement {
         let ssh_prompt = state.ssh_prompt.clone();
@@ -834,7 +839,7 @@ impl DevServerProjects {
         let theme = cx.theme();
 
         v_flex()
-            .id("create-dev-server")
+            .id("create-remote-server")
             .overflow_hidden()
             .size_full()
             .flex_1()
@@ -995,7 +1000,7 @@ impl DevServerProjects {
                     })
                     .child({
                         fn remove_ssh_server(
-                            dev_servers: View<DevServerProjects>,
+                            remote_servers: View<RemoteServerProjects>,
                             index: usize,
                             connection_string: SharedString,
                             cx: &mut WindowContext<'_>,
@@ -1011,7 +1016,7 @@ impl DevServerProjects {
 
                             cx.spawn(|mut cx| async move {
                                 if confirmation.await.ok() == Some(0) {
-                                    dev_servers
+                                    remote_servers
                                         .update(&mut cx, |this, cx| {
                                             this.delete_ssh_server(index, cx);
                                             this.mode = Mode::default_mode();
@@ -1108,21 +1113,21 @@ impl DevServerProjects {
             .ssh_connections()
             .collect::<Vec<_>>();
         self.selectable_items.add_item(Box::new(|this, cx| {
-            this.mode = Mode::CreateDevServer(CreateDevServer::new(cx));
+            this.mode = Mode::CreateRemoteServer(CreateRemoteServer::new(cx));
             cx.notify();
         }));
 
         let is_selected = self.selectable_items.is_selected();
 
-        let connect_button = ListItem::new("register-dev-server-button")
+        let connect_button = ListItem::new("register-remove-server-button")
             .selected(is_selected)
             .inset(true)
             .spacing(ui::ListItemSpacing::Sparse)
             .start_slot(Icon::new(IconName::Plus).color(Color::Muted))
             .child(Label::new("Connect New Server"))
             .on_click(cx.listener(|this, _, cx| {
-                let state = CreateDevServer::new(cx);
-                this.mode = Mode::CreateDevServer(state);
+                let state = CreateRemoteServer::new(cx);
+                this.mode = Mode::CreateRemoteServer(state);
 
                 cx.notify();
             }));
@@ -1145,7 +1150,7 @@ impl DevServerProjects {
                                 .child(ListSeparator)
                                 .child(
                                     div().px_3().child(
-                                        Label::new("No dev servers registered yet.")
+                                        Label::new("No remote servers registered yet.")
                                             .color(Color::Muted),
                                     ),
                                 )
@@ -1209,23 +1214,23 @@ fn get_text(element: &View<Editor>, cx: &mut WindowContext) -> String {
     element.read(cx).text(cx).trim().to_string()
 }
 
-impl ModalView for DevServerProjects {}
+impl ModalView for RemoteServerProjects {}
 
-impl FocusableView for DevServerProjects {
+impl FocusableView for RemoteServerProjects {
     fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
         self.focus_handle.clone()
     }
 }
 
-impl EventEmitter<DismissEvent> for DevServerProjects {}
+impl EventEmitter<DismissEvent> for RemoteServerProjects {}
 
-impl Render for DevServerProjects {
+impl Render for RemoteServerProjects {
     fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
         self.selectable_items.reset();
         div()
             .track_focus(&self.focus_handle)
             .elevation_3(cx)
-            .key_context("DevServerModal")
+            .key_context("RemoteServerModal")
             .on_action(cx.listener(Self::cancel))
             .on_action(cx.listener(Self::confirm))
             .on_action(cx.listener(Self::prev_item))
@@ -1245,9 +1250,9 @@ impl Render for DevServerProjects {
                     .render_view_options(*index, connection.clone(), cx)
                     .into_any_element(),
                 Mode::ProjectPicker(element) => element.clone().into_any_element(),
-                Mode::CreateDevServer(state) => {
-                    self.render_create_dev_server(state, cx).into_any_element()
-                }
+                Mode::CreateRemoteServer(state) => self
+                    .render_create_remote_server(state, cx)
+                    .into_any_element(),
                 Mode::EditNickname(state) => {
                     self.render_edit_nickname(state, cx).into_any_element()
                 }

crates/recent_projects/src/ssh_connections.rs 🔗

@@ -376,7 +376,14 @@ impl FocusableView for SshConnectionModal {
 
 impl EventEmitter<DismissEvent> for SshConnectionModal {}
 
-impl ModalView for SshConnectionModal {}
+impl ModalView for SshConnectionModal {
+    fn on_before_dismiss(&mut self, _: &mut ViewContext<Self>) -> workspace::DismissDecision {
+        return workspace::DismissDecision::Dismiss(false);
+    }
+    fn fade_out_background(&self) -> bool {
+        true
+    }
+}
 
 #[derive(Clone)]
 pub struct SshClientDelegate {

crates/remote/src/ssh_session.rs 🔗

@@ -186,7 +186,7 @@ impl SshConnectionOptions {
 
     // Uniquely identifies dev server projects on a remote host. Needs to be
     // stable for the same dev server project.
-    pub fn dev_server_identifier(&self) -> String {
+    pub fn remote_server_identifier(&self) -> String {
         let mut identifier = format!("dev-server-{:?}", self.host);
         if let Some(username) = self.username.as_ref() {
             identifier.push('-');

crates/title_bar/src/title_bar.rs 🔗

@@ -339,7 +339,7 @@ impl TitleBar {
                     .tooltip(move |cx| Tooltip::text("Project is hosted on a dev server", cx))
                     .on_click(cx.listener(|this, _, cx| {
                         if let Some(workspace) = this.workspace.upgrade() {
-                            recent_projects::DevServerProjects::open(workspace, cx)
+                            recent_projects::RemoteServerProjects::open(workspace, cx)
                         }
                     }))
                     .into_any_element(),