Files
smesh/src/components/NotificationList/NotificationItem/ReactionNotification.tsx
woikos 4c3e8d5cc7 Release v0.3.1
- Feed bounded context with DDD implementation (Phases 1-5)
- Domain event handlers for cross-context coordination
- Fix Blossom media upload setting persistence
- Fix wallet connection persistence on page reload
- New branding assets and icons
- Vitest testing infrastructure with 151 domain model tests
- Help page scaffolding
- Keyboard navigation provider

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 07:29:07 +01:00

75 lines
2.3 KiB
TypeScript

import Image from '@/components/Image'
import { useFetchEvent } from '@/hooks'
import { generateBech32IdFromATag, generateBech32IdFromETag, tagNameEquals } from '@/lib/tag'
import { useNostr } from '@/providers/NostrProvider'
import { Heart } from 'lucide-react'
import { Event } from 'nostr-tools'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import Notification from './Notification'
export function ReactionNotification({
notification,
isNew = false,
navIndex
}: {
notification: Event
isNew?: boolean
navIndex?: number
}) {
const { t } = useTranslation()
const { pubkey } = useNostr()
const eventId = useMemo(() => {
const aTag = notification.tags.findLast(tagNameEquals('a'))
if (aTag) {
return generateBech32IdFromATag(aTag)
}
const eTag = notification.tags.findLast(tagNameEquals('e'))
return eTag ? generateBech32IdFromETag(eTag) : undefined
}, [notification, pubkey])
const { event } = useFetchEvent(eventId)
const reaction = useMemo(() => {
if (!notification.content || notification.content === '+') {
return <Heart size={24} className="text-red-400" />
}
const emojiName = /^:([^:]+):$/.exec(notification.content)?.[1]
if (emojiName) {
const emojiTag = notification.tags.find((tag) => tag[0] === 'emoji' && tag[1] === emojiName)
const emojiUrl = emojiTag?.[2]
if (emojiUrl) {
return (
<Image
image={{ url: emojiUrl, pubkey: notification.pubkey }}
alt={emojiName}
className="w-6 h-6"
classNames={{ errorPlaceholder: 'bg-transparent', wrapper: 'rounded-md' }}
errorPlaceholder={<Heart size={24} className="text-red-400" />}
/>
)
}
}
if (notification.content.length > 4) {
return null
}
return notification.content
}, [notification])
if (!event || !eventId || !reaction) {
return null
}
return (
<Notification
notificationId={notification.id}
icon={<div className="text-xl min-w-6 text-center">{reaction}</div>}
sender={notification.pubkey}
sentAt={notification.created_at}
targetEvent={event}
description={t('reacted to your note')}
isNew={isNew}
navIndex={navIndex}
/>
)
}