From c98b9e8d7b58002c8d45799293fbbd394ae31de3 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Fri, 31 Mar 2023 15:39:54 +0200 Subject: [PATCH] qml: dashboard Balance details are shown if the user presses and holds the balance area; the idea is that this should be less chaotic than if the popup is triggerred by a simple click. However, we might as well try with a simple click, because we already do it with transaction details; I am not sure what is the best option, we should try both. This also makes 'new channel' and 'swap' buttons available from theBalance details, so that users do not need to visit the channels list. --- .../gui/qml/components/BalanceDetails.qml | 227 ++++++++++++++++++ electrum/gui/qml/components/Channels.qml | 54 ----- electrum/gui/qml/components/WalletDetails.qml | 88 ------- .../components/controls/BalanceSummary.qml | 35 +-- 4 files changed, 238 insertions(+), 166 deletions(-) create mode 100644 electrum/gui/qml/components/BalanceDetails.qml diff --git a/electrum/gui/qml/components/BalanceDetails.qml b/electrum/gui/qml/components/BalanceDetails.qml new file mode 100644 index 000000000..1500181db --- /dev/null +++ b/electrum/gui/qml/components/BalanceDetails.qml @@ -0,0 +1,227 @@ +import QtQuick 2.6 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.3 +import QtQuick.Controls.Material 2.0 + +import org.electrum 1.0 + +import "controls" + +Pane { + id: rootItem + objectName: 'BalanceDetails' + + padding: 0 + + property bool _is2fa: Daemon.currentWallet && Daemon.currentWallet.walletType == '2fa' + + function enableLightning() { + var dialog = app.messageDialog.createObject(rootItem, + {'text': qsTr('Enable Lightning for this wallet?'), 'yesno': true}) + dialog.yesClicked.connect(function() { + Daemon.currentWallet.enableLightning() + }) + dialog.open() + } + + function deleteWallet() { + var dialog = app.messageDialog.createObject(rootItem, + {'text': qsTr('Really delete this wallet?'), 'yesno': true}) + dialog.yesClicked.connect(function() { + Daemon.checkThenDeleteWallet(Daemon.currentWallet) + }) + dialog.open() + } + + function changePassword() { + // trigger dialog via wallet (auth then signal) + Daemon.startChangePassword() + } + + function importAddressesKeys() { + var dialog = importAddressesKeysDialog.createObject(rootItem) + dialog.open() + } + + ColumnLayout { + id: rootLayout + anchors.fill: parent + spacing: 0 + + Flickable { + Layout.fillWidth: true + Layout.fillHeight: true + + contentHeight: flickableRoot.height + clip:true + interactive: height < contentHeight + + Pane { + id: flickableRoot + width: parent.width + padding: constants.paddingLarge + + ColumnLayout { + width: parent.width + spacing: constants.paddingLarge + + Heading { + text: qsTr('Wallet balance') + } + + Piechart { + id: piechart + visible: Daemon.currentWallet.totalBalance.satsInt > 0 + Layout.preferredWidth: parent.width + implicitHeight: 220 // TODO: sane value dependent on screen + innerOffset: 6 + function updateSlices() { + var totalB = Daemon.currentWallet.totalBalance.satsInt + var onchainB = Daemon.currentWallet.confirmedBalance.satsInt + var frozenB = Daemon.currentWallet.frozenBalance.satsInt + var lnB = Daemon.currentWallet.lightningBalance.satsInt + piechart.slices = [ + { v: lnB/totalB, color: constants.colorPiechartLightning, text: 'Lightning' }, + { v: (onchainB-frozenB)/totalB, color: constants.colorPiechartOnchain, text: 'On-chain' }, + { v: frozenB/totalB, color: constants.colorPiechartFrozen, text: 'On-chain (frozen)' }, + ] + } + } + + GridLayout { + Layout.alignment: Qt.AlignHCenter + visible: Daemon.currentWallet + columns: 3 + + Item { + visible: !Daemon.currentWallet.totalBalance.isEmpty + Layout.preferredWidth: 1; Layout.preferredHeight: 1 + } + Label { + visible: !Daemon.currentWallet.totalBalance.isEmpty + text: qsTr('Total') + } + FormattedAmount { + visible: !Daemon.currentWallet.totalBalance.isEmpty + amount: Daemon.currentWallet.totalBalance + } + + Rectangle { + visible: !Daemon.currentWallet.lightningBalance.isEmpty + Layout.preferredWidth: constants.iconSizeXSmall + Layout.preferredHeight: constants.iconSizeXSmall + color: constants.colorPiechartLightning + } + Label { + visible: !Daemon.currentWallet.lightningBalance.isEmpty + text: qsTr('Lightning') + + } + FormattedAmount { + amount: Daemon.currentWallet.lightningBalance + visible: !Daemon.currentWallet.lightningBalance.isEmpty + } + + Rectangle { + visible: !Daemon.currentWallet.lightningBalance.isEmpty || !Daemon.currentWallet.frozenBalance.isEmpty + Layout.preferredWidth: constants.iconSizeXSmall + Layout.preferredHeight: constants.iconSizeXSmall + color: constants.colorPiechartOnchain + } + Label { + visible: !Daemon.currentWallet.lightningBalance.isEmpty || !Daemon.currentWallet.frozenBalance.isEmpty + text: qsTr('On-chain') + + } + FormattedAmount { + amount: Daemon.currentWallet.confirmedBalance + visible: !Daemon.currentWallet.lightningBalance.isEmpty || !Daemon.currentWallet.frozenBalance.isEmpty + } + + Rectangle { + visible: !Daemon.currentWallet.frozenBalance.isEmpty + Layout.preferredWidth: constants.iconSizeXSmall + Layout.preferredHeight: constants.iconSizeXSmall + color: constants.colorPiechartFrozen + } + Label { + visible: !Daemon.currentWallet.frozenBalance.isEmpty + text: qsTr('Frozen') + } + FormattedAmount { + amount: Daemon.currentWallet.frozenBalance + visible: !Daemon.currentWallet.frozenBalance.isEmpty + } + } + } + } + } + + ButtonContainer { + Layout.fillWidth: true + FlatButton { + Layout.fillWidth: true + Layout.preferredWidth: 1 + text: qsTr('Lightning swap'); + visible: Daemon.currentWallet.lightningCanSend.satsInt > 0 || Daemon.currentWallet.lightningCanReceive.satInt > 0 + icon.source: Qt.resolvedUrl('../../icons/update.png') + onClicked: { + var swaphelper = app.swaphelper.createObject(app) + swaphelper.swapStarted.connect(function() { + var dialog = swapProgressDialog.createObject(app, { swaphelper: swaphelper }) + dialog.open() + }) + var dialog = swapDialog.createObject(rootItem, { swaphelper: swaphelper }) + dialog.open() + } + } + + FlatButton { + Layout.fillWidth: true + Layout.preferredWidth: 1 + text: qsTr('Open Channel') + visible: Daemon.currentWallet.isLightning + onClicked: { + var dialog = openChannelDialog.createObject(rootItem) + dialog.open() + } + icon.source: '../../icons/lightning.png' + } + + } + + } + + Component { + id: swapDialog + SwapDialog { + onClosed: destroy() + } + } + + Component { + id: swapProgressDialog + SwapProgressDialog { + onClosed: destroy() + } + } + + Component { + id: openChannelDialog + OpenChannelDialog { + onClosed: destroy() + } + } + + Connections { + target: Daemon.currentWallet + function onBalanceChanged() { + piechart.updateSlices() + } + } + + Component.onCompleted: { + piechart.updateSlices() + } + +} diff --git a/electrum/gui/qml/components/Channels.qml b/electrum/gui/qml/components/Channels.qml index c75661bed..c186b7cf1 100644 --- a/electrum/gui/qml/components/Channels.qml +++ b/electrum/gui/qml/components/Channels.qml @@ -117,60 +117,6 @@ Pane { } } - ButtonContainer { - Layout.fillWidth: true - FlatButton { - Layout.fillWidth: true - Layout.preferredWidth: 1 - text: qsTr('Swap'); - visible: Daemon.currentWallet.lightningCanSend.satsInt > 0 || Daemon.currentWallet.lightningCanReceive.satInt > 0 - icon.source: Qt.resolvedUrl('../../icons/update.png') - onClicked: { - var swaphelper = app.swaphelper.createObject(app) - swaphelper.swapStarted.connect(function() { - var dialog = swapProgressDialog.createObject(app, { swaphelper: swaphelper }) - dialog.open() - }) - var dialog = swapDialog.createObject(root, { swaphelper: swaphelper }) - dialog.open() - } - } - - FlatButton { - Layout.fillWidth: true - Layout.preferredWidth: 1 - text: qsTr('Open Channel') - onClicked: { - var dialog = openChannelDialog.createObject(root) - dialog.open() - } - icon.source: '../../icons/lightning.png' - } - - } - - } - - Component { - id: swapDialog - SwapDialog { - onClosed: destroy() - } - } - - Component { - id: swapProgressDialog - SwapProgressDialog { - onClosed: destroy() - } - } - - Component { - id: openChannelDialog - OpenChannelDialog { - onClosed: destroy() - } - } Component { id: importChannelBackupDialog diff --git a/electrum/gui/qml/components/WalletDetails.qml b/electrum/gui/qml/components/WalletDetails.qml index 7e5f60c56..aa750fa35 100644 --- a/electrum/gui/qml/components/WalletDetails.qml +++ b/electrum/gui/qml/components/WalletDetails.qml @@ -135,91 +135,6 @@ Pane { } } - Piechart { - id: piechart - visible: Daemon.currentWallet.totalBalance.satsInt > 0 - Layout.preferredWidth: parent.width - implicitHeight: 220 // TODO: sane value dependent on screen - innerOffset: 6 - function updateSlices() { - var totalB = Daemon.currentWallet.totalBalance.satsInt - var onchainB = Daemon.currentWallet.confirmedBalance.satsInt - var frozenB = Daemon.currentWallet.frozenBalance.satsInt - var lnB = Daemon.currentWallet.lightningBalance.satsInt - piechart.slices = [ - { v: lnB/totalB, color: constants.colorPiechartLightning, text: 'Lightning' }, - { v: (onchainB-frozenB)/totalB, color: constants.colorPiechartOnchain, text: 'On-chain' }, - { v: frozenB/totalB, color: constants.colorPiechartFrozen, text: 'On-chain (frozen)' }, - ] - } - } - - GridLayout { - Layout.alignment: Qt.AlignHCenter - visible: Daemon.currentWallet - columns: 3 - - Item { - visible: !Daemon.currentWallet.totalBalance.isEmpty - Layout.preferredWidth: 1; Layout.preferredHeight: 1 - } - Label { - visible: !Daemon.currentWallet.totalBalance.isEmpty - text: qsTr('Total') - } - FormattedAmount { - visible: !Daemon.currentWallet.totalBalance.isEmpty - amount: Daemon.currentWallet.totalBalance - } - - Rectangle { - visible: !Daemon.currentWallet.lightningBalance.isEmpty - Layout.preferredWidth: constants.iconSizeXSmall - Layout.preferredHeight: constants.iconSizeXSmall - color: constants.colorPiechartLightning - } - Label { - visible: !Daemon.currentWallet.lightningBalance.isEmpty - text: qsTr('Lightning') - - } - FormattedAmount { - amount: Daemon.currentWallet.lightningBalance - visible: !Daemon.currentWallet.lightningBalance.isEmpty - } - - Rectangle { - visible: !Daemon.currentWallet.lightningBalance.isEmpty || !Daemon.currentWallet.frozenBalance.isEmpty - Layout.preferredWidth: constants.iconSizeXSmall - Layout.preferredHeight: constants.iconSizeXSmall - color: constants.colorPiechartOnchain - } - Label { - visible: !Daemon.currentWallet.lightningBalance.isEmpty || !Daemon.currentWallet.frozenBalance.isEmpty - text: qsTr('On-chain') - - } - FormattedAmount { - amount: Daemon.currentWallet.confirmedBalance - visible: !Daemon.currentWallet.lightningBalance.isEmpty || !Daemon.currentWallet.frozenBalance.isEmpty - } - - Rectangle { - visible: !Daemon.currentWallet.frozenBalance.isEmpty - Layout.preferredWidth: constants.iconSizeXSmall - Layout.preferredHeight: constants.iconSizeXSmall - color: constants.colorPiechartFrozen - } - Label { - visible: !Daemon.currentWallet.frozenBalance.isEmpty - text: qsTr('Frozen') - } - FormattedAmount { - amount: Daemon.currentWallet.frozenBalance - visible: !Daemon.currentWallet.frozenBalance.isEmpty - } - } - GridLayout { Layout.preferredWidth: parent.width visible: Daemon.currentWallet @@ -591,9 +506,6 @@ Pane { }) dialog.open() } - function onBalanceChanged() { - piechart.updateSlices() - } function onSeedRetrieved() { seedText.visible = true showSeedText.visible = false diff --git a/electrum/gui/qml/components/controls/BalanceSummary.qml b/electrum/gui/qml/components/controls/BalanceSummary.qml index 6c2571cb5..cb0d78b2d 100644 --- a/electrum/gui/qml/components/controls/BalanceSummary.qml +++ b/electrum/gui/qml/components/controls/BalanceSummary.qml @@ -23,17 +23,6 @@ Item { } } - state: 'fiat' - - states: [ - State { - name: 'fiat' - }, - State { - name: 'btc' - } - ] - TextHighlightPane { id: balancePane leftPadding: constants.paddingXLarge @@ -63,28 +52,28 @@ Item { } Item { - visible: Daemon.fx.enabled && root.state == 'fiat' + visible: Daemon.fx.enabled // attempt at making fiat state as tall as btc state: Layout.preferredHeight: fontMetrics.lineSpacing * 2 + balanceLayout.rowSpacing + 2 Layout.preferredWidth: 1 } Label { Layout.alignment: Qt.AlignRight - visible: Daemon.fx.enabled && root.state == 'fiat' + visible: Daemon.fx.enabled font.pixelSize: constants.fontSizeLarge font.family: FixedFont color: constants.mutedForeground text: formattedTotalBalanceFiat } Label { - visible: Daemon.fx.enabled && root.state == 'fiat' + visible: Daemon.fx.enabled font.pixelSize: constants.fontSizeLarge color: constants.mutedForeground text: Daemon.fx.fiatCurrency } RowLayout { - visible: Daemon.currentWallet.isLightning && root.state == 'btc' + visible: Daemon.currentWallet.isLightning Image { Layout.preferredWidth: constants.iconSizeSmall Layout.preferredHeight: constants.iconSizeSmall @@ -97,20 +86,20 @@ Item { } } Label { - visible: Daemon.currentWallet.isLightning && root.state == 'btc' + visible: Daemon.currentWallet.isLightning Layout.alignment: Qt.AlignRight text: formattedLightningBalance font.family: FixedFont } Label { - visible: Daemon.currentWallet.isLightning && root.state == 'btc' + visible: Daemon.currentWallet.isLightning font.pixelSize: constants.fontSizeSmall color: Material.accentColor text: Config.baseUnit } RowLayout { - visible: root.state == 'btc' + visible: Daemon.currentWallet.isLightning Image { Layout.preferredWidth: constants.iconSizeSmall Layout.preferredHeight: constants.iconSizeSmall @@ -124,13 +113,13 @@ Item { } Label { id: formattedConfirmedBalanceLabel - visible: root.state == 'btc' + visible: Daemon.currentWallet.isLightning Layout.alignment: Qt.AlignRight text: formattedConfirmedBalance font.family: FixedFont } Label { - visible: root.state == 'btc' + visible: Daemon.currentWallet.isLightning font.pixelSize: constants.fontSizeSmall color: Material.accentColor text: Config.baseUnit @@ -157,8 +146,8 @@ Item { MouseArea { anchors.fill: parent - onClicked: { - root.state = root.state == 'fiat' && Daemon.currentWallet.isLightning ? 'btc' : 'fiat' + onPressAndHold: { + app.stack.push(Qt.resolvedUrl('../BalanceDetails.qml')) } } @@ -174,8 +163,6 @@ Item { target: Daemon function onWalletLoaded() { setBalances() - if (!Daemon.currentWallet.isLightning) - root.state = 'fiat' } }