mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-29 11:12:12 +01:00
Merge branch 'next'
This commit is contained in:
commit
726c68b8b2
8
.changeset/README.md
Normal file
8
.changeset/README.md
Normal 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)
|
5
.changeset/big-bugs-repeat.md
Normal file
5
.changeset/big-bugs-repeat.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"nostrudel": minor
|
||||
---
|
||||
|
||||
Add github link to settings view
|
11
.changeset/config.json
Normal file
11
.changeset/config.json
Normal 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": []
|
||||
}
|
5
.changeset/yellow-trainers-sparkle.md
Normal file
5
.changeset/yellow-trainers-sparkle.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"nostrudel": minor
|
||||
---
|
||||
|
||||
Add lighting payment mode setting
|
@ -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",
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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>
|
||||
|
@ -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() {
|
||||
|
@ -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>
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user