don't toast on invoice cancellation
This commit is contained in:
parent
94d9d9513c
commit
6cf16d3da7
@ -8,7 +8,6 @@ import { amountSchema } from '@/lib/validate'
|
|||||||
import { useToast } from './toast'
|
import { useToast } from './toast'
|
||||||
import { useLightning } from './lightning'
|
import { useLightning } from './lightning'
|
||||||
import { nextTip } from './upvote'
|
import { nextTip } from './upvote'
|
||||||
import { InvoiceCanceledError } from './payment'
|
|
||||||
import { ZAP_UNDO_DELAY_MS } from '@/lib/constants'
|
import { ZAP_UNDO_DELAY_MS } from '@/lib/constants'
|
||||||
import { usePaidMutation } from './use-paid-mutation'
|
import { usePaidMutation } from './use-paid-mutation'
|
||||||
import { ACT_MUTATION } from '@/fragments/paidAction'
|
import { ACT_MUTATION } from '@/fragments/paidAction'
|
||||||
@ -72,7 +71,7 @@ export default function ItemAct ({ onClose, item, down, children, abortSignal })
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await act({
|
const { error } = await act({
|
||||||
variables: {
|
variables: {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
sats: Number(amount),
|
sats: Number(amount),
|
||||||
@ -95,6 +94,7 @@ export default function ItemAct ({ onClose, item, down, children, abortSignal })
|
|||||||
if (!me) setItemMeAnonSats({ id: item.id, amount })
|
if (!me) setItemMeAnonSats({ id: item.id, amount })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if (error) throw error
|
||||||
addCustomTip(Number(amount))
|
addCustomTip(Number(amount))
|
||||||
}, [me, act, down, item.id, onClose, abortSignal, strike])
|
}, [me, act, down, item.id, onClose, abortSignal, strike])
|
||||||
|
|
||||||
@ -219,15 +219,15 @@ export function useZap () {
|
|||||||
try {
|
try {
|
||||||
await abortSignal.pause({ me, amount: sats })
|
await abortSignal.pause({ me, amount: sats })
|
||||||
strike()
|
strike()
|
||||||
await act({ variables, optimisticResponse })
|
const { error } = await act({ variables, optimisticResponse })
|
||||||
|
if (error) throw error
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof InvoiceCanceledError || error instanceof ActCanceledError) {
|
if (error instanceof ActCanceledError) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const reason = error?.message || error?.toString?.()
|
const reason = error?.message || error?.toString?.()
|
||||||
|
toaster.danger(reason)
|
||||||
toaster.danger('zap failed: ' + reason)
|
|
||||||
}
|
}
|
||||||
}, [me?.id, strike])
|
}, [me?.id, strike])
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import { MuteSubDropdownItem, PinSubDropdownItem } from './territory-header'
|
|||||||
import UserPopover from './user-popover'
|
import UserPopover from './user-popover'
|
||||||
import { useQrPayment } from './payment'
|
import { useQrPayment } from './payment'
|
||||||
import { useRetryCreateItem } from './use-item-submit'
|
import { useRetryCreateItem } from './use-item-submit'
|
||||||
|
import { useToast } from './toast'
|
||||||
|
|
||||||
export default function ItemInfo ({
|
export default function ItemInfo ({
|
||||||
item, full, commentsText = 'comments',
|
item, full, commentsText = 'comments',
|
||||||
@ -32,6 +33,7 @@ export default function ItemInfo ({
|
|||||||
}) {
|
}) {
|
||||||
const editThreshold = new Date(item.invoice?.confirmedAt ?? item.createdAt).getTime() + 10 * 60000
|
const editThreshold = new Date(item.invoice?.confirmedAt ?? item.createdAt).getTime() + 10 * 60000
|
||||||
const me = useMe()
|
const me = useMe()
|
||||||
|
const toaster = useToast()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [canEdit, setCanEdit] =
|
const [canEdit, setCanEdit] =
|
||||||
useState(item.mine && (Date.now() < editThreshold))
|
useState(item.mine && (Date.now() < editThreshold))
|
||||||
@ -72,7 +74,14 @@ export default function ItemInfo ({
|
|||||||
if (me && item.invoice?.actionState && item.invoice?.actionState !== 'PAID') {
|
if (me && item.invoice?.actionState && item.invoice?.actionState !== 'PAID') {
|
||||||
if (item.invoice?.actionState === 'FAILED') {
|
if (item.invoice?.actionState === 'FAILED') {
|
||||||
Component = () => <span className='text-warning'>retry payment</span>
|
Component = () => <span className='text-warning'>retry payment</span>
|
||||||
onClick = async () => await retryCreateItem({ variables: { invoiceId: parseInt(item.invoice?.id) } }).catch(console.error)
|
onClick = async () => {
|
||||||
|
try {
|
||||||
|
const { error } = await retryCreateItem({ variables: { invoiceId: parseInt(item.invoice?.id) } })
|
||||||
|
if (error) throw error
|
||||||
|
} catch (error) {
|
||||||
|
toaster.danger(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Component = () => (
|
Component = () => (
|
||||||
<span
|
<span
|
||||||
|
@ -36,6 +36,7 @@ import { usePollVote } from './poll'
|
|||||||
import { paidActionCacheMods } from './use-paid-mutation'
|
import { paidActionCacheMods } from './use-paid-mutation'
|
||||||
import { useRetryCreateItem } from './use-item-submit'
|
import { useRetryCreateItem } from './use-item-submit'
|
||||||
import { payBountyCacheMods } from './pay-bounty'
|
import { payBountyCacheMods } from './pay-bounty'
|
||||||
|
import { useToast } from './toast'
|
||||||
|
|
||||||
function Notification ({ n, fresh }) {
|
function Notification ({ n, fresh }) {
|
||||||
const type = n.__typename
|
const type = n.__typename
|
||||||
@ -334,6 +335,7 @@ function useActRetry ({ invoice }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Invoicification ({ n: { invoice, sortTime } }) {
|
function Invoicification ({ n: { invoice, sortTime } }) {
|
||||||
|
const toaster = useToast()
|
||||||
const actRetry = useActRetry({ invoice })
|
const actRetry = useActRetry({ invoice })
|
||||||
const retryCreateItem = useRetryCreateItem({ id: invoice.item?.id })
|
const retryCreateItem = useRetryCreateItem({ id: invoice.item?.id })
|
||||||
const retryPollVote = usePollVote({ query: RETRY_PAID_ACTION, itemId: invoice.item?.id })
|
const retryPollVote = usePollVote({ query: RETRY_PAID_ACTION, itemId: invoice.item?.id })
|
||||||
@ -390,8 +392,13 @@ function Invoicification ({ n: { invoice, sortTime } }) {
|
|||||||
<Button
|
<Button
|
||||||
size='sm' variant='outline-warning ms-2 border-1 rounded py-0'
|
size='sm' variant='outline-warning ms-2 border-1 rounded py-0'
|
||||||
style={{ '--bs-btn-hover-color': '#fff', '--bs-btn-active-color': '#fff' }}
|
style={{ '--bs-btn-hover-color': '#fff', '--bs-btn-active-color': '#fff' }}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
retry({ variables: { invoiceId: parseInt(invoiceId) } }).catch(console.error)
|
try {
|
||||||
|
const { error } = await retry({ variables: { invoiceId: parseInt(invoiceId) } })
|
||||||
|
if (error) throw error
|
||||||
|
} catch (error) {
|
||||||
|
toaster.danger(error?.message || error?.toString?.())
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
retry
|
retry
|
||||||
|
@ -7,7 +7,6 @@ import { numWithUnits } from '@/lib/format'
|
|||||||
import { useShowModal } from './modal'
|
import { useShowModal } from './modal'
|
||||||
import { useRoot } from './root'
|
import { useRoot } from './root'
|
||||||
import { ActCanceledError, useAct } from './item-act'
|
import { ActCanceledError, useAct } from './item-act'
|
||||||
import { InvoiceCanceledError } from './payment'
|
|
||||||
import { useLightning } from './lightning'
|
import { useLightning } from './lightning'
|
||||||
import { useToast } from './toast'
|
import { useToast } from './toast'
|
||||||
|
|
||||||
@ -58,15 +57,15 @@ export default function PayBounty ({ children, item }) {
|
|||||||
const handlePayBounty = async onCompleted => {
|
const handlePayBounty = async onCompleted => {
|
||||||
try {
|
try {
|
||||||
strike()
|
strike()
|
||||||
await act({ onCompleted })
|
const { error } = await act({ onCompleted })
|
||||||
|
if (error) throw error
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof InvoiceCanceledError || error instanceof ActCanceledError) {
|
if (error instanceof ActCanceledError) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const reason = error?.message || error?.toString?.()
|
const reason = error?.message || error?.toString?.()
|
||||||
|
toaster.danger(reason)
|
||||||
toaster.danger('pay bounty failed: ' + reason)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ export class InvoiceCanceledError extends Error {
|
|||||||
super(actionError ?? `invoice canceled: ${hash}`)
|
super(actionError ?? `invoice canceled: ${hash}`)
|
||||||
this.name = 'InvoiceCanceledError'
|
this.name = 'InvoiceCanceledError'
|
||||||
this.hash = hash
|
this.hash = hash
|
||||||
|
this.actionError = actionError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import { useMe } from './me'
|
|||||||
import styles from './poll.module.css'
|
import styles from './poll.module.css'
|
||||||
import { signIn } from 'next-auth/react'
|
import { signIn } from 'next-auth/react'
|
||||||
import ActionTooltip from './action-tooltip'
|
import ActionTooltip from './action-tooltip'
|
||||||
import { InvoiceCanceledError, useQrPayment } from './payment'
|
import { useQrPayment } from './payment'
|
||||||
import { useToast } from './toast'
|
import { useToast } from './toast'
|
||||||
import { usePaidMutation } from './use-paid-mutation'
|
import { usePaidMutation } from './use-paid-mutation'
|
||||||
import { POLL_VOTE, RETRY_PAID_ACTION } from '@/fragments/paidAction'
|
import { POLL_VOTE, RETRY_PAID_ACTION } from '@/fragments/paidAction'
|
||||||
@ -25,18 +25,14 @@ export default function Poll ({ item }) {
|
|||||||
const variables = { id: v.id }
|
const variables = { id: v.id }
|
||||||
const optimisticResponse = { pollVote: { __typename: 'PollVotePaidAction', result: { id: v.id } } }
|
const optimisticResponse = { pollVote: { __typename: 'PollVotePaidAction', result: { id: v.id } } }
|
||||||
try {
|
try {
|
||||||
await pollVote({
|
const { error } = await pollVote({
|
||||||
variables,
|
variables,
|
||||||
optimisticResponse
|
optimisticResponse
|
||||||
})
|
})
|
||||||
|
if (error) throw error
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof InvoiceCanceledError) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const reason = error?.message || error?.toString?.()
|
const reason = error?.message || error?.toString?.()
|
||||||
|
toaster.danger(reason)
|
||||||
toaster.danger('poll vote failed: ' + reason)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: signIn}
|
: signIn}
|
||||||
|
@ -41,7 +41,7 @@ export default function TerritoryForm ({ sub }) {
|
|||||||
: await upsertSub({ variables: { oldName: sub?.name, ...variables } })
|
: await upsertSub({ variables: { oldName: sub?.name, ...variables } })
|
||||||
|
|
||||||
if (error) throw error
|
if (error) throw error
|
||||||
if (payError) throw new Error('payment required')
|
if (payError) return
|
||||||
|
|
||||||
// modify graphql cache to include new sub
|
// modify graphql cache to include new sub
|
||||||
client.cache.modify({
|
client.cache.modify({
|
||||||
|
@ -16,15 +16,13 @@ export default function TerritoryPaymentDue ({ sub }) {
|
|||||||
const client = useApolloClient()
|
const client = useApolloClient()
|
||||||
const [paySub] = usePaidMutation(SUB_PAY)
|
const [paySub] = usePaidMutation(SUB_PAY)
|
||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(async ({ ...variables }) => {
|
||||||
async ({ ...variables }) => {
|
const { error } = await paySub({
|
||||||
const { error, payError } = await paySub({
|
variables
|
||||||
variables
|
})
|
||||||
})
|
|
||||||
|
|
||||||
if (error) throw error
|
if (error) throw error
|
||||||
if (payError) throw new Error('payment required')
|
}, [client, paySub])
|
||||||
}, [client, paySub])
|
|
||||||
|
|
||||||
if (!sub || sub.userId !== Number(me?.id) || sub.status === 'ACTIVE') return null
|
if (!sub || sub.userId !== Number(me?.id) || sub.status === 'ACTIVE') return null
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export default function useItemSubmit (mutation,
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (error) throw error
|
if (error) throw error
|
||||||
if (payError) throw new Error('payment required')
|
if (payError) return
|
||||||
|
|
||||||
// we don't know the mutation name, so we have to extract the result
|
// we don't know the mutation name, so we have to extract the result
|
||||||
const response = Object.values(data)[0]
|
const response = Object.values(data)[0]
|
||||||
|
@ -63,6 +63,14 @@ export function usePaidMutation (mutation,
|
|||||||
|
|
||||||
// if the mutation returns an invoice, pay it
|
// if the mutation returns an invoice, pay it
|
||||||
if (invoice) {
|
if (invoice) {
|
||||||
|
// adds payError, escalating to a normal error if the invoice is not canceled or
|
||||||
|
// has an actionError
|
||||||
|
const addPayError = (e, rest) => ({
|
||||||
|
...rest,
|
||||||
|
payError: e,
|
||||||
|
error: e instanceof InvoiceCanceledError && e.actionError ? e : undefined
|
||||||
|
})
|
||||||
|
|
||||||
// should we wait for the invoice to be paid?
|
// should we wait for the invoice to be paid?
|
||||||
if (response?.paymentMethod === 'OPTIMISTIC' && !forceWaitForPayment) {
|
if (response?.paymentMethod === 'OPTIMISTIC' && !forceWaitForPayment) {
|
||||||
// onCompleted is called before the invoice is paid for optimistic updates
|
// onCompleted is called before the invoice is paid for optimistic updates
|
||||||
@ -75,7 +83,7 @@ export function usePaidMutation (mutation,
|
|||||||
// onPayError is called after the invoice fails to pay
|
// onPayError is called after the invoice fails to pay
|
||||||
// useful for updating invoiceActionState to FAILED
|
// useful for updating invoiceActionState to FAILED
|
||||||
onPayError?.(e, client.cache, { data })
|
onPayError?.(e, client.cache, { data })
|
||||||
setInnerResult(r => ({ payError: e, ...r }))
|
setInnerResult(r => addPayError(e, r))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// the action is pessimistic
|
// the action is pessimistic
|
||||||
@ -95,7 +103,7 @@ export function usePaidMutation (mutation,
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('usePaidMutation: failed to pay invoice', e)
|
console.error('usePaidMutation: failed to pay invoice', e)
|
||||||
onPayError?.(e, client.cache, { data })
|
onPayError?.(e, client.cache, { data })
|
||||||
rest = { ...rest, payError: e, error: e }
|
rest = addPayError(e, rest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user