diff --git a/assets/themes/cave-dark.json b/assets/themes/cave-dark.json index 347a8d90b9..3942296d48 100644 --- a/assets/themes/cave-dark.json +++ b/assets/themes/cave-dark.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#26232a", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/assets/themes/cave-light.json b/assets/themes/cave-light.json index 89acf414ab..cdf29c27e4 100644 --- a/assets/themes/cave-light.json +++ b/assets/themes/cave-light.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#e2dfe7", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#26232a", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/assets/themes/dark.json b/assets/themes/dark.json index e91642bb25..80423cc5da 100644 --- a/assets/themes/dark.json +++ b/assets/themes/dark.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#1c1c1c", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#f1f1f1", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/assets/themes/light.json b/assets/themes/light.json index 99c1bab730..1651d4209c 100644 --- a/assets/themes/light.json +++ b/assets/themes/light.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#f8f8f8", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#2b2b2b", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/assets/themes/solarized-dark.json b/assets/themes/solarized-dark.json index 8a75aa02dd..a60d59b85c 100644 --- a/assets/themes/solarized-dark.json +++ b/assets/themes/solarized-dark.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#073642", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#eee8d5", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/assets/themes/solarized-light.json b/assets/themes/solarized-light.json index 84bd0762ec..2e4224c2b1 100644 --- a/assets/themes/solarized-light.json +++ b/assets/themes/solarized-light.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#eee8d5", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#073642", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/assets/themes/sulphurpool-dark.json b/assets/themes/sulphurpool-dark.json index 716e81d6a2..5fd14a46cf 100644 --- a/assets/themes/sulphurpool-dark.json +++ b/assets/themes/sulphurpool-dark.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#293256", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/assets/themes/sulphurpool-light.json b/assets/themes/sulphurpool-light.json index 09bb2127df..65aaab6246 100644 --- a/assets/themes/sulphurpool-light.json +++ b/assets/themes/sulphurpool-light.json @@ -90,6 +90,12 @@ }, "workspace": { "background": "#dfe2f1", + "joining_project_message": { + "padding": 12, + "family": "Zed Sans", + "color": "#293256", + "size": 18 + }, "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 3aba2cbffb..4f937b0448 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1604,6 +1604,20 @@ impl MutableAppContext { }) } + pub fn replace_root_view(&mut self, window_id: usize, build_root_view: F) -> ViewHandle + where + T: View, + F: FnOnce(&mut ViewContext) -> T, + { + self.update(|this| { + let root_view = this.add_view(window_id, build_root_view); + let window = this.cx.windows.get_mut(&window_id).unwrap(); + window.root_view = root_view.clone().into(); + window.focused_view_id = Some(root_view.id()); + root_view + }) + } + pub fn remove_window(&mut self, window_id: usize) { self.cx.windows.remove(&window_id); self.presenters_and_platform_windows.remove(&window_id); diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 8ca7ce9ae2..f663071002 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -48,6 +48,7 @@ pub struct Workspace { pub modal: ContainerStyle, pub notification: ContainerStyle, pub notifications: Notifications, + pub joining_project_message: ContainedText, } #[derive(Clone, Deserialize, Default)] diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 26b355ae0a..8f659aa1d6 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -2272,6 +2272,34 @@ pub fn join_project( app_state: &Arc, cx: &mut MutableAppContext, ) -> Task>> { + struct JoiningNotice { + message: &'static str, + } + + impl Entity for JoiningNotice { + type Event = (); + } + + impl View for JoiningNotice { + fn ui_name() -> &'static str { + "JoiningProjectWindow" + } + + fn render(&mut self, cx: &mut RenderContext) -> ElementBox { + let theme = &cx.global::().theme.workspace; + Text::new( + self.message.to_string(), + theme.joining_project_message.text.clone(), + ) + .contained() + .with_style(theme.joining_project_message.container) + .aligned() + .contained() + .with_background_color(theme.background) + .boxed() + } + } + for window_id in cx.window_ids().collect::>() { if let Some(workspace) = cx.root_view::(window_id) { if workspace.read(cx).project().read(cx).remote_id() == Some(project_id) { @@ -2282,6 +2310,10 @@ pub fn join_project( let app_state = app_state.clone(); cx.spawn(|mut cx| async move { + let (window, joining_notice) = + cx.update(|cx| cx.add_window((app_state.build_window_options)(), |_| JoiningNotice { + message: "Loading remote project...", + })); let project = Project::remote( project_id, app_state.client.clone(), @@ -2290,13 +2322,28 @@ pub fn join_project( app_state.fs.clone(), &mut cx, ) - .await?; - Ok(cx.update(|cx| { - cx.add_window((app_state.build_window_options)(), |cx| { - (app_state.build_workspace)(project, &app_state, cx) - }) - .1 - })) + .await; + + cx.update(|cx| match project { + Ok(project) => Ok(cx.replace_root_view(window, |cx| { + let mut workspace = (app_state.build_workspace)(project, &app_state, cx); + workspace.toggle_sidebar_item( + &ToggleSidebarItem { + side: Side::Left, + item_index: 0, + }, + cx, + ); + workspace + })), + Err(error) => { + joining_notice.update(cx, |joining_notice, cx| { + joining_notice.message = "An error occurred trying to join the project. Please, close this window and retry."; + cx.notify(); + }); + Err(error) + }, + }) }) } diff --git a/styles/src/styleTree/workspace.ts b/styles/src/styleTree/workspace.ts index 65564f5cbc..7c17e4addd 100644 --- a/styles/src/styleTree/workspace.ts +++ b/styles/src/styleTree/workspace.ts @@ -41,6 +41,10 @@ export default function workspace(theme: Theme) { return { background: backgroundColor(theme, 300), + joiningProjectMessage: { + padding: 12, + ...text(theme, "sans", "primary", { size: "lg" }) + }, leaderBorderOpacity: 0.7, leaderBorderWidth: 2.0, tab,