diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index b805006b93..34706f1118 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -357,6 +357,7 @@ impl Project { for task in tasks { task.await?; } + this.update(&mut cx, |_, cx| cx.notify()); Ok(()) }) } @@ -371,7 +372,7 @@ impl Project { .. } = &mut this.client_state { - *is_shared = true; + *is_shared = false; remote_id_rx .borrow() .ok_or_else(|| anyhow!("no project id")) @@ -381,7 +382,10 @@ impl Project { })?; rpc.send(proto::UnshareProject { project_id }).await?; - + this.update(&mut cx, |this, cx| { + this.collaborators.clear(); + cx.notify() + }); Ok(()) }) } @@ -396,6 +400,13 @@ impl Project { } } + pub fn is_local(&self) -> bool { + match &self.client_state { + ProjectClientState::Local { .. } => true, + ProjectClientState::Remote { .. } => false, + } + } + pub fn open_buffer( &self, path: ProjectPath, @@ -408,7 +419,7 @@ impl Project { } } - fn is_shared(&self) -> bool { + pub fn is_shared(&self) -> bool { match &self.client_state { ProjectClientState::Local { is_shared, .. } => *is_shared, ProjectClientState::Remote { .. } => false, @@ -512,6 +523,7 @@ impl Project { } = &mut self.client_state { *sharing_has_stopped = true; + self.collaborators.clear(); cx.notify(); Ok(()) } else { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 7dfe81f84e..fdce6f6ff2 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -40,6 +40,7 @@ use theme::{Theme, ThemeRegistry}; action!(Open, Arc); action!(OpenNew, Arc); action!(OpenPaths, OpenParams); +action!(ToggleShare); action!(JoinProject, JoinProjectParams); action!(Save); action!(DebugElements); @@ -56,6 +57,7 @@ pub fn init(cx: &mut MutableAppContext) { join_project(action.0.project_id, &action.0.app_state, cx).detach(); }); + cx.add_action(Workspace::toggle_share); cx.add_action(Workspace::save_active_item); cx.add_action(Workspace::debug_elements); cx.add_action(Workspace::toggle_sidebar_item); @@ -992,6 +994,18 @@ impl Workspace { &self.active_pane } + fn toggle_share(&mut self, _: &ToggleShare, cx: &mut ViewContext) { + self.project.update(cx, |project, cx| { + if project.is_local() { + if project.is_shared() { + project.unshare(cx).detach(); + } else { + project.share(cx).detach(); + } + } + }); + } + fn render_connection_status(&self) -> Option { let theme = &self.settings.borrow().theme; match &*self.client.status().borrow() { @@ -1043,6 +1057,7 @@ impl Workspace { .with_child( Align::new( Flex::row() + .with_children(self.render_share_icon(cx)) .with_children(self.render_collaborators(theme, cx)) .with_child(self.render_avatar( self.user_store.read(cx).current_user().as_ref(), @@ -1133,6 +1148,35 @@ impl Workspace { .boxed() } } + + fn render_share_icon(&self, cx: &mut RenderContext) -> Option { + if self.project().read(cx).is_local() && self.client.user_id().is_some() { + enum Share {} + + let color = if self.project().read(cx).is_shared() { + Color::green() + } else { + Color::red() + }; + Some( + MouseEventHandler::new::(0, cx, |_, _| { + Align::new( + ConstrainedBox::new( + Svg::new("icons/broadcast-24.svg").with_color(color).boxed(), + ) + .with_width(24.) + .boxed(), + ) + .boxed() + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(|cx| cx.dispatch_action(ToggleShare)) + .boxed(), + ) + } else { + None + } + } } impl Entity for Workspace { diff --git a/crates/zed/assets/icons/broadcast-24.svg b/crates/zed/assets/icons/broadcast-24.svg new file mode 100644 index 0000000000..391528cdc7 --- /dev/null +++ b/crates/zed/assets/icons/broadcast-24.svg @@ -0,0 +1,6 @@ + + + + + +