feat: responsible new stream modal

This commit is contained in:
Alejandro Gomez
2023-06-27 23:59:37 +02:00
parent 699f825270
commit 391e549421
9 changed files with 451 additions and 169 deletions

View File

@ -9,107 +9,149 @@ import { findTag } from "utils";
import { Relays } from "index";
import QrCode from "./qr-code";
export function SendZaps({ lnurl, ev, targetName, onFinish }: { lnurl: string, ev?: NostrEvent, targetName?: string, onFinish: () => void }) {
const UsdRate = 30_000;
export function SendZaps({
lnurl,
ev,
targetName,
onFinish,
}: {
lnurl: string;
ev?: NostrEvent;
targetName?: string;
onFinish: () => void;
}) {
const UsdRate = 30_000;
const satsAmounts = [
100, 1_000, 5_000, 10_000, 50_000, 100_000, 500_000, 1_000_000
];
const usdAmounts = [
0.05, 0.50, 2, 5, 10, 50, 100, 200
]
const [isFiat, setIsFiat] = useState(false);
const [svc, setSvc] = useState<LNURL>();
const [amount, setAmount] = useState(satsAmounts[0]);
const [comment, setComment] = useState("");
const [invoice, setInvoice] = useState("");
const satsAmounts = [
100, 1_000, 5_000, 10_000, 50_000, 100_000, 500_000, 1_000_000,
];
const usdAmounts = [0.05, 0.5, 2, 5, 10, 50, 100, 200];
const [isFiat, setIsFiat] = useState(false);
const [svc, setSvc] = useState<LNURL>();
const [amount, setAmount] = useState(satsAmounts[0]);
const [comment, setComment] = useState("");
const [invoice, setInvoice] = useState("");
const name = targetName ?? svc?.name;
async function loadService() {
const s = new LNURL(lnurl);
await s.load();
setSvc(s);
const name = targetName ?? svc?.name;
async function loadService() {
const s = new LNURL(lnurl);
await s.load();
setSvc(s);
}
useEffect(() => {
if (!svc) {
loadService().catch(console.warn);
}
}, [lnurl]);
useEffect(() => {
if (!svc) {
loadService().catch(console.warn);
}
}, [lnurl]);
async function send() {
if (!svc) return;
const pub = await EventPublisher.nip7();
if (!pub) return;
const amountInSats = isFiat ? Math.floor((amount / UsdRate) * 1e8) : amount;
let zap: NostrEvent | undefined;
if (ev) {
zap = await pub.zap(amountInSats * 1000, ev.pubkey, Relays, undefined, comment, eb => {
return eb.tag(["a", `${ev.kind}:${ev.pubkey}:${findTag(ev, "d")}`]);
});
}
const invoice = await svc.getInvoice(amountInSats, comment, zap);
if (!invoice.pr) return;
if (window.webln) {
await window.webln.enable();
await window.webln.sendPayment(invoice.pr);
onFinish();
} else {
setInvoice(invoice.pr);
async function send() {
if (!svc) return;
const pub = await EventPublisher.nip7();
if (!pub) return;
const amountInSats = isFiat ? Math.floor((amount / UsdRate) * 1e8) : amount;
let zap: NostrEvent | undefined;
if (ev) {
zap = await pub.zap(
amountInSats * 1000,
ev.pubkey,
Relays,
undefined,
comment,
(eb) => {
return eb.tag(["a", `${ev.kind}:${ev.pubkey}:${findTag(ev, "d")}`]);
}
);
}
const invoice = await svc.getInvoice(amountInSats, comment, zap);
if (!invoice.pr) return;
function input() {
if (invoice) return;
return <>
<div className="flex g12">
<span className={`pill${isFiat ? "" : " active"}`} onClick={() => { setIsFiat(false); setAmount(satsAmounts[0]) }}>
SATS
</span>
<span className={`pill${isFiat ? " active" : ""}`} onClick={() => { setIsFiat(true); setAmount(usdAmounts[0]) }}>
USD
</span>
</div>
<div>
<small>Zap amount in {isFiat ? "USD" : "sats"}</small>
<div className="amounts">
{(isFiat ? usdAmounts : satsAmounts).map(a =>
<span key={a} className={`pill${a === amount ? " active" : ""}`} onClick={() => setAmount(a)}>
{isFiat ? `$${a.toLocaleString()}` : formatSats(a)}
</span>)}
</div>
</div>
<div>
<small>
Your comment for {name}
</small>
<div className="input">
<textarea placeholder="Nice!" value={comment} onChange={e => setComment(e.target.value)} />
</div>
</div>
<div>
<AsyncButton onClick={send} className="btn btn-primary">
Zap!
</AsyncButton>
</div>
</>
if (window.webln) {
await window.webln.enable();
await window.webln.sendPayment(invoice.pr);
onFinish();
} else {
setInvoice(invoice.pr);
}
}
function payInvoice() {
if (!invoice) return;
function input() {
if (invoice) return;
return (
<>
<div className="flex g12">
<span
className={`pill${isFiat ? "" : " active"}`}
onClick={() => {
setIsFiat(false);
setAmount(satsAmounts[0]);
}}
>
SATS
</span>
<span
className={`pill${isFiat ? " active" : ""}`}
onClick={() => {
setIsFiat(true);
setAmount(usdAmounts[0]);
}}
>
USD
</span>
</div>
<div>
<small>Zap amount in {isFiat ? "USD" : "sats"}</small>
<div className="amounts">
{(isFiat ? usdAmounts : satsAmounts).map((a) => (
<span
key={a}
className={`pill${a === amount ? " active" : ""}`}
onClick={() => setAmount(a)}
>
{isFiat ? `$${a.toLocaleString()}` : formatSats(a)}
</span>
))}
</div>
</div>
<div>
<small>Your comment for {name}</small>
<div className="input">
<textarea
placeholder="Nice!"
value={comment}
onChange={(e) => setComment(e.target.value)}
/>
</div>
</div>
<div>
<AsyncButton onClick={send} className="btn btn-primary">
Zap!
</AsyncButton>
</div>
</>
);
}
const link = `lightning:${invoice}`;
return <QrCode data={link} link={link} />
}
function payInvoice() {
if (!invoice) return;
return <div className="send-zap">
<h3>
Zap {name}
<Icon name="zap" />
</h3>
{input()}
{payInvoice()}
const link = `lightning:${invoice}`;
return <QrCode data={link} link={link} />;
}
return (
<div className="send-zap">
<h3>
Zap {name}
<Icon name="zap" />
</h3>
{input()}
{payInvoice()}
</div>
}
);
}
function SendZapDialog() {
return "TODO";
}