2023-10-27 13:10:07 -04:00
|
|
|
"use client";
|
|
|
|
import { cn, formatCount, getTwoLetters } from "@/lib/utils";
|
|
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
|
|
import useProfile from "@/lib/hooks/useProfile";
|
|
|
|
import { nip19 } from "nostr-tools";
|
|
|
|
|
|
|
|
type AvatarStackProps = {
|
|
|
|
pubkeys: string[];
|
|
|
|
remaining?: number;
|
|
|
|
className?: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
const zIndexes = ["z-50", "z-40", "z-30", "z-20", "z-10", "z-0"];
|
|
|
|
|
|
|
|
export default function AvatarStack({
|
|
|
|
pubkeys,
|
|
|
|
className,
|
|
|
|
remaining,
|
|
|
|
}: AvatarStackProps) {
|
|
|
|
return (
|
|
|
|
<div className="isolate flex -space-x-2 overflow-hidden py-[2px]">
|
2023-10-28 11:07:50 -04:00
|
|
|
{pubkeys.map((p, idx) => {
|
|
|
|
if (p) {
|
|
|
|
return (
|
|
|
|
<User key={p} pubkey={p} className={cn(zIndexes[idx], className)} />
|
|
|
|
);
|
|
|
|
}
|
|
|
|
})}
|
2023-10-27 13:10:07 -04:00
|
|
|
{!!remaining && (
|
|
|
|
<Avatar
|
|
|
|
className={cn(
|
|
|
|
"relative inline-block h-8 w-8 rounded-full text-xs ring-2 ring-background",
|
|
|
|
className,
|
|
|
|
"z-0",
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<AvatarFallback className="bg-muted font-semibold text-primary">{`+${formatCount(
|
|
|
|
remaining,
|
|
|
|
)}`}</AvatarFallback>
|
|
|
|
</Avatar>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function User({ pubkey, className }: { pubkey: string; className: string }) {
|
2024-05-07 20:46:50 -04:00
|
|
|
const { profile, npub } = useProfile(pubkey);
|
|
|
|
// const npub = profilenip19.npubEncode(pubkey);
|
2023-10-27 13:10:07 -04:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Avatar
|
|
|
|
className={cn(
|
|
|
|
"relative inline-block h-8 w-8 rounded-full ring-2 ring-background",
|
|
|
|
className,
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<AvatarImage src={profile?.image} />
|
|
|
|
<AvatarFallback>{getTwoLetters({ npub, profile })}</AvatarFallback>
|
|
|
|
</Avatar>
|
|
|
|
);
|
|
|
|
}
|