Browse Source

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.
master
ThomasV 3 years ago
parent
commit
c98b9e8d7b
  1. 227
      electrum/gui/qml/components/BalanceDetails.qml
  2. 54
      electrum/gui/qml/components/Channels.qml
  3. 88
      electrum/gui/qml/components/WalletDetails.qml
  4. 35
      electrum/gui/qml/components/controls/BalanceSummary.qml

227
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()
}
}

54
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 { Component {
id: importChannelBackupDialog id: importChannelBackupDialog

88
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 { GridLayout {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
visible: Daemon.currentWallet visible: Daemon.currentWallet
@ -591,9 +506,6 @@ Pane {
}) })
dialog.open() dialog.open()
} }
function onBalanceChanged() {
piechart.updateSlices()
}
function onSeedRetrieved() { function onSeedRetrieved() {
seedText.visible = true seedText.visible = true
showSeedText.visible = false showSeedText.visible = false

35
electrum/gui/qml/components/controls/BalanceSummary.qml

@ -23,17 +23,6 @@ Item {
} }
} }
state: 'fiat'
states: [
State {
name: 'fiat'
},
State {
name: 'btc'
}
]
TextHighlightPane { TextHighlightPane {
id: balancePane id: balancePane
leftPadding: constants.paddingXLarge leftPadding: constants.paddingXLarge
@ -63,28 +52,28 @@ Item {
} }
Item { Item {
visible: Daemon.fx.enabled && root.state == 'fiat' visible: Daemon.fx.enabled
// attempt at making fiat state as tall as btc state: // attempt at making fiat state as tall as btc state:
Layout.preferredHeight: fontMetrics.lineSpacing * 2 + balanceLayout.rowSpacing + 2 Layout.preferredHeight: fontMetrics.lineSpacing * 2 + balanceLayout.rowSpacing + 2
Layout.preferredWidth: 1 Layout.preferredWidth: 1
} }
Label { Label {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
visible: Daemon.fx.enabled && root.state == 'fiat' visible: Daemon.fx.enabled
font.pixelSize: constants.fontSizeLarge font.pixelSize: constants.fontSizeLarge
font.family: FixedFont font.family: FixedFont
color: constants.mutedForeground color: constants.mutedForeground
text: formattedTotalBalanceFiat text: formattedTotalBalanceFiat
} }
Label { Label {
visible: Daemon.fx.enabled && root.state == 'fiat' visible: Daemon.fx.enabled
font.pixelSize: constants.fontSizeLarge font.pixelSize: constants.fontSizeLarge
color: constants.mutedForeground color: constants.mutedForeground
text: Daemon.fx.fiatCurrency text: Daemon.fx.fiatCurrency
} }
RowLayout { RowLayout {
visible: Daemon.currentWallet.isLightning && root.state == 'btc' visible: Daemon.currentWallet.isLightning
Image { Image {
Layout.preferredWidth: constants.iconSizeSmall Layout.preferredWidth: constants.iconSizeSmall
Layout.preferredHeight: constants.iconSizeSmall Layout.preferredHeight: constants.iconSizeSmall
@ -97,20 +86,20 @@ Item {
} }
} }
Label { Label {
visible: Daemon.currentWallet.isLightning && root.state == 'btc' visible: Daemon.currentWallet.isLightning
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
text: formattedLightningBalance text: formattedLightningBalance
font.family: FixedFont font.family: FixedFont
} }
Label { Label {
visible: Daemon.currentWallet.isLightning && root.state == 'btc' visible: Daemon.currentWallet.isLightning
font.pixelSize: constants.fontSizeSmall font.pixelSize: constants.fontSizeSmall
color: Material.accentColor color: Material.accentColor
text: Config.baseUnit text: Config.baseUnit
} }
RowLayout { RowLayout {
visible: root.state == 'btc' visible: Daemon.currentWallet.isLightning
Image { Image {
Layout.preferredWidth: constants.iconSizeSmall Layout.preferredWidth: constants.iconSizeSmall
Layout.preferredHeight: constants.iconSizeSmall Layout.preferredHeight: constants.iconSizeSmall
@ -124,13 +113,13 @@ Item {
} }
Label { Label {
id: formattedConfirmedBalanceLabel id: formattedConfirmedBalanceLabel
visible: root.state == 'btc' visible: Daemon.currentWallet.isLightning
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
text: formattedConfirmedBalance text: formattedConfirmedBalance
font.family: FixedFont font.family: FixedFont
} }
Label { Label {
visible: root.state == 'btc' visible: Daemon.currentWallet.isLightning
font.pixelSize: constants.fontSizeSmall font.pixelSize: constants.fontSizeSmall
color: Material.accentColor color: Material.accentColor
text: Config.baseUnit text: Config.baseUnit
@ -157,8 +146,8 @@ Item {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onPressAndHold: {
root.state = root.state == 'fiat' && Daemon.currentWallet.isLightning ? 'btc' : 'fiat' app.stack.push(Qt.resolvedUrl('../BalanceDetails.qml'))
} }
} }
@ -174,8 +163,6 @@ Item {
target: Daemon target: Daemon
function onWalletLoaded() { function onWalletLoaded() {
setBalances() setBalances()
if (!Daemon.currentWallet.isLightning)
root.state = 'fiat'
} }
} }

Loading…
Cancel
Save