diff --git a/crates/collab_ui/src/contacts_popover.rs b/crates/collab_ui/src/contacts_popover.rs index 388b344879..074e816163 100644 --- a/crates/collab_ui/src/contacts_popover.rs +++ b/crates/collab_ui/src/contacts_popover.rs @@ -522,10 +522,31 @@ impl ContactsPopover { MouseEventHandler::::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( diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index b9de72065a..d70aaed189 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -95,6 +95,8 @@ pub struct ContactsPopover { pub project_row: Interactive, 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, pub contact_button_spacing: f32, diff --git a/styles/src/styleTree/contactsPopover.ts b/styles/src/styleTree/contactsPopover.ts index 82174fd672..16656c3fcd 100644 --- a/styles/src/styleTree/contactsPopover.ts +++ b/styles/src/styleTree/contactsPopover.ts @@ -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: { diff --git a/styles/src/styleTree/workspace.ts b/styles/src/styleTree/workspace.ts index 7ad99ef6ab..c970c38296 100644 --- a/styles/src/styleTree/workspace.ts +++ b/styles/src/styleTree/workspace.ts @@ -5,7 +5,6 @@ import { border, iconColor, modalShadow, - popoverShadow, text, } from "./components"; import statusBar from "./statusBar"; diff --git a/styles/src/themes/common/base16.ts b/styles/src/themes/common/base16.ts index 7aa72ef137..3612988075 100644 --- a/styles/src/themes/common/base16.ts +++ b/styles/src/themes/common/base16.ts @@ -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, }; diff --git a/styles/src/themes/common/theme.ts b/styles/src/themes/common/theme.ts index e01435b846..18ad8122e0 100644 --- a/styles/src/themes/common/theme.ts +++ b/styles/src/themes/common/theme.ts @@ -123,6 +123,7 @@ export default interface Theme { error: string; warning: string; info: string; + success: string; }; editor: { background: string;