feat: introduce TransactionSigner UI component

Closes #676
This commit is contained in:
Pascal Precht 2020-08-19 17:29:42 +02:00 committed by Iuri Matias
parent d35c971c8b
commit b528e784c9
7 changed files with 123 additions and 23 deletions

View File

@ -43,6 +43,7 @@ proc init*(self: WalletController) =
self.view.updateView() self.view.updateView()
self.view.setEtherscanLink(status_settings.getCurrentNetworkDetails().etherscanLink) self.view.setEtherscanLink(status_settings.getCurrentNetworkDetails().etherscanLink)
self.view.setSigningPhrase(status_settings.getSetting[string](Setting.SigningPhrase))
method onSignal(self: WalletController, data: Signal) = method onSignal(self: WalletController, data: Signal) =
debug "New signal received" debug "New signal received"

View File

@ -21,6 +21,7 @@ QtObject:
fastGasPrice: string fastGasPrice: string
fastestGasPrice: string fastestGasPrice: string
defaultGasLimit: string defaultGasLimit: string
signingPhrase: string
proc delete(self: WalletView) = proc delete(self: WalletView) =
self.accounts.delete self.accounts.delete
@ -47,6 +48,7 @@ QtObject:
result.fastGasPrice = "0" result.fastGasPrice = "0"
result.fastestGasPrice = "0" result.fastestGasPrice = "0"
result.defaultGasLimit = "22000" result.defaultGasLimit = "22000"
result.signingPhrase = ""
result.setup result.setup
proc etherscanLinkChanged*(self: WalletView) {.signal.} proc etherscanLinkChanged*(self: WalletView) {.signal.}
@ -58,10 +60,23 @@ QtObject:
self.etherscanLink = link self.etherscanLink = link
self.etherscanLinkChanged() self.etherscanLinkChanged()
proc signingPhraseChanged*(self: WalletView) {.signal.}
proc getSigningPhrase*(self: WalletView): QVariant {.slot.} =
newQVariant(self.signingPhrase)
proc setSigningPhrase*(self: WalletView, signingPhrase: string) =
self.signingPhrase = signingPhrase
self.signingPhraseChanged()
QtProperty[QVariant] etherscanLink: QtProperty[QVariant] etherscanLink:
read = getEtherscanLink read = getEtherscanLink
notify = etherscanLinkChanged notify = etherscanLinkChanged
QtProperty[QVariant] signingPhrase:
read = getSigningPhrase
notify = signingPhraseChanged
proc setCurrentAssetList*(self: WalletView, assetList: seq[Asset]) proc setCurrentAssetList*(self: WalletView, assetList: seq[Asset])
proc currentCollectiblesListChanged*(self: WalletView) {.signal.} proc currentCollectiblesListChanged*(self: WalletView) {.signal.}

View File

@ -158,6 +158,7 @@ type
LatestDerivedPath = "latest-derived-path" LatestDerivedPath = "latest-derived-path"
PreferredUsername = "preferred-name" PreferredUsername = "preferred-name"
Usernames = "usernames" Usernames = "usernames"
SigningPhrase = "signing-phrase"
UpstreamConfig* = ref object UpstreamConfig* = ref object
enabled* {.serializedFieldName("Enabled").}: bool enabled* {.serializedFieldName("Enabled").}: bool

View File

@ -56,8 +56,11 @@ ModalPopup {
anchors.right: parent.right anchors.right: parent.right
visible: !btnPreview.visible visible: !btnPreview.visible
//% "Send" //% "Send"
label: qsTrId("command-button-send") label: qsTrId("command-button-send") + " " + sendModalContent.amountInput.selectedAmount + " " + sendModalContent.amountInput.selectedAsset.symbol
onClicked: { onClicked: {
if (!sendModalContent.validatePassword()) {
return
}
sendModalContent.send() sendModalContent.send()
} }
} }

View File

