7 changed files with 132 additions and 9 deletions
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
import { getPubkeysFromPTags } from '@/lib/tag' |
||||
import { cn } from '@/lib/utils' |
||||
import { Event } from 'nostr-tools' |
||||
import { useMemo } from 'react' |
||||
import { useTranslation } from 'react-i18next' |
||||
import { SimpleUserAvatar } from '../UserAvatar' |
||||
import { Users, ExternalLink } from 'lucide-react' |
||||
import { Button } from '../ui/button' |
||||
import { toFollowPacks } from '@/lib/link' |
||||
import { useSecondaryPage } from '@/PageManager' |
||||
|
||||
export default function FollowPackPreview({ |
||||
event, |
||||
className |
||||
}: { |
||||
event: Event |
||||
className?: string |
||||
}) { |
||||
const { t } = useTranslation() |
||||
const { push } = useSecondaryPage() |
||||
|
||||
const packPubkeys = useMemo(() => getPubkeysFromPTags(event.tags), [event.tags]) |
||||
|
||||
const getPackTitle = (pack: Event): string => { |
||||
const titleTag = pack.tags.find(tag => tag[0] === 'title' || tag[0] === 'name') |
||||
return titleTag?.[1] || t('Follow Pack') |
||||
} |
||||
|
||||
const getPackDescription = (pack: Event): string => { |
||||
const descTag = pack.tags.find(tag => tag[0] === 'description' || tag[0] === 'd') |
||||
return descTag?.[1] || '' |
||||
} |
||||
|
||||
const title = getPackTitle(event) |
||||
const description = getPackDescription(event) |
||||
|
||||
const handleOpenInViewer = (e: React.MouseEvent) => { |
||||
e.stopPropagation() |
||||
push(toFollowPacks()) |
||||
} |
||||
|
||||
return ( |
||||
<div className={cn('border rounded-lg p-3 bg-muted/30', className)}> |
||||
<div className="flex items-center gap-1 mb-2"> |
||||
<span className="text-muted-foreground">[{t('Follow Pack')}]</span> |
||||
<span className="font-semibold text-sm">{title}</span> |
||||
</div> |
||||
|
||||
{description && ( |
||||
<div className="text-sm text-muted-foreground mb-3 line-clamp-2"> |
||||
{description} |
||||
</div> |
||||
)} |
||||
|
||||
<div className="flex items-center gap-3 mb-3"> |
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground"> |
||||
<Users className="size-4" /> |
||||
<span>{t('{{count}} profiles', { count: packPubkeys.length })}</span> |
||||
</div> |
||||
|
||||
{packPubkeys.length > 0 && ( |
||||
<div className="flex -space-x-2"> |
||||
{packPubkeys.slice(0, 5).map((pubkey) => ( |
||||
<SimpleUserAvatar
|
||||
key={pubkey}
|
||||
userId={pubkey}
|
||||
size="small"
|
||||
className="border-2 border-background" |
||||
/> |
||||
))} |
||||
{packPubkeys.length > 5 && ( |
||||
<div className="size-7 rounded-full border-2 border-background bg-muted flex items-center justify-center text-xs text-muted-foreground"> |
||||
+{packPubkeys.length - 5} |
||||
</div> |
||||
)} |
||||
</div> |
||||
)} |
||||
</div> |
||||
|
||||
<Button |
||||
variant="outline" |
||||
size="sm" |
||||
onClick={handleOpenInViewer} |
||||
className="w-full" |
||||
> |
||||
<ExternalLink className="size-4 mr-2" /> |
||||
{t('Open in Follow Pack Viewer')} |
||||
</Button> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
Loading…
Reference in new issue