RepostDescription.tsx raw
1 import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card'
2 import { cn } from '@/lib/utils'
3 import { Repeat2 } from 'lucide-react'
4 import { useTranslation } from 'react-i18next'
5 import UserAvatar from '../UserAvatar'
6 import Username from '../Username'
7
8 /**
9 * - reposters.length === 1: show "Alice reposted"
10 * - reposters.length === 2: show "Alice, Bob reposted"
11 * - reposters.length === 3: show "Alice, Bob, Charlie reposted"
12 * - reposters.length > 3: show "Alice, Bob, and x others reposted" (with hover card showing avatars of others)
13 */
14 export default function RepostDescription({
15 reposters,
16 className
17 }: {
18 reposters?: string[]
19 className?: string
20 }) {
21 const { t } = useTranslation()
22 if (!reposters?.length) return null
23
24 return (
25 <div className={cn('flex gap-1 text-sm items-center text-muted-foreground mb-1', className)}>
26 <Repeat2 size={16} className="shrink-0" />
27 <Username
28 key={reposters[0]}
29 userId={reposters[0]}
30 className={cn('font-semibold truncate', reposters.length > 1 && 'after:content-[","]')}
31 skeletonClassName="h-3"
32 />
33 {reposters.length > 1 && (
34 <Username
35 key={reposters[1]}
36 userId={reposters[1]}
37 className={cn('font-semibold truncate', reposters.length === 3 && 'after:content-[","]')}
38 skeletonClassName="h-3"
39 />
40 )}
41 {reposters.length > 3 ? (
42 <AndXOthers reposters={reposters.slice(2)} />
43 ) : reposters.length === 3 ? (
44 <Username
45 key={reposters[2]}
46 userId={reposters[2]}
47 className={cn('font-semibold truncate')}
48 skeletonClassName="h-3"
49 />
50 ) : null}
51 <div className="shrink-0">{t('reposted')}</div>
52 </div>
53 )
54 }
55
56 function AndXOthers({ reposters }: { reposters: string[] }) {
57 const { t } = useTranslation()
58
59 return (
60 <HoverCard>
61 <HoverCardTrigger asChild>
62 <span className="shrink-0 hover:underline">
63 {t('and {{x}} others', { x: reposters.length })}
64 </span>
65 </HoverCardTrigger>
66 <HoverCardContent className="w-fit max-w-60 flex flex-wrap p-2">
67 {reposters.map((pubkey) => (
68 <div key={pubkey} className="p-2">
69 <UserAvatar key={pubkey} userId={pubkey} size="small" />
70 </div>
71 ))}
72 </HoverCardContent>
73 </HoverCard>
74 )
75 }
76