feat: add support for displaying kind 7 and kind 17 reaction events
Reactions now render with a large emoji (matching emoji-only note sizing) and a "reacted to" preview pill linking to the target event, following the same pattern as comment parent previews. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5596e5eb7b
commit
234010c385
26 changed files with 209 additions and 29 deletions
50
src/components/ContentPreview/ReactionPreview.tsx
Normal file
50
src/components/ContentPreview/ReactionPreview.tsx
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import Image from '@/components/Image'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Heart } from 'lucide-react'
|
||||
import { Event } from 'nostr-tools'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function ReactionPreview({
|
||||
event,
|
||||
className
|
||||
}: {
|
||||
event: Event
|
||||
className?: string
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const reaction = useMemo(() => {
|
||||
if (!event.content || event.content === '+') {
|
||||
return <Heart size={14} className="inline text-red-400" />
|
||||
}
|
||||
|
||||
const emojiName = /^:([^:]+):$/.exec(event.content)?.[1]
|
||||
if (emojiName) {
|
||||
const emojiTag = event.tags.find((tag) => tag[0] === 'emoji' && tag[1] === emojiName)
|
||||
const emojiUrl = emojiTag?.[2]
|
||||
if (emojiUrl) {
|
||||
return (
|
||||
<Image
|
||||
image={{ url: emojiUrl, pubkey: event.pubkey }}
|
||||
alt={emojiName}
|
||||
className="inline-block h-4 w-4"
|
||||
classNames={{ errorPlaceholder: 'bg-transparent', wrapper: 'inline-block rounded-md' }}
|
||||
errorPlaceholder={<Heart size={14} className="inline text-red-400" />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
if (event.content.length > 4) {
|
||||
return <Heart size={14} className="inline text-red-400" />
|
||||
}
|
||||
return <span>{event.content}</span>
|
||||
}, [event])
|
||||
|
||||
return (
|
||||
<div className={cn('flex items-center gap-1 truncate', className)}>
|
||||
<span className="truncate">[{t('Reaction')}]</span>
|
||||
{reaction}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue