Rework Avatar indicator to be more general-purpose (#4073)

This PR reworks the way we add indicators to `Avatar`s to make them more
general-purpose.

Previously we had logic specific to the availability indicator embedded
in the `Avatar` component, which made it unwieldy to repurpose for
something else.

Now the `indicator` is just a slot that we can put anything into.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-01-16 14:05:05 -05:00 committed by GitHub
parent d00067cd86
commit ca4a8b2226
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 222 additions and 176 deletions

View file

@ -31,8 +31,8 @@ use smallvec::SmallVec;
use std::{mem, sync::Arc};
use theme::{ActiveTheme, ThemeSettings};
use ui::{
prelude::*, Avatar, Button, Color, ContextMenu, Icon, IconButton, IconName, IconSize, Label,
ListHeader, ListItem, Tooltip,
prelude::*, Avatar, AvatarAvailabilityIndicator, Button, Color, ContextMenu, Icon, IconButton,
IconName, IconSize, Label, ListHeader, ListItem, Tooltip,
};
use util::{maybe, ResultExt, TryFutureExt};
use workspace::{
@ -2000,43 +2000,49 @@ impl CollabPanel {
let busy = contact.busy || calling;
let user_id = contact.user.id;
let github_login = SharedString::from(contact.user.github_login.clone());
let item =
ListItem::new(github_login.clone())
.indent_level(1)
.indent_step_size(px(20.))
.selected(is_selected)
.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
.child(
h_flex()
.w_full()
.justify_between()
.child(Label::new(github_login.clone()))
.when(calling, |el| {
el.child(Label::new("Calling").color(Color::Muted))
})
.when(!calling, |el| {
el.child(
IconButton::new("remove_contact", IconName::Close)
.icon_color(Color::Muted)
.visible_on_hover("")
.tooltip(|cx| Tooltip::text("Remove Contact", cx))
.on_click(cx.listener({
let github_login = github_login.clone();
move |this, _, cx| {
this.remove_contact(user_id, &github_login, cx);
}
})),
)
}),
)
.start_slot(
// todo handle contacts with no avatar
Avatar::new(contact.user.avatar_uri.clone())
.availability_indicator(if online { Some(!busy) } else { None }),
)
.when(online && !busy, |el| {
el.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
});
let item = ListItem::new(github_login.clone())
.indent_level(1)
.indent_step_size(px(20.))
.selected(is_selected)
.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
.child(
h_flex()
.w_full()
.justify_between()
.child(Label::new(github_login.clone()))
.when(calling, |el| {
el.child(Label::new("Calling").color(Color::Muted))
})
.when(!calling, |el| {
el.child(
IconButton::new("remove_contact", IconName::Close)
.icon_color(Color::Muted)
.visible_on_hover("")
.tooltip(|cx| Tooltip::text("Remove Contact", cx))
.on_click(cx.listener({
let github_login = github_login.clone();
move |this, _, cx| {
this.remove_contact(user_id, &github_login, cx);
}
})),
)
}),
)
.start_slot(
// todo handle contacts with no avatar
Avatar::new(contact.user.avatar_uri.clone())
.indicator::<AvatarAvailabilityIndicator>(if online {
Some(AvatarAvailabilityIndicator::new(match busy {
true => ui::Availability::Busy,
false => ui::Availability::Free,
}))
} else {
None
}),
)
.when(online && !busy, |el| {
el.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
});
div()
.id(github_login.clone())