fix: consistent avatar gradient colors across all 17 call sites

Avatar fallback gradients were hashed by display name alone when no
user prop was passed, causing the same person to appear in different
colors across messages, replies, member lists, voice panels, etc.

Added userId prop to Avatar and wired it through all 17 call sites
so the gradient always hashes by user ID.
This commit is contained in:
Jannis Braun
2026-03-02 01:16:58 +01:00
parent 95fc6f0693
commit f79575ffa7
16 changed files with 20 additions and 11 deletions
@@ -231,7 +231,7 @@ function FriendItem({ friend, onRemove, onDm }: { friend: Friend, onRemove: () =
return (
<div className="flex items-center justify-between px-3 h-[62px] rounded-[8px] hover:bg-interactive-hover group transition-colors border-t border-interactive-muted mx-2">
<div className="flex items-center gap-3">
<Avatar src={friend.avatar} name={friend.displayName ?? friend.username} size={32} status={friend.status} />
<Avatar src={friend.avatar} name={friend.displayName ?? friend.username} size={32} status={friend.status} userId={friend.id} />
<div className="flex flex-col leading-tight">
<div className="flex items-center gap-1.5">
<span className="text-txt-primary font-semibold text-[15px]">{friend.displayName ?? friend.username}</span>
@@ -277,7 +277,7 @@ function RequestItem({ request, type, onAccept, onDecline, onCancel }: {
return (
<div className="flex items-center justify-between px-3 py-2.5 rounded-lg hover:bg-interactive-hover group transition-colors border-t border-interactive-muted mx-2">
<div className="flex items-center gap-3">
<Avatar src={user.avatar} name={user.displayName ?? user.username} size={32} status={user.status as any} />
<Avatar src={user.avatar} name={user.displayName ?? user.username} size={32} status={user.status as any} userId={user.id} />
<div className="flex flex-col">
<div className="flex items-center gap-1.5">
<span className="text-txt-primary font-bold text-sm">{user.displayName ?? user.username}</span>
@@ -71,6 +71,7 @@ export function MentionPopover({ query, selectedIndex, onSelect }: MentionPopove
name={displayName}
size={24}
status={member.user.status}
userId={member.user.id}
/>
<span
className="text-[14px] font-medium truncate"
+1 -1
View File
@@ -182,7 +182,7 @@ export function Message({ message, isCompact, isFirstInGroup }: MessageProps) {
<div className="flex-1 min-w-0 pr-4">
{message.replyTo && (
<div className="flex items-center gap-1 mb-1 ml-[-4px] opacity-80 hover:opacity-100 cursor-pointer group/reply">
<Avatar src={message.replyTo.user.avatar} name={message.replyTo.user.username} size={16} />
<Avatar src={message.replyTo.user.avatar} name={message.replyTo.user.username} size={16} user={message.replyTo.user} />
<span
className="text-[14px] font-bold text-txt-primary hover:underline"
style={message.replyTo ? replyRoleColor(message.replyTo) : undefined}
@@ -173,7 +173,7 @@ function WelcomeHeader({ channelId }: { channelId: string }) {
return (
<div className="px-4 pt-8 pb-4">
<div className="mb-2">
<Avatar src={otherUser?.avatar} name={displayName} size={80} />
<Avatar src={otherUser?.avatar} name={displayName} size={80} userId={otherUser?.id} />
</div>
<h3 className="text-[32px] leading-10 font-bold text-txt-primary">{displayName}</h3>
<p className="text-txt-secondary text-[14px] mt-1">