feat: auto zap
This commit is contained in:
parent
ef48f553b0
commit
335905449f
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { useIntl, FormattedMessage } from "react-intl";
|
||||
import { Menu, MenuItem } from "@szhsin/react-menu";
|
||||
@ -26,6 +26,39 @@ import { useWallet } from "Wallet";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
// a dumb cache to remember which notes we zapped
|
||||
class DumbZapCache {
|
||||
#set: Set<u256> = new Set();
|
||||
constructor() {
|
||||
this.#load();
|
||||
}
|
||||
|
||||
add(id: u256) {
|
||||
this.#set.add(this.#truncId(id));
|
||||
this.#save();
|
||||
}
|
||||
|
||||
has(id: u256) {
|
||||
return this.#set.has(this.#truncId(id));
|
||||
}
|
||||
|
||||
#truncId(id: u256) {
|
||||
return id.slice(0, 12);
|
||||
}
|
||||
|
||||
#save() {
|
||||
window.localStorage.setItem("zap-cache", JSON.stringify([...this.#set]));
|
||||
}
|
||||
|
||||
#load() {
|
||||
const data = window.localStorage.getItem("zap-cache");
|
||||
if (data) {
|
||||
this.#set = new Set<u256>(JSON.parse(data) as Array<u256>);
|
||||
}
|
||||
}
|
||||
}
|
||||
const ZapCache = new DumbZapCache();
|
||||
|
||||
export interface Translation {
|
||||
text: string;
|
||||
fromLanguage: string;
|
||||
@ -65,7 +98,7 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
type: "language",
|
||||
});
|
||||
const zapTotal = zaps.reduce((acc, z) => acc + z.amount, 0);
|
||||
const didZap = zaps.some(a => a.sender === login);
|
||||
const didZap = ZapCache.has(ev.Id) || zaps.some(a => a.sender === login);
|
||||
const longPress = useLongPress(
|
||||
e => {
|
||||
e.stopPropagation();
|
||||
@ -114,16 +147,6 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
if (wallet?.isReady() && lnurl) {
|
||||
setZapping(true);
|
||||
try {
|
||||
if (prefs.fastZapDonate > 0) {
|
||||
// spin off donate
|
||||
const donateAmount = Math.floor(prefs.defaultZapAmount * prefs.fastZapDonate);
|
||||
if (donateAmount > 0) {
|
||||
console.debug(`Donating ${donateAmount} sats to ${DonateLNURL}`);
|
||||
fastZapInner(DonateLNURL, donateAmount, bech32ToHex(SnortPubKey))
|
||||
.then(() => console.debug("Donation sent! Thank You!"))
|
||||
.catch(() => console.debug("Failed to donate"));
|
||||
}
|
||||
}
|
||||
await fastZapInner(lnurl, prefs.defaultZapAmount, ev.PubKey, ev.Id);
|
||||
} catch (e) {
|
||||
console.warn("Fast zap failed", e);
|
||||
@ -145,9 +168,37 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
const zap = handler.canZap ? await publisher.zap(amount * 1000, key, id) : undefined;
|
||||
const invoice = await handler.getInvoice(amount, undefined, zap);
|
||||
await wallet.payInvoice(unwrap(invoice.pr));
|
||||
|
||||
if (prefs.fastZapDonate > 0) {
|
||||
// spin off donate
|
||||
const donateAmount = Math.floor(prefs.defaultZapAmount * prefs.fastZapDonate);
|
||||
if (donateAmount > 0) {
|
||||
console.debug(`Donating ${donateAmount} sats to ${DonateLNURL}`);
|
||||
fastZapInner(DonateLNURL, donateAmount, bech32ToHex(SnortPubKey))
|
||||
.then(() => console.debug("Donation sent! Thank You!"))
|
||||
.catch(() => console.debug("Failed to donate"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (prefs.autoZap) {
|
||||
const lnurl = author?.lud16 || author?.lud06;
|
||||
if (wallet?.isReady() && lnurl && !ZapCache.has(ev.Id)) {
|
||||
queueMicrotask(async () => {
|
||||
setZapping(true);
|
||||
try {
|
||||
await fastZapInner(lnurl, prefs.defaultZapAmount, ev.PubKey, ev.Id);
|
||||
ZapCache.add(ev.Id);
|
||||
} finally {
|
||||
setZapping(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [prefs.autoZap]);
|
||||
|
||||
function tipButton() {
|
||||
const service = author?.lud16 || author?.lud06;
|
||||
if (service) {
|
||||
|
@ -191,6 +191,23 @@ const PreferencesPage = () => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card flex">
|
||||
<div className="flex f-col f-grow">
|
||||
<div>
|
||||
<FormattedMessage defaultMessage="Auto Zap" />
|
||||
</div>
|
||||
<small>
|
||||
<FormattedMessage defaultMessage="Automatically zap every note when loaded" />
|
||||
</small>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={perf.autoZap}
|
||||
onChange={e => dispatch(setPreferences({ ...perf, autoZap: e.target.checked }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card flex f-col">
|
||||
<div className="flex w-max">
|
||||
<div className="flex f-col f-grow">
|
||||
|
@ -85,6 +85,11 @@ export interface UserPreferences {
|
||||
* For each fast zap an additional X% will be sent to Snort donate address
|
||||
*/
|
||||
fastZapDonate: number;
|
||||
|
||||
/**
|
||||
* Auto-zap every post
|
||||
*/
|
||||
autoZap: boolean;
|
||||
}
|
||||
|
||||
export interface LoginStore {
|
||||
@ -243,8 +248,9 @@ export const InitState = {
|
||||
fileUploader: "void.cat",
|
||||
imgProxyConfig: DefaultImgProxy,
|
||||
defaultRootTab: "posts",
|
||||
defaultZapAmount: 500,
|
||||
defaultZapAmount: 50,
|
||||
fastZapDonate: 0.0,
|
||||
autoZap: false,
|
||||
},
|
||||
} as LoginStore;
|
||||
|
||||
|
@ -218,6 +218,9 @@
|
||||
"Cu/K85": {
|
||||
"defaultMessage": "Translated from {lang}"
|
||||
},
|
||||
"D+KzKd": {
|
||||
"defaultMessage": "Automatically zap every note when loaded"
|
||||
},
|
||||
"D3idYv": {
|
||||
"defaultMessage": "Settings"
|
||||
},
|
||||
@ -227,6 +230,9 @@
|
||||
"DZzCem": {
|
||||
"defaultMessage": "Show latest {n} notes"
|
||||
},
|
||||
"Dh3hbq": {
|
||||
"defaultMessage": "Auto Zap"
|
||||
},
|
||||
"Dt/Zd5": {
|
||||
"defaultMessage": "Media in posts will automatically be shown for selected people, otherwise only the link will show"
|
||||
},
|
||||
|
@ -70,9 +70,11 @@
|
||||
"CHTbO3": "Failed to load invoice",
|
||||
"CmZ9ls": "{n} Muted",
|
||||
"Cu/K85": "Translated from {lang}",
|
||||
"D+KzKd": "Automatically zap every note when loaded",
|
||||
"D3idYv": "Settings",
|
||||
"DKnriN": "Send sats",
|
||||
"DZzCem": "Show latest {n} notes",
|
||||
"Dh3hbq": "Auto Zap",
|
||||
"Dt/Zd5": "Media in posts will automatically be shown for selected people, otherwise only the link will show",
|
||||
"E8a4yq": "Follow some popular accounts",
|
||||
"EPYwm7": "Your private key is your password. If you lose this key, you will lose access to your account! Copy it and keep it in a safe place. There is no way to reset your private key.",
|
||||
@ -299,4 +301,4 @@
|
||||
"zjJZBd": "You're ready!",
|
||||
"zonsdq": "Failed to load LNURL service",
|
||||
"zvCDao": "Automatically show latest notes"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user