Merge branch 'next'

This commit is contained in:
hzrd149 2023-04-03 13:44:11 -05:00
commit 726c68b8b2
11 changed files with 1282 additions and 24 deletions

8
.changeset/README.md Normal file
View File

@ -0,0 +1,8 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

View File

@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Add github link to settings view

11
.changeset/config.json Normal file
View File

@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": []
}

View File

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

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
18

View File

@ -1,6 +1,6 @@
{
"name": "nostrudel",
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"scripts": {
"start": "vite serve",
@ -10,6 +10,7 @@
"dependencies": {
"@chakra-ui/icons": "^2.0.14",
"@chakra-ui/react": "^2.4.4",
"@changesets/cli": "^2.26.1",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"bech32": "^2.0.0",

View File

@ -239,3 +239,9 @@ export const PlusCircleIcon = createIcon({
d: "M11 11V7h2v4h4v2h-4v4h-2v-4H7v-2h4zm1 11C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16z",
defaultProps,
});
export const GithubIcon = createIcon({
displayName: "GithubIcon",
d: "M10 0a10 10 0 0 0-3.16 19.49c.5.1.68-.22.68-.48l-.01-1.7c-2.78.6-3.37-1.34-3.37-1.34-.46-1.16-1.11-1.47-1.11-1.47-.9-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.9 1.52 2.34 1.08 2.91.83.1-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.1.39-1.99 1.03-2.69a3.6 3.6 0 0 1 .1-2.64s.84-.27 2.75 1.02a9.58 9.58 0 0 1 5 0c1.91-1.3 2.75-1.02 2.75-1.02.55 1.37.2 2.4.1 2.64.64.7 1.03 1.6 1.03 2.69 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85l-.01 2.75c0 .26.18.58.69.48A10 10 0 0 0 10 0",
defaultProps,
});

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,15 @@ import {
AccordionIcon,
ButtonGroup,
FormHelperText,
Select,
Link,
} 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 { GithubIcon, LightningIcon, LogoutIcon } from "../../components/icons";
export default function SettingsView() {
const blurImages = useSubject(settings.blurImages);
@ -27,6 +29,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 +181,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>
@ -199,10 +238,13 @@ export default function SettingsView() {
</AccordionPanel>
</AccordionItem>
</Accordion>
<Flex gap="2" padding="4">
<Flex gap="2" padding="4" alignItems="center" justifyContent="space-between">
<Button leftIcon={<LogoutIcon />} onClick={() => accountService.logout()}>
Logout
</Button>
<Link isExternal href="https://github.com/hzrd149/nostrudel">
<GithubIcon /> Github
</Link>
</Flex>
</Flex>
);

1163
yarn.lock

File diff suppressed because it is too large Load Diff