diff --git a/components/invoice.js b/components/invoice.js
index ebe51d70e..be8b73cbd 100644
--- a/components/invoice.js
+++ b/components/invoice.js
@@ -267,6 +267,7 @@ export const useInvoiceable = (onSubmit, options = defaultOptions) => {
}
const waitForPayment = async ({ invoice, showModal, provider, pollInvoice, updateCache, undoUpdate }) => {
+ const INVOICE_CANCELED_ERROR = 'invoice was canceled'
try {
// try WebLN provider first
return await new Promise((resolve, reject) => {
@@ -275,7 +276,7 @@ const waitForPayment = async ({ invoice, showModal, provider, pollInvoice, updat
// can't use await here since we might be paying HODL invoices
// and sendPaymentAsync is not supported yet.
// see https://www.webln.guide/building-lightning-apps/webln-reference/webln.sendpaymentasync
- provider.sendPayment(invoice.bolt11)
+ provider.sendPayment(invoice)
// WebLN payment will never resolve here for HODL invoices
// since they only get resolved after settlement which can't happen here
.then(resolve)
@@ -295,6 +296,10 @@ const waitForPayment = async ({ invoice, showModal, provider, pollInvoice, updat
clearInterval(interval)
resolve()
}
+ if (inv.cancelled) {
+ clearInterval(interval)
+ reject(new Error(INVOICE_CANCELED_ERROR))
+ }
} catch (err) {
clearInterval(interval)
reject(err)
@@ -302,9 +307,12 @@ const waitForPayment = async ({ invoice, showModal, provider, pollInvoice, updat
}, 1000)
})
} catch (err) {
- console.error('WebLN payment failed:', err)
// undo attempt to make zapping UX consistent
undoUpdate?.()
+ console.error('WebLN payment failed:', err)
+ if (err.message === INVOICE_CANCELED_ERROR) {
+ throw err
+ }
}
// QR code as fallback
diff --git a/components/toast.js b/components/toast.js
index 64db1870b..6f358449c 100644
--- a/components/toast.js
+++ b/components/toast.js
@@ -35,6 +35,7 @@ export const ToastProvider = ({ children }) => {
})
},
warning: (body, options) => {
+ const id = toastId.current
dispatchToast({
body,
variant: 'warning',
@@ -42,6 +43,7 @@ export const ToastProvider = ({ children }) => {
delay: 5000,
...options
})
+ return () => removeToast(id)
},
danger: (body, options) => {
const id = toastId.current
@@ -52,9 +54,7 @@ export const ToastProvider = ({ children }) => {
autohide: false,
...options
})
- return {
- removeToast: () => removeToast(id)
- }
+ return () => removeToast(id)
}
}), [dispatchToast, removeToast])
@@ -71,28 +71,32 @@ export const ToastProvider = ({ children }) => {
return (
- {toasts.map(toast => (
- removeToast(toast.id)}
- >
-
-
-
{toast.body}
-
-
-
-
- ))}
+ {toasts.map(toast => {
+ const textStyle = toast.variant === 'warning' ? 'text-dark' : ''
+ return (
+ removeToast(toast.id)}
+ >
+
+
+
{toast.body}
+
+
+
+
+ )
+ })}
{children}
diff --git a/components/toast.module.css b/components/toast.module.css
index 6d09ad7bc..c66d1363c 100644
--- a/components/toast.module.css
+++ b/components/toast.module.css
@@ -21,6 +21,13 @@
border-color: var(--bs-warning-border-subtle);
}
+.toastCancel {
+ font-style: italic;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+}
+
.toastClose {
color: #fff;
font-family: "lightning";
diff --git a/components/use-crossposter.js b/components/use-crossposter.js
index ede0f45df..552bf50d9 100644
--- a/components/use-crossposter.js
+++ b/components/use-crossposter.js
@@ -27,7 +27,7 @@ export default function useCrossposter () {
const relayError = (failedRelays) => {
return new Promise(resolve => {
- const { removeToast } = toast.danger(
+ const removeToast = toast.danger(
<>
Crossposting failed for {failedRelays.join(', ')}