import { Event, nip19 } from 'nostr-tools' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import dayjs from 'dayjs' import { Button } from '@/components/ui/button' import { Copy, Check } from 'lucide-react' import { toast } from 'sonner' import logger from '@/lib/logger' import { cn } from '@/lib/utils' import { isRssThreadSyntheticParentEvent } from '@/lib/rss-article' import { isValidPubkey } from '@/lib/pubkey' import { getKindDescription } from '@/lib/kind-description' import UserAvatar from '@/components/UserAvatar' import Username from '@/components/Username' function isAllZeroPlaceholderPubkey(pk: string): boolean { return isValidPubkey(pk) && /^0+$/.test(pk) } export default function EventViewer({ event, className }: { event: Event className?: string }) { const { t } = useTranslation() const [copiedJson, setCopiedJson] = useState(false) const [copiedNevent, setCopiedNevent] = useState(false) const nevent = useMemo( () => nip19.neventEncode({ id: event.id, author: event.pubkey, kind: event.kind }), [event.id, event.pubkey, event.kind] ) const jsonPretty = useMemo(() => JSON.stringify(event, null, 2), [event]) const handleCopyJson = async () => { try { await navigator.clipboard.writeText(jsonPretty) setCopiedJson(true) toast.success(t('Copied to clipboard')) setTimeout(() => setCopiedJson(false), 2000) } catch (err) { logger.error('Failed to copy event JSON', { error: err, eventId: event.id }) toast.error(t('Failed to copy')) } } const handleCopyNevent = async () => { try { await navigator.clipboard.writeText(nevent) setCopiedNevent(true) toast.success(t('Copied to clipboard')) setTimeout(() => setCopiedNevent(false), 2000) } catch (err) { logger.error('Failed to copy nevent', { error: err }) toast.error(t('Failed to copy')) } } const createdAtFormatted = dayjs(event.created_at * 1000).format('LLL') const pubkey = event.pubkey ?? '' const hidePubkeyRow = isRssThreadSyntheticParentEvent(event) const showAuthorBadge = !hidePubkeyRow && isValidPubkey(pubkey) && !isAllZeroPlaceholderPubkey(pubkey) const kindLabel = getKindDescription(event.kind) return (
{nevent}
{jsonPretty}