Fixes payment polling issues

Improves the reliability of payment status updates by ensuring that the payment polling interval is properly cleared when a payment dialog is closed, when a payment is submitted, or when a new payment dialog is opened. This prevents multiple polling intervals from running simultaneously, which could lead to incorrect payment status updates.

Adds a watch to clear interval when the pay dialog closes.
This commit is contained in:
padreug 2025-10-22 16:56:07 +02:00
parent 854164614f
commit be386f60ef

View file

@ -35,6 +35,7 @@ window.app = Vue.createApp({
paymentRequest: null, paymentRequest: null,
paymentHash: null, paymentHash: null,
checkWalletKey: null, checkWalletKey: null,
pollIntervalId: null,
loading: false loading: false
}, },
settingsDialog: { settingsDialog: {
@ -59,6 +60,15 @@ window.app = Vue.createApp({
} }
} }
}, },
watch: {
'payDialog.show': function(newVal) {
// When dialog is closed, stop polling
if (!newVal && this.payDialog.pollIntervalId) {
clearInterval(this.payDialog.pollIntervalId)
this.payDialog.pollIntervalId = null
}
}
},
computed: { computed: {
expenseAccounts() { expenseAccounts() {
return this.accounts.filter(a => a.account_type === 'expense') return this.accounts.filter(a => a.account_type === 'expense')
@ -313,6 +323,13 @@ window.app = Vue.createApp({
}, },
async submitPayment() { async submitPayment() {
this.payDialog.loading = true this.payDialog.loading = true
// Clear any existing polling interval
if (this.payDialog.pollIntervalId) {
clearInterval(this.payDialog.pollIntervalId)
this.payDialog.pollIntervalId = null
}
try { try {
// Generate an invoice on the Castle wallet // Generate an invoice on the Castle wallet
const response = await LNbits.api.request( const response = await LNbits.api.request(
@ -344,6 +361,11 @@ window.app = Vue.createApp({
} }
}, },
async pollForPayment(paymentHash, checkWalletKey) { async pollForPayment(paymentHash, checkWalletKey) {
// Clear any existing interval
if (this.payDialog.pollIntervalId) {
clearInterval(this.payDialog.pollIntervalId)
}
// Poll every 2 seconds for payment status // Poll every 2 seconds for payment status
const checkPayment = async () => { const checkPayment = async () => {
try { try {
@ -382,6 +404,7 @@ window.app = Vue.createApp({
} }
return false return false
} catch (error) { } catch (error) {
// Silently ignore errors (payment might not exist yet)
return false return false
} }
} }
@ -389,11 +412,12 @@ window.app = Vue.createApp({
// Check every 2 seconds for up to 5 minutes // Check every 2 seconds for up to 5 minutes
let attempts = 0 let attempts = 0
const maxAttempts = 150 // 5 minutes const maxAttempts = 150 // 5 minutes
const intervalId = setInterval(async () => { this.payDialog.pollIntervalId = setInterval(async () => {
attempts++ attempts++
const paid = await checkPayment() const paid = await checkPayment()
if (paid || attempts >= maxAttempts) { if (paid || attempts >= maxAttempts) {
clearInterval(intervalId) clearInterval(this.payDialog.pollIntervalId)
this.payDialog.pollIntervalId = null
} }
}, 2000) }, 2000)
}, },
@ -414,6 +438,12 @@ window.app = Vue.createApp({
}) })
}, },
showPayBalanceDialog() { showPayBalanceDialog() {
// Clear any existing polling
if (this.payDialog.pollIntervalId) {
clearInterval(this.payDialog.pollIntervalId)
this.payDialog.pollIntervalId = null
}
this.payDialog.amount = Math.abs(this.balance.balance) this.payDialog.amount = Math.abs(this.balance.balance)
this.payDialog.paymentRequest = null this.payDialog.paymentRequest = null
this.payDialog.paymentHash = null this.payDialog.paymentHash = null