Detailed changes
@@ -1514,6 +1514,8 @@ impl CollabPanel {
) -> AnyElement<Self> {
let channel_id = channel.id;
+ const FACEPILE_LIMIT: usize = 4;
+
MouseEventHandler::<Channel, Self>::new(channel.id as usize, cx, |state, cx| {
Flex::row()
.with_child(
@@ -1532,20 +1534,37 @@ impl CollabPanel {
.left()
.flex(1., true),
)
- .with_child(
- FacePile::new(theme.face_overlap).with_children(
- self.channel_store
- .read(cx)
- .channel_participants(channel_id)
- .iter()
- .filter_map(|user| {
- Some(
- Image::from_data(user.avatar.clone()?)
- .with_style(theme.contact_avatar),
+ .with_children({
+ let participants = self.channel_store.read(cx).channel_participants(channel_id);
+ if !participants.is_empty() {
+ let extra_count = participants.len().saturating_sub(FACEPILE_LIMIT);
+
+ Some(
+ FacePile::new(theme.face_overlap)
+ .with_children(
+ participants
+ .iter()
+ .filter_map(|user| {
+ Some(
+ Image::from_data(user.avatar.clone()?)
+ .with_style(theme.contact_avatar),
+ )
+ })
+ .take(FACEPILE_LIMIT),
)
- }),
- ),
- )
+ .with_children((extra_count > 0).then(|| {
+ Label::new(
+ format!("+{}", extra_count),
+ theme.extra_participant_label.text.clone(),
+ )
+ .contained()
+ .with_style(theme.extra_participant_label.container)
+ })),
+ )
+ } else {
+ None
+ }
+ })
.align_children_center()
.constrained()
.with_height(theme.row_height)
@@ -68,6 +68,7 @@ impl<V: View> Element<V> for FacePile<V> {
for face in self.faces.iter_mut().rev() {
let size = face.size();
origin_x -= size.x();
+ let origin_y = origin_y + (bounds.height() - size.y()) / 2.0;
scene.paint_layer(None, |scene| {
face.paint(scene, vec2f(origin_x, origin_y), visible_bounds, view, cx);
});
@@ -241,6 +241,7 @@ pub struct CollabPanel {
pub project_row: Toggleable<Interactive<ProjectRow>>,
pub tree_branch: Toggleable<Interactive<TreeBranch>>,
pub contact_avatar: ImageStyle,
+ pub extra_participant_label: ContainedText,
pub contact_status_free: ContainerStyle,
pub contact_status_busy: ContainerStyle,
pub contact_username: ContainedText,
@@ -245,6 +245,15 @@ export default function contacts_panel(): any {
corner_radius: 10,
width: 20,
},
+ extra_participant_label: {
+ corner_radius: 10,
+ padding: {
+ left: 10,
+ right: 4,
+ },
+ background: background(layer, "hovered"),
+ ...text(layer, "ui_sans", "hovered", { size: "xs" })
+ },
contact_status_free: indicator({ layer, color: "positive" }),
contact_status_busy: indicator({ layer, color: "negative" }),
contact_username: {