From aa90c060127e4ff8eee7f9ee1f9001cdf770f6ee Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 16 May 2022 17:45:50 +0200 Subject: [PATCH] Display a temporary window while remote project is loading --- assets/themes/cave-dark.json | 6 +++ assets/themes/cave-light.json | 6 +++ assets/themes/dark.json | 6 +++ assets/themes/light.json | 6 +++ assets/themes/solarized-dark.json | 6 +++ assets/themes/solarized-light.json | 6 +++ assets/themes/sulphurpool-dark.json | 6 +++ assets/themes/sulphurpool-light.json | 6 +++ crates/gpui/src/app.rs | 14 +++++++ crates/theme/src/theme.rs | 1 + crates/workspace/src/workspace.rs | 61 ++++++++++++++++++++++++---- styles/src/styleTree/workspace.ts | 4 ++ 12 files changed, 121 insertions(+), 7 deletions(-) diff --git a/assets/themes/cave-dark.json b/assets/themes/cave-dark.json index 347a8d90b9b86abde5e2c0d4ce791e685c76af0a..3942296d48e29d7bcb910e75fa072df9a4a78bb6 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 89acf414ab2764905ca4770760f680a88a715cd0..cdf29c27e48c75697d9727920a82746fe69b4f1f 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 e91642bb25b512760e7600e7d5c6f5bb5c9c5799..80423cc5da1bbdd52a0ce14df9ab6283d58977d5 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 99c1bab730d3b7df7eea1fbc51e5f841ebab15b4..1651d4209c7fb03b225dbfbf0bf5a27b85c63193 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 8a75aa02dd184792b3f8dfdfaf31d74295356d4c..a60d59b85c1a2232257a92a80052e6cbe3df670e 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 84bd0762ec07789bd8570dd78f605061857d06e3..2e4224c2b18b208f13eca3f8a29fc9ca221f1bc0 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 716e81d6a298fff34f4cbeb39a65f4878829d884..5fd14a46cff0926bb4ba63a1ca844792cf7746ba 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 09bb2127df7f8080c7058fd0fe5abd9f449b2d0d..65aaab6246a81396227957a8fec9f656e581e5c4 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 3aba2cbffba0c71c82aae899a66178748718c33e..4f937b0448966c27cb3b46be2374b4da38974697 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 8ca7ce9ae2fe9832ce6f5e7a6b4c9b24af5b45a1..f663071002afdb1369e0e16fe8668efdfb110d08 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 26b355ae0a290adcbcd916e08a4f2adda478cec5..8f659aa1d6662abf15c13fabbd75222c027cb6b3 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 65564f5cbc35299fd49e39656e97370798312084..7c17e4addd070d16b47ee7ec386aec7e3f9043e7 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,