diff --git a/Cargo.lock b/Cargo.lock index 12ebae98f6..7a7b5bb5c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2359,6 +2359,7 @@ dependencies = [ "pretty_assertions", "project", "recent_projects", + "remote_projects", "rich_text", "rpc", "schemars", diff --git a/crates/collab_ui/Cargo.toml b/crates/collab_ui/Cargo.toml index ff78b50853..f5f25ce231 100644 --- a/crates/collab_ui/Cargo.toml +++ b/crates/collab_ui/Cargo.toml @@ -50,6 +50,7 @@ parking_lot.workspace = true picker.workspace = true project.workspace = true recent_projects.workspace = true +remote_projects.workspace = true rich_text.workspace = true rpc.workspace = true schemars.workspace = true diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index 5f9ee3a013..23876f0ca1 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -9,12 +9,12 @@ use gpui::{ }; use project::{Project, RepositoryEntry}; use recent_projects::RecentProjects; -use rpc::proto; +use rpc::proto::{self, DevServerStatus}; use std::sync::Arc; use theme::ActiveTheme; use ui::{ h_flex, popover_menu, prelude::*, Avatar, AvatarAudioStatusIndicator, Button, ButtonLike, - ButtonStyle, ContextMenu, Icon, IconButton, IconName, TintColor, TitleBar, Tooltip, + ButtonStyle, ContextMenu, Icon, IconButton, IconName, Indicator, TintColor, TitleBar, Tooltip, }; use util::ResultExt; use vcs_menu::{build_branch_list, BranchList, OpenRecent as ToggleVcsMenu}; @@ -375,7 +375,41 @@ impl CollabTitlebarItem { // resolve if you are in a room -> render_project_owner // render_project_owner -> resolve if you are in a room -> Option - pub fn render_project_host(&self, cx: &mut ViewContext) -> Option { + pub fn render_project_host(&self, cx: &mut ViewContext) -> Option { + if let Some(dev_server) = + self.project + .read(cx) + .remote_project_id() + .and_then(|remote_project_id| { + remote_projects::Store::global(cx) + .read(cx) + .dev_server_for_project(remote_project_id) + }) + { + return Some( + ButtonLike::new("dev_server_trigger") + .child(Indicator::dot().color( + if dev_server.status == DevServerStatus::Online { + Color::Created + } else { + Color::Disabled + }, + )) + .child( + Label::new(dev_server.name.clone()) + .size(LabelSize::Small) + .line_height_style(LineHeightStyle::UiLabel), + ) + .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::RemoteProjects::open(workspace, cx) + } + })) + .into_any_element(), + ); + } + let host = self.project.read(cx).host()?; let host_user = self.user_store.read(cx).get_cached_user(host.user_id)?; let participant_index = self @@ -406,7 +440,8 @@ impl CollabTitlebarItem { }) .log_err(); }) - }), + }) + .into_any_element(), ) } diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index 813f95e212..8b26d71c58 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -11,7 +11,7 @@ use picker::{ highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText}, Picker, PickerDelegate, }; -use remote_projects::RemoteProjects; +pub use remote_projects::RemoteProjects; use rpc::proto::DevServerStatus; use serde::Deserialize; use std::{ diff --git a/crates/recent_projects/src/remote_projects.rs b/crates/recent_projects/src/remote_projects.rs index 61900efef7..86a2495e4b 100644 --- a/crates/recent_projects/src/remote_projects.rs +++ b/crates/recent_projects/src/remote_projects.rs @@ -60,6 +60,12 @@ impl RemoteProjects { .detach(); } + pub fn open(workspace: View, cx: &mut WindowContext) { + workspace.update(cx, |workspace, cx| { + workspace.toggle_modal(cx, |cx| Self::new(cx)) + }) + } + pub fn new(cx: &mut ViewContext) -> Self { let remote_project_path_input = cx.new_view(|cx| TextField::new(cx, "", "Project path")); let dev_server_name_input = diff --git a/crates/remote_projects/src/remote_projects.rs b/crates/remote_projects/src/remote_projects.rs index 5e62d5c32e..93450ef837 100644 --- a/crates/remote_projects/src/remote_projects.rs +++ b/crates/remote_projects/src/remote_projects.rs @@ -114,6 +114,11 @@ impl Store { self.remote_projects.get(&id) } + pub fn dev_server_for_project(&self, id: RemoteProjectId) -> Option<&DevServer> { + self.remote_project(id) + .and_then(|project| self.dev_server(project.dev_server_id)) + } + async fn handle_remote_projects_update( this: Model, envelope: TypedEnvelope,