Highlight face pile which local user is following

This commit is contained in:
Julia 2023-02-09 14:38:43 -05:00
parent 1abb7794cb
commit 05e9615507
4 changed files with 46 additions and 32 deletions

View File

@ -459,7 +459,7 @@ impl Room {
self.participant_user_ids.contains(&user_id) self.participant_user_ids.contains(&user_id)
} }
pub fn follows(&self, leader_id: PeerId) -> &[PeerId] { pub fn followers_for(&self, leader_id: PeerId) -> &[PeerId] {
self.follows_by_leader_id self.follows_by_leader_id
.get(&leader_id) .get(&leader_id)
.map_or(&[], |v| v.as_slice()) .map_or(&[], |v| v.as_slice())

View File

@ -12,8 +12,8 @@ use gpui::{
elements::*, elements::*,
geometry::{rect::RectF, vector::vec2f, PathBuilder}, geometry::{rect::RectF, vector::vec2f, PathBuilder},
json::{self, ToJson}, json::{self, ToJson},
Border, CursorStyle, Entity, ImageData, ModelHandle, MouseButton, MutableAppContext, CursorStyle, Entity, ImageData, ModelHandle, MouseButton, MutableAppContext, RenderContext,
RenderContext, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
}; };
use settings::Settings; use settings::Settings;
use std::{ops::Range, sync::Arc}; use std::{ops::Range, sync::Arc};
@ -581,9 +581,10 @@ impl CollabTitlebarItem {
theme: &Theme, theme: &Theme,
cx: &mut RenderContext<Self>, cx: &mut RenderContext<Self>,
) -> ElementBox { ) -> ElementBox {
let is_followed = workspace.read(cx).is_following(peer_id); let room = ActiveCall::global(cx).read(cx).room();
let is_being_followed = workspace.read(cx).is_being_followed(peer_id);
let mut avatar_style; let avatar_style;
if let Some(location) = location { if let Some(location) = location {
if let ParticipantLocation::SharedProject { project_id } = location { if let ParticipantLocation::SharedProject { project_id } = location {
if Some(project_id) == workspace.read(cx).project().read(cx).remote_id() { if Some(project_id) == workspace.read(cx).project().read(cx).remote_id() {
@ -598,23 +599,14 @@ impl CollabTitlebarItem {
avatar_style = theme.workspace.titlebar.avatar; avatar_style = theme.workspace.titlebar.avatar;
} }
let mut replica_color = None;
if let Some(replica_id) = replica_id {
let color = theme.editor.replica_selection_style(replica_id).cursor;
replica_color = Some(color);
if is_followed {
avatar_style.border = Border::all(1.0, color);
}
}
let content = Stack::new() let content = Stack::new()
.with_children(user.avatar.as_ref().map(|avatar| { .with_children(user.avatar.as_ref().map(|avatar| {
Flex::row() let flex = Flex::row()
.with_child(Self::render_face(avatar.clone(), avatar_style, theme)) .with_child(Self::render_face(avatar.clone(), avatar_style, theme))
.with_children( .with_children(
(|| { (|| {
let room = ActiveCall::global(cx).read(cx).room()?.read(cx); let room = room?.read(cx);
let followers = room.follows(peer_id); let followers = room.followers_for(peer_id);
Some(followers.into_iter().flat_map(|&follower| { Some(followers.into_iter().flat_map(|&follower| {
let avatar = room let avatar = room
@ -639,18 +631,40 @@ impl CollabTitlebarItem {
})() })()
.into_iter() .into_iter()
.flatten(), .flatten(),
) );
.boxed()
})) let room = ActiveCall::global(cx).read(cx).room();
.with_children(replica_color.map(|replica_color| { if let (Some(replica_id), Some(room)) = (replica_id, room) {
AvatarRibbon::new(replica_color) let followed_by_self = is_being_followed
.constrained() && room
.with_width(theme.workspace.titlebar.avatar_ribbon.width) .read(cx)
.with_height(theme.workspace.titlebar.avatar_ribbon.height) .followers_for(peer_id)
.aligned() .iter()
.bottom() .any(|&follower| {
.boxed() Some(follower) == workspace.read(cx).client().peer_id()
});
if followed_by_self {
let color = theme.editor.replica_selection_style(replica_id).selection;
return flex.contained().with_background_color(color).boxed();
}
}
flex.boxed()
})) }))
.with_children((|| {
let replica_id = replica_id?;
let color = theme.editor.replica_selection_style(replica_id).cursor;
Some(
AvatarRibbon::new(color)
.constrained()
.with_width(theme.workspace.titlebar.avatar_ribbon.width)
.with_height(theme.workspace.titlebar.avatar_ribbon.height)
.aligned()
.bottom()
.boxed(),
)
})())
.contained() .contained()
.with_margin_left(theme.workspace.titlebar.avatar_margin) .with_margin_left(theme.workspace.titlebar.avatar_margin)
.boxed(); .boxed();
@ -664,7 +678,7 @@ impl CollabTitlebarItem {
}) })
.with_tooltip::<ToggleFollow, _>( .with_tooltip::<ToggleFollow, _>(
peer_id.as_u64() as usize, peer_id.as_u64() as usize,
if is_followed { if is_being_followed {
format!("Unfollow {}", user.github_login) format!("Unfollow {}", user.github_login)
} else { } else {
format!("Follow {}", user.github_login) format!("Follow {}", user.github_login)

View File

@ -117,7 +117,7 @@ fn join_project(action: &JoinProject, app_state: Arc<AppState>, cx: &mut Mutable
}); });
if let Some(follow_peer_id) = follow_peer_id { if let Some(follow_peer_id) = follow_peer_id {
if !workspace.is_following(follow_peer_id) { if !workspace.is_being_followed(follow_peer_id) {
workspace workspace
.toggle_follow(&ToggleFollow(follow_peer_id), cx) .toggle_follow(&ToggleFollow(follow_peer_id), cx)
.map(|follow| follow.detach_and_log_err(cx)); .map(|follow| follow.detach_and_log_err(cx));

View File

@ -1828,11 +1828,11 @@ impl Workspace {
None None
} }
pub fn is_following(&self, peer_id: PeerId) -> bool { pub fn is_being_followed(&self, peer_id: PeerId) -> bool {
self.follower_states_by_leader.contains_key(&peer_id) self.follower_states_by_leader.contains_key(&peer_id)
} }
pub fn is_followed(&self, peer_id: PeerId) -> bool { pub fn is_followed_by(&self, peer_id: PeerId) -> bool {
self.leader_state.followers.contains(&peer_id) self.leader_state.followers.contains(&peer_id)
} }