feat: extract seed textArea to shared component and use it in wallet

This commit is contained in:
Jonathan Rainville 2021-04-14 16:50:09 -04:00 committed by Iuri Matias
parent 757eb2bc9e
commit dae0d60684
7 changed files with 127 additions and 104 deletions

View File

@ -7,7 +7,7 @@ import "../../../../shared/status"
ModalPopup { ModalPopup {
id: popup id: popup
height: 600 height: 615
property int marginBetweenInputs: 38 property int marginBetweenInputs: 38
property string passwordValidationError: "" property string passwordValidationError: ""
@ -18,7 +18,7 @@ ModalPopup {
function reset() { function reset() {
passwordInput.text = "" passwordInput.text = ""
accountNameInput.text = "" accountNameInput.text = ""
accountSeedInput.text = "" seedPhraseTextArea.textArea.text = ""
} }
function validate() { function validate() {
@ -39,10 +39,10 @@ ModalPopup {
accountNameValidationError = "" accountNameValidationError = ""
} }
if (accountSeedInput.text === "") { if (seedPhraseTextArea.textArea.text === "") {
//% "You need to enter a seed phrase" //% "You need to enter a seed phrase"
seedValidationError = qsTrId("you-need-to-enter-a-seed-phrase") seedValidationError = qsTrId("you-need-to-enter-a-seed-phrase")
} else if (!Utils.isMnemonic(accountSeedInput.text)) { } else if (!Utils.isMnemonic(seedPhraseTextArea.textArea.text)) {
//% "Enter a valid mnemonic" //% "Enter a valid mnemonic"
seedValidationError = qsTrId("enter-a-valid-mnemonic") seedValidationError = qsTrId("enter-a-valid-mnemonic")
} else { } else {
@ -53,7 +53,7 @@ ModalPopup {
} }
onOpened: { onOpened: {
accountSeedInput.text = ""; seedPhraseTextArea.textArea.text = "";
passwordInput.text = ""; passwordInput.text = "";
accountNameInput.text = ""; accountNameInput.text = "";
passwordValidationError = ""; passwordValidationError = "";
@ -76,28 +76,16 @@ ModalPopup {
validationError: popup.passwordValidationError validationError: popup.passwordValidationError
} }
SeedPhraseTextArea {
StyledTextArea { id: seedPhraseTextArea
id: accountSeedInput
anchors.top: passwordInput.bottom anchors.top: passwordInput.bottom
anchors.topMargin: marginBetweenInputs anchors.topMargin: marginBetweenInputs
//% "Enter your seed phrase, separate words with commas or spaces..." width: parent.width
placeholderText: qsTrId("enter-your-seed-phrase,-separate-words-with-commas-or-spaces...")
//% "Seed phrase"
label: qsTrId("recovery-phrase")
customHeight: 88
validationError: popup.seedValidationError
}
StyledText {
text: Utils.seedPhraseWordCountText(accountSeedInput.text)
anchors.right: parent.right
anchors.top: accountSeedInput.bottom
} }
Input { Input {
id: accountNameInput id: accountNameInput
anchors.top: accountSeedInput.bottom anchors.top: seedPhraseTextArea.bottom
anchors.topMargin: marginBetweenInputs anchors.topMargin: marginBetweenInputs
//% "Enter an account name..." //% "Enter an account name..."
placeholderText: qsTrId("enter-an-account-name...") placeholderText: qsTrId("enter-an-account-name...")
@ -123,7 +111,7 @@ ModalPopup {
//% "Add account" //% "Add account"
qsTrId("add-account") qsTrId("add-account")
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== "" && accountSeedInput.text !== "" enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== "" && seedPhraseTextArea.correctWordCount
MessageDialog { MessageDialog {
id: accountError id: accountError
@ -133,14 +121,14 @@ ModalPopup {
} }
onClicked : { onClicked : {
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads // TODO the loading doesn't work because the function freezes the view. Might need to use threads
loading = true loading = true
if (!validate()) { if (!validate() || !seedPhraseTextArea.validateSeed()) {
errorSound.play() errorSound.play()
return loading = false return loading = false
} }
const error = walletModel.addAccountsFromSeed(accountSeedInput.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor) const error = walletModel.addAccountsFromSeed(seedPhraseTextArea.textArea.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
loading = false loading = false
if (error) { if (error) {
errorSound.play() errorSound.play()

View File

@ -125,7 +125,6 @@ QtObject {
function isMnemonic(value) { function isMnemonic(value) {
if(!value.match(/^([a-z\s]+)$/)){ if(!value.match(/^([a-z\s]+)$/)){
console.log('allo')
return false; return false;
} }
return Utils.seedPhraseValidWordCount(value); return Utils.seedPhraseValidWordCount(value);

View File

@ -387,6 +387,7 @@ DISTFILES += \
shared/GasValidator.qml \ shared/GasValidator.qml \
shared/RoundedImage.qml \ shared/RoundedImage.qml \
shared/SearchBox.qml \ shared/SearchBox.qml \
shared/SeedPhraseTextArea.qml \
shared/Select.qml \ shared/Select.qml \
shared/SendToContractWarning.qml \ shared/SendToContractWarning.qml \
shared/Separator.qml \ shared/Separator.qml \

View File

@ -7,69 +7,27 @@ import "../shared/status"
ModalPopup { ModalPopup {
property var onConfirmSeedClick: function () {} property var onConfirmSeedClick: function () {}
property alias error: errorText.text
property bool correctWordCount: Utils.seedPhraseValidWordCount(mnemonicTextField.text)
id: popup id: popup
//% "Enter seed phrase" //% "Enter seed phrase"
title: qsTrId("enter-seed-phrase") title: qsTrId("enter-seed-phrase")
height: 400 height: 400
onOpened: { onOpened: {
mnemonicTextField.text = ""; seedPhraseTextArea.textArea.text = "";
mnemonicTextField.forceActiveFocus(Qt.MouseFocusReason) seedPhraseTextArea.textArea.forceActiveFocus(Qt.MouseFocusReason)
} }
TextArea {
id: mnemonicTextField SeedPhraseTextArea {
id: seedPhraseTextArea
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 40 anchors.topMargin: 40
height: 100 width: parent.width
anchors.left: parent.left hideRectangle: true
anchors.leftMargin: 76
anchors.right: parent.right
anchors.rightMargin: 76
wrapMode: Text.WordWrap
horizontalAlignment: TextEdit.AlignHCenter
verticalAlignment: TextEdit.AlignVCenter
font.pixelSize: 15
font.weight: Font.DemiBold
//% "Start with the first word"
placeholderText: qsTrId("start-with-the-first-word")
placeholderTextColor: Style.current.secondaryText
selectByMouse: true
selectByKeyboard: true
selectionColor: Style.current.secondaryBackground
selectedTextColor: Style.current.secondaryText
Keys.onReleased: errorText.text = "" textArea.anchors.leftMargin: 76
textArea.anchors.rightMargin: 76
color: Style.current.textColor onEnterPressed: submitBtn.clicked()
Keys.onReturnPressed: {
submitBtn.clicked()
}
KeyNavigation.priority: KeyNavigation.BeforeItem
KeyNavigation.tab: submitBtn
}
StyledText {
visible: errorText.text === ""
text: Utils.seedPhraseWordCountText(mnemonicTextField.text)
anchors.right: parent.right
anchors.top: mnemonicTextField.bottom
anchors.topMargin: Style.current.smallPadding
color: correctWordCount ? Style.current.textColor : Style.current.secondaryText
}
StyledText {
id: errorText
visible: !!text && text != ""
wrapMode: Text.WordWrap
color: Style.current.danger
anchors.left: parent.left
anchors.right: parent.right
anchors.top: mnemonicTextField.bottom
anchors.topMargin: Style.current.smallPadding
horizontalAlignment: Text.AlignHCenter
} }
StyledText { StyledText {
@ -92,13 +50,15 @@ ModalPopup {
icon.name: "arrow-right" icon.name: "arrow-right"
icon.width: 20 icon.width: 20
icon.height: 16 icon.height: 16
enabled: correctWordCount enabled: seedPhraseTextArea.correctWordCount
onClicked : { onClicked : {
if (mnemonicTextField.text === "") { if (seedPhraseTextArea.textArea.text === "") {
return return
} }
onConfirmSeedClick(mnemonicTextField.text) if (seedPhraseTextArea.validateSeed()) {
onConfirmSeedClick(seedPhraseTextArea.textArea.text)
}
} }
} }
} }

View File

@ -15,28 +15,12 @@ Item {
property bool wentNext: false property bool wentNext: false
id: enterSeedPhraseModal id: enterSeedPhraseModal
onConfirmSeedClick: function (mnemonic) { onConfirmSeedClick: function (mnemonic) {
error = "";
if (!Utils.isMnemonic(mnemonic)) {
//% "Invalid seed phrase"
error = qsTrId("custom-seed-phrase")
} else {
error = onboardingModel.validateMnemonic(mnemonic)
const regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
if (regex.test(error)) {
error = qsTr('Invalid seed phrase') + '. ' +
qsTr("This seed phrase doesn't match our supported dictionary. Check for misspelled words.")
}
}
if (error === "") {
wentNext = true wentNext = true
enterSeedPhraseModal.close() enterSeedPhraseModal.close()
onboardingModel.importMnemonic(mnemonic) onboardingModel.importMnemonic(mnemonic)
removeMnemonicAfterLogin = true removeMnemonicAfterLogin = true
recoverySuccessModal.open() recoverySuccessModal.open()
} }
}
onClosed: function () { onClosed: function () {
if (!wentNext) { if (!wentNext) {
existingKeyView.onClosed() existingKeyView.onClosed()

View File

@ -0,0 +1,87 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import "../imports"
import "../shared"
Item {
property bool correctWordCount: Utils.seedPhraseValidWordCount(mnemonicTextField.text)
property alias textArea: mnemonicTextField.textField
signal enterPressed()
property var nextComponentTab
property bool hideRectangle: false
id: root
// Width controlled by parent component
height: childrenRect.height
function validateSeed() {
errorText.text = "";
if (!Utils.isMnemonic(mnemonicTextField.textField.text)) {
//% "Invalid seed phrase"
errorText.text = qsTrId("custom-seed-phrase")
} else {
errorText.text = onboardingModel.validateMnemonic(mnemonicTextField.textField.text)
const regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
if (regex.test(errorText.text)) {
errorText.text = qsTr('Invalid seed phrase') + '. ' +
qsTr("This seed phrase doesn't match our supported dictionary. Check for misspelled words.")
}
}
return errorText.text === ""
}
StyledTextArea {
id: mnemonicTextField
customHeight: 100
hideRectangle: root.hideRectangle
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
textField.wrapMode: Text.WordWrap
textField.horizontalAlignment: TextEdit.AlignHCenter
textField.verticalAlignment: TextEdit.AlignVCenter
textField.font.pixelSize: 15
textField.font.weight: Font.DemiBold
//% "Start with the first word"
placeholderText: qsTrId("start-with-the-first-word")
textField.placeholderTextColor: Style.current.secondaryText
textField.selectByMouse: true
textField.selectByKeyboard: true
textField.selectionColor: Style.current.secondaryBackground
textField.selectedTextColor: Style.current.secondaryText
onKeyPressed: {
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
event.accepted = true
root.enterPressed()
return
}
errorText.text = ""
}
textField.color: Style.current.textColor
}
StyledText {
visible: errorText.text === ""
text: Utils.seedPhraseWordCountText(mnemonicTextField.textField.text)
anchors.right: parent.right
anchors.top: mnemonicTextField.bottom
anchors.topMargin: Style.current.smallPadding
color: correctWordCount ? Style.current.textColor : Style.current.secondaryText
}
StyledText {
id: errorText
visible: !!text && text !== ""
wrapMode: Text.WordWrap
color: Style.current.danger
anchors.left: parent.left
anchors.right: parent.right
anchors.top: mnemonicTextField.bottom
anchors.topMargin: Style.current.smallPadding
horizontalAlignment: Text.AlignHCenter
}
}

View File

@ -17,6 +17,8 @@ Item {
} }
readonly property int labelMargin: 7 readonly property int labelMargin: 7
property int customHeight: 44 property int customHeight: 44
property bool hideRectangle: false
signal keyPressed(var event)
id: inputBox id: inputBox
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0) + (!!validationError ? validationErrorText.height : 0) height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0) + (!!validationError ? validationErrorText.height : 0)
@ -37,13 +39,13 @@ Item {
Rectangle { Rectangle {
id: inputRectangle id: inputRectangle
height: customHeight height: customHeight
color: bgColor color: hideRectangle ? Style.current.transparent : bgColor
radius: Style.current.radius radius: Style.current.radius
anchors.top: inputBox.hasLabel ? inputLabel.bottom : parent.top anchors.top: inputBox.hasLabel ? inputLabel.bottom : parent.top
anchors.topMargin: inputBox.hasLabel ? inputBox.labelMargin : 0 anchors.topMargin: inputBox.hasLabel ? inputBox.labelMargin : 0
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left
border.width: !!validationError ? 1 : 0 border.width: !!validationError && !hideRectangle ? 1 : 0
border.color: Style.current.red border.color: Style.current.red
TextArea { TextArea {
@ -61,6 +63,8 @@ Item {
color: Style.current.textColor color: Style.current.textColor
placeholderTextColor: Style.current.darkGrey placeholderTextColor: Style.current.darkGrey
selectionColor: Style.current.primarySelectionColor selectionColor: Style.current.primarySelectionColor
Keys.onPressed: inputBox.keyPressed(event)
} }
MouseArea { MouseArea {