Files
buzz/desktop/src/features/messages/ui/DirectMessageIntroAvatarStack.tsx
klopez4212 39ce3dfc3c fix(desktop): open profiles from avatars (#3751)
## Summary
- show profile descriptions in hover cards as a single truncated line
- open the profile panel when avatars are clicked across desktop
surfaces
- make the direct-message intro avatar clickable

## Validation
- Desktop static checks
- 3,807 desktop tests via pre-push

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
2026-07-31 14:24:51 +00:00

67 lines
2.3 KiB
TypeScript

import { getDmParticipantPreview } from "@/features/channels/lib/dmParticipantDisplay";
import { UserProfilePopover } from "@/features/profile/ui/UserProfilePopover";
import { UserAvatar } from "@/shared/ui/UserAvatar";
export type DirectMessageIntroParticipant = {
avatarUrl: string | null;
displayName: string;
pubkey: string;
};
export function DirectMessageIntroAvatarStack({
participants,
}: {
participants: DirectMessageIntroParticipant[];
}) {
const { hiddenCount, visibleParticipants } =
getDmParticipantPreview(participants);
const stackItemCount = visibleParticipants.length + (hiddenCount > 0 ? 1 : 0);
return (
<div
className="flex shrink-0 items-center"
data-testid="message-dm-intro-avatar-stack"
>
{visibleParticipants.map((participant, index) => (
<UserProfilePopover
key={participant.pubkey}
pubkey={participant.pubkey}
triggerAriaLabel={`Open profile for ${participant.displayName}`}
triggerElement="span"
>
<span
className={index > 0 ? "-ml-5" : ""}
data-testid="message-dm-intro-avatar-stack-participant"
style={{
zIndex: index + 1,
...(index < stackItemCount - 1 && {
mask: "radial-gradient(circle 34px at calc(100% + 10px) 50%, transparent 99%, #fff 100%)",
WebkitMask:
"radial-gradient(circle 34px at calc(100% + 10px) 50%, transparent 99%, #fff 100%)",
}),
}}
>
<UserAvatar
avatarUrl={participant.avatarUrl}
className="h-[60px] w-[60px] text-base"
displayName={participant.displayName}
size="md"
/>
</span>
</UserProfilePopover>
))}
{hiddenCount > 0 ? (
<div
className={visibleParticipants.length > 0 ? "-ml-5" : ""}
data-testid="message-dm-intro-avatar-stack-more"
style={{ zIndex: stackItemCount }}
>
<span className="flex h-[60px] w-[60px] items-center justify-center rounded-full bg-secondary font-semibold text-secondary-foreground shadow-xs">
<span className="text-lg leading-none">+{hiddenCount}</span>
</span>
</div>
) : null}
</div>
);
}