diff --git a/neode-ui/src/components/SendBitcoinModal.vue b/neode-ui/src/components/SendBitcoinModal.vue index 55a4364e..f3abe5fa 100644 --- a/neode-ui/src/components/SendBitcoinModal.vue +++ b/neode-ui/src/components/SendBitcoinModal.vue @@ -67,6 +67,7 @@
+ set by invoice
- +
+ + +
@@ -177,6 +193,35 @@ function toggleSendAll() { // Leaving the on-chain tab disarms the sweep so it can never apply elsewhere watch(sendMethod, (m) => { if (m !== 'onchain') sendAll.value = false }) +// Invoice-first lightning UX: a pasted invoice that fixes its amount locks +// the amount field (auto-filled, "set by invoice"); zero-amount invoices +// leave it editable. Clearing/leaving lightning unlocks again. +const pastedInvoiceAmount = computed(() => { + if (effectiveMethod.value !== 'lightning') return null + const d = dest.value.trim() + if (!d) return null + return parseBolt11AmountSats(d.toLowerCase().startsWith('lightning:') ? d.slice(10) : d) +}) +watch(pastedInvoiceAmount, (fixed, prev) => { + if (fixed !== null) amount.value = fixed + // Swapping a fixed-amount invoice for a zero-amount one: don't silently + // keep the previous invoice's sats — make the user type the new amount. + else if (prev !== null) amount.value = 0 +}) + +// Clipboard read needs a secure context (or the companion bridge); hide the +// button where it can't work — the textarea still accepts a manual paste. +const canReadClipboard = typeof navigator !== 'undefined' && !!navigator.clipboard?.readText + +async function pasteFromClipboard() { + try { + const text = (await navigator.clipboard.readText()).trim() + if (text) dest.value = text + } catch { + // Permission denied — user can long-press/Ctrl+V into the field instead. + } +} + const effectiveMethod = computed(() => { if (sendMethod.value !== 'auto') return sendMethod.value const amt = amount.value || 0