mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-29 04:20:46 +00:00
Absolute pain of the iterator kind (start laying out a user's followers)
This commit is contained in:
parent
2592ec7265
commit
58c41778e7
3 changed files with 70 additions and 26 deletions
|
@ -55,7 +55,7 @@ pub struct Room {
|
|||
leave_when_empty: bool,
|
||||
client: Arc<Client>,
|
||||
user_store: ModelHandle<UserStore>,
|
||||
follows_by_leader_id: HashMap<PeerId, HashSet<PeerId>>,
|
||||
follows_by_leader_id: HashMap<PeerId, Vec<PeerId>>,
|
||||
subscriptions: Vec<client::Subscription>,
|
||||
pending_room_update: Option<Task<()>>,
|
||||
maintain_connection: Option<Task<Option<()>>>,
|
||||
|
@ -459,6 +459,12 @@ impl Room {
|
|||
self.participant_user_ids.contains(&user_id)
|
||||
}
|
||||
|
||||
pub fn follows(&self, leader_id: PeerId) -> &[PeerId] {
|
||||
self.follows_by_leader_id
|
||||
.get(&leader_id)
|
||||
.map_or(&[], |v| v.as_slice())
|
||||
}
|
||||
|
||||
async fn handle_room_updated(
|
||||
this: ModelHandle<Self>,
|
||||
envelope: TypedEnvelope<proto::RoomUpdated>,
|
||||
|
@ -636,10 +642,13 @@ impl Room {
|
|||
}
|
||||
};
|
||||
|
||||
this.follows_by_leader_id
|
||||
let list = this
|
||||
.follows_by_leader_id
|
||||
.entry(leader)
|
||||
.or_insert(Default::default())
|
||||
.insert(follower);
|
||||
.or_insert(Vec::new());
|
||||
if !list.contains(&follower) {
|
||||
list.push(follower);
|
||||
}
|
||||
}
|
||||
|
||||
this.pending_room_update.take();
|
||||
|
|
|
@ -12,11 +12,11 @@ use gpui::{
|
|||
elements::*,
|
||||
geometry::{rect::RectF, vector::vec2f, PathBuilder},
|
||||
json::{self, ToJson},
|
||||
Border, CursorStyle, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext,
|
||||
Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
Border, CursorStyle, Entity, ImageData, ModelHandle, MouseButton, MutableAppContext,
|
||||
RenderContext, Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use settings::Settings;
|
||||
use std::ops::Range;
|
||||
use std::{ops::Range, sync::Arc};
|
||||
use theme::Theme;
|
||||
use util::ResultExt;
|
||||
use workspace::{FollowNextCollaborator, JoinProject, ToggleFollow, Workspace};
|
||||
|
@ -510,11 +510,7 @@ impl CollabTitlebarItem {
|
|||
Some(self.render_face_pile(
|
||||
&user,
|
||||
replica_id,
|
||||
Some((
|
||||
participant.peer_id,
|
||||
&user.github_login,
|
||||
participant.location,
|
||||
)),
|
||||
Some((participant.peer_id, participant.location)),
|
||||
workspace,
|
||||
theme,
|
||||
cx,
|
||||
|
@ -564,18 +560,23 @@ impl CollabTitlebarItem {
|
|||
&self,
|
||||
user: &User,
|
||||
replica_id: Option<ReplicaId>,
|
||||
peer: Option<(PeerId, &str, ParticipantLocation)>,
|
||||
peer_id_and_location: Option<(PeerId, ParticipantLocation)>,
|
||||
workspace: &ViewHandle<Workspace>,
|
||||
theme: &Theme,
|
||||
cx: &mut RenderContext<Self>,
|
||||
) -> ElementBox {
|
||||
let is_followed = peer.map_or(false, |(peer_id, _, _)| {
|
||||
let is_followed = peer_id_and_location.map_or(false, |(peer_id, _)| {
|
||||
workspace.read(cx).is_following(peer_id)
|
||||
});
|
||||
|
||||
let room = ActiveCall::global(cx).read(cx).room();
|
||||
let get_followers = |leader_id: PeerId| -> &[PeerId] {
|
||||
room.map_or(&[], |room| room.read(cx).follows(leader_id))
|
||||
};
|
||||
|
||||
let mut avatar_style;
|
||||
if let Some((_, _, location)) = peer.as_ref() {
|
||||
if let ParticipantLocation::SharedProject { project_id } = *location {
|
||||
if let Some((_, location)) = peer_id_and_location {
|
||||
if let ParticipantLocation::SharedProject { project_id } = location {
|
||||
if Some(project_id) == workspace.read(cx).project().read(cx).remote_id() {
|
||||
avatar_style = theme.workspace.titlebar.avatar;
|
||||
} else {
|
||||
|
@ -599,11 +600,36 @@ impl CollabTitlebarItem {
|
|||
|
||||
let content = Stack::new()
|
||||
.with_children(user.avatar.as_ref().map(|avatar| {
|
||||
Image::new(avatar.clone())
|
||||
.with_style(avatar_style)
|
||||
.constrained()
|
||||
.with_width(theme.workspace.titlebar.avatar_width)
|
||||
.aligned()
|
||||
Flex::row()
|
||||
.with_child(Self::render_face(avatar.clone(), avatar_style, theme))
|
||||
.with_children(
|
||||
peer_id_and_location
|
||||
.map(|(peer_id, _)| {
|
||||
get_followers(peer_id)
|
||||
.into_iter()
|
||||
.map(|&follower| {
|
||||
room.map(|room| {
|
||||
room.read(cx)
|
||||
.remote_participant_for_peer_id(follower)
|
||||
.map(|participant| {
|
||||
participant.user.avatar.as_ref().map(|avatar| {
|
||||
Self::render_face(
|
||||
avatar.clone(),
|
||||
avatar_style,
|
||||
theme,
|
||||
)
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
.into_iter()
|
||||
.flatten(),
|
||||
)
|
||||
.with_reversed_paint_order()
|
||||
.boxed()
|
||||
}))
|
||||
.with_children(replica_color.map(|replica_color| {
|
||||
|
@ -621,7 +647,7 @@ impl CollabTitlebarItem {
|
|||
.with_margin_left(theme.workspace.titlebar.avatar_margin)
|
||||
.boxed();
|
||||
|
||||
if let Some((peer_id, peer_github_login, location)) = peer {
|
||||
if let Some((peer_id, location)) = peer_id_and_location {
|
||||
if let Some(replica_id) = replica_id {
|
||||
MouseEventHandler::<ToggleFollow>::new(replica_id.into(), cx, move |_, _| content)
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
|
@ -631,9 +657,9 @@ impl CollabTitlebarItem {
|
|||
.with_tooltip::<ToggleFollow, _>(
|
||||
peer_id.as_u64() as usize,
|
||||
if is_followed {
|
||||
format!("Unfollow {}", peer_github_login)
|
||||
format!("Unfollow {}", user.github_login)
|
||||
} else {
|
||||
format!("Follow {}", peer_github_login)
|
||||
format!("Follow {}", user.github_login)
|
||||
},
|
||||
Some(Box::new(FollowNextCollaborator)),
|
||||
theme.tooltip.clone(),
|
||||
|
@ -654,7 +680,7 @@ impl CollabTitlebarItem {
|
|||
})
|
||||
.with_tooltip::<JoinProject, _>(
|
||||
peer_id.as_u64() as usize,
|
||||
format!("Follow {} into external project", peer_github_login),
|
||||
format!("Follow {} into external project", user.github_login),
|
||||
Some(Box::new(FollowNextCollaborator)),
|
||||
theme.tooltip.clone(),
|
||||
cx,
|
||||
|
@ -668,6 +694,15 @@ impl CollabTitlebarItem {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_face(avatar: Arc<ImageData>, avatar_style: ImageStyle, theme: &Theme) -> ElementBox {
|
||||
Image::new(avatar)
|
||||
.with_style(avatar_style)
|
||||
.constrained()
|
||||
.with_width(theme.workspace.titlebar.avatar_width)
|
||||
.aligned()
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn render_connection_status(
|
||||
&self,
|
||||
workspace: &ViewHandle<Workspace>,
|
||||
|
|
|
@ -837,7 +837,7 @@ impl Workspace {
|
|||
&self.project
|
||||
}
|
||||
|
||||
pub fn client(&self) -> &Arc<Client> {
|
||||
pub fn client(&self) -> &Client {
|
||||
&self.client
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue