import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Textarea } from '@/components/ui/textarea' import { cleanUrl } from '@/lib/url' import { X } from 'lucide-react' import { useState, useEffect } from 'react' import { useTranslation } from 'react-i18next' import { nip19 } from 'nostr-tools' export interface HighlightData { sourceType: 'nostr' | 'url' sourceValue: string // nevent/naddr/note/hex for nostr, https:// URL for url sourceHexId?: string // converted hex ID for nostr sources context?: string // the full text/quote that the highlight is from } interface HighlightEditorProps { highlightData: HighlightData setHighlightData: (data: HighlightData) => void setIsHighlight: (value: boolean) => void } export default function HighlightEditor({ highlightData, setHighlightData, setIsHighlight }: HighlightEditorProps) { const { t } = useTranslation() const [sourceInput, setSourceInput] = useState(highlightData.sourceValue) const [context, setContext] = useState(highlightData.context || '') const [error, setError] = useState('') // Validate and parse the source input useEffect(() => { if (!sourceInput.trim()) { setError('') return } // Check if it's a URL if (sourceInput.startsWith('https://') || sourceInput.startsWith('http://')) { // Clean tracking parameters from the URL before publishing const cleanedUrl = cleanUrl(sourceInput) setError('') setHighlightData({ sourceType: 'url', sourceValue: cleanedUrl, context }) return } // Try to parse as nostr identifier try { let hexId: string | undefined // Check if it's already a hex ID (64 char hex string) if (/^[a-f0-9]{64}$/i.test(sourceInput)) { hexId = sourceInput.toLowerCase() setError('') setHighlightData({ sourceType: 'nostr', sourceValue: sourceInput, sourceHexId: hexId, context }) return } // Try to decode as nip19 identifier const decoded = nip19.decode(sourceInput) if (decoded.type === 'note') { hexId = decoded.data setError('') setHighlightData({ sourceType: 'nostr', sourceValue: sourceInput, // Keep original for reference sourceHexId: hexId, // Store the hex ID context }) } else if (decoded.type === 'nevent') { hexId = decoded.data.id setError('') setHighlightData({ sourceType: 'nostr', sourceValue: sourceInput, // Keep the nevent for relay info sourceHexId: hexId, // Store the hex ID context }) } else if (decoded.type === 'naddr') { // For naddr, we need to keep the full naddr string to extract kind:pubkey:identifier setError('') setHighlightData({ sourceType: 'nostr', sourceValue: sourceInput, // Keep the naddr for a-tag building sourceHexId: undefined, // No hex ID for addressable events context }) } else { setError(t('Invalid source. Please enter a note ID, nevent, naddr, hex ID, or URL.')) return } } catch { setError(t('Invalid source. Please enter a note ID, nevent, naddr, hex ID, or URL.')) } }, [sourceInput, context, setHighlightData, t]) return (
{t('Highlight Settings')}
setSourceInput(e.target.value)} placeholder={t('nevent1..., naddr1..., note1..., hex ID, or https://...')} className={error ? 'border-destructive' : ''} /> {error && (

{error}

)}

{t('Enter a Nostr event identifier (nevent, naddr, note, or hex ID) OR a web URL (https://). Not both.')}