@@ -33,13 +33,13 @@ Pane {
|
||||
text: qsTr('Lightning payment details')
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Status')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: lnpaymentdetails.status
|
||||
InfoTextArea {
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: constants.paddingLarge
|
||||
visible: text
|
||||
text: lnpaymentdetails.status ? qsTr('Paid') : ''
|
||||
iconStyle: InfoTextArea.IconStyle.Done
|
||||
}
|
||||
|
||||
Label {
|
||||
|
||||
@@ -217,22 +217,6 @@ Pane {
|
||||
text: Daemon.currentWallet.lightningNumPeers
|
||||
}
|
||||
|
||||
Heading {
|
||||
Layout.columnSpan: 2
|
||||
text: qsTr('Nostr')
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Relays:')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: Config.nostrRelays.replace(/,/g, "\n")
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
Heading {
|
||||
Layout.columnSpan: 2
|
||||
text: qsTr('Proxy')
|
||||
|
||||
@@ -51,19 +51,15 @@ ElDialog {
|
||||
Layout.leftMargin: constants.paddingLarge
|
||||
Layout.rightMargin: constants.paddingLarge
|
||||
|
||||
RowLayout {
|
||||
TextHighlightPane {
|
||||
Layout.fillWidth: true
|
||||
TextHighlightPane {
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
text: qsTr('Enter the list of Nostr relays')
|
||||
width: parent.width
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
HelpButton {
|
||||
heading: Config.shortDescFor('NOSTR_RELAYS')
|
||||
helptext: Config.longDescFor('NOSTR_RELAYS')
|
||||
Label {
|
||||
text: qsTr('Enter the list of Nostr relays') + '<br/><br/>' +
|
||||
qsTr('Nostr relays are used to send and receive submarine swap offers.') +
|
||||
' ' + qsTr('For multisig wallets, nostr is also used to relay transactions to your co-signers.') +
|
||||
' ' + qsTr('Connections to nostr are only made when required, and ephemerally.')
|
||||
width: parent.width
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,23 +12,25 @@ ElDialog {
|
||||
id: dialog
|
||||
|
||||
title: qsTr('Receive Payment')
|
||||
iconSource: Qt.resolvedUrl('../../icons/tab_receive.png')
|
||||
|
||||
property string key
|
||||
property bool isLightning: request.isLightning
|
||||
|
||||
property string _bolt11: request.bolt11
|
||||
property string _bip21uri: request.bip21
|
||||
property string _address: request.address
|
||||
|
||||
property bool _render_qr: false // delay qr rendering until dialog is shown
|
||||
|
||||
property bool _ispaid: false
|
||||
|
||||
iconSource: Qt.resolvedUrl('../../icons/tab_receive.png')
|
||||
signal requestPaid
|
||||
|
||||
padding: 0
|
||||
|
||||
function getPaidTxid() {
|
||||
return request.paidTxid
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: !_ispaid
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
@@ -40,7 +42,7 @@ ElDialog {
|
||||
rightMargin: constants.paddingLarge
|
||||
|
||||
contentHeight: rootLayout.height
|
||||
clip:true
|
||||
clip: true
|
||||
interactive: height < contentHeight
|
||||
|
||||
ColumnLayout {
|
||||
@@ -186,43 +188,12 @@ ElDialog {
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: _ispaid
|
||||
anchors.centerIn: parent
|
||||
states: [
|
||||
State {
|
||||
name: 'paid'
|
||||
when: _ispaid
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
from: ''
|
||||
to: 'paid'
|
||||
NumberAnimation { target: paidIcon; properties: 'opacity'; from: 0; to: 1; duration: 200 }
|
||||
NumberAnimation { target: paidIcon; properties: 'scale'; from: 0; to: 1; duration: 500; easing.type: Easing.OutBack; easing.overshoot: 10 }
|
||||
}
|
||||
]
|
||||
Image {
|
||||
id: paidIcon
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: constants.iconSizeXXLarge
|
||||
Layout.preferredHeight: constants.iconSizeXXLarge
|
||||
source: '../../icons/confirmed.png'
|
||||
}
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr('Paid!')
|
||||
font.pixelSize: constants.fontSizeXXLarge
|
||||
}
|
||||
}
|
||||
|
||||
RequestDetails {
|
||||
id: request
|
||||
wallet: Daemon.currentWallet
|
||||
onStatusChanged: {
|
||||
if (status == RequestDetails.Paid || status == RequestDetails.Unconfirmed) {
|
||||
_ispaid = true
|
||||
requestPaid()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,10 +42,8 @@ ElDialog {
|
||||
text: qsTr('Ok')
|
||||
icon.source: '../../icons/confirmed.png'
|
||||
onClicked: {
|
||||
Network.oneServer = serverconfig.auto_connect
|
||||
? false
|
||||
: serverconfig.one_server
|
||||
Config.autoConnect = serverconfig.auto_connect
|
||||
Network.oneServer = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Single
|
||||
Config.autoConnect = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
|
||||
Network.server = serverconfig.address
|
||||
rootItem.close()
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ Pane {
|
||||
: txdetails.isRemoved ? qsTr('This transaction has been replaced or removed and is no longer valid')
|
||||
: txdetails.inMempool
|
||||
? qsTr('This transaction is still unconfirmed.') +
|
||||
(txdetails.canBump || txdetails.canCpfp || txdetails.canCancel
|
||||
(txdetails.canBump || txdetails.canCancel
|
||||
? txdetails.canCancel
|
||||
? '\n' + qsTr('You can bump its fee to speed up its confirmation, or cancel this transaction.')
|
||||
: '\n' + qsTr('You can bump its fee to speed up its confirmation.')
|
||||
|
||||
@@ -639,6 +639,15 @@ Item {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
onRequestPaid: {
|
||||
close()
|
||||
if (isLightning) {
|
||||
app.stack.push(Qt.resolvedUrl('LightningPaymentDetails.qml'), {'key': key})
|
||||
} else {
|
||||
let paidTxid = getPaidTxid()
|
||||
app.stack.push(Qt.resolvedUrl('TxDetails.qml'), {'txid': paidTxid})
|
||||
}
|
||||
}
|
||||
onClosed: destroy()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ Item {
|
||||
id: root
|
||||
|
||||
property bool showAutoselectServer: true
|
||||
property alias auto_connect: auto_server_cb.checked
|
||||
property alias address: address_tf.text
|
||||
property alias one_server: one_server_cb.checked
|
||||
property alias serverConnectMode: server_connect_mode_cb.currentValue
|
||||
|
||||
implicitHeight: rootLayout.height
|
||||
|
||||
@@ -23,12 +22,32 @@ Item {
|
||||
height: parent.height
|
||||
spacing: constants.paddingLarge
|
||||
|
||||
CheckBox {
|
||||
id: auto_server_cb
|
||||
visible: showAutoselectServer
|
||||
text: Config.shortDescFor('NETWORK_AUTO_CONNECT')
|
||||
checked: !showAutoselectServer
|
||||
enabled: !one_server_cb.checked
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
ServerConnectModeComboBox {
|
||||
id: server_connect_mode_cb
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
}
|
||||
|
||||
HelpButton {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
heading: qsTr('Connection mode')+':'
|
||||
helptext: Config.getTranslatedMessage('MSG_CONNECTMODE_SERVER_HELP') + '<br/><br/>' +
|
||||
Config.getTranslatedMessage('MSG_CONNECTMODE_NODES_HELP') + '<ul>' +
|
||||
'<li><b>' + Config.getTranslatedMessage('MSG_CONNECTMODE_AUTOCONNECT') +
|
||||
'</b>: ' + Config.getTranslatedMessage('MSG_CONNECTMODE_AUTOCONNECT_HELP') + '</li>' +
|
||||
'<li><b>' + Config.getTranslatedMessage('MSG_CONNECTMODE_MANUAL') +
|
||||
'</b>: ' + Config.getTranslatedMessage('MSG_CONNECTMODE_MANUAL_HELP') + '</li>' +
|
||||
'<li><b>' + Config.getTranslatedMessage('MSG_CONNECTMODE_ONESERVER') +
|
||||
'</b>: ' + Config.getTranslatedMessage('MSG_CONNECTMODE_ONESERVER_HELP') + '</li>' +
|
||||
'</ul>'
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
@@ -41,28 +60,12 @@ Item {
|
||||
|
||||
TextField {
|
||||
id: address_tf
|
||||
enabled: !auto_server_cb.checked
|
||||
enabled: server_connect_mode_cb.currentValue != ServerConnectModeComboBox.Mode.Autoconnect
|
||||
width: parent.width
|
||||
inputMethodHints: Qt.ImhNoPredictiveText
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
visible: !auto_server_cb.checked && address_tf.text
|
||||
|
||||
CheckBox {
|
||||
id: one_server_cb
|
||||
Layout.fillWidth: true
|
||||
text: Config.shortDescFor('NETWORK_ONESERVER')
|
||||
}
|
||||
|
||||
HelpButton {
|
||||
heading: Config.shortDescFor('NETWORK_ONESERVER')
|
||||
helptext: Config.longDescFor('NETWORK_ONESERVER')
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Heading {
|
||||
text: qsTr('Servers')
|
||||
@@ -112,9 +115,6 @@ Item {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.auto_connect = Config.autoConnectDefined ? Config.autoConnect : false
|
||||
root.address = Network.server
|
||||
one_server_cb.checked = Network.oneServer
|
||||
// TODO: initial setup should not connect already, is Network.server defined?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
import org.electrum 1.0
|
||||
|
||||
ElComboBox {
|
||||
id: control
|
||||
|
||||
enum Mode {
|
||||
Autoconnect,
|
||||
Manual,
|
||||
Single
|
||||
}
|
||||
|
||||
textRole: 'text'
|
||||
valueRole: 'value'
|
||||
|
||||
model: [
|
||||
{ text: qsTr('Auto-connect'), value: ServerConnectModeComboBox.Mode.Autoconnect },
|
||||
{ text: qsTr('Manual server selection'), value: ServerConnectModeComboBox.Mode.Manual },
|
||||
{ text: qsTr('Connect only to a single server'), value: ServerConnectModeComboBox.Mode.Single }
|
||||
]
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!Config.autoConnectDefined) { // initial setup
|
||||
server_connect_mode_cb.currentIndex = server_connect_mode_cb.indexOfValue(
|
||||
ServerConnectModeComboBox.Mode.Manual)
|
||||
} else {
|
||||
server_connect_mode_cb.currentIndex = server_connect_mode_cb.indexOfValue(
|
||||
Config.autoConnect
|
||||
? ServerConnectModeComboBox.Mode.Autoconnect
|
||||
: Network.oneServer
|
||||
? ServerConnectModeComboBox.Mode.Single
|
||||
: ServerConnectModeComboBox.Mode.Manual
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,9 @@ WizardComponent {
|
||||
title: qsTr('Server')
|
||||
|
||||
function apply() {
|
||||
wizard_data['autoconnect'] = sc.address.trim() == ""
|
||||
wizard_data['server'] = sc.address
|
||||
wizard_data['one_server'] = sc.one_server
|
||||
wizard_data['autoconnect'] = sc.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
|
||||
wizard_data['one_server'] = sc.serverConnectMode == ServerConnectModeComboBox.Mode.Single
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
@@ -21,7 +21,6 @@ WizardComponent {
|
||||
|
||||
ServerConfig {
|
||||
id: sc
|
||||
showAutoselectServer: false
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ class QEConfig(AuthMixin, QObject):
|
||||
@nostrRelays.setter
|
||||
def nostrRelays(self, nostr_relays):
|
||||
if nostr_relays != self.config.NOSTR_RELAYS:
|
||||
self.config.NOSTR_RELAYS = nostr_relays
|
||||
self.config.NOSTR_RELAYS = nostr_relays if nostr_relays else None
|
||||
self.nostrRelaysChanged.emit()
|
||||
|
||||
swapServerNPubChanged = pyqtSignal()
|
||||
|
||||
@@ -6,7 +6,7 @@ from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex
|
||||
|
||||
from electrum.logging import get_logger
|
||||
from electrum.util import Satoshis, format_time
|
||||
from electrum.invoices import BaseInvoice, PR_EXPIRED, LN_EXPIRY_NEVER, Invoice, Request
|
||||
from electrum.invoices import BaseInvoice, PR_EXPIRED, LN_EXPIRY_NEVER, Invoice, Request, PR_PAID
|
||||
|
||||
from .util import QtEventListener, qt_event_listener, status_update_timer_interval
|
||||
from .qetypes import QEAmount
|
||||
@@ -247,4 +247,7 @@ class QERequestListModel(QEAbstractInvoiceListModel, QtEventListener):
|
||||
|
||||
@pyqtSlot(str, int)
|
||||
def updateRequest(self, key, status):
|
||||
self.updateInvoice(key, status)
|
||||
if status == PR_PAID:
|
||||
self.delete_invoice(key)
|
||||
else:
|
||||
self.updateInvoice(key, status)
|
||||
|
||||
@@ -29,7 +29,7 @@ class QERequestDetails(QObject, QtEventListener):
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
detailsChanged = pyqtSignal() # generic request properties changed signal
|
||||
detailsChanged = pyqtSignal() # generic request properties changed signal
|
||||
statusChanged = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
@@ -95,7 +95,7 @@ class QERequestDetails(QObject, QtEventListener):
|
||||
|
||||
@pyqtProperty(bool, notify=detailsChanged)
|
||||
def isLightning(self):
|
||||
return self._req.is_lightning()
|
||||
return self._req.is_lightning() if self._req else False
|
||||
|
||||
@pyqtProperty(str, notify=detailsChanged)
|
||||
def address(self):
|
||||
@@ -118,6 +118,16 @@ class QERequestDetails(QObject, QtEventListener):
|
||||
def expiration(self):
|
||||
return self._req.get_expiration_date()
|
||||
|
||||
@pyqtProperty(str, notify=statusChanged)
|
||||
def paidTxid(self):
|
||||
"""only used when Request status is PR_PAID"""
|
||||
if not self._req:
|
||||
return ''
|
||||
is_paid, conf_needed, txids = self._wallet.wallet._is_onchain_invoice_paid(self._req)
|
||||
if len(txids) > 0:
|
||||
return txids[0]
|
||||
return ''
|
||||
|
||||
@pyqtProperty(str, notify=detailsChanged)
|
||||
def bolt11(self):
|
||||
wallet = self._wallet.wallet
|
||||
|
||||
Reference in New Issue
Block a user