ReactionNotification.tsx raw
1 import Image from '@/components/Image'
2 import { useFetchEvent } from '@/hooks'
3 import { generateBech32IdFromATag, generateBech32IdFromETag, tagNameEquals } from '@/lib/tag'
4 import { useNostr } from '@/providers/NostrProvider'
5 import { Heart } from 'lucide-react'
6 import { Event } from 'nostr-tools'
7 import { useMemo } from 'react'
8 import { useTranslation } from 'react-i18next'
9 import Notification from './Notification'
10
11 export function ReactionNotification({
12 notification,
13 isNew = false,
14 navIndex
15 }: {
16 notification: Event
17 isNew?: boolean
18 navIndex?: number
19 }) {
20 const { t } = useTranslation()
21 const { pubkey } = useNostr()
22 const eventId = useMemo(() => {
23 const aTag = notification.tags.findLast(tagNameEquals('a'))
24 if (aTag) {
25 return generateBech32IdFromATag(aTag)
26 }
27 const eTag = notification.tags.findLast(tagNameEquals('e'))
28 return eTag ? generateBech32IdFromETag(eTag) : undefined
29 }, [notification, pubkey])
30 const { event } = useFetchEvent(eventId)
31 const reaction = useMemo(() => {
32 if (!notification.content || notification.content === '+') {
33 return <Heart size={24} className="text-red-400" />
34 }
35
36 const emojiName = /^:([^:]+):$/.exec(notification.content)?.[1]
37 if (emojiName) {
38 const emojiTag = notification.tags.find((tag) => tag[0] === 'emoji' && tag[1] === emojiName)
39 const emojiUrl = emojiTag?.[2]
40 if (emojiUrl) {
41 return (
42 <Image
43 image={{ url: emojiUrl, pubkey: notification.pubkey }}
44 alt={emojiName}
45 className="w-6 h-6"
46 classNames={{ errorPlaceholder: 'bg-transparent', wrapper: 'rounded-md' }}
47 errorPlaceholder={<Heart size={24} className="text-red-400" />}
48 />
49 )
50 }
51 }
52 if (notification.content.length > 4) {
53 return null
54 }
55 return notification.content
56 }, [notification])
57
58 if (!event || !eventId || !reaction) {
59 return null
60 }
61
62 return (
63 <Notification
64 notificationId={notification.id}
65 icon={<div className="text-xl min-w-6 text-center">{reaction}</div>}
66 sender={notification.pubkey}
67 sentAt={notification.created_at}
68 targetEvent={event}
69 description={t('reacted to your note')}
70 isNew={isNew}
71 navIndex={navIndex}
72 />
73 )
74 }
75