add lightning payment mode setting

This commit is contained in:
hzrd149
2023-03-24 11:04:40 -05:00
parent a41c4d5041
commit 1f40f5643e
4 changed files with 88 additions and 15 deletions

View File

@@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Add lighting payment mode setting

View File

@@ -1,6 +1,7 @@
import {
Button,
ButtonGroup,
DefaultIcon,
Flex,
IconButton,
Input,
@@ -33,6 +34,7 @@ import { useSigningContext } from "../providers/signing-provider";
import QrCodeSvg from "./qr-code-svg";
import { CopyIconButton } from "./copy-icon-button";
import { useIsMobile } from "../hooks/use-is-mobile";
import settings from "../services/settings";
type FormValues = {
amount: number;
@@ -59,7 +61,7 @@ export default function ZapModal({
const metadata = useUserMetadata(pubkey);
const { requestSignature } = useSigningContext();
const toast = useToast();
const [invoice, setInvoice] = useState<string>();
const [promptInvoice, setPromptInvoice] = useState<string>();
const { isOpen: showQr, onToggle: toggleQr } = useDisclosure();
const isMobile = useIsMobile();
@@ -118,7 +120,7 @@ export default function ZapModal({
const parsed = parsePaymentRequest(payRequest);
if (parsed.amount !== amountInMilisat) throw new Error("incorrect amount");
setInvoice(payRequest);
payInvoice(payRequest);
} else throw new Error("Failed to get invoice");
}
} else {
@@ -131,7 +133,7 @@ export default function ZapModal({
const parsed = parsePaymentRequest(payRequest);
if (parsed.amount !== amountInMilisat) throw new Error("incorrect amount");
setInvoice(payRequest);
payInvoice(payRequest);
} else throw new Error("Failed to get invoice");
}
} else throw new Error("Failed to get LNURL metadata");
@@ -140,7 +142,7 @@ export default function ZapModal({
}
};
const payWithWebLn = async () => {
const payWithWebLn = async (invoice: string) => {
if (window.webln && invoice) {
if (!window.webln.enabled) await window.webln.enable();
await window.webln.sendPayment(invoice);
@@ -155,7 +157,7 @@ export default function ZapModal({
onClose();
}
};
const payWithApp = async () => {
const payWithApp = async (invoice: string) => {
window.open("lightning:" + invoice);
const listener = () => {
@@ -170,9 +172,24 @@ export default function ZapModal({
}, 1000 * 2);
};
const payInvoice = (invoice: string) => {
switch (settings.lightningPayMode.value) {
case "webln":
payWithWebLn(invoice);
break;
case "external":
payWithApp(invoice);
break;
default:
case "prompt":
setPromptInvoice(invoice);
break;
}
};
const handleClose = () => {
// if there was an invoice and we a closing the modal. presume it was paid
if (invoice && onPaid) {
// if there was an invoice and we are closing the modal. presume it was paid
if (promptInvoice && onPaid) {
onPaid();
}
onClose();
@@ -183,11 +200,11 @@ export default function ZapModal({
<ModalOverlay />
<ModalContent>
<ModalBody padding="4">
{invoice ? (
{promptInvoice ? (
<Flex gap="4" direction="column">
{showQr && <QrCodeSvg content={invoice} />}
{showQr && <QrCodeSvg content={promptInvoice} />}
<Flex gap="2">
<Input value={invoice} readOnly />
<Input value={promptInvoice} readOnly />
<IconButton
icon={<QrCodeIcon />}
aria-label="Show QrCode"
@@ -195,15 +212,21 @@ export default function ZapModal({
variant="solid"
size="md"
/>
<CopyIconButton text={invoice} aria-label="Copy Invoice" variant="solid" size="md" />
<CopyIconButton text={promptInvoice} aria-label="Copy Invoice" variant="solid" size="md" />
</Flex>
<Flex gap="2">
{window.webln && (
<Button onClick={payWithWebLn} flex={1} variant="solid" size="md">
<Button onClick={() => payWithWebLn(promptInvoice)} flex={1} variant="solid" size="md">
Pay with WebLN
</Button>
)}
<Button leftIcon={<ExternalLinkIcon />} onClick={payWithApp} flex={1} variant="solid" size="md">
<Button
leftIcon={<ExternalLinkIcon />}
onClick={() => payWithApp(promptInvoice)}
flex={1}
variant="solid"
size="md"
>
Open App
</Button>
</Flex>

View File

@@ -2,6 +2,12 @@ import { PersistentSubject } from "../classes/subject";
import db from "./db";
import { Account } from "./account";
export enum LightningPayMode {
Prompt = "prompt",
Webln = "webln",
External = "external",
}
const settings = {
blurImages: new PersistentSubject(true),
autoShowMedia: new PersistentSubject(true),
@@ -9,6 +15,7 @@ const settings = {
showReactions: new PersistentSubject(true),
showSignatureVerification: new PersistentSubject(false),
accounts: new PersistentSubject<Account[]>([]),
lightningPayMode: new PersistentSubject<LightningPayMode>(LightningPayMode.Prompt),
};
async function loadSettings() {

View File

@@ -13,13 +13,14 @@ import {
AccordionIcon,
ButtonGroup,
FormHelperText,
Select,
} from "@chakra-ui/react";
import { useState } from "react";
import settings from "../../services/settings";
import settings, { LightningPayMode } from "../../services/settings";
import { clearCacheData, deleteDatabase } from "../../services/db";
import accountService from "../../services/account";
import useSubject from "../../hooks/use-subject";
import { LogoutIcon } from "../../components/icons";
import { LightningIcon, LogoutIcon } from "../../components/icons";
export default function SettingsView() {
const blurImages = useSubject(settings.blurImages);
@@ -27,6 +28,7 @@ export default function SettingsView() {
const proxyUserMedia = useSubject(settings.proxyUserMedia);
const showReactions = useSubject(settings.showReactions);
const showSignatureVerification = useSubject(settings.showSignatureVerification);
const lightningPayMode = useSubject(settings.lightningPayMode);
const { colorMode, setColorMode } = useColorMode();
@@ -178,6 +180,42 @@ export default function SettingsView() {
</AccordionPanel>
</AccordionItem>
<AccordionItem>
<h2>
<AccordionButton>
<Box as="span" flex="1" textAlign="left">
Lightning <LightningIcon color="yellow.400" />
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel>
<Flex direction="column" gap="4">
<FormControl>
<FormLabel htmlFor="lightning-payment-mode" mb="0">
Payment mode
</FormLabel>
<Select
id="lightning-payment-mode"
value={lightningPayMode}
onChange={(e) => settings.lightningPayMode.next(e.target.value as LightningPayMode)}
>
<option value="prompt">Prompt</option>
<option value="webln">WebLN</option>
<option value="external">External</option>
</Select>
<FormHelperText>
<span>Prompt: Ask every time</span>
<br />
<span>WebLN: Use browser extension</span>
<br />
<span>External: Open an external app using "lightning:" link</span>
</FormHelperText>
</FormControl>
</Flex>
</AccordionPanel>
</AccordionItem>
<AccordionItem>
<h2>
<AccordionButton>