From a29ce9f82722077199fa00684457c11059d53b8d Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Fri, 25 Sep 2026 14:56:49 +0700 Subject: [PATCH] update avatar --- CHANGELOG.md | 3 +- crates/assets/assets/themes/signed.json | 12 +++--- crates/dock/src/tab_panel.rs | 12 +++--- .../src/{user_avatar.rs => avatar.rs} | 40 +++++++++++++------ crates/signed_ui/src/lib.rs | 4 +- crates/signed_ui/src/pixel_avatar.rs | 34 ++++++++++------ crates/workspace/src/views/discussion.rs | 6 +-- crates/workspace/src/views/inbox.rs | 4 +- crates/workspace/src/views/issues/detail.rs | 6 +-- crates/workspace/src/views/issues/mod.rs | 4 +- crates/workspace/src/views/mod.rs | 6 +-- .../src/views/pull_requests/detail.rs | 4 +- .../workspace/src/views/pull_requests/mod.rs | 4 +- crates/workspace/src/views/repo/about.rs | 4 +- crates/workspace/src/views/repo/mod.rs | 6 +-- crates/workspace/src/views/repo_list.rs | 4 +- crates/workspace/src/views/sidebar/mod.rs | 13 +++--- 17 files changed, 94 insertions(+), 72 deletions(-) rename crates/signed_ui/src/{user_avatar.rs => avatar.rs} (51%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eec138..4fe5879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,12 @@ ### Changed - Migrate the GPUI foundation to the published `gpui-pre` crates and GPUI Kit 0.6, off the zed and gpui-component git pins +- Use the pixel avatar as the single fallback for a missing picture, sized and rounded to match the other avatars - Redesign the dock tab bar, using muted grey active tab, added close buttons, double-click to zoom, and removed panel toolbar ### Fixed -- Honor an explicit size on the pixel-art avatar, so the repository header's avatar is no longer stuck at the 16px default +- Render every avatar at one consistent size, where a surrounding border had shrunk pictures by two pixels and the pixel avatar ignored an explicit size ### Removed diff --git a/crates/assets/assets/themes/signed.json b/crates/assets/assets/themes/signed.json index 3c10784..de082cf 100644 --- a/crates/assets/assets/themes/signed.json +++ b/crates/assets/assets/themes/signed.json @@ -77,9 +77,9 @@ "success.foreground": "#052E16", "switch.background": "#CECECE", "switch.thumb.background": "#FFFFFF", - "tab.background": "#00000000", - "tab.active.background": "#EBFFC1", - "tab.active.foreground": "#3F6212", + "tab.background": "#E8E8E8", + "tab.active.background": "#F5F5F5", + "tab.active.foreground": "#18181B", "tab.foreground": "#646464", "tab_bar.background": "#F0F0F0", "tab_bar.segmented.background": "#F0F0F0", @@ -286,9 +286,9 @@ "success.foreground": "#052E16", "switch.background": "#484848", "switch.thumb.background": "#0A0A0A", - "tab.background": "#00000000", - "tab.active.background": "#19200A", - "tab.active.foreground": "#C6FF4D", + "tab.background": "#2E2E2E", + "tab.active.background": "#2A2A2A", + "tab.active.foreground": "#FAFAFA", "tab.foreground": "#B4B4B4", "tab_bar.background": "#191919", "tab_bar.segmented.background": "#191919", diff --git a/crates/dock/src/tab_panel.rs b/crates/dock/src/tab_panel.rs index c847fe2..44ffc0b 100644 --- a/crates/dock/src/tab_panel.rs +++ b/crates/dock/src/tab_panel.rs @@ -352,15 +352,13 @@ impl SignedTabGroupSkin { .items_center() .flex_shrink_0() .h_7() - .min_w_32() + .min_w_40() .gap_1() .px_1p5() .text_sm() .overflow_hidden() .rounded(cx.theme().radius) .text_color(cx.theme().tab_foreground) - // The title claims the free space and starts at the left, so a name - // narrower than the tab leaves blank space before the close button. .child( h_flex() .flex_1() @@ -406,16 +404,16 @@ impl SignedTabGroupSkin { .styles(|styles| { styles.selected(|style| { style - .text_color(cx.theme().foreground) - .bg(cx.theme().secondary) + .text_color(cx.theme().tab_active_foreground) + .bg(cx.theme().tab_active) }) }) .hover(|this| { if active { this } else { - this.text_color(cx.theme().foreground) - .bg(cx.theme().secondary_hover) + this.text_color(cx.theme().tab_foreground) + .bg(cx.theme().tab) } }) .selected(active) diff --git a/crates/signed_ui/src/user_avatar.rs b/crates/signed_ui/src/avatar.rs similarity index 51% rename from crates/signed_ui/src/user_avatar.rs rename to crates/signed_ui/src/avatar.rs index c080a56..a866b33 100644 --- a/crates/signed_ui/src/user_avatar.rs +++ b/crates/signed_ui/src/avatar.rs @@ -1,21 +1,26 @@ use gpui::prelude::*; use gpui::{App, SharedString, StyleRefinement, Window}; -use gpui_component::avatar::Avatar; +use gpui_base::{Avatar as BaseAvatar, AvatarFallback, AvatarImage}; use gpui_component::{ActiveTheme, Sizable, Size, StyledExt}; -/// A small user avatar from gpui-component [`Avatar`], rounded with the theme radius. -/// It shows the user's picture or falls back to name initials. +use crate::pixel_avatar::{PixelAvatar, side_length}; + +/// A user avatar built on the unstyled [`gpui_base::Avatar`]. +/// +/// It shows the user's picture when one is set, and falls back to the +/// deterministic pixel avatar seeded from the name otherwise. #[derive(IntoElement)] -pub struct UserAvatar { +pub struct Avatar { name: SharedString, picture: Option, size: Size, style: StyleRefinement, } -impl UserAvatar { +impl Avatar { /// Create an avatar for `name`. - /// The name seeds the initials fallback shown when no picture is set. + /// + /// The name seeds the pixel fallback shown when no picture is set. pub fn new(name: impl Into) -> Self { Self { name: name.into(), @@ -32,26 +37,35 @@ impl UserAvatar { } } -impl Sizable for UserAvatar { +impl Sizable for Avatar { fn with_size(mut self, size: impl Into) -> Self { self.size = size.into(); self } } -impl Styled for UserAvatar { +impl Styled for Avatar { fn style(&mut self) -> &mut StyleRefinement { &mut self.style } } -impl RenderOnce for UserAvatar { +impl RenderOnce for Avatar { fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement { - Avatar::new() - .name(self.name) - .when_some(self.picture, |this, url| this.src(url)) + let fallback = AvatarFallback::new() + .size_full() + .child(PixelAvatar::new(self.name.clone()).size_full()); + + BaseAvatar::new() + .size(side_length(self.size)) + .flex_shrink_0() .rounded(cx.theme().radius) + .overflow_hidden() + .bg(cx.theme().secondary) + .when_some(self.picture, |this, url| { + this.image(AvatarImage::new(url).size_full().rounded(cx.theme().radius)) + }) + .fallback(fallback) .refine_style(&self.style) - .with_size(self.size) } } diff --git a/crates/signed_ui/src/lib.rs b/crates/signed_ui/src/lib.rs index 7c63981..bad4e4d 100644 --- a/crates/signed_ui/src/lib.rs +++ b/crates/signed_ui/src/lib.rs @@ -1,3 +1,4 @@ +mod avatar; mod dropdown_button; mod nav_item; mod pixel_avatar; @@ -8,11 +9,11 @@ mod setting; mod status_badge; mod title_bar; mod tree_row; -mod user_avatar; pub mod copy_row; pub mod util; +pub use avatar::Avatar; pub use copy_row::{copy_row, menu_copy_row}; pub use dropdown_button::DropdownButton; pub use nav_item::NavItem; @@ -24,5 +25,4 @@ pub use setting::{SelectOption, setting_block, setting_row}; pub use status_badge::status_badge; pub use title_bar::title_bar_drag_handlers; pub use tree_row::tree_row; -pub use user_avatar::UserAvatar; pub use util::middle_truncate; diff --git a/crates/signed_ui/src/pixel_avatar.rs b/crates/signed_ui/src/pixel_avatar.rs index 2e74173..22dad72 100644 --- a/crates/signed_ui/src/pixel_avatar.rs +++ b/crates/signed_ui/src/pixel_avatar.rs @@ -5,7 +5,10 @@ use gpui_component::{ActiveTheme, Colorize, Sizable, Size}; /// Number of rows and columns in the pixel grid. const GRID_SIZE: usize = 8; -/// Probability that a cell in the left half is filled. +/// Empty cells kept between the pattern and the avatar edge, so the art +/// gathers in the center instead of filling the whole avatar. +const MARGIN: usize = 1; +/// Probability that a cell in the left half of the pattern area is filled. const FILL_PROBABILITY: f32 = 0.42; /// Probability that a filled cell uses the accent shade instead of the main color. const ACCENT_PROBABILITY: f32 = 0.25; @@ -22,12 +25,10 @@ pub struct PixelAvatar { impl PixelAvatar { /// Create an avatar seeded from `seed`. - /// - /// The seed should be a stable string unique to the entity the avatar represents. pub fn new(seed: impl AsRef) -> Self { Self { seed: fnv1a(seed.as_ref().as_bytes()), - size: Size::XSmall, + size: Size::Small, style: StyleRefinement::default(), } } @@ -84,6 +85,7 @@ impl RenderOnce for PixelAvatar { .grid_rows(GRID_SIZE as u16) .size(side_length(self.size)) .flex_shrink_0() + .rounded(theme.radius) .overflow_hidden() .bg(main.opacity(0.16)) .children(cells) @@ -91,7 +93,8 @@ impl RenderOnce for PixelAvatar { } } -fn side_length(size: Size) -> Pixels { +/// The rendered side length of an avatar at `size`, shared with [`Avatar`]. +pub(crate) fn side_length(size: Size) -> Pixels { match size { Size::XSmall => px(16.), Size::Small => px(24.), @@ -106,8 +109,13 @@ fn pattern(seed: u64) -> [u8; GRID_SIZE * GRID_SIZE] { let mut pattern = [0u8; GRID_SIZE * GRID_SIZE]; let mut filled = 0usize; - for row in 0..GRID_SIZE { - for col in 0..GRID_SIZE / 2 { + // Only the inner rows and the inner left half are candidates; mirroring + // then keeps the art within the same inset, leaving the outer ring empty. + let art_rows = GRID_SIZE - 2 * MARGIN; + let art_columns = GRID_SIZE / 2 - MARGIN; + + for row in MARGIN..GRID_SIZE - MARGIN { + for col in MARGIN..GRID_SIZE / 2 { if rng.chance(FILL_PROBABILITY) { let accent = rng.chance(ACCENT_PROBABILITY); set_cell(&mut pattern, row, col, if accent { 2 } else { 1 }); @@ -117,17 +125,17 @@ fn pattern(seed: u64) -> [u8; GRID_SIZE * GRID_SIZE] { } if filled < MIN_FILLED { - let half = GRID_SIZE * GRID_SIZE / 2; - let start = (rng.next() % half as u64) as usize; + let total = art_rows * art_columns; + let start = (rng.next() % total as u64) as usize; - for offset in 0..half { + for offset in 0..total { if filled >= MIN_FILLED { break; } - let ix = (start + offset) % half; - let row = ix / (GRID_SIZE / 2); - let col = ix % (GRID_SIZE / 2); + let ix = (start + offset) % total; + let row = MARGIN + ix / art_columns; + let col = MARGIN + ix % art_columns; if pattern[row * GRID_SIZE + col] == 0 { set_cell(&mut pattern, row, col, 1); diff --git a/crates/workspace/src/views/discussion.rs b/crates/workspace/src/views/discussion.rs index 8f52a56..771c44e 100644 --- a/crates/workspace/src/views/discussion.rs +++ b/crates/workspace/src/views/discussion.rs @@ -7,7 +7,7 @@ use gpui_component::tag::Tag; use gpui_component::{ActiveTheme, Icon, Sizable, StyledExt, h_flex, v_flex}; use nostr::prelude::{Event, EventId, PublicKey}; use signed_state::{ProfileStore, RepoStore}; -use signed_ui::UserAvatar; +use signed_ui::Avatar; use utils::relative_time; pub(crate) fn issue_roots(store: &RepoStore) -> &[Event] { @@ -71,7 +71,7 @@ pub(crate) fn sidebar_section( h_flex() .gap_1() .items_center() - .child(UserAvatar::new(name.clone()).picture(picture)) + .child(Avatar::new(name.clone()).picture(picture)) .child(div().text_sm().truncate().text_ellipsis().child(name)) .into_any_element() })), @@ -137,7 +137,7 @@ pub(crate) fn comments_section(store: &Entity, root: EventId, cx: &Ap .child( h_flex() .gap_1() - .child(UserAvatar::new(author.clone()).picture(picture)) + .child(Avatar::new(author.clone()).picture(picture)) .child(author), ) .child( diff --git a/crates/workspace/src/views/inbox.rs b/crates/workspace/src/views/inbox.rs index df319ec..38fe63a 100644 --- a/crates/workspace/src/views/inbox.rs +++ b/crates/workspace/src/views/inbox.rs @@ -15,7 +15,7 @@ use signed_core::{COVER_NOTE_KIND, InboxItem, InboxReadState, RepoAddr, filters} use signed_state::{ Backend, BackendEvent, ProfileStore, RefreshGate, RefreshRequest, RepoListStore, query_inbox, }; -use signed_ui::{CountBadge, UserAvatar}; +use signed_ui::{Avatar, CountBadge}; use utils::relative_time; use super::{RepoItem, open_repo_item, panel_avatar, tab_title}; @@ -553,7 +553,7 @@ fn sub_activity(event: &Event, me: Option, cx: &App) -> AnyElement { .items_center() .text_xs() .child( - UserAvatar::new(name.clone()) + Avatar::new(name.clone()) .picture(profile.picture()) .xsmall(), ) diff --git a/crates/workspace/src/views/issues/detail.rs b/crates/workspace/src/views/issues/detail.rs index f8ef447..a401252 100644 --- a/crates/workspace/src/views/issues/detail.rs +++ b/crates/workspace/src/views/issues/detail.rs @@ -10,7 +10,7 @@ use gpui_component::{ActiveTheme, StyledExt, h_flex, v_flex}; use nostr::prelude::EventId; use signed_core::activity_subject; use signed_state::{ProfileStore, RepoStore}; -use signed_ui::{UserAvatar, placeholder, status_badge}; +use signed_ui::{Avatar, placeholder, status_badge}; use utils::relative_time; use crate::views::discussion::{comment_form, comments_section, issue_roots, sidebar_section}; @@ -153,9 +153,7 @@ impl Render for IssueDetailView { .child( h_flex() .gap_1() - .child( - UserAvatar::new(&author).picture(picture), - ) + .child(Avatar::new(&author).picture(picture)) .child(author), ) .child( diff --git a/crates/workspace/src/views/issues/mod.rs b/crates/workspace/src/views/issues/mod.rs index bf65e99..b082548 100644 --- a/crates/workspace/src/views/issues/mod.rs +++ b/crates/workspace/src/views/issues/mod.rs @@ -18,7 +18,7 @@ use gpui_component::{ use nostr::prelude::EventId; use signed_core::{RepoStatus, activity_subject}; use signed_state::{ProfileStore, RepoStore}; -use signed_ui::{SegmentButton, UserAvatar, placeholder, status_badge}; +use signed_ui::{Avatar, SegmentButton, placeholder, status_badge}; use utils::relative_time; pub(super) mod detail; @@ -189,7 +189,7 @@ impl IssuesView { .child( h_flex() .gap_1() - .child(UserAvatar::new(author.clone()).picture(picture)) + .child(Avatar::new(author.clone()).picture(picture)) .child(div().child(author)), ) .child(SharedString::from("opened")) diff --git a/crates/workspace/src/views/mod.rs b/crates/workspace/src/views/mod.rs index 598c273..b1ae8a1 100644 --- a/crates/workspace/src/views/mod.rs +++ b/crates/workspace/src/views/mod.rs @@ -20,11 +20,11 @@ pub(crate) use repo::{RepoItem, open_repo_item, open_repo_panel}; pub use repo_list::RepoListView; pub use sidebar::SidebarPanel; use signed_state::{ProfileStore, RepoStore}; -use signed_ui::{PixelAvatar, UserAvatar}; +use signed_ui::{Avatar, PixelAvatar}; pub(crate) fn tab_title(avatar: AnyElement, label: impl IntoElement) -> impl IntoElement { h_flex() - .gap_1() + .gap_1p5() .items_center() .child(div().flex_shrink_0().child(avatar)) .child(label) @@ -54,7 +54,7 @@ pub(crate) fn repo_tab_avatar(store: &RepoStore, cx: &App) -> AnyElement { .map(|announcement| ProfileStore::global(cx).read(cx).get(&announcement.owner)); match owner.and_then(|profile| profile.picture().map(|picture| (profile.name(), picture))) { - Some((name, picture)) => UserAvatar::new(name) + Some((name, picture)) => Avatar::new(name) .picture(Some(picture)) .xsmall() .into_any_element(), diff --git a/crates/workspace/src/views/pull_requests/detail.rs b/crates/workspace/src/views/pull_requests/detail.rs index 9748efd..89dd0e4 100644 --- a/crates/workspace/src/views/pull_requests/detail.rs +++ b/crates/workspace/src/views/pull_requests/detail.rs @@ -27,7 +27,7 @@ use signed_core::{ }; use signed_git::{FileCommit, patch_commits, patch_diffs}; use signed_state::{Backend, ProfileStore, RepoStore, ensure_repo_mirror}; -use signed_ui::{CountBadge, UserAvatar, placeholder, status_badge}; +use signed_ui::{Avatar, CountBadge, placeholder, status_badge}; use utils::{relative_time, relative_time_secs}; use crate::views::commit_diff::{CommitDiffView, DiffPane}; @@ -453,7 +453,7 @@ impl PullRequestDetailView { h_flex() .gap_1() .child( - UserAvatar::new(author.clone()) + Avatar::new(author.clone()) .picture(picture), ) .child(author), diff --git a/crates/workspace/src/views/pull_requests/mod.rs b/crates/workspace/src/views/pull_requests/mod.rs index 36e9cfc..b14bf99 100644 --- a/crates/workspace/src/views/pull_requests/mod.rs +++ b/crates/workspace/src/views/pull_requests/mod.rs @@ -16,7 +16,7 @@ use gpui_component::{ use nostr::prelude::{EventId, Kind}; use signed_core::{RepoStatus, activity_subject}; use signed_state::{ProfileStore, RepoStore}; -use signed_ui::{DropdownButton, SegmentButton, UserAvatar, placeholder, status_badge}; +use signed_ui::{Avatar, DropdownButton, SegmentButton, placeholder, status_badge}; use utils::relative_time; pub(super) mod detail; @@ -203,7 +203,7 @@ impl PullRequestsView { .child( h_flex() .gap_1() - .child(UserAvatar::new(author.clone()).picture(picture)) + .child(Avatar::new(author.clone()).picture(picture)) .child(div().child(author)), ) .child(SharedString::from("opened")) diff --git a/crates/workspace/src/views/repo/about.rs b/crates/workspace/src/views/repo/about.rs index 3b8b7e4..bfd6fbc 100644 --- a/crates/workspace/src/views/repo/about.rs +++ b/crates/workspace/src/views/repo/about.rs @@ -5,7 +5,7 @@ use gpui_component::{ActiveTheme, StyledExt, WindowExt, h_flex, v_flex}; use nostr::prelude::PublicKey; use signed_core::Announcement; use signed_state::ProfileStore; -use signed_ui::{UserAvatar, middle_truncate}; +use signed_ui::{Avatar, middle_truncate}; pub(super) fn open_about_dialog(announcement: Announcement, window: &mut Window, cx: &mut App) { window.open_dialog(cx, move |dialog, _window, cx| { @@ -173,7 +173,7 @@ fn maintainers(maintainers: &[PublicKey], cx: &App) -> AnyElement { .gap_2() .items_center() .min_w_0() - .child(UserAvatar::new(name.clone()).picture(picture)) + .child(Avatar::new(name.clone()).picture(picture)) .child( div() .flex_1() diff --git a/crates/workspace/src/views/repo/mod.rs b/crates/workspace/src/views/repo/mod.rs index eb467b9..8161042 100644 --- a/crates/workspace/src/views/repo/mod.rs +++ b/crates/workspace/src/views/repo/mod.rs @@ -31,7 +31,7 @@ use signed_state::{ pr_proposes_checkout, }; use signed_ui::{ - CountBadge, DropdownButton, PixelAvatar, UserAvatar, copy_row, menu_copy_row, middle_truncate, + Avatar, CountBadge, DropdownButton, PixelAvatar, copy_row, menu_copy_row, middle_truncate, ref_selector_trigger, }; @@ -1491,7 +1491,7 @@ impl RepoDetailView { .child( h_flex() .gap_1() - .child(UserAvatar::new(owner_name.clone()).picture(owner_picture)) + .child(Avatar::new(owner_name.clone()).picture(owner_picture)) .child(div().text_xs().whitespace_nowrap().child(owner_name)), ) .when(!rest.is_empty(), |this| { @@ -2032,7 +2032,7 @@ fn bound_repo_label(binding: &Nip34Binding, cx: &App) -> AnyElement { h_flex() .gap_1() .text_color(cx.theme().foreground) - .child(UserAvatar::new(profile.name()).picture(profile.picture())) + .child(Avatar::new(profile.name()).picture(profile.picture())) .child(profile.name()), ) }) diff --git a/crates/workspace/src/views/repo_list.rs b/crates/workspace/src/views/repo_list.rs index fae8991..2fde423 100644 --- a/crates/workspace/src/views/repo_list.rs +++ b/crates/workspace/src/views/repo_list.rs @@ -16,7 +16,7 @@ use gpui_component::{ }; use signed_core::Announcement; use signed_state::{ProfileStore, RepoListStore, Timestamp}; -use signed_ui::{SegmentButton, UserAvatar}; +use signed_ui::{Avatar, SegmentButton}; use utils::relative_time; use super::{open_repo_panel, panel_avatar, tab_title}; @@ -289,7 +289,7 @@ impl RepoListView { h_flex() .gap_2() .items_center() - .child(UserAvatar::new(owner.name()).picture(owner.picture())) + .child(Avatar::new(owner.name()).picture(owner.picture())) .child( div() .text_xs() diff --git a/crates/workspace/src/views/sidebar/mod.rs b/crates/workspace/src/views/sidebar/mod.rs index 4f0804d..fa4eaf9 100644 --- a/crates/workspace/src/views/sidebar/mod.rs +++ b/crates/workspace/src/views/sidebar/mod.rs @@ -23,7 +23,7 @@ use signed_state::{ Backend, BackendEvent, CheckoutsStore, LocalReposStore, Nip34Binding, Nip34Kind, Profile, ProfileStore, RepoListStore, ResolvedLocalRepo, resolve_local_repos, }; -use signed_ui::{NavItem, PixelAvatar, UserAvatar, title_bar_drag_handlers}; +use signed_ui::{Avatar, NavItem, PixelAvatar, title_bar_drag_handlers}; use super::{InboxView, RepoDetailView, RepoListView, open_repo_panel}; @@ -447,7 +447,9 @@ impl SidebarPanel { cx: &mut Context, ) -> impl IntoElement { let name = announcement.name().map(SharedString::from); - let avatar = PixelAvatar::new(format!("{}:{}", announcement.owner, announcement.id)); + // The sidebar rows are compact, so the avatar matches the 16px nav icons. + let avatar = + PixelAvatar::new(format!("{}:{}", announcement.owner, announcement.id)).xsmall(); let announcement = announcement.clone(); let unpushed = self @@ -552,7 +554,7 @@ impl SidebarPanel { Button::new("user").text().dropdown_caret(true).child( h_flex() .gap_1() - .child(UserAvatar::new(name.clone()).picture(picture)) + .child(Avatar::new(name.clone()).picture(picture)) .child(div().text_xs().font_semibold().child(name)), ), ), @@ -654,7 +656,8 @@ pub(super) fn server_host(relay: &RelayUrl) -> SharedString { /// The repository's pixel avatar, with the bound owner's avatar at its bottom right. fn local_avatar(entry: &ResolvedLocalRepo, cx: &App) -> AnyElement { - let avatar = PixelAvatar::new(entry.path.to_string_lossy()); + // Matches the other sidebar rows, and the badge below sits at its corner. + let avatar = PixelAvatar::new(entry.path.to_string_lossy()).xsmall(); let Some(owner) = entry.nip34.as_ref().and_then(|binding| binding.owner) else { return avatar.into_any_element(); @@ -668,7 +671,7 @@ fn local_avatar(entry: &ResolvedLocalRepo, cx: &App) -> AnyElement { .child(avatar) .child( div().absolute().bottom_neg_0p5().right_neg_0p5().child( - UserAvatar::new(profile.name()) + Avatar::new(profile.name()) .picture(profile.picture()) .size(px(14.)), ),