mirror of
https://github.com/logos-storage/logos-storage-app-skeleton.git
synced 2026-06-16 05:19:27 +00:00
Add components
This commit is contained in:
parent
e8c524dc41
commit
9b85c68aaf
91
src/qml/DebugPanel.qml
Normal file
91
src/qml/DebugPanel.qml
Normal file
@ -0,0 +1,91 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Logos.Theme
|
||||
import Logos.Controls
|
||||
|
||||
// qmllint disable unqualified
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property var backend
|
||||
property bool running: false
|
||||
|
||||
color: Theme.palette.backgroundElevated
|
||||
border.color: Theme.palette.borderSecondary
|
||||
border.width: 1
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 10
|
||||
Layout.topMargin: 6
|
||||
Layout.bottomMargin: 4
|
||||
spacing: 6
|
||||
|
||||
LogosStorageButton {
|
||||
text: "Debug"
|
||||
enabled: root.running
|
||||
onClicked: root.backend.tryDebug()
|
||||
}
|
||||
LogosStorageButton {
|
||||
text: "Peer ID"
|
||||
enabled: root.running
|
||||
onClicked: root.backend.showPeerId()
|
||||
}
|
||||
LogosStorageButton {
|
||||
text: "Data dir"
|
||||
enabled: root.running
|
||||
onClicked: root.backend.dataDir()
|
||||
}
|
||||
LogosStorageButton {
|
||||
text: "SPR"
|
||||
enabled: root.running
|
||||
onClicked: root.backend.spr()
|
||||
}
|
||||
LogosStorageButton {
|
||||
text: "Version"
|
||||
enabled: root.running
|
||||
onClicked: root.backend.version()
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Theme.palette.borderSecondary
|
||||
}
|
||||
|
||||
Flickable {
|
||||
id: logFlick
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
contentWidth: width
|
||||
contentHeight: debugText.paintedHeight
|
||||
|
||||
TextEdit {
|
||||
id: debugText
|
||||
width: logFlick.width
|
||||
text: root.backend.debugLogs
|
||||
color: Theme.palette.textSecondary
|
||||
font.family: "monospace"
|
||||
font.pixelSize: 11
|
||||
wrapMode: Text.WrapAnywhere
|
||||
readOnly: true
|
||||
padding: 8
|
||||
bottomPadding: 20
|
||||
|
||||
onTextChanged: Qt.callLater(function () {
|
||||
logFlick.contentY = Math.max(0, logFlick.contentHeight - logFlick.height)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
147
src/qml/NodeHeader.qml
Normal file
147
src/qml/NodeHeader.qml
Normal file
@ -0,0 +1,147 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Logos.Theme
|
||||
import Logos.Controls
|
||||
|
||||
// qmllint disable unqualified
|
||||
RowLayout {
|
||||
id: root
|
||||
|
||||
property var backend
|
||||
property bool nodeIsUp: false
|
||||
property bool blinkOn: false
|
||||
|
||||
readonly property int stopped: 0
|
||||
readonly property int starting: 1
|
||||
readonly property int running: 2
|
||||
readonly property int stopping: 3
|
||||
readonly property int destroyed: 4
|
||||
|
||||
signal settingsRequested()
|
||||
|
||||
spacing: Theme.spacing.medium
|
||||
|
||||
StorageIcon {
|
||||
animated: root.backend.status === root.starting
|
||||
|| root.backend.status === root.stopping
|
||||
dotColor: {
|
||||
if (root.backend.status === root.starting)
|
||||
return Theme.palette.warning
|
||||
if (root.backend.status !== root.running)
|
||||
return Theme.palette.textMuted
|
||||
return root.nodeIsUp ? Theme.palette.success : Theme.palette.error
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 6
|
||||
|
||||
LogosText {
|
||||
text: "Logos Storage"
|
||||
font.pixelSize: Theme.typography.titleText
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 7
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 7
|
||||
Layout.preferredHeight: 7
|
||||
radius: 3.5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: {
|
||||
if (root.backend.status === root.starting)
|
||||
return Theme.palette.warning
|
||||
if (root.backend.status !== root.running)
|
||||
return Theme.palette.textMuted
|
||||
return root.nodeIsUp ? Theme.palette.success : Theme.palette.error
|
||||
}
|
||||
opacity: root.backend.status === root.running
|
||||
? (root.blinkOn ? 1.0 : 0.15) : 1.0
|
||||
}
|
||||
|
||||
LogosText {
|
||||
text: {
|
||||
switch (root.backend.status) {
|
||||
case root.stopped: return "Stopped"
|
||||
case root.starting: return "Starting…"
|
||||
case root.running: return "Running"
|
||||
case root.stopping: return "Stopping…"
|
||||
case root.destroyed: return "Not initialised"
|
||||
default: return ""
|
||||
}
|
||||
}
|
||||
font.pixelSize: Theme.typography.primaryText
|
||||
color: Theme.palette.textSecondary
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 44
|
||||
Layout.preferredHeight: 44
|
||||
radius: 8
|
||||
color: settingsHover.hovered ? Theme.palette.backgroundElevated : "transparent"
|
||||
border.color: Theme.palette.borderSecondary
|
||||
border.width: 1
|
||||
|
||||
SettingsIcon {
|
||||
anchors.centerIn: parent
|
||||
dotColor: Theme.palette.text
|
||||
dotSize: 5
|
||||
dotSpacing: 2
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: settingsHover
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.settingsRequested()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 44
|
||||
Layout.preferredHeight: 44
|
||||
radius: 8
|
||||
color: startStopHover.hovered ? Theme.palette.backgroundElevated : "transparent"
|
||||
border.color: Theme.palette.borderSecondary
|
||||
border.width: 1
|
||||
opacity: (root.backend.status === root.running
|
||||
|| root.backend.status === root.stopped) ? 1.0 : 0.4
|
||||
|
||||
PlayIcon {
|
||||
anchors.centerIn: parent
|
||||
dotColor: Theme.palette.text
|
||||
dotSize: 5
|
||||
dotSpacing: 2
|
||||
visible: root.backend.status !== root.running
|
||||
}
|
||||
StopIcon {
|
||||
anchors.centerIn: parent
|
||||
dotColor: Theme.palette.text
|
||||
dotSize: 5
|
||||
dotSpacing: 2
|
||||
visible: root.backend.status === root.running
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: startStopHover
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: root.backend.status === root.running
|
||||
|| root.backend.status === root.stopped
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.backend.status === root.running
|
||||
? root.backend.stop() : root.backend.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
155
src/qml/StatusWidgets.qml
Normal file
155
src/qml/StatusWidgets.qml
Normal file
@ -0,0 +1,155 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Dialogs
|
||||
import QtQuick.Layouts
|
||||
import Logos.Theme
|
||||
import Logos.Controls
|
||||
|
||||
// qmllint disable unqualified
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var backend
|
||||
property bool running: false
|
||||
|
||||
spacing: 0
|
||||
|
||||
TextEdit {
|
||||
id: clipHelper
|
||||
visible: false
|
||||
function copyText(str) {
|
||||
clipHelper.text = str
|
||||
clipHelper.selectAll()
|
||||
clipHelper.copy()
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: uploadDialog
|
||||
onAccepted: root.backend.tryUploadFile(selectedFile)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.backend
|
||||
function onUploadCompleted(cid) { root._lastCid = cid }
|
||||
function onDownloadCompleted(cid) { root._lastCid = cid }
|
||||
}
|
||||
|
||||
property string _lastCid: ""
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Theme.spacing.medium
|
||||
|
||||
UploadWidget {
|
||||
uploadProgress: root.backend.uploadProgress
|
||||
running: root.running
|
||||
onUploadRequested: uploadDialog.open()
|
||||
}
|
||||
|
||||
DiskWidget {
|
||||
backend: root.backend
|
||||
}
|
||||
|
||||
PeersWidget {
|
||||
backend: root.backend
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
Layout.preferredHeight: 36
|
||||
|
||||
opacity: root._lastCid.length > 0 ? 1.0 : 0.0
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 36
|
||||
width: cidBadgeRow.implicitWidth + 28
|
||||
radius: 6
|
||||
color: Theme.palette.backgroundSecondary
|
||||
border.color: Theme.palette.borderSecondary
|
||||
border.width: 1
|
||||
|
||||
RowLayout {
|
||||
id: cidBadgeRow
|
||||
anchors.centerIn: parent
|
||||
spacing: 8
|
||||
|
||||
LogosText {
|
||||
text: "CID"
|
||||
font.pixelSize: 10
|
||||
color: Theme.palette.textTertiary
|
||||
}
|
||||
|
||||
LogosText {
|
||||
text: {
|
||||
var c = root._lastCid
|
||||
return c.length > 20 ? c.substring(0, 8) + "…" + c.slice(-6) : c
|
||||
}
|
||||
font.pixelSize: 11
|
||||
font.family: "monospace"
|
||||
color: Theme.palette.text
|
||||
}
|
||||
|
||||
LogosText {
|
||||
text: "COPY"
|
||||
font.pixelSize: 9
|
||||
color: Theme.palette.textTertiary
|
||||
font.letterSpacing: 0.8
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: copyFlash
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
color: Theme.palette.success
|
||||
opacity: 0
|
||||
|
||||
SequentialAnimation on opacity {
|
||||
id: copyFlashAnim
|
||||
running: false
|
||||
NumberAnimation {
|
||||
to: 0.18
|
||||
duration: 80
|
||||
}
|
||||
NumberAnimation {
|
||||
to: 0
|
||||
duration: 500
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: cidBadgeHover
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
color: cidBadgeHover.hovered ? Qt.rgba(1, 1, 1, 0.04) : "transparent"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
clipHelper.copyText(root._lastCid)
|
||||
copyFlashAnim.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user