Warning, /utilities/keysmith/src/contents/ui/AccountsOverview.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2020-2021 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0004 * SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com> 0005 */ 0006 0007 import QtQuick 0008 import QtQuick.Layouts 0009 import org.kde.kirigami as Kirigami 0010 0011 import Keysmith.Application as Application 0012 import Keysmith.Models as Models 0013 0014 Kirigami.ScrollablePage { 0015 id: root 0016 /* 0017 * Explicitly opt-out of scroll-to-refresh/drag-to-refresh behaviour 0018 * Underlying model implementations don't offer the hooks for that. 0019 */ 0020 supportsRefreshing: false 0021 title: i18nc("@title:window", "Accounts") 0022 0023 property Application.AccountsOverviewViewModel vm 0024 0025 property string accountErrorMessage: i18nc("generic error shown when adding or updating an account failed", "Failed to update accounts") 0026 property string loadingErrorMessage: i18nc("error message shown when loading accounts from storage failed", "Some accounts failed to load.") 0027 property string errorMessage: loadingErrorMessage 0028 0029 header: ColumnLayout { 0030 id: column 0031 Layout.margins: 0 0032 spacing: 0 0033 Kirigami.InlineMessage { 0034 id: message 0035 visible: vm.accounts.error // FIXME : should be managed via vm 0036 type: Kirigami.MessageType.Error 0037 text: root.errorMessage // FIXME : should be managed via vm 0038 Layout.fillWidth: true 0039 Layout.margins: Kirigami.Units.smallSpacing 0040 /* 0041 * There is supposed to be a more Kirigami-way to allow the user to dismiss the error message: showCloseButton 0042 * Unfortunately: 0043 * 0044 * - Kirigami doesn't really offer a direct API for detecting when the close button is clicked. 0045 * Observing the close button's effect via the visible property works just as well, but it is a bit of a hack. 0046 * - It results in a rather unattractive vertical sizing problem: the close button is rather big for inline text 0047 * This makes the internal horizontal spacing look completely out of proportion with the vertical spacing. 0048 * - The actual click/tap target is only a small fraction of the entire message (banner). 0049 * In this case, making the entire message click/tap target would be much better. 0050 * 0051 * Solution: add a MouseArea for dismissing the message via click/tap. 0052 */ 0053 MouseArea { 0054 anchors.fill: parent 0055 onClicked: { 0056 // FIXME : should be managed via vm 0057 vm.accounts.error = false; 0058 } 0059 } 0060 } 0061 Kirigami.Separator { 0062 Layout.fillWidth: true 0063 visible: vm.accounts.error // FIXME : should be managed via vm 0064 } 0065 } 0066 0067 Component { 0068 id: hotpDelegate 0069 HOTPAccountEntryView { 0070 account: value 0071 onActionTriggered: { 0072 // FIXME : should be managed via vm 0073 vm.accounts.error = false; 0074 root.errorMessage = root.accountErrorMessage; 0075 } 0076 } 0077 } 0078 0079 Component { 0080 id: totpDelegate 0081 TOTPAccountEntryView { 0082 account: value 0083 onActionTriggered: { 0084 // FIXME : should be managed via vm 0085 vm.accounts.error = false; 0086 root.errorMessage = root.accountErrorMessage; 0087 } 0088 } 0089 } 0090 0091 ListView { 0092 id: mainList 0093 model: Models.SortedAccountListModel { 0094 sourceModel: vm.accounts 0095 } 0096 0097 Kirigami.PlaceholderMessage { 0098 anchors.centerIn: parent 0099 width: parent.width - (Kirigami.Units.largeSpacing * 4) 0100 visible: vm.accounts.loaded && mainList.count == 0 0101 text: i18n("No accounts added") 0102 icon.name: "unlock" 0103 0104 helpfulAction: Kirigami.Action { 0105 icon.name: "list-add" 0106 text: i18nc("@action:button add new account, shown instead of overview list when no accounts have been added yet", "Add Account") 0107 onTriggered: { 0108 // FIXME : should be managed via vm 0109 vm.accounts.error = false; 0110 root.errorMessage = root.accountErrorMessage; 0111 vm.addNewAccount(); 0112 } 0113 } 0114 } 0115 0116 /* 0117 * Use a Loader to get a switch-like statement to select an 0118 * appropriate delegate based on properties of the account model. 0119 */ 0120 delegate: Loader { 0121 /* 0122 * Fix up width manually. 0123 * It doesn't seem to be propagated correctly by itself otherwise. 0124 */ 0125 width: mainList.width 0126 0127 /* 0128 * The `model` and related properties from the ListView delegate 0129 * context will not survive into the actual delegate components. 0130 * However Loader will also inject properties in *its* context 0131 * which will be observed by those delegate components. 0132 * 0133 * Fill the Loader's context with properties from the model passed 0134 * by ListView, to make these values propagate into delegates. 0135 * 0136 * See also: https://doc.qt.io/qt-5/qml-qtquick-loader.html#using-a-loader-within-a-view-delegate 0137 */ 0138 property Models.Account value: model.account 0139 property int index: model.index 0140 0141 sourceComponent: { 0142 /* 0143 * Guard against a broken account model. 0144 * Will simply render nothing at all in that case. 0145 */ 0146 if (!value) { 0147 // TODO warn about this 0148 return null; 0149 } 0150 if (value.isHotp) { 0151 return hotpDelegate; 0152 } 0153 if (value.isTotp) { 0154 return totpDelegate; 0155 } 0156 0157 // TODO warn about this 0158 return null; 0159 } 0160 } 0161 section { 0162 property: "account.issuer" 0163 delegate: Kirigami.ListSectionHeader { 0164 width: parent.width 0165 text: section 0166 } 0167 } 0168 } 0169 0170 actions: Kirigami.Action { 0171 id: addAction 0172 text: i18nc("@action:button add new account, shown in toolbar", "Add") 0173 icon.name: "list-add" 0174 enabled: vm.actionsEnabled 0175 visible: vm.actionsEnabled 0176 onTriggered: { 0177 // FIXME : should be managed via vm 0178 vm.accounts.error = false; 0179 root.errorMessage = root.accountErrorMessage; 0180 vm.addNewAccount(); 0181 } 0182 } 0183 }