From 5f62a8315e13f1cbc34fb3922607d4b530002501 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Wed, 22 Jul 2026 14:59:02 +0200 Subject: [PATCH] Add a "withdraw full balance" checkbox to the withdrawal form Checking it disables the amount field, autofills it with the current balance, and keeps it in sync if the balance changes while checked. The actual withdrawal request uses the raw balance_sats value directly instead of round-tripping through the PLM input field, avoiding float-rounding drift when withdrawing the exact full balance. Co-Authored-By: Claude Sonnet 5 --- app/static/index.html | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/app/static/index.html b/app/static/index.html index 8ab5cf7..5ebfe67 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -90,6 +90,7 @@ outline: none; border-color: var(--color-ring); box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-ring) 25%, transparent); } + input:disabled { background: var(--color-surface-inset); color: var(--color-muted-foreground); } button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; @@ -122,6 +123,15 @@ .row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; } + .checkbox-row { + display: flex; align-items: center; gap: 8px; + font-size: 0.85rem; font-weight: 500; color: var(--color-foreground); + margin-top: 14px; cursor: pointer; + } + .checkbox-row input[type="checkbox"] { + width: 18px; height: 18px; min-height: auto; flex-shrink: 0; accent-color: var(--color-primary); cursor: pointer; + } + /* --- app navbar: brand/balance row (sticky top) + section nav (bottom tab bar on mobile, promoted back to an inline tab strip once there's room — see the min-width breakpoint below), shown only when logged in --- */ @@ -556,6 +566,10 @@

Solo indirizzi P2WPKH bech32 (quelli che iniziano con plm1q...). Indirizzi legacy (P...) o P2SH non sono supportati.

+ @@ -998,6 +1012,7 @@ async function copyAddress() { } let myUserId = null; +let myBalanceSats = 0; async function refreshMe() { const btn = document.getElementById('refresh-btn'); @@ -1005,18 +1020,30 @@ async function refreshMe() { try { const data = await call('GET', '/users/me'); myUserId = data.id; + myBalanceSats = data.balance_sats; document.getElementById('dash-balance').textContent = data.balance_sats / SATS_PER_PLM; document.getElementById('navbar-balance').textContent = (data.balance_sats / SATS_PER_PLM) + ' PLM'; document.getElementById('profile-username').textContent = data.username; document.getElementById('profile-address').textContent = data.address; document.getElementById('profile-balance').textContent = data.balance_sats / SATS_PER_PLM; document.getElementById('profile-created-at').textContent = new Date(data.created_at).toLocaleDateString('it-IT'); + document.getElementById('wd-full-amount-value').textContent = data.balance_sats / SATS_PER_PLM; + if (document.getElementById('wd-full-amount').checked) { + document.getElementById('wd-amount').value = data.balance_sats / SATS_PER_PLM; + } } catch (e) { toast(e.message, 'error'); } }); } +function toggleWithdrawFullAmount() { + const checked = document.getElementById('wd-full-amount').checked; + const amountInput = document.getElementById('wd-amount'); + amountInput.disabled = checked; + if (checked) amountInput.value = myBalanceSats / SATS_PER_PLM; +} + async function changePassword() { const btn = document.getElementById('change-password-btn'); const currentPassword = document.getElementById('settings-current-password').value; @@ -1065,12 +1092,17 @@ async function placeBet() { async function withdraw() { const btn = document.getElementById('withdraw-btn'); const ext = document.getElementById('wd-address').value; - const amtPlm = parseFloat(document.getElementById('wd-amount').value); - const amtSats = Math.round(amtPlm * SATS_PER_PLM); + const isFullAmount = document.getElementById('wd-full-amount').checked; + const amtSats = isFullAmount + ? myBalanceSats + : Math.round(parseFloat(document.getElementById('wd-amount').value) * SATS_PER_PLM); await withLoading(btn, 'Invio…', async () => { try { await call('POST', '/withdrawals', { external_address: ext, amount_sats: amtSats }); toast('Withdrawal inviato.', 'success'); + document.getElementById('wd-full-amount').checked = false; + toggleWithdrawFullAmount(); + document.getElementById('wd-amount').value = ''; } catch (e) { toast(e.message, 'error'); }