feat: zap all on pubkey list
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Kieran 2023-05-25 23:16:22 +01:00
parent 5b0af9ecfc
commit 86ed386bb6
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 105 additions and 6 deletions

View File

@ -12,6 +12,7 @@ export default function AsyncButton(props: AsyncButtonProps) {
const [loading, setLoading] = useState<boolean>(false);
async function handle(e: React.MouseEvent) {
e.stopPropagation();
if (loading || props.disabled) return;
setLoading(true);
try {

View File

@ -10,12 +10,21 @@ import messages from "./messages";
export interface FollowListBaseProps {
pubkeys: HexKey[];
title?: ReactNode | string;
title?: ReactNode;
showFollowAll?: boolean;
showAbout?: boolean;
className?: string;
actions?: ReactNode;
}
export default function FollowListBase({ pubkeys, title, showFollowAll, showAbout, className }: FollowListBaseProps) {
export default function FollowListBase({
pubkeys,
title,
showFollowAll,
showAbout,
className,
actions,
}: FollowListBaseProps) {
const publisher = useEventPublisher();
const { follows, relays } = useLogin();
@ -31,6 +40,7 @@ export default function FollowListBase({ pubkeys, title, showFollowAll, showAbou
{(showFollowAll ?? true) && (
<div className="flex mt10 mb10">
<div className="f-grow bold">{title}</div>
{actions}
<button className="transparent" type="button" onClick={() => followAll()}>
<FormattedMessage {...messages.FollowAll} />
</button>

View File

@ -1,8 +1,84 @@
import { RawEvent } from "@snort/nostr";
import { dedupe } from "Util";
import FollowListBase from "./FollowListBase";
import { FormattedMessage, FormattedNumber } from "react-intl";
import { dedupe, hexToBech32, unixNow } from "Util";
import FollowListBase from "Element/FollowListBase";
import AsyncButton from "Element/AsyncButton";
import { useWallet } from "Wallet";
import { Toastore } from "Toaster";
import { getDisplayName } from "Element/ProfileImage";
import { UserCache } from "Cache";
import useLogin from "Hooks/useLogin";
import { LNURL } from "LNURL";
import useEventPublisher from "Feed/EventPublisher";
import { WalletInvoiceState } from "Wallet";
export default function PubkeyList({ ev, className }: { ev: RawEvent; className?: string }) {
const wallet = useWallet();
const login = useLogin();
const publisher = useEventPublisher();
const ids = dedupe(ev.tags.filter(a => a[0] === "p").map(a => a[1]));
return <FollowListBase pubkeys={ids} showAbout={true} className={className} />;
async function zapAll() {
for (const pk of ids) {
try {
const profile = await UserCache.get(pk);
const amtSend = login.preferences.defaultZapAmount;
const lnurl = profile?.lud16 || profile?.lud06;
if (lnurl) {
const svc = new LNURL(lnurl);
await svc.load();
const zap = await publisher?.zap(
amtSend * 1000,
pk,
Object.keys(login.relays.item),
undefined,
`Zap from ${hexToBech32("note", ev.id)}`
);
const invoice = await svc.getInvoice(amtSend, undefined, zap);
if (invoice.pr) {
const rsp = await wallet.wallet?.payInvoice(invoice.pr);
if (rsp?.state === WalletInvoiceState.Paid) {
Toastore.push({
element: (
<FormattedMessage
defaultMessage="Sent {n} sats to {name}"
values={{
n: amtSend,
name: getDisplayName(profile, pk),
}}
/>
),
icon: "zap",
});
}
}
}
} catch (e) {
console.debug("Failed to zap", pk, e);
}
}
}
return (
<FollowListBase
pubkeys={ids}
showAbout={true}
className={className}
title={ev.tags.find(a => a[0] === "d")?.[1]}
actions={
<>
<AsyncButton className="mr5 transparent" onClick={() => zapAll()}>
<FormattedMessage
defaultMessage="Zap All {n} sats"
values={{
n: <FormattedNumber value={login.preferences.defaultZapAmount * ids.length} />,
}}
/>
</AsyncButton>
</>
}
/>
);
}

View File

@ -225,6 +225,9 @@
"defaultMessage": "Parent",
"description": "Link to parent note in thread"
},
"AGNz71": {
"defaultMessage": "Zap All {n} sats"
},
"ASRK0S": {
"defaultMessage": "This author has been muted"
},
@ -428,6 +431,9 @@
"IUZC+0": {
"defaultMessage": "This means that nobody can modify notes which you have created and everybody can easily verify that the notes they are reading are created by you."
},
"Ig9/a1": {
"defaultMessage": "Sent {n} sats to {name}"
},
"Iwm6o2": {
"defaultMessage": "NIP-05 Shop"
},
@ -1232,6 +1238,9 @@
"defaultMessage": "Unlock",
"description": "Unlock wallet"
},
"xaj9Ba": {
"defaultMessage": "Provider"
},
"xbVgIm": {
"defaultMessage": "Automatically load media"
},

View File

@ -73,6 +73,7 @@
"9pMqYs": "Nostr Address",
"9wO4wJ": "Lightning Invoice",
"ADmfQT": "Parent",
"AGNz71": "Zap All {n} sats",
"ASRK0S": "This author has been muted",
"Adk34V": "Setup your Profile",
"Ai8VHU": "Unlimited note retention on Snort relay",
@ -140,6 +141,7 @@
"IEwZvs": "Are you sure you want to unpin this note?",
"INSqIz": "Twitter username...",
"IUZC+0": "This means that nobody can modify notes which you have created and everybody can easily verify that the notes they are reading are created by you.",
"Ig9/a1": "Sent {n} sats to {name}",
"Iwm6o2": "NIP-05 Shop",
"Ix8l+B": "Trending Notes",
"J+dIsA": "Subscriptions",
@ -402,6 +404,7 @@
"xJ9n2N": "Your public key",
"xKflGN": "{username}''s Follows on Nostr",
"xQtL3v": "Unlock",
"xaj9Ba": "Provider",
"xbVgIm": "Automatically load media",
"xhQMeQ": "Expires",
"xmcVZ0": "Search",
@ -415,4 +418,4 @@
"zjJZBd": "You're ready!",
"zonsdq": "Failed to load LNURL service",
"zvCDao": "Automatically show latest notes"
}
}