import { Button } from '@/components/ui/button' import { DialogFooter } from '@/components/ui/dialog' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Slider } from '@/components/ui/slider' import { Textarea } from '@/components/ui/textarea' import { ExtendedKind } from '@/constants' import { createPaymentNotificationDraftEvent } from '@/lib/draft-event' import { createFakeEvent } from '@/lib/event' import { clampZapSats, formatSatsGrouped, parseGroupedIntegerInput } from '@/lib/lightning' import { parsePaytoTagType } from '@/lib/payto' import { LoginRequiredError } from '@/lib/nostr-errors' import { paymentNotificationReferenceTags, type PostPaymentContext } from '@/lib/post-payment-context' import { showSimplePublishSuccess } from '@/lib/publishing-feedback' import { cn } from '@/lib/utils' import { useNostr } from '@/providers/NostrProvider' import { useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import SatsAmountEquivalents from '@/components/SatsAmountEquivalents' import MarkdownArticle from '../Note/MarkdownArticle/MarkdownArticle' import SuperchatPaymentMethodLabel from '../Note/SuperchatPaymentMethodLabel' export default function SuperchatRequestForm({ recipientPubkey, paymentContext, onBack, onDone }: { recipientPubkey: string paymentContext?: PostPaymentContext | null onBack: () => void onDone: () => void }) { const { t } = useTranslation() const { publish, checkLogin, pubkey: selfPubkey } = useNostr() const [message, setMessage] = useState('') const [amountSats, setAmountSats] = useState(0) const [minPow, setMinPow] = useState(0) const [sending, setSending] = useState(false) const textareaRef = useRef(null) useEffect(() => { setMessage(paymentContext?.messageDraft ?? '') setAmountSats( paymentContext?.amountMsat ? clampZapSats(Math.floor(paymentContext.amountMsat / 1000)) : 0 ) }, [paymentContext?.messageDraft, paymentContext?.amountMsat]) const amountMsat = amountSats > 0 ? clampZapSats(amountSats) * 1000 : undefined useEffect(() => { const id = requestAnimationFrame(() => textareaRef.current?.focus()) return () => cancelAnimationFrame(id) }, []) const previewEvent = useMemo(() => { const tags: string[][] = [['p', recipientPubkey]] if (amountMsat) { tags.push(['amount', String(amountMsat)]) } if (paymentContext?.payto) { tags.push(['payto', paymentContext.payto]) } tags.push(...paymentNotificationReferenceTags(paymentContext?.referencedEvent)) return createFakeEvent({ kind: ExtendedKind.PAYMENT_NOTIFICATION, pubkey: selfPubkey ?? '', content: message, tags }) }, [amountMsat, message, paymentContext, recipientPubkey, selfPubkey]) const handleSend = () => { const trimmed = message.trim() if (!trimmed) return checkLogin(async () => { setSending(true) try { const draft = await createPaymentNotificationDraftEvent(trimmed, recipientPubkey, { amountMsat, payto: paymentContext?.payto, referencedEvent: paymentContext?.referencedEvent, addClientTag: true }) await publish(draft, { disableFallbacks: true, minPow }) showSimplePublishSuccess(t('Superchat request sent')) onDone() } catch (error) { if (error instanceof LoginRequiredError) return toast.error( t('Failed to send superchat request', { error: error instanceof Error ? error.message : String(error) }) ) } finally { setSending(false) } }) } const paytoType = paymentContext?.payto ? parsePaytoTagType(paymentContext.payto) : null return (

{t('Superchat request prompt description')}

{paytoType ? (
) : null}
0 ? formatSatsGrouped(amountSats) : ''} onChange={(e) => setAmountSats(parseGroupedIntegerInput(e.target.value))} placeholder="0" disabled={sending} className="min-w-0 flex-1 tabular-nums" aria-describedby="superchat-amount-equiv superchat-amount-hint" /> {t('sats')}

{t('Superchat estimated amount hint')}