Browse Source

implement success and failure paths, keep dialog over multiple tries

patch-4
Sander van Grieken 2 years ago
parent
commit
acb88f21c1
  1. 63
      electrum/gui/qml/components/OtpDialog.qml
  2. 2
      electrum/gui/qml/components/WalletMainView.qml
  3. 12
      electrum/gui/qml/qewallet.py

63
electrum/gui/qml/components/OtpDialog.qml

@ -10,13 +10,13 @@ import "controls"
ElDialog { ElDialog {
id: dialog id: dialog
title: qsTr('OTP auth') title: qsTr('Trustedcoin')
iconSource: '../../../icons/trustedcoin-status.png'
property string otpauth property string otpauth
// property var lnurlData property bool _waiting: false
// property InvoiceParser invoiceParser property string _otpError
// property alias lnurlData: dialog.invoiceParser.lnurlData
standardButtons: Dialog.Cancel standardButtons: Dialog.Cancel
@ -26,28 +26,67 @@ ElDialog {
color: "#aa000000" color: "#aa000000"
} }
GridLayout { focus: true
columns: 2
implicitWidth: parent.width ColumnLayout {
width: parent.width
Label { Label {
text: qsTr('code') text: qsTr('Enter Authenticator code')
font.pixelSize: constants.fontSizeLarge
Layout.alignment: Qt.AlignHCenter
} }
TextField { TextField {
id: otpEdit id: otpEdit
Layout.preferredWidth: fontMetrics.advanceWidth(passwordCharacter) * 6
Layout.alignment: Qt.AlignHCenter
font.pixelSize: constants.fontSizeXXLarge
maximumLength: 6
inputMethodHints: Qt.ImhSensitiveData | Qt.ImhDigitsOnly
echoMode: TextInput.Password
focus: true
onTextChanged: {
if (activeFocus)
_otpError = ''
}
}
Label {
opacity: _otpError ? 1 : 0
text: _otpError
color: constants.colorError
Layout.alignment: Qt.AlignHCenter
} }
Button { Button {
Layout.columnSpan: 2 Layout.columnSpan: 2
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: qsTr('Proceed') text: qsTr('Submit')
enabled: !_waiting
onClicked: { onClicked: {
// dialog.close() _waiting = true
otpauth = otpEdit.text Daemon.currentWallet.submitOtp(otpEdit.text)
dialog.accept()
} }
} }
}
Connections {
target: Daemon.currentWallet
function onOtpSuccess() {
_waiting = false
otpauth = otpEdit.text
dialog.accept()
}
function onOtpFailed(code, message) {
_waiting = false
_otpError = message
otpEdit.text = ''
}
}
FontMetrics {
id: fontMetrics
font: otpEdit.font
} }
} }

2
electrum/gui/qml/components/WalletMainView.qml

@ -321,7 +321,7 @@ Item {
Component { Component {
id: otpDialog id: otpDialog
OtpDialog { OtpDialog {
width: parent.width * 0.9 width: parent.width * 2/3
anchors.centerIn: parent anchors.centerIn: parent
onClosed: destroy() onClosed: destroy()

12
electrum/gui/qml/qewallet.py

@ -66,6 +66,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
broadcastFailed = pyqtSignal([str,str,str], arguments=['txid','code','reason']) broadcastFailed = pyqtSignal([str,str,str], arguments=['txid','code','reason'])
labelsUpdated = pyqtSignal() labelsUpdated = pyqtSignal()
otpRequested = pyqtSignal() otpRequested = pyqtSignal()
otpSuccess = pyqtSignal()
otpFailed = pyqtSignal([str,str], arguments=['code','message'])
_network_signal = pyqtSignal(str, object) _network_signal = pyqtSignal(str, object)
@ -426,7 +428,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
@auth_protect @auth_protect
def sign(self, tx, *, broadcast: bool = False): def sign(self, tx, *, broadcast: bool = False):
sign_hook = run_hook('tc_sign_wrapper', self.wallet, tx, partial(self.on_sign_complete, broadcast), None) sign_hook = run_hook('tc_sign_wrapper', self.wallet, tx, partial(self.on_sign_complete, broadcast),
self.on_sign_failed)
if sign_hook: if sign_hook:
self.do_sign(tx, False) self.do_sign(tx, False)
self._logger.debug('plugin needs to sign tx too') self._logger.debug('plugin needs to sign tx too')
@ -454,16 +457,21 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
if broadcast: if broadcast:
self.broadcast(tx) self.broadcast(tx)
# this assumes a 2fa wallet, but there are no other tc_sign_wrapper hooks, so that's ok
def on_sign_complete(self, broadcast, tx): def on_sign_complete(self, broadcast, tx):
self.otpSuccess.emit()
if broadcast: if broadcast:
self.broadcast(tx) self.broadcast(tx)
def on_sign_failed(self, error):
self.otpFailed.emit('error', error)
def request_otp(self, on_submit): def request_otp(self, on_submit):
self._otp_on_submit = on_submit self._otp_on_submit = on_submit
self.otpRequested.emit() self.otpRequested.emit()
@pyqtSlot(str) @pyqtSlot(str)
def finish_otp(self, otp): def submitOtp(self, otp):
self._otp_on_submit(otp) self._otp_on_submit(otp)
def broadcast(self, tx): def broadcast(self, tx):

Loading…
Cancel
Save