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).master
parent
c64273355a
commit
4d7bf2f975
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,6 +63,21 @@ Kirigami.ApplicationWindow {
|
||||||
id: view
|
id: view
|
||||||
model: accounts
|
model: accounts
|
||||||
delegate: Kirigami.AbstractCard {
|
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 {
|
contentItem: Item {
|
||||||
implicitWidth: delegateLayout.implicitWidth
|
implicitWidth: delegateLayout.implicitWidth
|
||||||
implicitHeight: delegateLayout.implicitHeight
|
implicitHeight: delegateLayout.implicitHeight
|
||||||
|
@ -144,7 +159,16 @@ Kirigami.ApplicationWindow {
|
||||||
text: "Add"
|
text: "Add"
|
||||||
iconName: "answer-correct"
|
iconName: "answer-correct"
|
||||||
onTriggered: {
|
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();
|
var newAccount = accounts.createAccount();
|
||||||
|
|
||||||
newAccount.name = accountName.text;
|
newAccount.name = accountName.text;
|
||||||
newAccount.type = tokenDetails.type
|
newAccount.type = tokenDetails.type
|
||||||
newAccount.secret = tokenDetails.secret
|
newAccount.secret = tokenDetails.secret
|
||||||
|
@ -165,6 +189,17 @@ Kirigami.ApplicationWindow {
|
||||||
if (pageStack.depth < 1) {
|
if (pageStack.depth < 1) {
|
||||||
pageStack.push(mainPageComponent);
|
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.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file alias="main.qml">contents/ui/main.qml</file>
|
<file alias="main.qml">contents/ui/main.qml</file>
|
||||||
<file alias="TokenDetailsForm.qml">contents/ui/TokenDetailsForm.qml</file>
|
<file alias="TokenDetailsForm.qml">contents/ui/TokenDetailsForm.qml</file>
|
||||||
|
<file alias="AccountDetailsPage.qml">contents/ui/AccountDetailsPage.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
Loading…
Reference in New Issue