diff --git a/src/BlockchainBackend.cpp b/src/BlockchainBackend.cpp index 342df00..c0ffa05 100644 --- a/src/BlockchainBackend.cpp +++ b/src/BlockchainBackend.cpp @@ -147,6 +147,15 @@ BlockchainBackend::~BlockchainBackend() stopBlockchain(); } +QString BlockchainBackend::claimLeaderRewards() +{ + if (!m_blockchainClient) + return QStringLiteral("Error: Module not initialized."); + + return toDisplayMessage(toLogosResult(m_blockchainClient->invokeRemoteMethod( + BLOCKCHAIN_MODULE_NAME, "leader_claim"))); +} + void BlockchainBackend::startBlockchain() { if (!m_blockchainClient) { diff --git a/src/BlockchainBackend.h b/src/BlockchainBackend.h index e10be38..5e9d0e3 100644 --- a/src/BlockchainBackend.h +++ b/src/BlockchainBackend.h @@ -43,6 +43,7 @@ public slots: void refreshAccounts() override; QString getBalance(QString addressHex) override; QString transferFunds(QString fromKeyHex, QString toKeyHex, QString amountStr) override; + QString claimLeaderRewards() override; int generateConfig(QString outputPath, QStringList initialPeers, int netPort, int blendPort, QString httpAddr, QString externalAddress, bool noPublicIpCheck, int deploymentMode, diff --git a/src/BlockchainBackend.rep b/src/BlockchainBackend.rep index 8184c5c..b75e191 100644 --- a/src/BlockchainBackend.rep +++ b/src/BlockchainBackend.rep @@ -14,6 +14,7 @@ class BlockchainBackend SLOT(void refreshAccounts()) SLOT(QString getBalance(QString addressHex)) SLOT(QString transferFunds(QString fromKeyHex, QString toKeyHex, QString amountStr)) + SLOT(QString claimLeaderRewards()) SLOT(int generateConfig(QString outputPath, QStringList initialPeers, int netPort, int blendPort, QString httpAddr, QString externalAddress, bool noPublicIpCheck, int deploymentMode, QString deploymentConfigPath, QString statePath)) SLOT(void clearLogs()) SLOT(void copyToClipboard(QString text)) diff --git a/src/qml/BlockchainView.qml b/src/qml/BlockchainView.qml index a6ff565..bd4832d 100644 --- a/src/qml/BlockchainView.qml +++ b/src/qml/BlockchainView.qml @@ -217,6 +217,14 @@ Rectangle { function(error) { walletView.setTransferResult("Error: " + error) } ) } + onClaimLeaderRewardsRequested: function() { + if (!root.backend) return + logos.watch( + root.backend.claimLeaderRewards(), + function(result) { walletView.setLeaderClaimResult(result) }, + function(error) { walletView.setLeaderClaimResult("Error: " + error) } + ) + } } Item { diff --git a/src/qml/views/WalletView.qml b/src/qml/views/WalletView.qml index a722a46..8fe2164 100644 --- a/src/qml/views/WalletView.qml +++ b/src/qml/views/WalletView.qml @@ -17,18 +17,23 @@ RowLayout { signal getBalanceRequested(string addressHex) signal transferRequested(string fromKeyHex, string toKeyHex, string amount) + signal claimLeaderRewardsRequested() signal copyToClipboard(string text) function setTransferResult(text) { transferResultText.text = text } + function setLeaderClaimResult(text) { + leaderClaimResultText.text = text + } + spacing: Theme.spacing.medium // Get balance card Rectangle { Layout.fillWidth: true - implicitHeight: transferRect.height + implicitHeight: actionsCol.height Layout.preferredHeight: Math.min(implicitHeight, 400) color: Theme.palette.backgroundTertiary radius: Theme.spacing.radiusLarge @@ -75,84 +80,156 @@ RowLayout { } } - // Transfer funds card - Rectangle { - id: transferRect + ColumnLayout { + id: actionsCol + Layout.fillWidth: true - Layout.preferredHeight: transferCol.height + 2 * Theme.spacing.large - color: Theme.palette.backgroundTertiary - radius: Theme.spacing.radiusLarge - border.color: Theme.palette.border - border.width: 1 + spacing: Theme.spacing.large - ColumnLayout { - id: transferCol - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacing.large - spacing: Theme.spacing.small + // Transfer funds card + Rectangle { + id: transferRect - LogosText { - text: qsTr("Transfer funds") - font.pixelSize: Theme.typography.secondaryText - font.bold: true - } + Layout.fillWidth: true + Layout.preferredHeight: transferCol.height + 2 * Theme.spacing.large + color: Theme.palette.backgroundTertiary + radius: Theme.spacing.radiusLarge + border.color: Theme.palette.border + border.width: 1 - StyledAddressComboBox { - id: transferFromCombo - model: root.accountsModel - textRole: "address" - } + ColumnLayout { + id: transferCol + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Theme.spacing.large + spacing: Theme.spacing.small - LogosTextField { - id: transferToField - Layout.fillWidth: true - Layout.preferredHeight: 30 - placeholderText: qsTr("To key (64 hex chars)") - } - - LogosTextField { - id: transferAmountField - Layout.fillWidth: true - Layout.preferredHeight: 30 - placeholderText: qsTr("Amount") - } - - RowLayout { - Layout.fillWidth: true - Layout.preferredHeight: transferButton.implicitHeight - - LogosButton { - id: transferButton - Layout.preferredWidth: 60 - Layout.alignment: Qt.AlignRight - text: qsTr("Send") - onClicked: root.transferRequested(transferFromCombo.currentText.trim(), transferToField.text.trim(), transferAmountField.text) + LogosText { + text: qsTr("Transfer funds") + font.pixelSize: Theme.typography.secondaryText + font.bold: true } - LogosButton { + StyledAddressComboBox { + id: transferFromCombo + model: root.accountsModel + textRole: "address" + } + + LogosTextField { + id: transferToField Layout.fillWidth: true - enabled: true - padding: Theme.spacing.small - contentItem: RowLayout { - width: parent.width - anchors.centerIn: parent - LogosText { - id: transferResultText - Layout.fillWidth: true - color: Theme.palette.textSecondary - font.pixelSize: Theme.typography.secondaryText - font.weight: Theme.typography.weightMedium - wrapMode: Text.WordWrap - elide: Text.ElideRight + Layout.preferredHeight: 30 + placeholderText: qsTr("To key (64 hex chars)") + } + + LogosTextField { + id: transferAmountField + Layout.fillWidth: true + Layout.preferredHeight: 30 + placeholderText: qsTr("Amount") + } + + RowLayout { + Layout.fillWidth: true + Layout.preferredHeight: transferButton.implicitHeight + + LogosButton { + id: transferButton + Layout.preferredWidth: 60 + Layout.alignment: Qt.AlignRight + text: qsTr("Send") + onClicked: root.transferRequested(transferFromCombo.currentText.trim(), transferToField.text.trim(), transferAmountField.text) + } + + LogosButton { + Layout.fillWidth: true + enabled: true + padding: Theme.spacing.small + contentItem: RowLayout { + width: parent.width + anchors.centerIn: parent + LogosText { + id: transferResultText + Layout.fillWidth: true + color: Theme.palette.textSecondary + font.pixelSize: Theme.typography.secondaryText + font.weight: Theme.typography.weightMedium + wrapMode: Text.WordWrap + elide: Text.ElideRight + } + LogosCopyButton { + Layout.alignment: Qt.AlignRight + Layout.preferredHeight: 40 + Layout.preferredWidth: 40 + onCopyText: root.copyToClipboard(transferResultText.text) + visible: transferResultText.text + } } - LogosCopyButton { - Layout.alignment: Qt.AlignRight - Layout.preferredHeight: 40 - Layout.preferredWidth: 40 - onCopyText: root.copyRequested(transferResultText.text) - visible: transferResultText.text + } + } + } + } + + // Leader rewards card + Rectangle { + id: leaderRewardsRect + + Layout.fillWidth: true + Layout.preferredHeight: leaderRewardsCol.height + 2 * Theme.spacing.large + color: Theme.palette.backgroundTertiary + radius: Theme.spacing.radiusLarge + border.color: Theme.palette.border + border.width: 1 + + ColumnLayout { + id: leaderRewardsCol + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Theme.spacing.large + spacing: Theme.spacing.small + + LogosText { + text: qsTr("Leader rewards") + font.pixelSize: Theme.typography.secondaryText + font.bold: true + } + + RowLayout { + Layout.fillWidth: true + + LogosButton { + id: leaderClaimButton + Layout.preferredWidth: 140 + text: qsTr("Claim") + onClicked: root.claimLeaderRewardsRequested() + } + + LogosButton { + Layout.fillWidth: true + enabled: true + padding: Theme.spacing.small + contentItem: RowLayout { + width: parent.width + anchors.centerIn: parent + LogosText { + id: leaderClaimResultText + Layout.fillWidth: true + color: Theme.palette.textSecondary + font.pixelSize: Theme.typography.secondaryText + font.weight: Theme.typography.weightMedium + wrapMode: Text.WordWrap + elide: Text.ElideRight + } + LogosCopyButton { + Layout.alignment: Qt.AlignRight + Layout.preferredHeight: 40 + Layout.preferredWidth: 40 + onCopyText: root.copyToClipboard(leaderClaimResultText.text) + visible: leaderClaimResultText.text + } } } }