replace swipeview, send & receive now dialogs
send mostly working, though no user entered payment yet
This commit is contained in:
@@ -27,6 +27,8 @@ Item {
|
||||
property color colorCredit: "#ff80ff80"
|
||||
property color colorDebit: "#ffff8080"
|
||||
property color mutedForeground: 'gray' //Qt.lighter(Material.background, 2)
|
||||
property color darkerBackground: Qt.darker(Material.background, 1.20)
|
||||
property color lighterBackground: Qt.lighter(Material.background, 1.10)
|
||||
property color colorMine: "yellow"
|
||||
property color colorError: '#ffff8080'
|
||||
property color colorLightningLocal: "blue"
|
||||
|
||||
@@ -14,10 +14,15 @@ Pane {
|
||||
padding: 0
|
||||
clip: true
|
||||
|
||||
background: Rectangle {
|
||||
color: constants.darkerBackground
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listview
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
||||
model: visualModel
|
||||
|
||||
|
||||
320
electrum/gui/qml/components/ReceiveDialog.qml
Normal file
320
electrum/gui/qml/components/ReceiveDialog.qml
Normal file
@@ -0,0 +1,320 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQml.Models 2.1
|
||||
|
||||
import org.electrum 1.0
|
||||
|
||||
import "controls"
|
||||
|
||||
ElDialog {
|
||||
id: dialog
|
||||
|
||||
property string _bolt11
|
||||
property string _bip21uri
|
||||
property string _address
|
||||
|
||||
property bool _render_qr: false // delay qr rendering until dialog is shown
|
||||
|
||||
parent: Overlay.overlay
|
||||
modal: true
|
||||
standardButtons: Dialog.Close
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Overlay.modal: Rectangle {
|
||||
color: "#aa000000"
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: rootLayout
|
||||
width: parent.width
|
||||
spacing: constants.paddingMedium
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: 'bolt11'
|
||||
PropertyChanges { target: qrloader; sourceComponent: qri_bolt11 }
|
||||
PropertyChanges { target: bolt11label; font.bold: true }
|
||||
},
|
||||
State {
|
||||
name: 'bip21uri'
|
||||
PropertyChanges { target: qrloader; sourceComponent: qri_bip21uri }
|
||||
PropertyChanges { target: bip21label; font.bold: true }
|
||||
},
|
||||
State {
|
||||
name: 'address'
|
||||
PropertyChanges { target: qrloader; sourceComponent: qri_address }
|
||||
PropertyChanges { target: addresslabel; font.bold: true }
|
||||
}
|
||||
]
|
||||
|
||||
Rectangle {
|
||||
height: 1
|
||||
Layout.fillWidth: true
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: constants.paddingSmall
|
||||
Layout.bottomMargin: constants.paddingSmall
|
||||
|
||||
Layout.preferredWidth: qrloader.width
|
||||
Layout.preferredHeight: qrloader.height
|
||||
|
||||
Loader {
|
||||
id: qrloader
|
||||
Component {
|
||||
id: qri_bolt11
|
||||
QRImage {
|
||||
qrdata: _bolt11
|
||||
render: _render_qr
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: qri_bip21uri
|
||||
QRImage {
|
||||
qrdata: _bip21uri
|
||||
render: _render_qr
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: qri_address
|
||||
QRImage {
|
||||
qrdata: _address
|
||||
render: _render_qr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if (rootLayout.state == 'bolt11') {
|
||||
if (_bip21uri != '')
|
||||
rootLayout.state = 'bip21uri'
|
||||
else if (_address != '')
|
||||
rootLayout.state = 'address'
|
||||
} else if (rootLayout.state == 'bip21uri') {
|
||||
if (_address != '')
|
||||
rootLayout.state = 'address'
|
||||
else if (_bolt11 != '')
|
||||
rootLayout.state = 'bolt11'
|
||||
} else if (rootLayout.state == 'address') {
|
||||
if (_bolt11 != '')
|
||||
rootLayout.state = 'bolt11'
|
||||
else if (_bip21uri != '')
|
||||
rootLayout.state = 'bip21uri'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: constants.paddingLarge
|
||||
Label {
|
||||
id: bolt11label
|
||||
text: qsTr('BOLT11')
|
||||
color: _bolt11 ? Material.foreground : constants.mutedForeground
|
||||
}
|
||||
Rectangle {
|
||||
Layout.preferredWidth: constants.paddingXXSmall
|
||||
Layout.preferredHeight: constants.paddingXXSmall
|
||||
radius: constants.paddingXXSmall / 2
|
||||
color: Material.accentColor
|
||||
}
|
||||
Label {
|
||||
id: bip21label
|
||||
text: qsTr('BIP21')
|
||||
color: _bip21uri ? Material.foreground : constants.mutedForeground
|
||||
}
|
||||
Rectangle {
|
||||
Layout.preferredWidth: constants.paddingXXSmall
|
||||
Layout.preferredHeight: constants.paddingXXSmall
|
||||
radius: constants.paddingXXSmall / 2
|
||||
color: Material.accentColor
|
||||
}
|
||||
Label {
|
||||
id: addresslabel
|
||||
text: qsTr('ADDRESS')
|
||||
color: _address ? Material.foreground : constants.mutedForeground
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 1
|
||||
Layout.fillWidth: true
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
// aaaaaaaaaaaaaaaaaaaa
|
||||
|
||||
|
||||
GridLayout {
|
||||
id: form
|
||||
width: parent.width
|
||||
rowSpacing: constants.paddingSmall
|
||||
columnSpacing: constants.paddingSmall
|
||||
columns: 4
|
||||
|
||||
Label {
|
||||
text: qsTr('Message')
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: message
|
||||
placeholderText: qsTr('Description of payment request')
|
||||
Layout.columnSpan: 3
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Request')
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.rightMargin: constants.paddingXLarge
|
||||
}
|
||||
|
||||
BtcField {
|
||||
id: amount
|
||||
fiatfield: amountFiat
|
||||
Layout.preferredWidth: parent.width /3
|
||||
}
|
||||
|
||||
Label {
|
||||
text: Config.baseUnit
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Item { width: 1; height: 1; Layout.fillWidth: true }
|
||||
|
||||
Item { visible: Daemon.fx.enabled; width: 1; height: 1 }
|
||||
|
||||
FiatField {
|
||||
id: amountFiat
|
||||
btcfield: amount
|
||||
visible: Daemon.fx.enabled
|
||||
Layout.preferredWidth: parent.width /3
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: Daemon.fx.enabled
|
||||
text: Daemon.fx.fiatCurrency
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Item { visible: Daemon.fx.enabled; width: 1; height: 1; Layout.fillWidth: true }
|
||||
|
||||
Label {
|
||||
text: qsTr('Expires after')
|
||||
Layout.fillWidth: false
|
||||
}
|
||||
|
||||
ElComboBox {
|
||||
id: expires
|
||||
Layout.columnSpan: 2
|
||||
|
||||
textRole: 'text'
|
||||
valueRole: 'value'
|
||||
|
||||
model: ListModel {
|
||||
id: expiresmodel
|
||||
Component.onCompleted: {
|
||||
// we need to fill the model like this, as ListElement can't evaluate script
|
||||
expiresmodel.append({'text': qsTr('10 minutes'), 'value': 10*60})
|
||||
expiresmodel.append({'text': qsTr('1 hour'), 'value': 60*60})
|
||||
expiresmodel.append({'text': qsTr('1 day'), 'value': 24*60*60})
|
||||
expiresmodel.append({'text': qsTr('1 week'), 'value': 7*24*60*60})
|
||||
expiresmodel.append({'text': qsTr('1 month'), 'value': 31*24*60*60})
|
||||
expiresmodel.append({'text': qsTr('Never'), 'value': 0})
|
||||
expires.currentIndex = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item { width: 1; height: 1; Layout.fillWidth: true }
|
||||
|
||||
Button {
|
||||
Layout.columnSpan: 4
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr('Create Request')
|
||||
icon.source: '../../icons/qrcode.png'
|
||||
onClicked: {
|
||||
createRequest()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// make clicking the dialog background move the scope away from textedit fields
|
||||
// so the keyboard goes away
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
z: -1000
|
||||
onClicked: parkFocus.focus = true
|
||||
FocusScope { id: parkFocus }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: requestdialog
|
||||
RequestDialog {
|
||||
onClosed: destroy()
|
||||
}
|
||||
}
|
||||
|
||||
function createRequest(ignoreGaplimit = false) {
|
||||
var qamt = Config.unitsToSats(amount.text)
|
||||
if (qamt.satsInt > Daemon.currentWallet.lightningCanReceive.satsInt) {
|
||||
console.log('Creating OnChain request')
|
||||
Daemon.currentWallet.create_request(qamt, message.text, expires.currentValue, false, ignoreGaplimit)
|
||||
} else {
|
||||
console.log('Creating Lightning request')
|
||||
Daemon.currentWallet.create_request(qamt, message.text, expires.currentValue, true)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Daemon.currentWallet
|
||||
function onRequestCreateSuccess(key) {
|
||||
message.text = ''
|
||||
amount.text = ''
|
||||
var dialog = requestdialog.createObject(app, { key: key })
|
||||
dialog.open()
|
||||
}
|
||||
function onRequestCreateError(code, error) {
|
||||
if (code == 'gaplimit') {
|
||||
var dialog = app.messageDialog.createObject(app, {'text': error, 'yesno': true})
|
||||
dialog.yesClicked.connect(function() {
|
||||
createRequest(true)
|
||||
})
|
||||
} else {
|
||||
console.log(error)
|
||||
var dialog = app.messageDialog.createObject(app, {'text': error})
|
||||
}
|
||||
dialog.open()
|
||||
}
|
||||
function onRequestStatusChanged(key, status) {
|
||||
Daemon.currentWallet.requestModel.updateRequest(key, status)
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
_address = '1234567890'
|
||||
rootLayout.state = 'address'
|
||||
}
|
||||
|
||||
// hack. delay qr rendering until dialog is shown
|
||||
Connections {
|
||||
target: dialog.enter
|
||||
function onRunningChanged() {
|
||||
if (!dialog.enter.running) {
|
||||
dialog._render_qr = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
58
electrum/gui/qml/components/SendDialog.qml
Normal file
58
electrum/gui/qml/components/SendDialog.qml
Normal file
@@ -0,0 +1,58 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQml.Models 2.1
|
||||
|
||||
import org.electrum 1.0
|
||||
|
||||
import "controls"
|
||||
|
||||
ElDialog {
|
||||
id: dialog
|
||||
|
||||
property InvoiceParser invoiceParser
|
||||
|
||||
signal manualInput
|
||||
|
||||
parent: Overlay.overlay
|
||||
modal: true
|
||||
standardButtons: Dialog.Close
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Overlay.modal: Rectangle {
|
||||
color: "#aa000000"
|
||||
}
|
||||
|
||||
padding: 0
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
QRScan {
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.fillHeight: true
|
||||
|
||||
onFound: invoiceParser.recipient = scanData
|
||||
}
|
||||
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr('Manual input')
|
||||
onClicked: {
|
||||
manualInput()
|
||||
}
|
||||
}
|
||||
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr('Paste from clipboard')
|
||||
onClicked: invoiceParser.recipient = AppController.clipboardToText()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,8 +3,12 @@ import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQml 2.6
|
||||
|
||||
import org.electrum 1.0
|
||||
|
||||
import "controls"
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
id: mainView
|
||||
|
||||
property string title: Daemon.currentWallet ? Daemon.currentWallet.name : ''
|
||||
|
||||
@@ -69,6 +73,8 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
property var _sendDialog
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
@@ -94,71 +100,137 @@ Item {
|
||||
anchors.fill: parent
|
||||
visible: Daemon.currentWallet
|
||||
|
||||
SwipeView {
|
||||
id: swipeview
|
||||
|
||||
History {
|
||||
id: history
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
currentIndex: tabbar.currentIndex
|
||||
|
||||
Item {
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
Receive {
|
||||
id: receive
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
History {
|
||||
id: history
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
Send {
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: tabbar
|
||||
position: TabBar.Footer
|
||||
Layout.fillWidth: true
|
||||
currentIndex: swipeview.currentIndex
|
||||
TabButton {
|
||||
text: qsTr('Receive')
|
||||
font.pixelSize: constants.fontSizeLarge
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr('History')
|
||||
font.pixelSize: constants.fontSizeLarge
|
||||
}
|
||||
TabButton {
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 1
|
||||
text: qsTr('Send')
|
||||
font.pixelSize: constants.fontSizeLarge
|
||||
onClicked: {
|
||||
console.log('send')
|
||||
var comp = Qt.createComponent(Qt.resolvedUrl('SendDialog.qml'))
|
||||
if (comp.status == Component.Error)
|
||||
console.log(comp.errorString())
|
||||
_sendDialog = comp.createObject(mainView, { invoiceParser: invoiceParser } )
|
||||
// dialog.
|
||||
_sendDialog.open()
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
Layout.fillWidth: false
|
||||
Layout.preferredWidth: 2
|
||||
Layout.preferredHeight: parent.height * 2/3
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: constants.darkerBackground
|
||||
}
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 1
|
||||
text: qsTr('Receive')
|
||||
onClicked: {
|
||||
var comp = Qt.createComponent(Qt.resolvedUrl('ReceiveDialog.qml'))
|
||||
var dialog = comp.createObject(mainView)
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: tabbar.setCurrentIndex(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Daemon
|
||||
function onWalletLoaded() {
|
||||
tabbar.setCurrentIndex(1)
|
||||
InvoiceParser {
|
||||
id: invoiceParser
|
||||
wallet: Daemon.currentWallet
|
||||
onValidationError: {
|
||||
var dialog = app.messageDialog.createObject(app, {'text': message })
|
||||
dialog.open()
|
||||
}
|
||||
onValidationWarning: {
|
||||
if (code == 'no_channels') {
|
||||
var dialog = app.messageDialog.createObject(app, {'text': message })
|
||||
dialog.open()
|
||||
// TODO: ask user to open a channel, if funds allow
|
||||
// and maybe store invoice if expiry allows
|
||||
}
|
||||
}
|
||||
onValidationSuccess: {
|
||||
_sendDialog.close()
|
||||
// address only -> fill form fields and clear this instance
|
||||
// else -> show invoice confirmation dialog
|
||||
if (invoiceType == Invoice.OnchainOnlyAddress) {
|
||||
recipient.text = invoice.recipient
|
||||
invoiceParser.clear()
|
||||
} else {
|
||||
var dialog = invoiceDialog.createObject(app, {'invoice': invoiceParser})
|
||||
// dialog.invoice = invoiceParser
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
onInvoiceCreateError: console.log(code + ' ' + message)
|
||||
|
||||
onInvoiceSaved: {
|
||||
Daemon.currentWallet.invoiceModel.init_model()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: invoiceDialog
|
||||
InvoiceDialog {
|
||||
onDoPay: {
|
||||
if (invoice.invoiceType == Invoice.OnchainInvoice) {
|
||||
var dialog = confirmPaymentDialog.createObject(mainView, {
|
||||
'address': invoice.address,
|
||||
'satoshis': invoice.amount,
|
||||
'message': invoice.message
|
||||
})
|
||||
var wo = Daemon.currentWallet.isWatchOnly
|
||||
dialog.txaccepted.connect(function() {
|
||||
if (wo) {
|
||||
showUnsignedTx(dialog.finalizer.serializedTx(false), dialog.finalizer.serializedTx(true))
|
||||
} else {
|
||||
dialog.finalizer.send_onchain()
|
||||
}
|
||||
})
|
||||
dialog.open()
|
||||
} else if (invoice.invoiceType == Invoice.LightningInvoice) {
|
||||
console.log('About to pay lightning invoice')
|
||||
if (invoice.key == '') {
|
||||
console.log('No invoice key, aborting')
|
||||
return
|
||||
}
|
||||
var dialog = lightningPaymentProgressDialog.createObject(mainView, {
|
||||
invoice_key: invoice.key
|
||||
})
|
||||
dialog.open()
|
||||
Daemon.currentWallet.pay_lightning_invoice(invoice.key)
|
||||
}
|
||||
close()
|
||||
}
|
||||
// onClosed: destroy()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: confirmPaymentDialog
|
||||
ConfirmTxDialog {
|
||||
title: qsTr('Confirm Payment')
|
||||
finalizer: TxFinalizer {
|
||||
wallet: Daemon.currentWallet
|
||||
canRbf: true
|
||||
}
|
||||
onClosed: destroy()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: lightningPaymentProgressDialog
|
||||
LightningPaymentProgressDialog {
|
||||
onClosed: destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
electrum/gui/qml/components/controls/FlatButton.qml
Normal file
24
electrum/gui/qml/components/controls/FlatButton.qml
Normal file
@@ -0,0 +1,24 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias text: buttonLabel.text
|
||||
property alias font: buttonLabel.font
|
||||
|
||||
signal clicked
|
||||
|
||||
implicitWidth: buttonLabel.width + constants.paddingXXLarge
|
||||
implicitHeight: buttonLabel.height + constants.paddingXXLarge
|
||||
|
||||
Label {
|
||||
id: buttonLabel
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: root
|
||||
onClicked: root.clicked()
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ Item {
|
||||
x: constants.paddingSmall
|
||||
width: delegate.width - 2*constants.paddingSmall
|
||||
|
||||
Item { Layout.columnSpan: 3; Layout.preferredWidth: 1; Layout.preferredHeight: 1}
|
||||
Item { Layout.columnSpan: 3; Layout.preferredWidth: 1; Layout.preferredHeight: constants.paddingSmall }
|
||||
|
||||
Image {
|
||||
readonly property variant tx_icons : [
|
||||
@@ -113,15 +113,17 @@ Item {
|
||||
}
|
||||
Component.onCompleted: updateText()
|
||||
}
|
||||
Item { Layout.columnSpan: 3; Layout.preferredWidth: 1; Layout.preferredHeight: 1 }
|
||||
Item { Layout.columnSpan: 3; Layout.preferredWidth: 1; Layout.preferredHeight: constants.paddingSmall }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: delegate.ListView.section == delegate.ListView.nextSection
|
||||
Layout.fillWidth: true
|
||||
// Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width * 2/3
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredHeight: constants.paddingTiny
|
||||
color: Qt.rgba(0,0,0,0.10)
|
||||
color: Material.background //Qt.rgba(0,0,0,0.10)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ class QEInvoiceParser(QEInvoice):
|
||||
@recipient.setter
|
||||
def recipient(self, recipient: str):
|
||||
#if self._recipient != recipient:
|
||||
self.canPay = False
|
||||
self._recipient = recipient
|
||||
if recipient:
|
||||
self.validateRecipient(recipient)
|
||||
@@ -249,24 +250,24 @@ class QEInvoiceParser(QEInvoice):
|
||||
self.userinfo = _('Can\'t pay, insufficient balance')
|
||||
else:
|
||||
self.userinfo = {
|
||||
PR_EXPIRED: _('Can\'t pay, invoice is expired'),
|
||||
PR_PAID: _('Can\'t pay, invoice is already paid'),
|
||||
PR_INFLIGHT: _('Can\'t pay, invoice is already being paid'),
|
||||
PR_ROUTING: _('Can\'t pay, invoice is already being paid'),
|
||||
PR_UNKNOWN: _('Can\'t pay, invoice has unknown status'),
|
||||
PR_EXPIRED: _('Invoice is expired'),
|
||||
PR_PAID: _('Invoice is already paid'),
|
||||
PR_INFLIGHT: _('Invoice is already being paid'),
|
||||
PR_ROUTING: _('Invoice is already being paid'),
|
||||
PR_UNKNOWN: _('Invoice has unknown status'),
|
||||
}[self.status]
|
||||
elif self.invoiceType == QEInvoice.Type.OnchainInvoice:
|
||||
if self.status in [PR_UNPAID, PR_FAILED]:
|
||||
if self.get_max_spendable_onchain() >= self.amount.satsInt:
|
||||
self.canPay = True
|
||||
else:
|
||||
self.userinfo = _('Can\'t pay, insufficient balance')
|
||||
self.userinfo = _('Insufficient balance')
|
||||
else:
|
||||
self.userinfo = {
|
||||
PR_EXPIRED: _('Can\'t pay, invoice is expired'),
|
||||
PR_PAID: _('Can\'t pay, invoice is already paid'),
|
||||
PR_UNCONFIRMED: _('Can\'t pay, invoice is already paid'),
|
||||
PR_UNKNOWN: _('Can\'t pay, invoice has unknown status'),
|
||||
PR_EXPIRED: _('Invoice is expired'),
|
||||
PR_PAID: _('Invoice is already paid'),
|
||||
PR_UNCONFIRMED: _('Invoice is already paid'),
|
||||
PR_UNKNOWN: _('Invoice has unknown status'),
|
||||
}[self.status]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user