feat(onboarding): Adding import seed screens for old&new users
Closes #4955 Closes #5230
This commit is contained in:
parent
b1e5ecc115
commit
a8e946f602
|
@ -44,26 +44,9 @@ QtObject {
|
|||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: welcomeMainState
|
||||
targetState: importSeedState
|
||||
signal: Global.applicationWindow.navigateTo
|
||||
guard: path === "Welcome"
|
||||
}
|
||||
}
|
||||
|
||||
DSM.State {
|
||||
id: existingKeyState
|
||||
onEntered: { onBoardingStepChanged(existingKey, ""); }
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: genKeyState
|
||||
signal: Global.applicationWindow.navigateTo
|
||||
guard: path === "GenKey"
|
||||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: appState
|
||||
signal: startupModule.appStateChanged
|
||||
guard: state === Constants.appState.main
|
||||
guard: path === "ImportSeed"
|
||||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
|
@ -71,6 +54,12 @@ QtObject {
|
|||
signal: Global.applicationWindow.navigateTo
|
||||
guard: path === "Welcome"
|
||||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: stateLogin
|
||||
signal: Global.applicationWindow.navigateTo
|
||||
guard: path === "LogIn"
|
||||
}
|
||||
}
|
||||
|
||||
DSM.State {
|
||||
|
@ -95,6 +84,24 @@ QtObject {
|
|||
}
|
||||
}
|
||||
|
||||
DSM.State {
|
||||
id: importSeedState
|
||||
property string seedInputState: "existingUser"
|
||||
onEntered: { onBoardingStepChanged(seedPhrase, seedInputState); }
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: keysMainState
|
||||
signal: Global.applicationWindow.navigateTo
|
||||
guard: path === "KeyMain"
|
||||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: genKeyState
|
||||
signal: Global.applicationWindow.navigateTo
|
||||
guard: path === "GenKey"
|
||||
}
|
||||
}
|
||||
|
||||
DSM.State {
|
||||
id: keycardState
|
||||
onEntered: { onBoardingStepChanged(keycardFlowSelection, ""); }
|
||||
|
@ -106,28 +113,6 @@ QtObject {
|
|||
}
|
||||
}
|
||||
|
||||
DSM.State {
|
||||
id: createPasswordState
|
||||
onEntered: loader.sourceComponent = createPassword
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: appState
|
||||
signal: startupModule.appStateChanged
|
||||
guard: state === Constants.appState.main
|
||||
}
|
||||
}
|
||||
|
||||
DSM.State {
|
||||
id: confirmPasswordState
|
||||
onEntered: loader.sourceComponent = confirmPassword
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: appState
|
||||
signal: startupModule.appStateChanged
|
||||
guard: state === Constants.appState.main
|
||||
}
|
||||
}
|
||||
|
||||
DSM.State {
|
||||
id: stateLogin
|
||||
onEntered: { onBoardingStepChanged(login, ""); }
|
||||
|
@ -157,12 +142,6 @@ QtObject {
|
|||
guard: path === "KeysMain"
|
||||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: existingKeyState
|
||||
signal: Global.applicationWindow.navigateTo
|
||||
guard: path === "ExistingKey"
|
||||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
targetState: keycardState
|
||||
signal: Global.applicationWindow.navigateTo
|
||||
|
@ -203,43 +182,51 @@ QtObject {
|
|||
id: keysMain
|
||||
KeysMainView {
|
||||
onButtonClicked: {
|
||||
OnboardingStore.accountImported = false
|
||||
Global.applicationWindow.navigateTo("GenKey");
|
||||
if (state === "importseed") {
|
||||
importSeedState.seedInputState = "newUser";
|
||||
Global.applicationWindow.navigateTo("ImportSeed");
|
||||
} else {
|
||||
Global.applicationWindow.navigateTo("GenKey");
|
||||
}
|
||||
}
|
||||
onKeycardLinkClicked: {
|
||||
OnboardingStore.accountImported = false
|
||||
Global.applicationWindow.navigateTo("KeycardFlowSelection");
|
||||
}
|
||||
onSeedLinkClicked: {
|
||||
Global.applicationWindow.navigateTo("ExistingKey");
|
||||
importSeedState.seedInputState = "existingUser";
|
||||
Global.applicationWindow.navigateTo("ImportSeed");
|
||||
}
|
||||
onBackClicked: {
|
||||
OnboardingStore.accountImported = false
|
||||
Global.applicationWindow.navigateTo("Welcome");
|
||||
if (root.keysMainSetState === "connectkeys" && LoginStore.currentAccount.username !== "") {
|
||||
Global.applicationWindow.navigateTo("LogIn");
|
||||
} else {
|
||||
Global.applicationWindow.navigateTo("Welcome");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property var existingKeyComponent: Component {
|
||||
id: existingKey
|
||||
ExistingKeyView {
|
||||
onShowCreatePasswordView: {
|
||||
Global.applicationWindow.navigateTo("GenKey");
|
||||
}
|
||||
onClosed: function () {
|
||||
if (root.hasAccounts) {
|
||||
Global.applicationWindow.navigateTo("InitialState")
|
||||
property var seedPhraseInputComponent: Component {
|
||||
id: seedPhrase
|
||||
SeedPhraseInputView {
|
||||
onExit: {
|
||||
if (root.keysMainSetState === "connectkeys") {
|
||||
Global.applicationWindow.navigateTo("KeyMain");
|
||||
} else {
|
||||
Global.applicationWindow.navigateTo("KeysMain")
|
||||
root.keysMainSetState = "importseed";
|
||||
Global.applicationWindow.navigateTo("KeyMain");
|
||||
}
|
||||
}
|
||||
onSeedValidated: {
|
||||
Global.applicationWindow.navigateTo("GenKey");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property var genKeyComponent: Component {
|
||||
id: genKey
|
||||
GenKeyView {
|
||||
onFinished: {
|
||||
onExit: {
|
||||
if (LoginStore.currentAccount.username !== "") {
|
||||
Global.applicationWindow.navigateTo("LogIn");
|
||||
} else {
|
||||
|
@ -268,11 +255,12 @@ QtObject {
|
|||
property var loginComponent: Component {
|
||||
id: login
|
||||
LoginView {
|
||||
onGenKeyClicked: function () {
|
||||
Global.applicationWindow.navigateTo("GenKey")
|
||||
onGenKeyClicked: {
|
||||
Global.applicationWindow.navigateTo("GenKey");
|
||||
}
|
||||
onExistingKeyClicked: function () {
|
||||
Global.applicationWindow.navigateTo("ExistingKey")
|
||||
onAddExistingKeyClicked: {
|
||||
root.keysMainSetState = "connectkeys";
|
||||
Global.applicationWindow.navigateTo("KeysMain");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import utils 1.0
|
|||
|
||||
Page {
|
||||
id: root
|
||||
signal exit()
|
||||
signal backClicked()
|
||||
signal finished()
|
||||
|
||||
background: Rectangle {
|
||||
color: Style.current.background
|
||||
|
|
|
@ -10,11 +10,11 @@ import shared.popups 1.0
|
|||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
property var onOpenModalClick: function () {}
|
||||
id: popup
|
||||
//% "Enter seed phrase"
|
||||
title: qsTrId("enter-seed-phrase")
|
||||
height: 200
|
||||
signal openModalClicked()
|
||||
|
||||
StyledText {
|
||||
text: "Do you want to add another existing key?"
|
||||
|
@ -30,7 +30,7 @@ ModalPopup {
|
|||
text: "Add another existing key"
|
||||
|
||||
onClicked : {
|
||||
onOpenModalClick()
|
||||
openModalClicked()
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
property var onConfirmSeedClick: function () {}
|
||||
id: popup
|
||||
//% "Enter seed phrase"
|
||||
title: qsTrId("enter-seed-phrase")
|
||||
height: 400
|
||||
|
||||
onOpened: {
|
||||
seedPhraseTextArea.textArea.text = "";
|
||||
seedPhraseTextArea.textArea.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
SeedPhraseTextArea {
|
||||
id: seedPhraseTextArea
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 20
|
||||
anchors.bottomMargin: 20
|
||||
width: parent.width
|
||||
hideRectangle: true
|
||||
|
||||
textArea.anchors.leftMargin: 76
|
||||
textArea.anchors.rightMargin: 76
|
||||
|
||||
onEnterPressed: submitBtn.clicked()
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: helpText
|
||||
//% "Enter 12, 15, 18, 21 or 24 words.\nSeperate words by a single space."
|
||||
text: qsTrId("enter-12--15--18--21-or-24-words--nseperate-words-by-a-single-space-")
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 0
|
||||
horizontalAlignment: TextEdit.AlignHCenter
|
||||
color: Style.current.secondaryText
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
footer: StatusRoundButton {
|
||||
id: submitBtn
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 20
|
||||
icon.height: 16
|
||||
enabled: seedPhraseTextArea.correctWordCount
|
||||
|
||||
onClicked : {
|
||||
if (seedPhraseTextArea.textArea.text === "") {
|
||||
return
|
||||
}
|
||||
if (seedPhraseTextArea.validateSeed()) {
|
||||
onConfirmSeedClick(seedPhraseTextArea.textArea.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import "../panels"1
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
property int selectedIndex: 0
|
||||
property var onClosed: function () {}
|
||||
property var onNextClick: function () {}
|
||||
id: popup
|
||||
//% "Choose a chat name"
|
||||
title: qsTrId("intro-wizard-title2")
|
||||
height: 504
|
||||
|
||||
property string displayNameValidationError: ""
|
||||
|
||||
Input {
|
||||
id: displayNameInput
|
||||
placeholderText: "DisplayName"
|
||||
validationError: displayNameValidationError
|
||||
maxLength: 24
|
||||
onTextChanged: {
|
||||
let trimmedText = displayNameInput.text.trim()
|
||||
if(displayNameInput.text === ""){
|
||||
displayNameValidationError = qsTr("Display name is required")
|
||||
} else if (!trimmedText.match(/^[a-zA-Z0-9\- ]+$/)){
|
||||
displayNameValidationError = qsTr("Only letters, numbers, underscores and hyphens allowed")
|
||||
} else if (trimmedText.length > 24) {
|
||||
displayNameValidationError = qsTr("24 character username limit")
|
||||
} else if (trimmedText.length < 5) {
|
||||
displayNameValidationError = qsTr("Username must be at least 5 characters")
|
||||
} else if (trimmedText.endsWith(".eth")) {
|
||||
displayNameValidationError = qsTr(`Usernames ending with ".eth" are not allowed`)
|
||||
} else if (trimmedText.endsWith("-eth")) {
|
||||
displayNameValidationError = qsTr(`Usernames ending with "-eth" are not allowed`)
|
||||
} else if (trimmedText.endsWith("_eth")) {
|
||||
displayNameValidationError = qsTr(`Usernames ending with "_eth" are not allowed`)
|
||||
} else if (globalUtils.isAlias(trimmedText)){
|
||||
displayNameValidationError = qsTr("Sorry, the name you have chosen is not allowed, try picking another username")
|
||||
} else {
|
||||
displayNameValidationError = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AccountListPanel {
|
||||
id: accountList
|
||||
anchors.top: displayNameInput.bottom
|
||||
anchors.topMargin: 100
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
interactive: false
|
||||
|
||||
model: OnboardingStore.onBoardingModul.accountsModel
|
||||
isSelected: function (index) {
|
||||
return index === selectedIndex
|
||||
}
|
||||
onAccountSelect: function(index) {
|
||||
selectedIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
footer: StatusRoundButton {
|
||||
objectName: "submitButton"
|
||||
id: submitBtn
|
||||
enabled: displayNameInput.text.trim() !== "" && displayNameInput.text.trim().length >= 5
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
icon.name: "arrow-right"
|
||||
icon.width: 20
|
||||
icon.height: 16
|
||||
onClicked : {
|
||||
onNextClick(selectedIndex, displayNameInput.text.trim());
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
id: popup
|
||||
//% "Invalid seed phrase"
|
||||
title: qsTrId("custom-seed-phrase")
|
||||
height: 200
|
||||
property string error: "Invalid seed phrase."
|
||||
|
||||
StyledText {
|
||||
text: popup.error
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
footer: StatusButton {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
//% "Cancel"
|
||||
text: qsTrId("browsing-cancel")
|
||||
anchors.bottom: parent.bottom
|
||||
onClicked: {
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Controls 0.1 as StatusQControls
|
||||
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.status 1.0
|
||||
import "../stores"
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
id: popup
|
||||
//% "Your keys have been successfully recovered"
|
||||
title: qsTrId("your-keys-have-been-successfully-recovered")
|
||||
height: 400
|
||||
|
||||
signal buttonClicked()
|
||||
|
||||
StyledText {
|
||||
id: info
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.current.bigPadding
|
||||
anchors.rightMargin: Style.current.bigPadding
|
||||
//% "You will have to create a new code or password to re-encrypt your keys"
|
||||
text: qsTrId("recovery-success-text")
|
||||
font.pixelSize: 15
|
||||
color: Style.current.secondaryText
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
StatusSmartIdenticon {
|
||||
id: identicon
|
||||
anchors.top: info.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
image.source: OnboardingStore.onboardingModuleInst.importedAccountIdenticon
|
||||
image.width: 60
|
||||
image.height: 60
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: username
|
||||
anchors.top: identicon.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.horizontalCenter: identicon.horizontalCenter
|
||||
text: OnboardingStore.onboardingModuleInst.importedAccountAlias
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
Address {
|
||||
anchors.top: username.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
anchors.horizontalCenter: username.horizontalCenter
|
||||
text: OnboardingStore.onboardingModuleInst.importedAccountAddress
|
||||
width: 120
|
||||
}
|
||||
|
||||
footer: Item {
|
||||
width: parent.width
|
||||
height: reencryptBtn.height
|
||||
|
||||
StatusQControls.StatusButton {
|
||||
id: reencryptBtn
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
//% "Re-encrypt your keys"
|
||||
text: qsTrId("re-encrypt-key")
|
||||
|
||||
onClicked: {
|
||||
OnboardingStore.accountImported = true
|
||||
popup.buttonClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,8 +12,8 @@ import "../stores"
|
|||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
property var onAccountSelect: function () {}
|
||||
property var onOpenModalClick: function () {}
|
||||
signal accountSelected(int index)
|
||||
signal openModalClicked()
|
||||
id: popup
|
||||
//% "Your keys"
|
||||
title: qsTrId("your-keys")
|
||||
|
@ -28,7 +28,7 @@ ModalPopup {
|
|||
}
|
||||
|
||||
onAccountSelect: function(index) {
|
||||
popup.onAccountSelect(index)
|
||||
popup.accountSelected(index)
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ ModalPopup {
|
|||
text: qsTrId("add-another-existing-key")
|
||||
|
||||
onClicked : {
|
||||
onOpenModalClick()
|
||||
openModalClicked()
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import QtQuick 2.13
|
||||
|
||||
ListModel {
|
||||
Component.onCompleted: {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "english.txt");
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
var words = xhr.responseText.split('\n');
|
||||
for (var i = 0; i < words.length; i++) {
|
||||
if (words[i] !== "") {
|
||||
insert(count, {"seedWord": words[i]});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.send();
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ QtObject {
|
|||
property real profImgBX: 0.0
|
||||
property real profImgBY: 0.0
|
||||
property bool accountCreated: false
|
||||
property bool accountImported: false
|
||||
|
||||
property bool showBeforeGetStartedPopup: true
|
||||
|
||||
|
@ -27,13 +26,11 @@ QtObject {
|
|||
onboardingModuleInst.importMnemonic(mnemonic)
|
||||
}
|
||||
|
||||
function setCurrentAccountAndDisplayName(selectedAccountIdx, displayName) {
|
||||
onboardingModuleInst.setDisplayName(displayName)
|
||||
onboardingModuleInst.setSelectedAccountByIndex(selectedAccountIdx)
|
||||
}
|
||||
|
||||
function importAccountAndDisplayName(displayName) {
|
||||
onboardingModuleInst.setDisplayName(displayName)
|
||||
function setCurrentAccountAndDisplayName(displayName) {
|
||||
onboardingModuleInst.setDisplayName(displayName);
|
||||
if (!onboardingModuleInst.importedAccountPubKey) {
|
||||
onboardingModuleInst.setSelectedAccountByIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
function updatedDisplayName(displayName) {
|
||||
|
@ -68,7 +65,11 @@ QtObject {
|
|||
}
|
||||
|
||||
function changePassword(password, newPassword) {
|
||||
root.privacyModule.changePassword(password, newPassword)
|
||||
root.privacyModule.changePassword(password, newPassword);
|
||||
}
|
||||
|
||||
function validateMnemonic(text) {
|
||||
root.onboardingModuleInst.validateMnemonic(text);
|
||||
}
|
||||
|
||||
property ListModel accountsSampleData: ListModel {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -121,17 +121,12 @@ OnboardingBasePage {
|
|||
root.tmpPass = root.password;
|
||||
} else {
|
||||
submitBtn.loading = false
|
||||
root.finished();
|
||||
root.exit();
|
||||
}
|
||||
} else {
|
||||
root.tmpPass = root.password;
|
||||
submitBtn.loading = true
|
||||
if (OnboardingStore.accountImported) {
|
||||
OnboardingStore.importAccountAndDisplayName(root.displayName);
|
||||
} else {
|
||||
OnboardingStore.setCurrentAccountAndDisplayName(0, root.displayName);
|
||||
}
|
||||
|
||||
OnboardingStore.setCurrentAccountAndDisplayName(root.displayName);
|
||||
pause.start();
|
||||
}
|
||||
}
|
||||
|
@ -183,11 +178,11 @@ OnboardingBasePage {
|
|||
onAppStateChanged: {
|
||||
if (state === Constants.appState.main) {
|
||||
if (!!OnboardingStore.profImgUrl) {
|
||||
OnboardingStore.saveImage()
|
||||
OnboardingStore.saveImage();
|
||||
OnboardingStore.accountCreated = true;
|
||||
}
|
||||
submitBtn.loading = false
|
||||
root.finished()
|
||||
root.exit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +192,7 @@ OnboardingBasePage {
|
|||
onPasswordChanged: {
|
||||
if (success) {
|
||||
submitBtn.loading = false
|
||||
root.finished();
|
||||
root.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ OnboardingBasePage {
|
|||
onClicked: {
|
||||
root.newPassword = view.newPswText
|
||||
root.confirmationPassword = view.confirmationPswText
|
||||
root.finished()
|
||||
root.exit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../popups"
|
||||
import "../stores"
|
||||
import "../shared"
|
||||
|
||||
Item {
|
||||
property var onClosed: function () {}
|
||||
|
||||
signal showCreatePasswordView()
|
||||
|
||||
id: existingKeyView
|
||||
anchors.fill: parent
|
||||
|
||||
Component.onCompleted: {
|
||||
enterSeedPhraseModal.open()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: onboardingModule
|
||||
onAccountImportError: {
|
||||
if (error === Constants.existingAccountError) {
|
||||
importSeedError.title = qsTr("Keys for this account already exist")
|
||||
importSeedError.text = qsTr("Keys for this account already exist and can't be added again. If you've lost your password, passcode or Keycard, uninstall the app, reinstall and access your keys by entering your seed phrase")
|
||||
} else {
|
||||
importSeedError.title = qsTr("Error importing seed")
|
||||
importSeedError.text = error
|
||||
}
|
||||
importSeedError.open()
|
||||
}
|
||||
onAccountImportSuccess: {
|
||||
enterSeedPhraseModal.wentNext = true
|
||||
enterSeedPhraseModal.close()
|
||||
recoverySuccessModal.open()
|
||||
}
|
||||
}
|
||||
MessageDialog {
|
||||
id: importSeedError
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
EnterSeedPhraseModal {
|
||||
property bool wentNext: false
|
||||
id: enterSeedPhraseModal
|
||||
onConfirmSeedClick: function (mnemonic) {
|
||||
OnboardingStore.importMnemonic(mnemonic)
|
||||
}
|
||||
onClosed: function () {
|
||||
if (!wentNext) {
|
||||
existingKeyView.onClosed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MnemonicRecoverySuccessModal {
|
||||
property bool wentNext: false
|
||||
id: recoverySuccessModal
|
||||
onButtonClicked: {
|
||||
recoverySuccessModal.wentNext = true
|
||||
recoverySuccessModal.close()
|
||||
showCreatePasswordView()
|
||||
}
|
||||
onClosed: function () {
|
||||
if (!recoverySuccessModal.wentNext) {
|
||||
existingKeyView.onClosed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ OnboardingBasePage {
|
|||
newPassword: d.newPassword
|
||||
confirmationPassword: d.confirmationPassword
|
||||
|
||||
onFinished: {
|
||||
onExit: {
|
||||
d.newPassword = newPassword
|
||||
d.confirmationPassword = confirmationPassword
|
||||
gotoKeysStack(GenKeyView.KeysStack.CONFRIM_PWD)
|
||||
|
@ -76,7 +76,7 @@ OnboardingBasePage {
|
|||
id: confirmPswView
|
||||
password: d.newPassword
|
||||
displayName: userDetailsPanel.displayName
|
||||
onFinished: {
|
||||
onExit: {
|
||||
if (Qt.platform.os == "osx") {
|
||||
gotoKeysStack(GenKeyView.KeysStack.TOUCH_ID);
|
||||
} else {
|
||||
|
@ -96,7 +96,7 @@ OnboardingBasePage {
|
|||
if (userDetailsPanel.state === "chatkey") {
|
||||
userDetailsPanel.state = "username";
|
||||
} else {
|
||||
root.finished();
|
||||
root.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,22 +23,21 @@ Item {
|
|||
state: "username"
|
||||
|
||||
Component.onCompleted: {
|
||||
if (OnboardingStore.accountImported) {
|
||||
if (!!OnboardingStore.onboardingModuleInst.importedAccountPubKey) {
|
||||
root.address = OnboardingStore.onboardingModuleInst.importedAccountAddress ;
|
||||
root.pubKey = OnboardingStore.onboardingModuleInst.importedAccountPubKey;
|
||||
root.address = OnboardingStore.onboardingModuleInst.importedAccountAddress;
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: !OnboardingStore.accountImported
|
||||
active: !OnboardingStore.onboardingModuleInst.importedAccountPubKey
|
||||
sourceComponent: ListView {
|
||||
id: accountsList
|
||||
model: OnboardingStore.onboardingModuleInst.accountsModel
|
||||
delegate: Item {
|
||||
Component.onCompleted: {
|
||||
if (index === 0) {
|
||||
root.pubKey = model.pubKey;
|
||||
root.address = model.address;
|
||||
root.pubKey = model.pubKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,6 +163,7 @@ Item {
|
|||
if (OnboardingStore.accountCreated) {
|
||||
OnboardingStore.updatedDisplayName(nameInput.text);
|
||||
}
|
||||
OnboardingStore.displayName = nameInput.text
|
||||
root.displayName = nameInput.text;
|
||||
root.state = "chatkey";
|
||||
} else {
|
||||
|
|
|
@ -84,25 +84,25 @@ OnboardingBasePage {
|
|||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: keycardLink
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: Theme.palette.primaryColor1
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
parent.font.underline = true
|
||||
}
|
||||
onExited: {
|
||||
parent.font.underline = false
|
||||
}
|
||||
onClicked: {
|
||||
root.keycardLinkClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
// StatusBaseText {
|
||||
// id: keycardLink
|
||||
// Layout.alignment: Qt.AlignHCenter
|
||||
// color: Theme.palette.primaryColor1
|
||||
// MouseArea {
|
||||
// anchors.fill: parent
|
||||
// cursorShape: Qt.PointingHandCursor
|
||||
// hoverEnabled: true
|
||||
// onEntered: {
|
||||
// parent.font.underline = true
|
||||
// }
|
||||
// onExited: {
|
||||
// parent.font.underline = false
|
||||
// }
|
||||
// onClicked: {
|
||||
// root.keycardLinkClicked();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
StatusBaseText {
|
||||
id: seedLink
|
||||
|
@ -119,7 +119,11 @@ OnboardingBasePage {
|
|||
parent.font.underline = false
|
||||
}
|
||||
onClicked: {
|
||||
root.seedLinkClicked();
|
||||
if (root.state === "getkeys") {
|
||||
root.state = "importseed";
|
||||
} else {
|
||||
root.seedLinkClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,15 +145,15 @@ OnboardingBasePage {
|
|||
}
|
||||
PropertyChanges {
|
||||
target: button
|
||||
text: qsTr("Scan sync code")
|
||||
enabled: false
|
||||
|
||||
visible: false
|
||||
//text: qsTr("Scan sync code")
|
||||
}
|
||||
PropertyChanges {
|
||||
target: keycardLink
|
||||
text: qsTr("Login with Keycard")
|
||||
|
||||
}
|
||||
// PropertyChanges {
|
||||
// target: keycardLink
|
||||
// text: qsTr("Login with Keycard")
|
||||
|
||||
// }
|
||||
PropertyChanges {
|
||||
target: seedLink
|
||||
text: qsTr("Enter a seed phrase")
|
||||
|
@ -173,11 +177,11 @@ OnboardingBasePage {
|
|||
text: qsTr("Generate new keys")
|
||||
|
||||
}
|
||||
PropertyChanges {
|
||||
target: keycardLink
|
||||
text: qsTr("Generate keys for a new Keycard")
|
||||
// PropertyChanges {
|
||||
// target: keycardLink
|
||||
// text: qsTr("Generate keys for a new Keycard")
|
||||
|
||||
}
|
||||
// }
|
||||
PropertyChanges {
|
||||
target: seedLink
|
||||
text: qsTr("Import a seed phrase")
|
||||
|
@ -202,11 +206,11 @@ Only use this option if you already have a seed phrase.")
|
|||
text: qsTr("Import a seed phrase")
|
||||
|
||||
}
|
||||
PropertyChanges {
|
||||
target: keycardLink
|
||||
text: qsTr("Import a seed phrase into a new Keycard")
|
||||
// PropertyChanges {
|
||||
// target: keycardLink
|
||||
// text: qsTr("Import a seed phrase into a new Keycard")
|
||||
|
||||
}
|
||||
// }
|
||||
PropertyChanges {
|
||||
target: seedLink
|
||||
text: ""
|
||||
|
|
|
@ -18,9 +18,9 @@ import StatusQ.Components 0.1
|
|||
import utils 1.0
|
||||
|
||||
Item {
|
||||
property var onGenKeyClicked: function () {}
|
||||
property var onExistingKeyClicked: function () {}
|
||||
property bool loading: false
|
||||
signal genKeyClicked()
|
||||
signal addExistingKeyClicked()
|
||||
|
||||
id: loginView
|
||||
anchors.fill: parent
|
||||
|
@ -107,19 +107,19 @@ Item {
|
|||
|
||||
ConfirmAddExistingKeyModal {
|
||||
id: confirmAddExstingKeyModal
|
||||
onOpenModalClick: function () {
|
||||
onExistingKeyClicked()
|
||||
onOpenModalClicked: {
|
||||
addExistingKeyClicked()
|
||||
}
|
||||
}
|
||||
|
||||
SelectAnotherAccountModal {
|
||||
id: selectAnotherAccountModal
|
||||
onAccountSelect: function (index) {
|
||||
onAccountSelected: {
|
||||
LoginStore.setCurrentAccount(index)
|
||||
resetLogin()
|
||||
}
|
||||
onOpenModalClick: function () {
|
||||
onExistingKeyClicked()
|
||||
onOpenModalClicked: {
|
||||
addExistingKeyClicked()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,8 +248,7 @@ Item {
|
|||
anchors.topMargin: 16
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
onClicked: {
|
||||
OnboardingStore.accountImported = false
|
||||
onGenKeyClicked()
|
||||
genKeyClicked();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
import QtQuick 2.12
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import utils 1.0
|
||||
import "../controls"
|
||||
import "../stores"
|
||||
|
||||
OnboardingBasePage {
|
||||
id: root
|
||||
|
||||
state: "existingUser"
|
||||
|
||||
property bool existingUser: (root.state === "existingUser")
|
||||
property var mnemonicInput: []
|
||||
property string mnemonicString
|
||||
|
||||
signal seedValidated()
|
||||
|
||||
Item {
|
||||
implicitWidth: 731
|
||||
implicitHeight: 472
|
||||
anchors.centerIn: parent
|
||||
StatusSwitchTabBar {
|
||||
id: switchTabBar
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
StatusSwitchTabButton {
|
||||
text: qsTr("12 words")
|
||||
}
|
||||
StatusSwitchTabButton {
|
||||
text: qsTr("18 words")
|
||||
}
|
||||
StatusSwitchTabButton {
|
||||
text: qsTr("24 words")
|
||||
}
|
||||
onCurrentIndexChanged: {
|
||||
root.mnemonicString = "";
|
||||
root.mnemonicInput = [];
|
||||
}
|
||||
}
|
||||
clip: true
|
||||
|
||||
GridView {
|
||||
id: grid
|
||||
width: parent.width
|
||||
property var wordIndex: ["1", "5", "9", "2", "6", "10", "3", "7", "11", "4", "8", "12",
|
||||
"13", "17", "21", "14", "18", "22", "15", "19", "23", "16", "20", "24"]
|
||||
property var wordIndex18: ["1", "5", "9", "2", "6", "10", "3", "7", "11", "4", "8", "12",
|
||||
"13", "", "14", "17", "15", "18", "16", ""]
|
||||
height: (grid.count === 20 && !grid.atXBeginning) ? 144 : 244
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 12
|
||||
anchors.top: switchTabBar.bottom
|
||||
anchors.topMargin: ((grid.count === 20) && !grid.atXBeginning) ? 74 : 24
|
||||
flow: GridView.FlowTopToBottom
|
||||
cellWidth: (parent.width/4)
|
||||
cellHeight: 72
|
||||
interactive: false
|
||||
z: 100000
|
||||
model: switchTabBar.currentItem.text.substring(0,2) === "12" ? 12 :
|
||||
switchTabBar.currentItem.text.substring(0,2) === "18" ? 20 : 24
|
||||
delegate: StatusSeedPhraseInput {
|
||||
id: seedWordInput
|
||||
width: (grid.cellWidth - 24)
|
||||
height: (grid.cellHeight - 28)
|
||||
textEdit.input.anchors.leftMargin: 16
|
||||
textEdit.input.anchors.rightMargin: 16
|
||||
visible: !(((index === 13) || (index === 19)) && (grid.count === 20))
|
||||
leftComponentText: (grid.count === 20) ? grid.wordIndex18[index] : grid.wordIndex[index]
|
||||
inputList: BIP39_en { }
|
||||
property int itemIndex: index
|
||||
z: (grid.currentIndex === index) ? 150000000 : 0
|
||||
onTextChanged: {
|
||||
invalidSeedTxt.visible = false;
|
||||
}
|
||||
onDoneInsertingWord: {
|
||||
root.mnemonicInput.push({"pos": leftComponentText, "seed": word.replace(/\s/g, '')});
|
||||
for (var j = 0; j < mnemonicInput.length; j++) {
|
||||
if (mnemonicInput[j].pos === leftComponentText && mnemonicInput[j].seed !== word) {
|
||||
mnemonicInput[j].seed = word;
|
||||
}
|
||||
}
|
||||
//remove duplicates
|
||||
var valueArr = mnemonicInput.map(function(item){ return item.pos });
|
||||
var isDuplicate = valueArr.some(function(item, idx){
|
||||
if (valueArr.indexOf(item) !== idx) {
|
||||
root.mnemonicInput.splice(idx, 1);
|
||||
}
|
||||
return valueArr.indexOf(item) !== idx
|
||||
});
|
||||
for (var i = !grid.atXBeginning ? 12 : 0; i < grid.count; i++) {
|
||||
if (parseInt(grid.itemAtIndex(i).leftComponentText) === (parseInt(leftComponentText)+1)) {
|
||||
grid.currentIndex = grid.itemAtIndex(i).itemIndex;
|
||||
grid.itemAtIndex(i).textEdit.input.edit.forceActiveFocus();
|
||||
if (grid.currentIndex === 11) {
|
||||
grid.positionViewAtEnd();
|
||||
if (grid.count === 20) {
|
||||
grid.contentX = 1500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
submitButton.enabled = (root.mnemonicInput.length === (grid.atXBeginning ? 12 : submitButton.gridCount));
|
||||
}
|
||||
onEditClicked: {
|
||||
grid.currentIndex = index;
|
||||
grid.itemAtIndex(index).textEdit.input.edit.forceActiveFocus();
|
||||
}
|
||||
onKeyPressed: {
|
||||
if (event.key === Qt.Key_Tab || event.key === Qt.Key_Right) {
|
||||
for (var i = !grid.atXBeginning ? 12 : 0; i < grid.count; i++) {
|
||||
if (parseInt(grid.itemAtIndex(i).leftComponentText) === ((parseInt(leftComponentText)+1) <= grid.count ? (parseInt(leftComponentText)+1) : grid.count)) {
|
||||
grid.itemAtIndex(i).textEdit.input.edit.forceActiveFocus();
|
||||
textEdit.input.tabNavItem = grid.itemAtIndex(i).textEdit.input.edit;
|
||||
}
|
||||
}
|
||||
} else if (event.key === Qt.Key_Left) {
|
||||
for (var i = !grid.atXBeginning ? 12 : 0; i < grid.count; i++) {
|
||||
if (parseInt(grid.itemAtIndex(i).leftComponentText) === ((parseInt(leftComponentText)-1) >= 0 ? (parseInt(leftComponentText)-1) : 0)) {
|
||||
grid.itemAtIndex(i).textEdit.input.edit.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
} else if (event.key === Qt.Key_Down) {
|
||||
grid.itemAtIndex((index+1 < grid.count) ? (index+1) : (grid.count-1)).textEdit.input.edit.forceActiveFocus();
|
||||
} else if (event.key === Qt.Key_Up) {
|
||||
grid.itemAtIndex((index-1 >= 0) ? (index-1) : 0).textEdit.input.edit.forceActiveFocus();
|
||||
}
|
||||
|
||||
if (event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) {
|
||||
var wordIndex = mnemonicInput.findIndex(x => x.pos === leftComponentText);
|
||||
if (wordIndex > -1) {
|
||||
mnemonicInput.splice(wordIndex , 1);
|
||||
submitButton.enabled = (root.mnemonicInput.length === (grid.atXBeginning ? 12 : submitButton.gridCount));
|
||||
}
|
||||
}
|
||||
|
||||
grid.currentIndex = index;
|
||||
}
|
||||
Component.onCompleted: { grid.itemAtIndex(0).textEdit.input.edit.forceActiveFocus(); }
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: invalidSeedTxt
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: grid.bottom
|
||||
anchors.topMargin: (grid.count === 20 && !grid.atXBeginning) ? 74 : 24
|
||||
color: Theme.palette.dangerColor1
|
||||
visible: false
|
||||
text: qsTr("Invalid seed")
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
id: submitButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: invalidSeedTxt.bottom
|
||||
anchors.topMargin: 24
|
||||
enabled: false
|
||||
property int gridCount: (grid.count === 20) ? 18 : grid.count
|
||||
text: root.existingUser ? qsTr("Restore Status Profile") :
|
||||
((grid.count > 12) && grid.atXBeginning) ? qsTr("Next") : qsTr("Import")
|
||||
onClicked: {
|
||||
if ((grid.count > 12) && grid.atXBeginning) {
|
||||
grid.positionViewAtEnd();
|
||||
if (grid.count === 20) {
|
||||
grid.contentX = 1500;
|
||||
}
|
||||
} else {
|
||||
root.mnemonicString = "";
|
||||
var sortTable = mnemonicInput.sort(function (a, b) {
|
||||
return a.pos - b.pos;
|
||||
});
|
||||
for (var i = 0; i < mnemonicInput.length; i++) {
|
||||
root.mnemonicString += sortTable[i].seed + ((i === (gridCount-1)) ? "" : " ");
|
||||
}
|
||||
if (Utils.isMnemonic(root.mnemonicString) && !OnboardingStore.validateMnemonic(root.mnemonicString)) {
|
||||
OnboardingStore.importMnemonic(root.mnemonicString)
|
||||
root.seedValidated();
|
||||
root.mnemonicString = "";
|
||||
root.mnemonicInput = [];
|
||||
} else {
|
||||
invalidSeedTxt.visible = true;
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onBackClicked: {
|
||||
root.mnemonicString = "";
|
||||
root.mnemonicInput = [];
|
||||
if (!grid.atXBeginning) {
|
||||
grid.positionViewAtBeginning();
|
||||
} else {
|
||||
root.exit();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,8 @@ var qrcExtensions = map[string]bool{
|
|||
".otf": true,
|
||||
".ttf": true,
|
||||
".webm": true,
|
||||
".qm": true,
|
||||
".qm": true,
|
||||
".txt": true,
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
Loading…
Reference in New Issue