mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-22 11:38:57 +00:00
feat(settings): Adding new Backup Seed Phrase section & modal
Closes #4918
This commit is contained in:
parent
6e682e353c
commit
046aa36565
@ -30,8 +30,21 @@ Column {
|
||||
icon.name: model.icon
|
||||
selected: Global.settingsSubsection === model.subsection
|
||||
onClicked: root.menuItemClicked(model)
|
||||
badge.value: {
|
||||
switch (model.subsection) {
|
||||
case Constants.settingsSubsection.backUpSeed:
|
||||
return !root.privacyStore.mnemonicBackedUp
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
visible: {
|
||||
(model.subsection !== Constants.settingsSubsection.ensUsernames || root.walletMenuItemEnabled)
|
||||
switch (model.subsection) {
|
||||
case Constants.settingsSubsection.ensUsernames:
|
||||
return root.walletMenuItemEnabled;
|
||||
case Constants.settingsSubsection.backUpSeed:
|
||||
return !root.privacyStore.mnemonicBackedUp;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,13 +89,6 @@ Column {
|
||||
selected: Global.settingsSubsection === model.subsection
|
||||
onClicked: root.menuItemClicked(model)
|
||||
visible: model.subsection !== Constants.settingsSubsection.browserSettings || root.browserMenuItemEnabled
|
||||
badge.value: {
|
||||
switch (model.subsection) {
|
||||
case Constants.settingsSubsection.privacyAndSecurity:
|
||||
return !root.privacyStore.mnemonicBackedUp
|
||||
default: return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,293 +1,115 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import utils 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
import "backupseed"
|
||||
|
||||
StatusModal {
|
||||
id: popup
|
||||
width: 480
|
||||
height: 748
|
||||
header.title: qsTr("Back up your seed phrase")
|
||||
|
||||
property var privacyStore
|
||||
|
||||
property bool showWarning: true
|
||||
property int seedWord1Idx: -1;
|
||||
property int seedWord2Idx: -1;
|
||||
property string validationError: ""
|
||||
|
||||
focus: visible
|
||||
|
||||
onOpened: {
|
||||
seedWord1Idx = -1;
|
||||
seedWord2Idx = -1;
|
||||
txtFieldWord.text = "";
|
||||
validationError = "";
|
||||
}
|
||||
|
||||
header: Item {
|
||||
height: 50
|
||||
StyledText {
|
||||
id: lblTitle
|
||||
//% "Back up seed phrase"
|
||||
text: qsTrId("back-up-seed-phrase")
|
||||
font.pixelSize: 17
|
||||
font.bold: true
|
||||
anchors.left: parent.left
|
||||
}
|
||||
StyledText {
|
||||
anchors.top: lblTitle.bottom
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
//% "Step %1 of 3"
|
||||
text: qsTrId("step--1-of-3").arg(seedWord2Idx > -1 ? 3 : (seedWord1Idx > -1 ? 2 : 1))
|
||||
font.pixelSize: 14
|
||||
anchors.left: parent.left
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: popup.opened && !showWarning && seedWord1Idx == -1
|
||||
width: parent.width
|
||||
height: item ? item.height : 0
|
||||
|
||||
sourceComponent: Component {
|
||||
id: seedComponent
|
||||
Item {
|
||||
id: seed
|
||||
width: parent.width
|
||||
height: children[0].height
|
||||
|
||||
Rectangle {
|
||||
id: wrapper
|
||||
property int len: mnemonicRepeater.count
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.padding
|
||||
height: 40 * (len / 2)
|
||||
width: 350
|
||||
border.width: 1
|
||||
color: Style.current.background
|
||||
border.color: Style.current.border
|
||||
radius: Style.current.radius
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Repeater {
|
||||
id: mnemonicRepeater
|
||||
model: popup.privacyStore.getMnemonic().split(" ")
|
||||
Rectangle {
|
||||
id: word
|
||||
height: 40
|
||||
width: 175
|
||||
color: "transparent"
|
||||
anchors.top: (index == 0
|
||||
|| index == (wrapper.len / 2)) ? parent.top : parent.children[index - 1].bottom
|
||||
anchors.left: (index < (wrapper.len / 2)) ? parent.left : undefined
|
||||
anchors.right: (index >= wrapper.len / 2) ? parent.right : undefined
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 175
|
||||
color: Style.current.inputBackground
|
||||
visible: index >= wrapper.len / 2
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: count
|
||||
text: index + 1
|
||||
color: Style.current.secondaryText
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.current.smallPadding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.bigPadding
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
StyledTextEdit {
|
||||
text: modelData
|
||||
font.pixelSize: 15
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.current.smallPadding
|
||||
anchors.left: count.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
selectByMouse: true
|
||||
readOnly: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rightButtons: [
|
||||
StatusFlatButton {
|
||||
text: "Not Now"
|
||||
visible: (stack.currentIndex === 0)
|
||||
border.color: Theme.palette.baseColor2
|
||||
onClicked: {
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: showWarning
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
StyledText {
|
||||
id: lblLoseSeed
|
||||
//% "If you lose your seed phrase you lose your data and funds"
|
||||
text: qsTrId("your-data-belongs-to-you")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 17
|
||||
font.bold: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
StyledText {
|
||||
anchors.top: lblLoseSeed.bottom
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
wrapMode: Text.WordWrap
|
||||
//% "If you lose access, for example by losing your phone, you can only access your keys with your seed phrase. No one, but you has your seed phrase. Write it down. Keep it safe"
|
||||
text: qsTrId("your-data-belongs-to-you-description")
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: textInput
|
||||
visible: seedWord1Idx > -1 || seedWord2Idx > -1
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
focus: visible
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus)
|
||||
txtFieldWord.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
Keys.onReturnPressed: function(event) {
|
||||
confirmButton.clicked()
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: txtChk
|
||||
//% "Check your seed phrase"
|
||||
text: qsTrId("check-your-recovery-phrase")
|
||||
}
|
||||
StyledText {
|
||||
//% "Word #%1"
|
||||
text: qsTrId("word---1").arg((seedWord2Idx > -1 ? seedWord2Idx : seedWord1Idx) + 1)
|
||||
anchors.left: txtChk.right
|
||||
anchors.leftMargin: 5
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
|
||||
Input {
|
||||
id: txtFieldWord
|
||||
anchors.top: txtChk.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.left: txtChk.left
|
||||
anchors.right: parent.right
|
||||
//% "Enter word"
|
||||
placeholderText: qsTrId("enter-word")
|
||||
text: ""
|
||||
validationError: popup.validationError
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.top: txtFieldWord.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
//% "In order to check if you have backed up your seed phrase correctly, enter the word #%1 above"
|
||||
text: qsTrId("in-order-to-check-if-you-have-backed-up-your-seed-phrase-correctly--enter-the-word---1-above").arg((seedWord2Idx > -1 ? seedWord2Idx : seedWord1Idx) + 1)
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
|
||||
Component {
|
||||
id: removeSeedPhraseConfirmDialogComponent
|
||||
ConfirmationDialog {
|
||||
id: confirmPopup
|
||||
//% "Are you sure?"
|
||||
header.title: qsTrId("are-you-sure?")
|
||||
//% "You will not be able to see the whole seed phrase again"
|
||||
confirmationText: qsTrId("are-you-sure-description")
|
||||
onConfirmButtonClicked: {
|
||||
popup.privacyStore.removeMnemonic()
|
||||
popup.close();
|
||||
confirmPopup.close();
|
||||
}
|
||||
onClosed: {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: confirmationsInfo
|
||||
visible: !showWarning && seedWord1Idx == -1
|
||||
//% "With this 12 words you can always get your key back. Write it down. Keep it safe, offline, and separate from this device."
|
||||
text: qsTrId(
|
||||
"with-this-12-words-you-can-always-get-your-key-back.-write-it-down.-keep-it-safe,-offline,-and-separate-from-this-device.")
|
||||
font.pixelSize: 14
|
||||
font.weight: Font.Medium
|
||||
color: Style.current.secondaryText
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.current.padding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
|
||||
|
||||
footer: StatusButton {
|
||||
id: confirmButton
|
||||
text: showWarning ?
|
||||
//% "Okay, continue"
|
||||
qsTrId("ok-continue") :
|
||||
//% "Next"
|
||||
qsTrId("next")
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
anchors.bottom: parent.bottom
|
||||
focus: !textInput.visible
|
||||
Keys.onReturnPressed: function(event) {
|
||||
confirmButton.clicked()
|
||||
}
|
||||
onClicked: {
|
||||
if(showWarning){
|
||||
showWarning = false;
|
||||
} else {
|
||||
if(seedWord1Idx == -1){
|
||||
seedWord1Idx = Math.floor(Math.random() * 12);
|
||||
},
|
||||
StatusButton {
|
||||
enabled: {
|
||||
if (stack.currentIndex === 0) {
|
||||
return acknowledgment.allAccepted;
|
||||
} else {
|
||||
if(seedWord2Idx == -1){
|
||||
if(popup.privacyStore.getMnemonicWordAtIndex(seedWord1Idx) !== txtFieldWord.text){
|
||||
//% "Wrong word"
|
||||
validationError = qsTrId("wrong-word");
|
||||
return;
|
||||
}
|
||||
|
||||
validationError = "";
|
||||
txtFieldWord.text = "";
|
||||
|
||||
do {
|
||||
seedWord2Idx = Math.floor(Math.random() * 12);
|
||||
} while(seedWord2Idx == seedWord1Idx);
|
||||
switch (backUp.bar.currentIndex) {
|
||||
case 0:
|
||||
return !backUp.seedHidden;
|
||||
case 1:
|
||||
return backUp.validFirstSeedWord;
|
||||
case 2:
|
||||
return backUp.validSecondSeedWord;
|
||||
case 3:
|
||||
return backUp.seedStored;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
text: {
|
||||
if (stack.currentIndex === 1) {
|
||||
if (backUp.bar.currentIndex === 0) {
|
||||
return qsTr("Confirm Seed Phrase");
|
||||
} else if (backUp.bar.currentIndex === 1 ||
|
||||
backUp.bar.currentIndex === 2) {
|
||||
return qsTr("Continue");
|
||||
} else {
|
||||
if(popup.privacyStore.getMnemonicWordAtIndex(seedWord2Idx) !== txtFieldWord.text){
|
||||
//% "Wrong word"
|
||||
validationError = qsTrId("wrong-word");
|
||||
return;
|
||||
}
|
||||
|
||||
validationError = "";
|
||||
txtFieldWord.text = "";
|
||||
Global.openPopup(removeSeedPhraseConfirmDialogComponent);
|
||||
return qsTr("Complete & Delete My Seed Phrase");
|
||||
}
|
||||
} else {
|
||||
return qsTr("Confirm Seed Phrase");
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
if (stack.currentIndex === 0) {
|
||||
stack.currentIndex = 1;
|
||||
} else {
|
||||
switch (backUp.bar.currentIndex) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
backUp.bar.currentIndex++;
|
||||
break;
|
||||
case 3:
|
||||
popup.privacyStore.removeMnemonic();
|
||||
popup.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
leftButtons: [
|
||||
StatusRoundButton {
|
||||
visible: (stack.currentIndex === 1)
|
||||
icon.name: "arrow-right"
|
||||
rotation: 180
|
||||
onClicked: {
|
||||
if (backUp.bar.currentIndex === 0) {
|
||||
stack.currentIndex = 0;
|
||||
} else {
|
||||
backUp.bar.currentIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
contentItem: StackLayout {
|
||||
id: stack
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 80
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 88
|
||||
Acknowledgements { id: acknowledgment }
|
||||
Backup { id: backUp; privacyStore: popup.privacyStore }
|
||||
}
|
||||
}
|
||||
|
106
ui/app/AppLayouts/Profile/popups/backupseed/Acknowledgements.qml
Normal file
106
ui/app/AppLayouts/Profile/popups/backupseed/Acknowledgements.qml
Normal file
@ -0,0 +1,106 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import shared.panels 1.0
|
||||
import utils 1.0
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
objectName: "acknowledgment"
|
||||
property bool allAccepted: (havePen.checked && writeDown.checked && storeIt.checked)
|
||||
Image {
|
||||
id: keysImg
|
||||
width: 120
|
||||
height: 120
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: Style.png("onboarding/keys")
|
||||
mipmap: true
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: txtTitle
|
||||
text: qsTr("Secure Your Assets and Funds")
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
font.bold: true
|
||||
anchors.top: keysImg.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
font.pixelSize: 22
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: txtDesc
|
||||
anchors.top: txtTitle.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
font.letterSpacing: -0.2
|
||||
text: qsTr("Your seed phrase is a 12-word passcode to your funds.")
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: secondTxtDesc
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.left: parent.left
|
||||
anchors.top: txtDesc.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
textFormat: Text.RichText
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
text: qsTr("Your seed phrase cannot be recovered if lost. Therefore, you <b>must</b> back it up. The simplest way is to <b>write it down offline and store it somewhere secure.</b>")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.topMargin: 49
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: secondTxtDesc.bottom
|
||||
spacing: Style.current.padding
|
||||
StatusCheckBox {
|
||||
id: havePen
|
||||
width: parent.width
|
||||
text: qsTrId("I have a pen and paper")
|
||||
}
|
||||
StatusCheckBox {
|
||||
id: writeDown
|
||||
width: parent.width
|
||||
text: qsTrId("I am ready to write down my seed phrase")
|
||||
}
|
||||
StatusCheckBox {
|
||||
id: storeIt
|
||||
width: parent.width
|
||||
text: qsTr("I know where I’ll store it")
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 60
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
StyledText {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.current.halfPadding
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
wrapMode: Text.WordWrap
|
||||
color: Theme.palette.dangerColor1
|
||||
text: qsTr("You can only complete this process once. Status will not store your seed phrase and can never help you recover it.")
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 8
|
||||
color: Theme.palette.dangerColor1
|
||||
opacity: 0.1
|
||||
}
|
||||
}
|
||||
}
|
79
ui/app/AppLayouts/Profile/popups/backupseed/Backup.qml
Normal file
79
ui/app/AppLayouts/Profile/popups/backupseed/Backup.qml
Normal file
@ -0,0 +1,79 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import shared.panels 1.0
|
||||
import utils 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property var privacyStore
|
||||
property alias bar: bar
|
||||
property alias seedHidden: confirmSeedPhrase.hideSeed
|
||||
property alias seedStored: confirmStoringSeedPhrase.seedStored
|
||||
property int firstRandomNo: Math.floor(Math.random() * 12)
|
||||
property alias validFirstSeedWord: confirmFirstWord.inputValid
|
||||
property alias validSecondSeedWord: confirmSecondWord.inputValid
|
||||
property int secondRandomNo: {
|
||||
var num = Math.floor(Math.random() * 12);
|
||||
return (num === firstRandomNo) ? Math.floor(Math.random() * 12) : num;
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
StyledText {
|
||||
id: txtDesc
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: Style.current.additionalTextSize
|
||||
color: Style.current.secondaryText
|
||||
text: qsTr("Step " + (bar.currentIndex+1) + " of " + bar.count)
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: bar
|
||||
width: (59 * count)
|
||||
height: 4
|
||||
anchors.top: txtDesc.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: 2
|
||||
background: null
|
||||
TabBarButton { index: 0; currentIndex: bar.currentIndex }
|
||||
TabBarButton { index: 1; currentIndex: bar.currentIndex }
|
||||
TabBarButton { index: 2; currentIndex: bar.currentIndex }
|
||||
TabBarButton { index: 3; currentIndex: bar.currentIndex }
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: stack
|
||||
anchors.top: bar.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
currentIndex: bar.currentIndex
|
||||
ConfirmSeedPhrasePanel {
|
||||
id: confirmSeedPhrase
|
||||
seedPhrase: root.privacyStore.getMnemonic().split(" ")
|
||||
}
|
||||
BackupSeedStepBase {
|
||||
id: confirmFirstWord
|
||||
titleText: qsTr("Confirm word #" + (root.firstRandomNo+1) + " of your seed phrase")
|
||||
wordRandomNumber: root.firstRandomNo
|
||||
wordAtRandomNumber: root.privacyStore.getMnemonicWordAtIndex(root.firstRandomNo)
|
||||
}
|
||||
BackupSeedStepBase {
|
||||
id: confirmSecondWord
|
||||
titleText: qsTr("Confirm word #" + (root.secondRandomNo+1) + " of your seed phrase")
|
||||
wordRandomNumber: root.secondRandomNo
|
||||
wordAtRandomNumber: root.privacyStore.getMnemonicWordAtIndex(root.secondRandomNo)
|
||||
}
|
||||
ConfirmStoringSeedPhrasePanel { id: confirmStoringSeedPhrase }
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import StatusQ.Controls 0.1
|
||||
import shared.panels 1.0
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
import utils 1.0
|
||||
|
||||
Item {
|
||||
property int wordRandomNumber: -1
|
||||
property string wordAtRandomNumber
|
||||
property bool secondWordValid: true
|
||||
property alias titleText: txtTitle.text
|
||||
property alias inputValid: inputText.valid
|
||||
|
||||
StyledText {
|
||||
id: txtTitle
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: inputText
|
||||
visible: (wordRandomNumber > -1)
|
||||
implicitWidth: 448
|
||||
input.implicitHeight: 44
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 40
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
validationMode: StatusInput.ValidationMode.Always
|
||||
label: qsTr("Word #" + (wordRandomNumber+1))
|
||||
input.placeholderText: qsTr("Enter word")
|
||||
validators: [
|
||||
StatusValidator {
|
||||
validate: function (t) { return (wordAtRandomNumber === inputText.text); }
|
||||
errorMessage: (inputText.text.length) > 0 ? qsTr("Wrong word") : ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
import QtQuick 2.12
|
||||
import StatusQ.Controls 0.1
|
||||
import QtGraphicalEffects 1.13
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import shared.panels 1.0
|
||||
import utils 1.0
|
||||
|
||||
BackupSeedStepBase {
|
||||
id: root
|
||||
property var seedPhrase
|
||||
property bool hideSeed: true
|
||||
|
||||
titleText: qsTr("Write down your 12-word seed phrase to keep offline")
|
||||
|
||||
GridView {
|
||||
id: grid
|
||||
width: parent.width
|
||||
height: 304
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 2
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 88
|
||||
flow: GridView.FlowTopToBottom
|
||||
cellWidth: 208
|
||||
cellHeight: 48
|
||||
interactive: false
|
||||
model: 12
|
||||
property var wordIndex: ["1", "3", "5", "7", "9", "11", "2", "4", "6", "8", "10", "12"]
|
||||
delegate: StatusSeedPhraseInput {
|
||||
id: seedWordInput
|
||||
width: (grid.cellWidth - 4)
|
||||
height: (grid.cellHeight - 4)
|
||||
textEdit.input.edit.enabled: false
|
||||
text: root.seedPhrase[parseInt(leftComponentText)-1]
|
||||
leftComponentText: grid.wordIndex[index]
|
||||
}
|
||||
}
|
||||
|
||||
GaussianBlur {
|
||||
id: blur
|
||||
anchors.fill: grid
|
||||
visible: hideSeed
|
||||
source: grid
|
||||
radius: 16
|
||||
samples: 16
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
anchors.centerIn: grid
|
||||
visible: hideSeed
|
||||
icon.name: "view"
|
||||
text: qsTr("Reveal seed phrase")
|
||||
onClicked: {
|
||||
hideSeed = false;
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: text
|
||||
anchors.left: parent.left
|
||||
//anchors.leftMargin: Style.current.bigPadding
|
||||
anchors.right: parent.right
|
||||
//anchors.rightMargin: Style.current.bigPadding
|
||||
anchors.top: grid.bottom
|
||||
anchors.topMargin: 36
|
||||
visible: hideSeed
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
wrapMode: Text.WordWrap
|
||||
textFormat: Text.RichText
|
||||
color: Theme.palette.dangerColor1
|
||||
text: qsTr("The next screen contains your seed phrase.\n<b>Anyone</b> who sees it can use it to access to your funds.")
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
import QtQuick 2.12
|
||||
import utils 1.0
|
||||
import shared.panels 1.0
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
BackupSeedStepBase {
|
||||
titleText: qsTr("Complete back up")
|
||||
property bool seedStored: storeCheck.checked
|
||||
|
||||
StyledText {
|
||||
id: txtTitle
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 40
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
font.bold: true
|
||||
font.pixelSize: 17
|
||||
text: qsTr("Store Your Phrase Offline and Complete Your Back Up")
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: txtDesc
|
||||
anchors.top: txtTitle.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
text: qsTr("By completing this process, you will remove your seed phrase from this application’s storage. This makes your funds more secure.")
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: secondTxtDesc
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.top: txtDesc.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
text: qsTr("You will remain logged in, and your seed phrase will be entirely in your hands.")
|
||||
}
|
||||
|
||||
StatusCheckBox {
|
||||
id: storeCheck
|
||||
width: parent.width
|
||||
anchors.top: secondTxtDesc.bottom
|
||||
anchors.topMargin: 48
|
||||
text: qsTr("I aknowledge that Status will not be able to show me my seed phrase again.")
|
||||
}
|
||||
}
|
18
ui/app/AppLayouts/Profile/popups/backupseed/TabBarButton.qml
Normal file
18
ui/app/AppLayouts/Profile/popups/backupseed/TabBarButton.qml
Normal file
@ -0,0 +1,18 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
TabButton {
|
||||
id: root
|
||||
property int index: 0
|
||||
property int currentIndex: 0
|
||||
implicitWidth: 59
|
||||
implicitHeight: 4
|
||||
enabled: false
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 4
|
||||
color: (root.currentIndex === index) || (root.currentIndex > index) ?
|
||||
Theme.palette.primaryColor1 : Theme.palette.primaryColor2
|
||||
}
|
||||
}
|
@ -65,6 +65,9 @@ QtObject {
|
||||
|
||||
property ListModel mainMenuItems: ListModel {
|
||||
Component.onCompleted: {
|
||||
append({subsection: Constants.settingsSubsection.backUpSeed,
|
||||
text: qsTr("Back up seed phrase"),
|
||||
icon: "seed-phrase"})
|
||||
append({subsection: Constants.settingsSubsection.profile,
|
||||
text: qsTr("Profile"),
|
||||
icon: "profile"})
|
||||
@ -96,12 +99,12 @@ QtObject {
|
||||
append({subsection: Constants.settingsSubsection.appearance,
|
||||
text: qsTr("Appearance"),
|
||||
icon: "appearance"})
|
||||
append({subsection: Constants.settingsSubsection.language,
|
||||
text: qsTr("Language & Currency"),
|
||||
icon: "language"})
|
||||
append({subsection: Constants.settingsSubsection.notifications,
|
||||
text: qsTr("Notifications & Sounds"),
|
||||
icon: "notification"})
|
||||
append({subsection: Constants.settingsSubsection.language,
|
||||
text: qsTr("Language & Currency"),
|
||||
icon: "language"})
|
||||
append({subsection: Constants.settingsSubsection.devicesSettings,
|
||||
text: qsTr("Devices settings"),
|
||||
icon: "mobile"})
|
||||
|
@ -41,12 +41,15 @@ Item {
|
||||
appsMenuItems: store.appsMenuItems
|
||||
browserMenuItemEnabled: store.browserMenuItemEnabled
|
||||
walletMenuItemEnabled: store.walletMenuItemEnabled
|
||||
|
||||
onMenuItemClicked: {
|
||||
if (menu_item.subsection === Constants.settingsSubsection.signout) {
|
||||
return confirmDialog.open()
|
||||
if (menu_item.subsection === Constants.settingsSubsection.backUpSeed) {
|
||||
Global.openBackUpSeedPopup();
|
||||
} else {
|
||||
if (menu_item.subsection === Constants.settingsSubsection.signout) {
|
||||
return confirmDialog.open();
|
||||
}
|
||||
Global.settingsSubsection = menu_item.subsection;
|
||||
}
|
||||
Global.settingsSubsection = menu_item.subsection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,28 +24,6 @@ SettingsContentBase {
|
||||
spacing: Constants.settingsSection.itemSpacing
|
||||
width: root.contentWidth
|
||||
|
||||
StatusListItem {
|
||||
id: backupSeedPhrase
|
||||
Layout.fillWidth: true
|
||||
//% "Backup Seed Phrase"
|
||||
title: qsTrId("backup-seed-phrase")
|
||||
enabled: !root.privacyStore.mnemonicBackedUp
|
||||
implicitHeight: 52
|
||||
components: [
|
||||
StatusBadge {
|
||||
value: !root.privacyStore.mnemonicBackedUp
|
||||
visible: !root.privacyStore.mnemonicBackedUp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
},
|
||||
StatusIcon {
|
||||
icon: "chevron-down"
|
||||
rotation: 270
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
]
|
||||
sensor.onClicked: Global.openBackUpSeedPopup()
|
||||
}
|
||||
|
||||
StatusListItem {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Change password")
|
||||
|
@ -98,7 +98,7 @@ Item {
|
||||
var popup = changeProfilePicComponent.createObject(appMain);
|
||||
popup.open();
|
||||
}
|
||||
onOpenBackUpSeedPopup : {
|
||||
onOpenBackUpSeedPopup: {
|
||||
var popup = backupSeedModalComponent.createObject(appMain)
|
||||
popup.open()
|
||||
}
|
||||
@ -145,6 +145,7 @@ Item {
|
||||
|
||||
property Component backupSeedModalComponent: BackupSeedModal {
|
||||
id: backupSeedModal
|
||||
anchors.centerIn: parent
|
||||
privacyStore: appMain.rootStore.profileSectionStore.privacyStore
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ QtObject {
|
||||
property int advanced: 11
|
||||
property int about: 12
|
||||
property int signout: 13
|
||||
property int backUpSeed: 14
|
||||
}
|
||||
|
||||
readonly property QtObject userStatus: QtObject{
|
||||
|
Loading…
x
Reference in New Issue
Block a user