@ -8,19 +8,19 @@ Item {
id: sendModalContent id: sendModalContent
property var closePopup: function(){} property var closePopup: function(){}
property alias amountInput: txtAmount property alias amountInput: txtAmount
property alias passwordInput: txtPassword property alias passwordInput: transactionSigner.passwordInput
property string passwordValidationError: "" property string passwordValidationError: ""
function send() { function send() {
if (!validate()) { if (!validate() || !validatePassword()) {
return; return;
} }
let result = walletModel.onSendTransaction(selectFromAccount.selectedAccount.address, let result = walletModel.onSendTransaction(selectFromAccount.selectedAccount.address,
selectRecipient.selectedRecipient, selectRecipient.selectedRecipient,
txtAmount.selectedAsset.address, txtAmount.selectedAsset.address,
txtAmount.text, txtAmount.text,
txtPassword.text) transactionSigner.passwordInput.text)
if (!result.startsWith('0x')) { if (!result.startsWith('0x')) {
// It's an error // It's an error
@ -32,30 +32,37 @@ Item {
sendingSuccess.open() sendingSuccess.open()
} }
function validate() { function validatePassword() {
const isRecipientValid = selectRecipient.validate() if (transactionSigner.passwordInput.text === "") {
const isAssetAndAmountValid = txtAmount.validate()
if (txtPassword.text === "") {
//% "You need to enter a password" //% "You need to enter a password"
passwordValidationError = qsTrId("you-need-to-enter-a-password") passwordValidationError = qsTrId("you-need-to-enter-a-password")
} else if (txtPassword.text.length < 4) { } else if (transactionSigner.passwordInput.text.length < 4) {
//% "Password needs to be 4 characters or more" //% "Password needs to be 4 characters or more"
passwordValidationError = qsTrId("password-needs-to-be-4-characters-or-more") passwordValidationError = qsTrId("password-needs-to-be-4-characters-or-more")
} else { } else {
passwordValidationError = "" passwordValidationError = ""
} }
return passwordValidationError === "" && isRecipientValid && isAssetAndAmountValid return passwordValidationError === ""
}
function validate() {
const isRecipientValid = selectRecipient.validate()
const isAssetAndAmountValid = txtAmount.validate()
return isRecipientValid && isAssetAndAmountValid
} }
function showPreview() { function showPreview() {
pvwTransaction.visible = true pvwTransaction.visible = true
txtAmount.visible = selectFromAccount.visible = selectRecipient.visible = txtPassword.visible = gasSelector.visible = false transactionSigner.visible = true
txtAmount.visible = selectFromAccount.visible = selectRecipient.visible = gasSelector.visible = false
} }
function showInputs() { function showInputs() {
pvwTransaction.visible = false pvwTransaction.visible = false
txtAmount.visible = selectFromAccount.visible = selectRecipient.visible = txtPassword.visible = gasSelector.visible = true transactionSigner.visible = false
txtAmount.visible = selectFromAccount.visible = selectRecipient.visible = gasSelector.visible = true
} }
anchors.left: parent.left anchors.left: parent.left
@ -144,18 +151,16 @@ Item {
currency: walletModel.defaultCurrency currency: walletModel.defaultCurrency
} }
Input { TransactionSigner {
id: txtPassword id: transactionSigner
//% "Password" visible: false
label: qsTrId("password") anchors.left: parent.left
//% "Enter Password" anchors.right: parent.right
placeholderText: qsTrId("biometric-auth-login-ios-fallback-label") anchors.top: pvwTransaction.bottom
anchors.top: selectRecipient.bottom anchors.topMargin: Style.current.smallPadding
anchors.topMargin: Style.current.padding signingPhrase: walletModel.signingPhrase
textField.echoMode: TextInput.Password validationError: sendModalContent.passwordValidationError
validationError: passwordValidationError
} }
} }
/*##^## /*##^##

View File

@ -0,0 +1,74 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../imports"
Item {
id: root
height: signingPhraseItem.height + signingPhrase.height + txtPassword.height + Style.current.smallPadding + Style.current.bigPadding
property string signingPhrase: "not a real one"
property alias passwordInput: txtPassword
property string validationError: ""
Item {
id: signingPhraseItem
anchors.horizontalCenter: parent.horizontalCenter
height: labelSigningPhrase.height
width: labelSigningPhrase.width + infoButton.width + infoButton.anchors.leftMargin
StyledText {
id: labelSigningPhrase
color: Style.current.secondaryText
font.pixelSize: 15
text: qsTr("Signing phrase")
}
IconButton {
id: infoButton
clickable: false
anchors.left: labelSigningPhrase.right
anchors.leftMargin: 7
anchors.verticalCenter: parent.verticalCenter
width: 13
height: 13
iconName: "info"
color: Style.current.lightBlue
}
}
StyledText {
id: signingPhrase
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: signingPhraseItem.bottom
anchors.topMargin: Style.current.smallPadding
font.pixelSize: 15
text: root.signingPhrase
}
IconButton {
id: passwordInfoButton
clickable: false
anchors.left: parent.left
anchors.leftMargin: 67
anchors.top: txtPassword.top
anchors.topMargin: 2
width: 13
height: 13
iconName: "info"
color: Style.current.lightBlue
}
Input {
anchors.top: signingPhrase.bottom
anchors.topMargin: Style.current.bigPadding
id: txtPassword
//% "Password"
label: qsTrId("password")
//% "Enter Password"
placeholderText: qsTrId("enter-password")
textField.echoMode: TextInput.Password
validationError: root.validationError
}
}

View File

@ -21,3 +21,4 @@ BlockContactConfirmationDialog 1.0 BlockContactConfirmationDialog.qml
ConfirmationDialog 1.0 ConfirmationDialog.qml ConfirmationDialog 1.0 ConfirmationDialog.qml
StatusSlider 1.0 StatusSlider.qml StatusSlider 1.0 StatusSlider.qml
Timer 1.0 Timer.qml Timer 1.0 Timer.qml
TransactionSigner 1.0 TransactionSigner.qml