diff --git a/.changeset/brave-dolls-glow.md b/.changeset/brave-dolls-glow.md new file mode 100644 index 000000000..355900eb7 --- /dev/null +++ b/.changeset/brave-dolls-glow.md @@ -0,0 +1,5 @@ +--- +"nostrudel": minor +--- + +Blur images in stream chat diff --git a/src/components/embed-types/common.tsx b/src/components/embed-types/common.tsx index d62fbec9e..5de4dcfee 100644 --- a/src/components/embed-types/common.tsx +++ b/src/components/embed-types/common.tsx @@ -2,7 +2,7 @@ import { Box, Image, ImageProps, Link, useDisclosure } from "@chakra-ui/react"; import appSettings from "../../services/app-settings"; import { ImageGalleryLink } from "../image-gallery"; import { useIsMobile } from "../../hooks/use-is-mobile"; -import { useTrusted } from "../note/trust"; +import { useTrusted } from "../../providers/trust"; import OpenGraphCard from "../open-graph-card"; const BlurredImage = (props: ImageProps) => { diff --git a/src/components/invoice-modal.tsx b/src/components/invoice-modal.tsx index 684872804..2c76b8540 100644 --- a/src/components/invoice-modal.tsx +++ b/src/components/invoice-modal.tsx @@ -11,10 +11,9 @@ import { useDisclosure, useToast, } from "@chakra-ui/react"; -import { ExternalLinkIcon, LightningIcon, QrCodeIcon } from "./icons"; +import { ExternalLinkIcon, QrCodeIcon } from "./icons"; import QrCodeSvg from "./qr-code-svg"; import { CopyIconButton } from "./copy-icon-button"; -import { useIsMobile } from "../hooks/use-is-mobile"; export default function InvoiceModal({ invoice, @@ -22,17 +21,20 @@ export default function InvoiceModal({ onPaid, ...props }: Omit & { invoice: string; onPaid: () => void }) { - const isMobile = useIsMobile(); const toast = useToast(); const showQr = useDisclosure(); const payWithWebLn = async (invoice: string) => { - if (window.webln && invoice) { - if (!window.webln.enabled) await window.webln.enable(); - await window.webln.sendPayment(invoice); + try { + if (window.webln && invoice) { + if (!window.webln.enabled) await window.webln.enable(); + await window.webln.sendPayment(invoice); - if (onPaid) onPaid(); - onClose(); + if (onPaid) onPaid(); + onClose(); + } + } catch (e) { + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }; const payWithApp = async (invoice: string) => { diff --git a/src/components/note/buttons/repost-button.tsx b/src/components/note/buttons/repost-button.tsx index ca526d45c..2c42d45bc 100644 --- a/src/components/note/buttons/repost-button.tsx +++ b/src/components/note/buttons/repost-button.tsx @@ -37,9 +37,7 @@ export function RepostButton({ event }: { event: NostrEvent }) { await nostrPostAction(clientRelaysService.getWriteUrls(), repost); onClose(); } catch (e) { - if (e instanceof Error) { - toast({ status: "error", description: e.message }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } setLoading(false); }; diff --git a/src/components/note/embeded-note.tsx b/src/components/note/embeded-note.tsx index d673613ea..8f0590c80 100644 --- a/src/components/note/embeded-note.tsx +++ b/src/components/note/embeded-note.tsx @@ -9,7 +9,7 @@ import { UserDnsIdentityIcon } from "../user-dns-identity-icon"; import useSubject from "../../hooks/use-subject"; import appSettings from "../../services/app-settings"; import EventVerificationIcon from "../event-verification-icon"; -import { TrustProvider } from "./trust"; +import { TrustProvider } from "../../providers/trust"; import { NoteLink } from "../note-link"; export default function EmbeddedNote({ note }: { note: NostrEvent }) { diff --git a/src/components/note/index.tsx b/src/components/note/index.tsx index 1902873f5..e6f7e028c 100644 --- a/src/components/note/index.tsx +++ b/src/components/note/index.tsx @@ -32,7 +32,7 @@ import { RepostButton } from "./buttons/repost-button"; import { QuoteRepostButton } from "./buttons/quote-repost-button"; import { ExternalLinkIcon } from "../icons"; import NoteContentWithWarning from "./note-content-with-warning"; -import { TrustProvider } from "./trust"; +import { TrustProvider } from "../../providers/trust"; import { NoteLink } from "../note-link"; import { useRegisterIntersectionEntity } from "../../providers/intersection-observer"; diff --git a/src/components/note/note-contents.tsx b/src/components/note/note-contents.tsx index 0c16dadd7..0168dedbf 100644 --- a/src/components/note/note-contents.tsx +++ b/src/components/note/note-contents.tsx @@ -21,11 +21,10 @@ import { renderOpenGraphUrl, } from "../embed-types"; import { ImageGalleryProvider } from "../image-gallery"; -import { useTrusted } from "./trust"; import { renderRedditUrl } from "../embed-types/reddit"; import EmbeddedContent from "../embeded-content"; -function buildContents(event: NostrEvent | DraftNostrEvent, trusted = false) { +function buildContents(event: NostrEvent | DraftNostrEvent) { let content: EmbedableContent = [event.content.trim()]; // common @@ -70,8 +69,7 @@ export type NoteContentsProps = { }; export const NoteContents = React.memo(({ event, maxHeight }: NoteContentsProps) => { - const trusted = useTrusted(); - const content = buildContents(event, trusted); + const content = buildContents(event); const expand = useExpand(); const [innerHeight, setInnerHeight] = useState(0); const ref = useRef(null); diff --git a/src/components/note/note-menu.tsx b/src/components/note/note-menu.tsx index fa1b1ce2e..ac1355d9e 100644 --- a/src/components/note/note-menu.tsx +++ b/src/components/note/note-menu.tsx @@ -53,12 +53,7 @@ export const NoteMenu = ({ event, ...props }: { event: NostrEvent } & Omit setDraft((d) => ({ ...d, content: (d.content += imageUrl) })); } } catch (e) { - if (e instanceof Error) { - toast({ - status: "error", - description: e.message, - }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } setUploading(false); }; diff --git a/src/components/repost-note.tsx b/src/components/repost-note.tsx index 1fc74da87..cb983a81f 100644 --- a/src/components/repost-note.tsx +++ b/src/components/repost-note.tsx @@ -9,7 +9,7 @@ import { NoteMenu } from "./note/note-menu"; import { UserAvatar } from "./user-avatar"; import { UserDnsIdentityIcon } from "./user-dns-identity-icon"; import { UserLink } from "./user-link"; -import { TrustProvider } from "./note/trust"; +import { TrustProvider } from "../providers/trust"; import { safeJson } from "../helpers/parse"; import { verifySignature } from "nostr-tools"; import { useReadRelayUrls } from "../hooks/use-client-relays"; diff --git a/src/components/zap-modal.tsx b/src/components/zap-modal.tsx index 474ed4a68..d8a324b72 100644 --- a/src/components/zap-modal.tsx +++ b/src/components/zap-modal.tsx @@ -59,13 +59,13 @@ export default function ZapModal({ initialAmount, ...props }: ZapModalProps) { + const isMobile = useIsMobile(); const metadata = useUserMetadata(pubkey); const { requestSignature } = useSigningContext(); const toast = useToast(); const [promptInvoice, setPromptInvoice] = useState(); const { isOpen: showQr, onToggle: toggleQr } = useDisclosure(); - const isMobile = useIsMobile(); - const { zapAmounts } = useSubject(appSettings); + const { customZapAmounts } = useSubject(appSettings); const { register, @@ -76,7 +76,7 @@ export default function ZapModal({ } = useForm({ mode: "onBlur", defaultValues: { - amount: initialAmount ?? zapAmounts[0], + amount: initialAmount ?? (parseInt(customZapAmounts.split(",")[0]) || 100), comment: initialComment ?? "", }, }); @@ -160,19 +160,11 @@ export default function ZapModal({ }, 1000 * 2); }; - const payInvoice = (invoice: string) => { - switch (appSettings.value.lightningPayMode) { - case "webln": - payWithWebLn(invoice); - break; - case "external": - payWithApp(invoice); - break; - default: - case "prompt": - setPromptInvoice(invoice); - break; + const payInvoice = async (invoice: string) => { + if (appSettings.value.autoPayWithWebLN) { + await payWithWebLn(invoice); } + setPromptInvoice(invoice); }; const handleClose = () => { @@ -228,11 +220,14 @@ export default function ZapModal({ - {zapAmounts.map((amount, i) => ( - - ))} + {customZapAmounts + .split(",") + .map((v) => parseInt(v)) + .map((amount, i) => ( + + ))} diff --git a/src/hooks/use-app-settings.ts b/src/hooks/use-app-settings.ts index 203502079..1dec16e0b 100644 --- a/src/hooks/use-app-settings.ts +++ b/src/hooks/use-app-settings.ts @@ -13,12 +13,7 @@ export default function useAppSettings() { try { return replaceSettings({ ...settings, ...newSettings }); } catch (e) { - if (e instanceof Error) { - toast({ - status: "error", - description: e.message, - }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }, [settings] diff --git a/src/providers/invoice-modal.tsx b/src/providers/invoice-modal.tsx index 512fcf55e..87f9f0783 100644 --- a/src/providers/invoice-modal.tsx +++ b/src/providers/invoice-modal.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useContext, useState } from "react"; import InvoiceModal from "../components/invoice-modal"; import createDefer, { Deferred } from "../classes/deferred"; +import appSettings from "../services/app-settings"; export type InvoiceModalContext = { requestPay: (invoice: string) => Promise; @@ -20,7 +21,17 @@ export const InvoiceModalProvider = ({ children }: { children: React.ReactNode } const [invoice, setInvoice] = useState(); const [defer, setDefer] = useState>(); - const requestPay = useCallback((invoice: string) => { + const requestPay = useCallback(async (invoice: string) => { + if (window.webln && appSettings.value.autoPayWithWebLN) { + try { + if (!window.webln.enabled) await window.webln.enable(); + await window.webln.sendPayment(invoice); + + handlePaid(); + return; + } catch (e) {} + } + const defer = createDefer(); setDefer(defer); setInvoice(invoice); diff --git a/src/providers/signing-provider.tsx b/src/providers/signing-provider.tsx index e23fe19e0..1c6b75987 100644 --- a/src/providers/signing-provider.tsx +++ b/src/providers/signing-provider.tsx @@ -37,12 +37,7 @@ export const SigningProvider = ({ children }: { children: React.ReactNode }) => if (!current) throw new Error("No account"); return await signingService.requestSignature(draft, current); } catch (e) { - if (e instanceof Error) { - toast({ - status: "error", - description: e.message, - }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }, [toast, current] @@ -53,12 +48,7 @@ export const SigningProvider = ({ children }: { children: React.ReactNode }) => if (!current) throw new Error("No account"); return await signingService.requestDecrypt(data, pubkey, current); } catch (e) { - if (e instanceof Error) { - toast({ - status: "error", - description: e.message, - }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }, [toast, current] @@ -69,12 +59,7 @@ export const SigningProvider = ({ children }: { children: React.ReactNode }) => if (!current) throw new Error("No account"); return await signingService.requestEncrypt(data, pubkey, current); } catch (e) { - if (e instanceof Error) { - toast({ - status: "error", - description: e.message, - }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }, [toast, current] diff --git a/src/components/note/trust.tsx b/src/providers/trust.tsx similarity index 74% rename from src/components/note/trust.tsx rename to src/providers/trust.tsx index 6fd3731fe..32f9c3649 100644 --- a/src/components/note/trust.tsx +++ b/src/providers/trust.tsx @@ -1,8 +1,8 @@ import React, { PropsWithChildren, useContext } from "react"; -import { NostrEvent } from "../../types/nostr-event"; -import { useCurrentAccount } from "../../hooks/use-current-account"; -import clientFollowingService from "../../services/client-following"; -import useSubject from "../../hooks/use-subject"; +import { NostrEvent } from "../types/nostr-event"; +import { useCurrentAccount } from "../hooks/use-current-account"; +import clientFollowingService from "../services/client-following"; +import useSubject from "../hooks/use-subject"; const TrustContext = React.createContext(false); diff --git a/src/services/user-app-settings.ts b/src/services/user-app-settings.ts index f179bae01..f3441956c 100644 --- a/src/services/user-app-settings.ts +++ b/src/services/user-app-settings.ts @@ -9,12 +9,6 @@ import db from "./db"; const DTAG = "nostrudel-settings"; -export enum LightningPayMode { - Prompt = "prompt", - Webln = "webln", - External = "external", -} - export type AppSettings = { colorMode: ColorMode; blurImages: boolean; @@ -22,8 +16,10 @@ export type AppSettings = { proxyUserMedia: boolean; showReactions: boolean; showSignatureVerification: boolean; - lightningPayMode: LightningPayMode; - zapAmounts: number[]; + + autoPayWithWebLN: boolean; + customZapAmounts: string; + primaryColor: string; imageProxy: string; corsProxy: string; @@ -40,8 +36,10 @@ export const defaultSettings: AppSettings = { proxyUserMedia: false, showReactions: true, showSignatureVerification: false, - lightningPayMode: LightningPayMode.Prompt, - zapAmounts: [50, 200, 500, 1000], + + autoPayWithWebLN: true, + customZapAmounts: "50,200,500,1000,2000,5000", + primaryColor: "#8DB600", imageProxy: "", corsProxy: "", diff --git a/src/views/note/thread-post.tsx b/src/views/note/thread-post.tsx index e3c0f1801..f32ac1077 100644 --- a/src/views/note/thread-post.tsx +++ b/src/views/note/thread-post.tsx @@ -4,7 +4,7 @@ import { ArrowDownSIcon, ArrowUpSIcon } from "../../components/icons"; import { Note } from "../../components/note"; import { countReplies, ThreadItem as ThreadItemData } from "../../helpers/thread"; import { useIsMobile } from "../../hooks/use-is-mobile"; -import { TrustProvider } from "../../components/note/trust"; +import { TrustProvider } from "../../providers/trust"; export type ThreadItemProps = { post: ThreadItemData; diff --git a/src/views/profile/edit.tsx b/src/views/profile/edit.tsx index bb0d142f0..f544b4062 100644 --- a/src/views/profile/edit.tsx +++ b/src/views/profile/edit.tsx @@ -243,12 +243,7 @@ export const ProfileEditView = () => { await results.onComplete; } catch (e) { - if (e instanceof Error) { - toast({ - status: "error", - description: e.message, - }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }; diff --git a/src/views/relays/index.tsx b/src/views/relays/index.tsx index 519f01468..1f0ff96e2 100644 --- a/src/views/relays/index.tsx +++ b/src/views/relays/index.tsx @@ -61,9 +61,7 @@ function RelaysPage() { } setRelayInputValue(""); } catch (e) { - if (e instanceof Error) { - toast({ status: "error", description: e.message }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }; const savePending = async () => { diff --git a/src/views/settings/index.tsx b/src/views/settings/index.tsx index 8b32e9bdf..0f71d51a3 100644 --- a/src/views/settings/index.tsx +++ b/src/views/settings/index.tsx @@ -1,4 +1,4 @@ -import { Button, Flex, Accordion, Link } from "@chakra-ui/react"; +import { Button, Flex, Accordion, Link, useToast } from "@chakra-ui/react"; import { Link as RouterLink } from "react-router-dom"; import { GithubIcon, ToolsIcon } from "../../components/icons"; import LightningSettings from "./lightning-settings"; @@ -10,6 +10,7 @@ import useAppSettings from "../../hooks/use-app-settings"; import { FormProvider, useForm } from "react-hook-form"; export default function SettingsView() { + const toast = useToast(); const { updateSettings, ...settings } = useAppSettings(); const form = useForm({ @@ -18,7 +19,12 @@ export default function SettingsView() { }); const saveSettings = form.handleSubmit(async (values) => { - await updateSettings(values); + try { + await updateSettings(values); + toast({ title: "Settings saved", status: "success" }); + } catch (e) { + if (e instanceof Error) toast({ description: e.message, status: "error" }); + } }); return ( diff --git a/src/views/settings/lightning-settings.tsx b/src/views/settings/lightning-settings.tsx index 7cfba80fe..51c46a012 100644 --- a/src/views/settings/lightning-settings.tsx +++ b/src/views/settings/lightning-settings.tsx @@ -10,13 +10,15 @@ import { FormHelperText, Input, Select, + Switch, + FormErrorMessage, } from "@chakra-ui/react"; import { LightningIcon } from "../../components/icons"; import { AppSettings } from "../../services/user-app-settings"; import { useFormContext } from "react-hook-form"; export default function LightningSettings() { - const { register } = useFormContext(); + const { register, formState } = useFormContext(); return ( @@ -31,44 +33,35 @@ export default function LightningSettings() { - - Payment mode - - + + + Auto pay with WebLN + + + + - Prompt: Ask every time -
- WebLN: Use browser extension -
- External: Open an external app using "lightning:" link + Enabled: Attempt to automatically pay with WebLN if its available
- + Zap Amounts { - if (Array.isArray(value)) { - return Array.from(value).join(","); - } else { - return value - .split(",") - .map((v) => parseInt(v)) - .filter(Boolean) - .sort((a, b) => a - b); - } + {...register("customZapAmounts", { + validate: (v) => { + if (!/^[\d,]*$/.test(v)) return "Must be a list of comma separated numbers"; + return true; }, })} /> + {formState.errors.customZapAmounts && ( + {formState.errors.customZapAmounts.message} + )} Comma separated list of custom zap amounts diff --git a/src/views/streams/components/stream-card.tsx b/src/views/streams/components/stream-card.tsx index 159548b57..8bc6b5390 100644 --- a/src/views/streams/components/stream-card.tsx +++ b/src/views/streams/components/stream-card.tsx @@ -36,7 +36,7 @@ import RawValue from "../../../components/debug-modals/raw-value"; import RawJson from "../../../components/debug-modals/raw-json"; export default function StreamCard({ stream, ...props }: CardProps & { stream: ParsedStream }) { - const { title, summary, identifier, image } = stream; + const { title, identifier, image } = stream; const devModal = useDisclosure(); const naddr = useMemo(() => { diff --git a/src/views/streams/stream/stream-chat.tsx b/src/views/streams/stream/stream-chat.tsx index 975cced46..530d8746c 100644 --- a/src/views/streams/stream/stream-chat.tsx +++ b/src/views/streams/stream/stream-chat.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useRef } from "react"; +import { useMemo, useRef } from "react"; import dayjs from "dayjs"; import { Box, @@ -11,8 +11,15 @@ import { Heading, IconButton, Input, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalHeader, + ModalOverlay, Spacer, Text, + useDisclosure, useToast, } from "@chakra-ui/react"; import { ParsedStream, buildChatMessage, getATag } from "../../../helpers/nostr/stream"; @@ -26,8 +33,15 @@ import { UserLink } from "../../../components/user-link"; import { DraftNostrEvent, NostrEvent } from "../../../types/nostr-event"; import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../../providers/intersection-observer"; import { useTimelineCurserIntersectionCallback } from "../../../hooks/use-timeline-cursor-intersection-callback"; -import { embedUrls } from "../../../helpers/embeds"; -import { embedEmoji, renderGenericUrl, renderImageUrl } from "../../../components/embed-types"; +import { EmbedableContent, embedUrls } from "../../../helpers/embeds"; +import { + embedEmoji, + embedNostrHashtags, + embedNostrLinks, + embedNostrMentions, + renderGenericUrl, + renderImageUrl, +} from "../../../components/embed-types"; import EmbeddedContent from "../../../components/embeded-content"; import { useForm } from "react-hook-form"; import { useSigningContext } from "../../../providers/signing-provider"; @@ -41,33 +55,50 @@ import { readablizeSats } from "../../../helpers/bolt11"; import { Kind } from "nostr-tools"; import useUserLNURLMetadata from "../../../hooks/use-user-lnurl-metadata"; import { useInvoiceModalContext } from "../../../providers/invoice-modal"; +import { ImageGalleryProvider } from "../../../components/image-gallery"; +import appSettings from "../../../services/app-settings"; +import { TrustProvider } from "../../../providers/trust"; + +function ChatMessageContent({ event }: { event: NostrEvent }) { + const content = useMemo(() => { + let c: EmbedableContent = [event.content]; + + c = embedUrls(c, [renderImageUrl, renderGenericUrl]); + + // nostr + c = embedNostrLinks(c); + c = embedNostrMentions(c, event); + c = embedNostrHashtags(c, event); + c = embedEmoji(c, event); + + return c; + }, [event.content]); + + return ; +} function ChatMessage({ event, stream }: { event: NostrEvent; stream: ParsedStream }) { const ref = useRef(null); useRegisterIntersectionEntity(ref, event.id); - const content = useMemo(() => { - let c = embedUrls([event.content], [renderImageUrl, renderGenericUrl]); - c = embedEmoji(c, event); - return c; - }, [event.content]); - return ( - - - - - - {dayjs.unix(event.created_at).fromNow()} + + + + + + + {dayjs.unix(event.created_at).fromNow()} + + + + - - - - + ); } @@ -76,28 +107,24 @@ function ZapMessage({ zap, stream }: { zap: NostrEvent; stream: ParsedStream }) useRegisterIntersectionEntity(ref, zap.id); const { request, payment } = parseZapEvent(zap); - const content = useMemo(() => { - let c = embedUrls([request.content], [renderImageUrl, renderGenericUrl]); - c = embedEmoji(c, request); - return c; - }, [request.content]); - if (!payment.amount) return null; return ( - - - - - - zapped {readablizeSats(payment.amount / 1000)} sats - - {dayjs.unix(request.created_at).fromNow()} + + + + + + + zapped {readablizeSats(payment.amount / 1000)} sats + + {dayjs.unix(request.created_at).fromNow()} + + + + - - - - + ); } @@ -106,6 +133,7 @@ export default function StreamChat({ actions, ...props }: CardProps & { stream: ParsedStream; actions?: React.ReactNode }) { + const { customZapAmounts } = useSubject(appSettings); const toast = useToast(); const contextRelays = useAdditionalRelayContext(); const readRelays = useReadRelayUrls(contextRelays); @@ -135,18 +163,18 @@ export default function StreamChat({ nostrPostAction(unique([...contextRelays, ...writeRelays]), signed); reset(); } catch (e) { - if (e instanceof Error) toast({ description: e.message }); + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }); + const zapAmountModal = useDisclosure(); const { requestPay } = useInvoiceModalContext(); const zapMetadata = useUserLNURLMetadata(stream.author); - const zapMessage = async () => { + const zapMessage = async (amount: number) => { try { if (!zapMetadata.metadata?.callback) throw new Error("bad lnurl endpoint"); const content = getValues().content; - const amount = 100; const zapRequest: DraftNostrEvent = { kind: Kind.ZapRequest, created_at: dayjs().unix(), @@ -167,53 +195,93 @@ export default function StreamChat({ reset(); } catch (e) { - if (e instanceof Error) toast({ description: e.message }); + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }; return ( - - - - Stream Chat - {actions} - - - - {events.map((event) => - event.kind === 1311 ? ( - - ) : ( - - ) - )} - - - - - {zapMetadata.metadata?.allowsNostr && ( - } - aria-label="Zap stream" - borderColor="yellow.400" - variant="outline" - onClick={zapMessage} - /> - )} - - - - + <> + + + + + Stream Chat + {actions} + + + + {events.map((event) => + event.kind === 1311 ? ( + + ) : ( + + ) + )} + + + + + {zapMetadata.metadata?.allowsNostr && ( + } + aria-label="Zap stream" + borderColor="yellow.400" + variant="outline" + onClick={zapAmountModal.onOpen} + /> + )} + + + + + + + + + Zap Amount + + + + {customZapAmounts + .split(",") + .map((v) => parseInt(v)) + .map((amount, i) => ( + + ))} + + + + + ); } diff --git a/src/views/tools/nip19.tsx b/src/views/tools/nip19.tsx index ea483d6f3..8c92f854c 100644 --- a/src/views/tools/nip19.tsx +++ b/src/views/tools/nip19.tsx @@ -45,9 +45,7 @@ function EncodeForm() { setOutput(nprofile); } catch (e) { - if (e instanceof Error) { - toast({ description: e.message }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } }); @@ -92,9 +90,7 @@ function DecodeForm() { try { setOutput(nip19.decode(values.input)); } catch (e) { - if (e instanceof Error) { - toast({ description: e.message }); - } + if (e instanceof Error) toast({ description: e.message, status: "error" }); } });