Allow following users into external projects

This commit is contained in:
Antonio Scandurra 2022-10-05 15:32:55 +02:00
parent 8f8843711f
commit 183ca5da6f
2 changed files with 46 additions and 33 deletions

View file

@ -1,10 +1,10 @@
use crate::{FollowerStatesByLeader, Pane}; use crate::{FollowerStatesByLeader, JoinProject, Pane, Workspace};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use call::ActiveCall; use call::ActiveCall;
use client::PeerId; use gpui::{
use collections::HashMap; elements::*, Axis, Border, CursorStyle, ModelHandle, MouseButton, RenderContext, ViewHandle,
use gpui::{elements::*, AppContext, Axis, Border, ViewHandle}; };
use project::Collaborator; use project::Project;
use serde::Deserialize; use serde::Deserialize;
use theme::Theme; use theme::Theme;
@ -57,14 +57,12 @@ impl PaneGroup {
pub(crate) fn render( pub(crate) fn render(
&self, &self,
project_id: Option<u64>, project: &ModelHandle<Project>,
theme: &Theme, theme: &Theme,
follower_states: &FollowerStatesByLeader, follower_states: &FollowerStatesByLeader,
collaborators: &HashMap<PeerId, Collaborator>, cx: &mut RenderContext<Workspace>,
cx: &AppContext,
) -> ElementBox { ) -> ElementBox {
self.root self.root.render(project, theme, follower_states, cx)
.render(project_id, theme, follower_states, collaborators, cx)
} }
pub(crate) fn panes(&self) -> Vec<&ViewHandle<Pane>> { pub(crate) fn panes(&self) -> Vec<&ViewHandle<Pane>> {
@ -104,12 +102,13 @@ impl Member {
pub fn render( pub fn render(
&self, &self,
project_id: Option<u64>, project: &ModelHandle<Project>,
theme: &Theme, theme: &Theme,
follower_states: &FollowerStatesByLeader, follower_states: &FollowerStatesByLeader,
collaborators: &HashMap<PeerId, Collaborator>, cx: &mut RenderContext<Workspace>,
cx: &AppContext,
) -> ElementBox { ) -> ElementBox {
enum FollowIntoExternalProject {}
match self { match self {
Member::Pane(pane) => { Member::Pane(pane) => {
let leader = follower_states let leader = follower_states
@ -123,7 +122,7 @@ impl Member {
}) })
.and_then(|leader_id| { .and_then(|leader_id| {
let room = ActiveCall::global(cx).read(cx).room()?.read(cx); let room = ActiveCall::global(cx).read(cx).room()?.read(cx);
let collaborator = collaborators.get(leader_id)?; let collaborator = project.read(cx).collaborators().get(leader_id)?;
let participant = room.remote_participants().get(&leader_id)?; let participant = room.remote_participants().get(&leader_id)?;
Some((collaborator.replica_id, participant)) Some((collaborator.replica_id, participant))
}); });
@ -133,18 +132,36 @@ impl Member {
call::ParticipantLocation::Project { call::ParticipantLocation::Project {
project_id: leader_project_id, project_id: leader_project_id,
} => { } => {
if Some(leader_project_id) == project_id { if Some(leader_project_id) == project.read(cx).remote_id() {
ChildView::new(pane).boxed() ChildView::new(pane).boxed()
} else { } else {
Label::new( let leader_user = leader.user.clone();
format!( let leader_user_id = leader.user.id;
"Follow {} on their currently active project", MouseEventHandler::<FollowIntoExternalProject>::new(
leader.user.github_login, pane.id(),
), cx,
theme.workspace.external_location_message.text.clone(), |_, _| {
Label::new(
format!(
"Follow {} on their currently active project",
leader_user.github_login,
),
theme.workspace.external_location_message.text.clone(),
)
.contained()
.with_style(
theme.workspace.external_location_message.container,
)
.boxed()
},
) )
.contained() .with_cursor_style(CursorStyle::PointingHand)
.with_style(theme.workspace.external_location_message.container) .on_click(MouseButton::Left, move |_, cx| {
cx.dispatch_action(JoinProject {
project_id: leader_project_id,
follow_user_id: leader_user_id,
})
})
.aligned() .aligned()
.boxed() .boxed()
} }
@ -173,9 +190,7 @@ impl Member {
ChildView::new(pane).boxed() ChildView::new(pane).boxed()
} }
} }
Member::Axis(axis) => { Member::Axis(axis) => axis.render(project, theme, follower_states, cx),
axis.render(project_id, theme, follower_states, collaborators, cx)
}
} }
} }
@ -277,17 +292,15 @@ impl PaneAxis {
fn render( fn render(
&self, &self,
project_id: Option<u64>, project: &ModelHandle<Project>,
theme: &Theme, theme: &Theme,
follower_state: &FollowerStatesByLeader, follower_state: &FollowerStatesByLeader,
collaborators: &HashMap<PeerId, Collaborator>, cx: &mut RenderContext<Workspace>,
cx: &AppContext,
) -> ElementBox { ) -> ElementBox {
let last_member_ix = self.members.len() - 1; let last_member_ix = self.members.len() - 1;
Flex::new(self.axis) Flex::new(self.axis)
.with_children(self.members.iter().enumerate().map(|(ix, member)| { .with_children(self.members.iter().enumerate().map(|(ix, member)| {
let mut member = let mut member = member.render(project, theme, follower_state, cx);
member.render(project_id, theme, follower_state, collaborators, cx);
if ix < last_member_ix { if ix < last_member_ix {
let mut border = theme.workspace.pane_divider; let mut border = theme.workspace.pane_divider;
border.left = false; border.left = false;

View file

@ -2416,6 +2416,7 @@ impl View for Workspace {
.with_child( .with_child(
Stack::new() Stack::new()
.with_child({ .with_child({
let project = self.project.clone();
Flex::row() Flex::row()
.with_children( .with_children(
if self.left_sidebar.read(cx).active_item().is_some() { if self.left_sidebar.read(cx).active_item().is_some() {
@ -2433,10 +2434,9 @@ impl View for Workspace {
Flex::column() Flex::column()
.with_child( .with_child(
FlexItem::new(self.center.render( FlexItem::new(self.center.render(
self.project.read(cx).remote_id(), &project,
&theme, &theme,
&self.follower_states_by_leader, &self.follower_states_by_leader,
self.project.read(cx).collaborators(),
cx, cx,
)) ))
.flex(1., true) .flex(1., true)