logos-blockchain-ui/src/qml/BlockchainView.qml

121 lines
4.7 KiB
QML
Raw Normal View History

2026-02-11 20:39:32 +01:00
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import QtCore
import BlockchainBackend
import Logos.Theme
2026-02-11 20:39:32 +01:00
2026-02-19 13:31:33 +01:00
import "views"
2026-02-11 20:39:32 +01:00
Rectangle {
id: root
QtObject {
id: _d
function getStatusString(status) {
switch(status) {
case BlockchainBackend.NotStarted: return qsTr("Not Started");
case BlockchainBackend.Starting: return qsTr("Starting...");
case BlockchainBackend.Running: return qsTr("Running");
case BlockchainBackend.Stopping: return qsTr("Stopping...");
case BlockchainBackend.Stopped: return qsTr("Stopped");
case BlockchainBackend.Error: return qsTr("Error");
case BlockchainBackend.ErrorNotInitialized: return qsTr("Error: Module not initialized");
case BlockchainBackend.ErrorConfigMissing: return qsTr("Error: Config path missing");
case BlockchainBackend.ErrorStartFailed: return qsTr("Error: Failed to start node");
case BlockchainBackend.ErrorStopFailed: return qsTr("Error: Failed to stop node");
case BlockchainBackend.ErrorSubscribeFailed: return qsTr("Error: Failed to subscribe to events");
default: return qsTr("Unknown");
}
}
function getStatusColor(status) {
switch(status) {
case BlockchainBackend.Running: return Theme.palette.success;
case BlockchainBackend.Starting: return Theme.palette.warning;
case BlockchainBackend.Stopping: return Theme.palette.warning;
case BlockchainBackend.NotStarted: return Theme.palette.error;
case BlockchainBackend.Stopped: return Theme.palette.error;
case BlockchainBackend.Error:
case BlockchainBackend.ErrorNotInitialized:
case BlockchainBackend.ErrorConfigMissing:
case BlockchainBackend.ErrorStartFailed:
case BlockchainBackend.ErrorStopFailed:
case BlockchainBackend.ErrorSubscribeFailed: return Theme.palette.error;
default: return Theme.palette.textSecondary;
}
}
}
color: Theme.palette.background
SplitView {
anchors.fill: parent
anchors.margins: Theme.spacing.large
orientation: Qt.Vertical
// Top: Status/Config + Wallet side-by-side
RowLayout {
SplitView.fillWidth: true
SplitView.minimumHeight: 200
StatusConfigView {
Layout.preferredWidth: parent.width / 2
statusText: _d.getStatusString(backend.status)
statusColor: _d.getStatusColor(backend.status)
userConfig: backend.userConfig
deploymentConfig: backend.deploymentConfig
canStart: !!backend.userConfig
2026-02-11 20:39:32 +01:00
&& backend.status !== BlockchainBackend.Starting
&& backend.status !== BlockchainBackend.Stopping
isRunning: backend.status === BlockchainBackend.Running
onStartRequested: backend.startBlockchain()
onStopRequested: backend.stopBlockchain()
onChangeUserConfigRequested: userConfigFileDialog.open()
onChangeDeploymentConfigRequested: deploymentConfigFileDialog.open()
2026-02-11 20:39:32 +01:00
}
WalletView {
id: walletView
Layout.preferredWidth: parent.width / 2
2026-02-17 21:22:38 +01:00
knownAddresses: backend.knownAddresses
2026-02-11 20:39:32 +01:00
onGetBalanceRequested: function(addressHex) {
walletView.setBalanceResult(backend.getBalance(addressHex))
}
onTransferRequested: function(fromKeyHex, toKeyHex, amount) {
walletView.setTransferResult(backend.transferFunds(fromKeyHex, toKeyHex, amount))
}
}
}
// Bottom: Logs
LogsView {
SplitView.fillWidth: true
SplitView.minimumHeight: 150
logModel: backend.logModel
onClearRequested: backend.clearLogs()
onCopyToClipboard: (text) => backend.copyToClipboard(text)
2026-02-11 20:39:32 +01:00
}
}
FileDialog {
id: userConfigFileDialog
2026-02-11 20:39:32 +01:00
modality: Qt.NonModal
nameFilters: ["YAML files (*.yaml)"]
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
onAccepted: backend.userConfig = selectedFile
}
FileDialog {
id: deploymentConfigFileDialog
modality: Qt.NonModal
nameFilters: ["YAML files (*.yaml)"]
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
onAccepted: backend.deploymentConfig = selectedFile
2026-02-11 20:39:32 +01:00
}
}