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 colorCredit: "#ff80ff80"
|
||||||
property color colorDebit: "#ffff8080"
|
property color colorDebit: "#ffff8080"
|
||||||
property color mutedForeground: 'gray' //Qt.lighter(Material.background, 2)
|
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 colorMine: "yellow"
|
||||||
property color colorError: '#ffff8080'
|
property color colorError: '#ffff8080'
|
||||||
property color colorLightningLocal: "blue"
|
property color colorLightningLocal: "blue"
|
||||||
|
|||||||
@@ -14,10 +14,15 @@ Pane {
|
|||||||
padding: 0
|
padding: 0
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: constants.darkerBackground
|
||||||
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: listview
|
id: listview
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
model: visualModel
|
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 QtQuick.Layouts 1.0
|
||||||
import QtQml 2.6
|
import QtQml 2.6
|
||||||
|
|
||||||
|
import org.electrum 1.0
|
||||||
|
|
||||||
|
import "controls"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: rootItem
|
id: mainView
|
||||||
|
|
||||||
property string title: Daemon.currentWallet ? Daemon.currentWallet.name : ''
|
property string title: Daemon.currentWallet ? Daemon.currentWallet.name : ''
|
||||||
|
|
||||||
@@ -69,6 +73,8 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var _sendDialog
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -94,71 +100,137 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: Daemon.currentWallet
|
visible: Daemon.currentWallet
|
||||||
|
|
||||||
SwipeView {
|
History {
|
||||||
id: swipeview
|
id: history
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
Layout.fillHeight: true
|
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 {
|
RowLayout {
|
||||||
id: tabbar
|
spacing: 0
|
||||||
position: TabBar.Footer
|
|
||||||
Layout.fillWidth: true
|
FlatButton {
|
||||||
currentIndex: swipeview.currentIndex
|
Layout.fillWidth: true
|
||||||
TabButton {
|
Layout.preferredWidth: 1
|
||||||
text: qsTr('Receive')
|
|
||||||
font.pixelSize: constants.fontSizeLarge
|
|
||||||
}
|
|
||||||
TabButton {
|
|
||||||
text: qsTr('History')
|
|
||||||
font.pixelSize: constants.fontSizeLarge
|
|
||||||
}
|
|
||||||
TabButton {
|
|
||||||
text: qsTr('Send')
|
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 {
|
InvoiceParser {
|
||||||
target: Daemon
|
id: invoiceParser
|
||||||
function onWalletLoaded() {
|
wallet: Daemon.currentWallet
|
||||||
tabbar.setCurrentIndex(1)
|
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
|
x: constants.paddingSmall
|
||||||
width: delegate.width - 2*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 {
|
Image {
|
||||||
readonly property variant tx_icons : [
|
readonly property variant tx_icons : [
|
||||||
@@ -113,15 +113,17 @@ Item {
|
|||||||
}
|
}
|
||||||
Component.onCompleted: updateText()
|
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 {
|
Rectangle {
|
||||||
visible: delegate.ListView.section == delegate.ListView.nextSection
|
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
|
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
|
@recipient.setter
|
||||||
def recipient(self, recipient: str):
|
def recipient(self, recipient: str):
|
||||||
#if self._recipient != recipient:
|
#if self._recipient != recipient:
|
||||||
|
self.canPay = False
|
||||||
self._recipient = recipient
|
self._recipient = recipient
|
||||||
if recipient:
|
if recipient:
|
||||||
self.validateRecipient(recipient)
|
self.validateRecipient(recipient)
|
||||||
@@ -249,24 +250,24 @@ class QEInvoiceParser(QEInvoice):
|
|||||||
self.userinfo = _('Can\'t pay, insufficient balance')
|
self.userinfo = _('Can\'t pay, insufficient balance')
|
||||||
else:
|
else:
|
||||||
self.userinfo = {
|
self.userinfo = {
|
||||||
PR_EXPIRED: _('Can\'t pay, invoice is expired'),
|
PR_EXPIRED: _('Invoice is expired'),
|
||||||
PR_PAID: _('Can\'t pay, invoice is already paid'),
|
PR_PAID: _('Invoice is already paid'),
|
||||||
PR_INFLIGHT: _('Can\'t pay, invoice is already being paid'),
|
PR_INFLIGHT: _('Invoice is already being paid'),
|
||||||
PR_ROUTING: _('Can\'t pay, invoice is already being paid'),
|
PR_ROUTING: _('Invoice is already being paid'),
|
||||||
PR_UNKNOWN: _('Can\'t pay, invoice has unknown status'),
|
PR_UNKNOWN: _('Invoice has unknown status'),
|
||||||
}[self.status]
|
}[self.status]
|
||||||
elif self.invoiceType == QEInvoice.Type.OnchainInvoice:
|
elif self.invoiceType == QEInvoice.Type.OnchainInvoice:
|
||||||
if self.status in [PR_UNPAID, PR_FAILED]:
|
if self.status in [PR_UNPAID, PR_FAILED]:
|
||||||
if self.get_max_spendable_onchain() >= self.amount.satsInt:
|
if self.get_max_spendable_onchain() >= self.amount.satsInt:
|
||||||
self.canPay = True
|
self.canPay = True
|
||||||
else:
|
else:
|
||||||
self.userinfo = _('Can\'t pay, insufficient balance')
|
self.userinfo = _('Insufficient balance')
|
||||||
else:
|
else:
|
||||||
self.userinfo = {
|
self.userinfo = {
|
||||||
PR_EXPIRED: _('Can\'t pay, invoice is expired'),
|
PR_EXPIRED: _('Invoice is expired'),
|
||||||
PR_PAID: _('Can\'t pay, invoice is already paid'),
|
PR_PAID: _('Invoice is already paid'),
|
||||||
PR_UNCONFIRMED: _('Can\'t pay, invoice is already paid'),
|
PR_UNCONFIRMED: _('Invoice is already paid'),
|
||||||
PR_UNKNOWN: _('Can\'t pay, invoice has unknown status'),
|
PR_UNKNOWN: _('Invoice has unknown status'),
|
||||||
}[self.status]
|
}[self.status]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user