You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

93 lines
3.4 KiB

import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle
} from '@/components/ui/dialog'
import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area'
import { Button } from '@/components/ui/button'
import { Event } from 'nostr-tools'
import { WrapText, Copy, Check } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import logger from '@/lib/logger'
export default function RawEventDialog({
event,
isOpen,
onClose
}: {
event: Event
isOpen: boolean
onClose: () => void
}) {
const { t } = useTranslation()
const [wordWrapEnabled, setWordWrapEnabled] = useState(true)
const [copied, setCopied] = useState(false)
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(JSON.stringify(event, null, 2))
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch (err) {
logger.error('Failed to copy raw event', { error: err, eventId: event.id })
}
}
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="h-[60vh] w-[95vw] max-w-[400px] sm:w-[90vw] sm:max-w-[600px] md:w-[85vw] md:max-w-[800px] lg:w-[80vw] lg:max-w-[1000px] xl:w-[75vw] xl:max-w-[1200px] 2xl:w-[70vw] 2xl:max-w-[1400px] flex flex-col overflow-hidden">
<DialogHeader className="shrink-0 pr-8">
<div className="flex items-center justify-between gap-2">
<div className="flex-1 min-w-0">
<DialogTitle>Raw Event</DialogTitle>
<DialogDescription className="sr-only">View the raw event data</DialogDescription>
</div>
<div className="flex items-center gap-1 shrink-0">
<Button
variant="ghost"
size="sm"
onClick={handleCopy}
title={copied ? t('Copied!') : t('Copy to clipboard')}
>
{copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
<Button
variant="ghost"
size="sm"
onClick={() => setWordWrapEnabled(!wordWrapEnabled)}
title={wordWrapEnabled ? t('Disable word wrap') : t('Enable word wrap')}
>
<WrapText className={`h-4 w-4 ${wordWrapEnabled ? '' : 'opacity-50'}`} />
</Button>
</div>
</div>
</DialogHeader>
<div className="flex-1 min-h-0 min-w-0 overflow-hidden">
<ScrollArea className="h-full w-full">
<div className="w-full min-w-0 max-w-full pr-4">
<pre
className={`text-sm text-muted-foreground select-text min-w-0 ${wordWrapEnabled ? 'whitespace-pre-wrap overflow-x-hidden' : 'whitespace-pre overflow-x-auto'}`}
style={{
wordBreak: wordWrapEnabled ? 'break-all' : 'normal',
overflowWrap: wordWrapEnabled ? 'anywhere' : 'normal',
maxWidth: '100%',
width: '100%',
boxSizing: 'border-box'
}}
>
{JSON.stringify(event, null, 2)}
</pre>
</div>
<ScrollBar
orientation="horizontal"
className={wordWrapEnabled ? 'opacity-0 pointer-events-none' : ''}
/>
</ScrollArea>
</div>
</DialogContent>
</Dialog>
)
}