Detailed changes
@@ -522,10 +522,31 @@ impl ContactsPopover {
MouseEventHandler::<Contact>::new(contact.user.id as usize, cx, |_, _| {
Flex::row()
.with_children(contact.user.avatar.clone().map(|avatar| {
- Image::new(avatar)
- .with_style(theme.contact_avatar)
- .aligned()
- .left()
+ let status_badge = if contact.online {
+ Some(
+ Empty::new()
+ .collapsed()
+ .contained()
+ .with_style(if contact.busy {
+ theme.contact_status_busy
+ } else {
+ theme.contact_status_free
+ })
+ .aligned()
+ .boxed(),
+ )
+ } else {
+ None
+ };
+ Stack::new()
+ .with_child(
+ Image::new(avatar)
+ .with_style(theme.contact_avatar)
+ .aligned()
+ .left()
+ .boxed(),
+ )
+ .with_children(status_badge)
.boxed()
}))
.with_child(
@@ -95,6 +95,8 @@ pub struct ContactsPopover {
pub project_row: Interactive<ProjectRow>,
pub row_height: f32,
pub contact_avatar: ImageStyle,
+ pub contact_status_free: ContainerStyle,
+ pub contact_status_busy: ContainerStyle,
pub contact_username: ContainedText,
pub contact_button: Interactive<IconButton>,
pub contact_button_spacing: f32,
@@ -116,6 +116,18 @@ export default function contactsPopover(theme: Theme) {
cornerRadius: 10,
width: 18,
},
+ contactStatusFree: {
+ cornerRadius: 4,
+ padding: 4,
+ margin: { top: 12, left: 12 },
+ background: iconColor(theme, "success"),
+ },
+ contactStatusBusy: {
+ cornerRadius: 3,
+ padding: 2,
+ margin: { top: 3, left: 3 },
+ background: iconColor(theme, "feature"),
+ },
contactUsername: {
...text(theme, "mono", "primary", { size: "sm" }),
margin: {
@@ -5,7 +5,6 @@ import {
border,
iconColor,
modalShadow,
- popoverShadow,
text,
} from "./components";
import statusBar from "./statusBar";
@@ -137,6 +137,7 @@ export function createTheme(
ok: sample(ramps.green, 0.5),
error: sample(ramps.red, 0.5),
warning: sample(ramps.yellow, 0.5),
+ success: sample(ramps.green, 0.5),
info: sample(ramps.blue, 0.5),
onMedia: darkest,
};
@@ -123,6 +123,7 @@ export default interface Theme {
error: string;
warning: string;
info: string;
+ success: string;
};
editor: {
background: string;