From 4d7bf2f9752c9d651daadfefa4c619702befada2 Mon Sep 17 00:00:00 2001 From: Johan Ouwerkerk Date: Wed, 9 Oct 2019 21:34:32 +0200 Subject: [PATCH] Add a rudimentary details page for accounts and wire up navigation to/from it. The account details page has a kind of modality: - hide mode: in which the user is shown the account info but sensitive information such as secret keys should not be displayed openly visible. - show mode: the same, but in this case all details are openly visible. This will be useful for showing QR codes explicitly. - edit mode: in which the user may edit account details (all except the name). --- src/contents/ui/AccountDetailsPage.qml | 86 ++++++++++++++++++++++++++++++++++ src/contents/ui/main.qml | 51 ++++++++++++++++++++ src/resources.qrc | 1 + 3 files changed, 138 insertions(+) create mode 100644 src/contents/ui/AccountDetailsPage.qml diff --git a/src/contents/ui/AccountDetailsPage.qml b/src/contents/ui/AccountDetailsPage.qml new file mode 100644 index 0000000..63d8189 --- /dev/null +++ b/src/contents/ui/AccountDetailsPage.qml @@ -0,0 +1,86 @@ +/* + * Copyright 2019 Johan Ouwerkerk + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of + * the License or any later version accepted by the membership of + * KDE e.V. (or its successor approved by the membership of KDE + * e.V.), which shall act as a proxy defined in Section 14 of + * version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +import Oath 1.0 +import Oath.Validators 1.0 as Validators +import QtQuick 2.1 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.0 as Controls +import org.kde.kirigami 2.4 as Kirigami + +Kirigami.Page { + id: root + + property Account account + property int accountIndex; + + signal accountUpdate(Account account, int index) + signal tokenRefresh(Account account, int index) + + property bool editMode: false + property bool hideSensitive: true + + Kirigami.Action { + id: leftAction + text: root.hideSensitive ? "Show" : "Hide" + iconName: root.hideSensitive ? "view-visible" : "view-hidden" + onTriggered: { + root.hideSensitive = !root.hideSensitive; + root.editMode = false; + } + } + + Kirigami.Action { + id: rightAction + text: "Generate token" + iconName: "view-refresh" + onTriggered: { + root.tokenRefresh(account, accountIndex) + } + } + + Kirigami.Action { + id: mainAction + text: root.editMode ? "Apply" : "Edit" + iconName: root.editMode ? "document-save" : "document-edit" + onTriggered: { + var fromEditor = root.editMode; + root.editMode = !fromEditor; + if (fromEditor) { + accountUpdate(root.account, root.accountIndex); + } + } + } + + actions.main: mainAction + actions.left: editMode ? null : leftAction + actions.right: editMode ? null : rightAction + title: account ? account.name : "Account Details" + + ColumnLayout { + id: layout + TokenDetailsForm { + id: tokenDetails + account: root.account + editable: editMode + } + } +} diff --git a/src/contents/ui/main.qml b/src/contents/ui/main.qml index f10f53f..e857be1 100644 --- a/src/contents/ui/main.qml +++ b/src/contents/ui/main.qml @@ -63,6 +63,21 @@ Kirigami.ApplicationWindow { id: view model: accounts delegate: Kirigami.AbstractCard { + onClicked: { + /* + * `model` is some kind of wrapper item that exposes + * bound properties but is not a *real* account. + * + * Retrieve the actual underlying account by its index + */ + var actualAccount = accounts.get(index); + pageStack.push(accountDetailsPageComponent, { + account: actualAccount, + accountIndex: index, + editMode: false, + hideSensitive: true + }); + } contentItem: Item { implicitWidth: delegateLayout.implicitWidth implicitHeight: delegateLayout.implicitHeight @@ -144,7 +159,16 @@ Kirigami.ApplicationWindow { text: "Add" iconName: "answer-correct" onTriggered: { + /* + * Nota Bene: order is significant. + * Accounts are being appended in order of creation, + * meaning the account index for the newly created + * account is equal to the size of the list as it was + * before createAccount() (which will add the new entry). + */ + var newAccountIndex = accounts.rowCount(); var newAccount = accounts.createAccount(); + newAccount.name = accountName.text; newAccount.type = tokenDetails.type newAccount.secret = tokenDetails.secret @@ -165,6 +189,17 @@ Kirigami.ApplicationWindow { if (pageStack.depth < 1) { pageStack.push(mainPageComponent); } + + /* + * Auto navigate to the details page for the newly + * created account + */ + pageStack.push(accountDetailsPageComponent, { + account: newAccount, + accountIndex: newAccountIndex, + editMode: false, + hideSensitive: true + }); } } @@ -190,4 +225,20 @@ Kirigami.ApplicationWindow { } } } + + Component { + id: accountDetailsPageComponent + AccountDetailsPage { + onTokenRefresh: { + accounts.generateNext(index); + } + onAccountUpdate: { + /* + * This is a NOP for now because account edits are instant + * apply, possibly by accident of implementation rather + * than by design. I.e. there is nothing to do here, yet. + */ + } + } + } } diff --git a/src/resources.qrc b/src/resources.qrc index d863868..f82cef8 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -2,5 +2,6 @@ contents/ui/main.qml contents/ui/TokenDetailsForm.qml + contents/ui/AccountDetailsPage.qml