Detailed changes
@@ -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": {
@@ -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": {
@@ -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": {
@@ -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": {
@@ -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": {
@@ -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": {
@@ -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": {
@@ -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": {
@@ -1604,6 +1604,20 @@ impl MutableAppContext {
})
}
+ pub fn replace_root_view<T, F>(&mut self, window_id: usize, build_root_view: F) -> ViewHandle<T>
+ where
+ T: View,
+ F: FnOnce(&mut ViewContext<T>) -> 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);
@@ -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)]
@@ -2272,6 +2272,34 @@ pub fn join_project(
app_state: &Arc<AppState>,
cx: &mut MutableAppContext,
) -> Task<Result<ViewHandle<Workspace>>> {
+ 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<Self>) -> ElementBox {
+ let theme = &cx.global::<Settings>().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::<Vec<_>>() {
if let Some(workspace) = cx.root_view::<Workspace>(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)
+ },
+ })
})
}
@@ -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,