aboutsummaryrefslogtreecommitdiff
path: root/wizard
diff options
context:
space:
mode:
authorJaquee <jaquee.monero@gmail.com>2017-01-04 17:25:22 +0100
committerJaquee <jaquee.monero@gmail.com>2017-01-15 12:32:25 +0100
commitfd983955b4dbdbd612fbdf5ed08d8c8a049fb840 (patch)
tree998ef5867e5439aa96c19439c1fe65eb244d51cb /wizard
parent8f56e9839739c8b0d821b1b38c06e458a1ab6d06 (diff)
downloadmonzero-gui-fd983955b4dbdbd612fbdf5ed08d8c8a049fb840.tar.gz
monzero-gui-fd983955b4dbdbd612fbdf5ed08d8c8a049fb840.tar.xz
monzero-gui-fd983955b4dbdbd612fbdf5ed08d8c8a049fb840.zip
view only wallets
wizard: fix dots on pw page wizard: fix focus on pw field viewOnly: added success message
Diffstat (limited to 'wizard')
-rw-r--r--wizard/WizardCreateViewOnlyWallet.qml94
-rw-r--r--wizard/WizardMain.qml81
-rw-r--r--wizard/WizardManageWalletUI.qml6
-rw-r--r--wizard/WizardPassword.qml75
-rw-r--r--wizard/WizardPasswordUI.qml96
-rw-r--r--wizard/utils.js7
6 files changed, 293 insertions, 66 deletions
diff --git a/wizard/WizardCreateViewOnlyWallet.qml b/wizard/WizardCreateViewOnlyWallet.qml
new file mode 100644
index 00000000..dc1b813e
--- /dev/null
+++ b/wizard/WizardCreateViewOnlyWallet.qml
@@ -0,0 +1,94 @@
+// Copyright (c) 2014-2015, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import moneroComponents.WalletManager 1.0
+import QtQuick 2.2
+import "../components"
+import "utils.js" as Utils
+
+Item {
+
+ id: passwordPage
+ opacity: 0
+ visible: false
+
+ Behavior on opacity {
+ NumberAnimation { duration: 100; easing.type: Easing.InQuad }
+ }
+
+ onOpacityChanged: visible = opacity !== 0
+
+
+ function onPageOpened(settingsObject) {
+ wizard.nextButton.enabled = true
+ }
+
+ function onPageClosed(settingsObject) {
+ var walletFullPath = wizard.createWalletPath(uiItem.walletPath,uiItem.accountNameText);
+ settingsObject['view_only_wallet_path'] = walletFullPath
+ console.log("wallet path", walletFullPath)
+ return wizard.walletPathValid(walletFullPath);
+ }
+
+ Row {
+ id: dotsRow
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.topMargin: 85
+ spacing: 6
+
+ ListModel {
+ id: dotsModel
+ ListElement { dotColor: "#FFE00A" }
+ ListElement { dotColor: "#DBDBDB" }
+ }
+
+ Repeater {
+ model: dotsModel
+ delegate: Rectangle {
+ width: 12; height: 12
+ radius: 6
+ color: dotColor
+ }
+ }
+ }
+
+ WizardManageWalletUI {
+ id: uiItem
+ titleText: qsTr("Give your view only wallet a name") + translationManager.emptyString
+ wordsTextItem.visible: false
+ restoreHeightVisible:false
+ walletName: appWindow.walletName + "-viewonly"
+ progressDotsModel: dotsModel
+ }
+
+
+ Component.onCompleted: {
+ //parent.wizardRestarted.connect(onWizardRestarted)
+ }
+}
diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml
index ec720026..124a5784 100644
--- a/wizard/WizardMain.qml
+++ b/wizard/WizardMain.qml
@@ -44,6 +44,7 @@ Rectangle {
// disable donation page
"create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, finishPage ],
"recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, finishPage ],
+ "create_view_only_wallet" : [ createViewOnlyWalletPage, passwordPage ],
}
property string currentPath: "create_wallet"
@@ -89,15 +90,12 @@ Rectangle {
currentPage += step_value
pages[currentPage].opacity = 1;
- var nextButtonVisible = pages[currentPage] !== optionsPage;
+ var nextButtonVisible = pages[currentPage] !== optionsPage && currentPage < pages.length - 1;
nextButton.visible = nextButtonVisible;
if (typeof pages[currentPage].onPageOpened !== 'undefined') {
pages[currentPage].onPageOpened(settings,next)
}
-
-
-
}
}
@@ -130,6 +128,16 @@ Rectangle {
wizard.openWalletFromFileClicked();
}
+ function openCreateViewOnlyWalletPage(){
+ pages[currentPage].opacity = 0
+ currentPath = "create_view_only_wallet"
+ pages = paths[currentPath]
+ currentPage = pages.indexOf(createViewOnlyWalletPage)
+ createViewOnlyWalletPage.opacity = 1
+ nextButton.visible = true
+ rootItem.state = "wizard";
+ }
+
function createWalletPath(folder_path,account_name){
// Remove trailing slash - (default on windows and mac)
@@ -274,6 +282,16 @@ Rectangle {
anchors.rightMargin: 50
}
+ WizardCreateViewOnlyWallet {
+ id: createViewOnlyWalletPage
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.right: nextButton.left
+ anchors.left: prevButton.right
+ anchors.leftMargin: 50
+ anchors.rightMargin: 50
+ }
+
WizardRecoveryWallet {
id: recoveryWalletPage
anchors.top: parent.top
@@ -356,4 +374,59 @@ Rectangle {
wizard.useMoneroClicked();
}
}
+
+ StandardButton {
+ id: createViewOnlyWalletButton
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.margins: 50
+ width: 110
+ text: qsTr("Create wallet") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ visible: currentPath === "create_view_only_wallet" && parent.paths[currentPath][currentPage] === passwordPage
+ enabled: passwordPage.passwordsMatch
+ onClicked: {
+ if (currentWallet.createViewOnly(settings['view_only_wallet_path'],passwordPage.password)) {
+ console.log("view only wallet created in ",settings['view_only_wallet_path']);
+ informationPopup.title = qsTr("Success") + translationManager.emptyString;
+ informationPopup.text = qsTr('The view only wallet has been created. You can open it by closing this current wallet, clicking the "Open wallet from file" option, and selecting the view wallet in: \n%1')
+ .arg(settings['view_only_wallet_path']);
+ informationPopup.open()
+ informationPopup.onCloseCallback = null
+ rootItem.state = "normal"
+ wizard.restart();
+
+ } else {
+ informationPopup.title = qsTr("Error") + translationManager.emptyString;
+ informationPopup.text = currentWallet.errorString;
+ informationPopup.open()
+ }
+
+ }
+ }
+
+ StandardButton {
+ id: abortViewOnlyButton
+ anchors.right: createViewOnlyWalletButton.left
+ anchors.bottom: parent.bottom
+ anchors.margins: 50
+ width: 110
+ text: qsTr("Abort") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ visible: currentPath === "create_view_only_wallet" && parent.paths[currentPath][currentPage] === passwordPage
+ onClicked: {
+ wizard.restart();
+ rootItem.state = "normal"
+ }
+ }
+
+
+
+
}
diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml
index 4420de2d..d3bfb558 100644
--- a/wizard/WizardManageWalletUI.qml
+++ b/wizard/WizardManageWalletUI.qml
@@ -43,7 +43,8 @@ Item {
property alias wordsTextItem : memoTextItem
property alias restoreHeight : restoreHeightItem.text
property alias restoreHeightVisible: restoreHeightItem.visible
-
+ property alias walletName : accountName.text
+ property alias progressDotsModel : progressDots.model
// TODO extend properties if needed
@@ -64,6 +65,7 @@ Item {
}
Repeater {
+ id: progressDots
model: dotsModel
delegate: Rectangle {
width: 12; height: 12
@@ -184,7 +186,7 @@ Item {
Row {
anchors.left: parent.left
anchors.right: parent.right
- anchors.top: (restoreHeightItem.visible)? restoreHeightItem.bottom : memoTextItem.bottom
+ anchors.top: (restoreHeightItem.visible)? restoreHeightItem.bottom : (memoTextItem.visible)? memoTextItem.bottom : frameHeader.bottom
anchors.topMargin: 24
spacing: 16
diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml
index c26a7407..adba7a94 100644
--- a/wizard/WizardPassword.qml
+++ b/wizard/WizardPassword.qml
@@ -36,8 +36,9 @@ Item {
id: passwordPage
opacity: 0
visible: false
-
property alias titleText: titleText.text
+ property alias passwordsMatch: passwordUI.passwordsMatch
+ property alias password: passwordUI.password
Behavior on opacity {
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
}
@@ -47,7 +48,7 @@ Item {
function onPageOpened(settingsObject) {
wizard.nextButton.enabled = true
- handlePassword();
+ passwordUI.handlePassword();
if (wizard.currentPath === "create_wallet") {
passwordPage.titleText = qsTr("Give your wallet a password") + translationManager.emptyString
@@ -55,44 +56,22 @@ Item {
passwordPage.titleText = qsTr("Give your wallet a password") + translationManager.emptyString
}
- passwordItem.focus = true;
+ passwordUI.focus = true;
}
function onPageClosed(settingsObject) {
// TODO: set password on the final page
// settingsObject.wallet.setPassword(passwordItem.password)
- settingsObject['wallet_password'] = passwordItem.password
+ settingsObject['wallet_password'] = passwordUI.password
return true
}
function onWizardRestarted(){
// Reset password fields
- passwordItem.password = "";
- retypePasswordItem.password = "";
- }
-
- function handlePassword() {
- // allow to forward step only if passwords match
-
- wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
-
- // scorePassword returns value from 0 to... lots
- var strength = walletManager.getPasswordStrength(passwordItem.password);
- // consider anything below 10 bits as dire
- strength -= 10
- if (strength < 0)
- strength = 0
- // use a slight parabola to discourage short passwords
- strength = strength ^ 1.2 / 3
- // mapScope does not clamp
- if (strength > 100)
- strength = 100
- // privacyLevel component uses 1..13 scale
- privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
+ passwordUI.password = "";
+ passwordUI.confirmPassword = "";
}
-
-
Row {
id: dotsRow
anchors.top: parent.top
@@ -111,6 +90,9 @@ Item {
Repeater {
model: dotsModel
delegate: Rectangle {
+ // Password page is last page when creating view only wallet
+ // TODO: make this dynamic for all pages in wizard
+ visible: (wizard.currentPath != "create_view_only_wallet" || index < 2)
width: 12; height: 12
radius: 6
color: dotColor
@@ -157,39 +139,12 @@ Item {
}
- WizardPasswordInput {
- id: passwordItem
- anchors.top: headerColumn.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 24
- width: 300
- height: 62
- placeholderText : qsTr("Password") + translationManager.emptyString;
- KeyNavigation.tab: retypePasswordItem
- onChanged: handlePassword()
-
- }
-
- WizardPasswordInput {
- id: retypePasswordItem
- anchors.top: passwordItem.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 24
- width: 300
- height: 62
- placeholderText : qsTr("Confirm password") + translationManager.emptyString;
- KeyNavigation.tab: passwordItem
- onChanged: handlePassword()
- }
-
- PrivacyLevelSmall {
- id: privacyLevel
- anchors.left: parent.left
+ WizardPasswordUI {
+ id: passwordUI
anchors.right: parent.right
- anchors.top: retypePasswordItem.bottom
- anchors.topMargin: 60
- background: "#F0EEEE"
- interactive: false
+ anchors.left: parent.left
+ anchors.top: headerColumn.bottom
+ anchors.topMargin: 30
}
Component.onCompleted: {
diff --git a/wizard/WizardPasswordUI.qml b/wizard/WizardPasswordUI.qml
new file mode 100644
index 00000000..c9a4b0c8
--- /dev/null
+++ b/wizard/WizardPasswordUI.qml
@@ -0,0 +1,96 @@
+// Copyright (c) 2014-2015, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import moneroComponents.WalletManager 1.0
+import QtQuick 2.2
+import "../components"
+import "utils.js" as Utils
+
+FocusScope {
+ property alias password: passwordItem.password
+ property alias confirmPassword: retypePasswordItem.password
+ property bool passwordsMatch: passwordItem.password === retypePasswordItem.password
+
+ function handlePassword() {
+ // allow to forward step only if passwords match
+
+ wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
+
+ // scorePassword returns value from 0 to... lots
+ var strength = walletManager.getPasswordStrength(passwordItem.password);
+ // consider anything below 10 bits as dire
+ strength -= 10
+ if (strength < 0)
+ strength = 0
+ // use a slight parabola to discourage short passwords
+ strength = strength ^ 1.2 / 3
+ // mapScope does not clamp
+ if (strength > 100)
+ strength = 100
+ // privacyLevel component uses 1..13 scale
+ privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
+ }
+
+ WizardPasswordInput {
+ id: passwordItem
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 24
+ width: 300
+ height: 62
+ placeholderText : qsTr("Password") + translationManager.emptyString;
+ KeyNavigation.tab: retypePasswordItem
+ onChanged: handlePassword()
+ focus: true
+ }
+
+ WizardPasswordInput {
+ id: retypePasswordItem
+ anchors.top: passwordItem.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 24
+ width: 300
+ height: 62
+ placeholderText : qsTr("Confirm password") + translationManager.emptyString;
+ KeyNavigation.tab: passwordItem
+ onChanged: handlePassword()
+ }
+
+ PrivacyLevelSmall {
+ id: privacyLevel
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: retypePasswordItem.bottom
+ anchors.topMargin: 60
+ background: "#F0EEEE"
+ interactive: false
+ }
+
+ Component.onCompleted: {
+ //parent.wizardRestarted.connect(onWizardRestarted)
+ }
+}
diff --git a/wizard/utils.js b/wizard/utils.js
index 7b9fc241..65409046 100644
--- a/wizard/utils.js
+++ b/wizard/utils.js
@@ -15,3 +15,10 @@ function tr(text) {
function lineBreaksToSpaces(text) {
return text.trim().replace(/(\r\n|\n|\r)/gm, " ");
}
+
+function usefulName(path) {
+ // arbitrary "short enough" limit
+ if (path.length < 32)
+ return path
+ return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
+}