Files

197 lines
4.1 KiB
QML

import QtQuick
import QtQuick.Layouts
import ZShell.Internal
import ZShell.Config
import qs.Helpers
import qs.Components
import qs.Services
CustomRect {
id: root
color: Colors.tPalette.m3surfaceContainer
implicitHeight: 220
implicitWidth: 300
radius: Tokens.rounding.large - Tokens.padding.normal
Ref {
service: NetworkUsage
}
ColumnLayout {
id: layout
anchors.bottomMargin: Tokens.padding.larger
anchors.fill: parent
anchors.margins: Tokens.padding.large
spacing: 0
RowLayout {
spacing: Tokens.spacing.small
MaterialIcon {
color: Colors.palette.m3primary
text: "swap_vert"
}
CustomText {
text: qsTr("Network")
}
}
Item {
Layout.bottomMargin: Tokens.spacing.small
Layout.fillHeight: true
Layout.fillWidth: true
Layout.topMargin: Tokens.spacing.larger
SparklineItem {
id: sparkline
property bool initialized: false
property real smoothMax: targetMax
property real targetMax: 1024
anchors.fill: parent
historyLength: NetworkUsage.historyLength
line1: NetworkUsage.uploadBuffer // qmllint disable missing-type
line1Color: Colors.palette.m3secondary
line1FillAlpha: 0.15
line2: NetworkUsage.downloadBuffer // qmllint disable missing-type
line2Color: Colors.palette.m3tertiary
line2FillAlpha: 0.2
maxValue: smoothMax
slideProgress: 1
Behavior on smoothMax {
enabled: sparkline.initialized
Anim {
}
}
Component.onCompleted: {
sparkline.targetMax = Math.max(NetworkUsage.downloadBuffer.maximum, NetworkUsage.uploadBuffer.maximum, 1024);
sparkline.smoothMax = Qt.binding(() => sparkline.targetMax);
sparkline.initialized = true;
}
Connections {
function onValuesChanged(): void {
sparkline.targetMax = Math.max(NetworkUsage.downloadBuffer.maximum, NetworkUsage.uploadBuffer.maximum, 1024);
slideAnim.restart();
}
target: NetworkUsage.downloadBuffer
}
NumberAnimation {
id: slideAnim
duration: Config.dashboard.resourceUpdateInterval
easing.type: Easing.Linear
from: 0
property: "slideProgress"
target: sparkline
to: 1
}
}
// "Collecting data" placeholder
CustomText {
anchors.centerIn: parent
color: Colors.palette.m3outline
text: qsTr("Collecting data...")
visible: NetworkUsage.downloadBuffer.count < 2
}
}
// Download row
RowLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.small
MaterialIcon {
color: Colors.palette.m3tertiary
text: "download"
}
CustomText {
color: Colors.palette.m3onSurfaceVariant
text: qsTr("Download")
}
Item {
Layout.fillWidth: true
}
CustomText {
color: Colors.palette.m3tertiary
text: {
const fmt = NetworkUsage.formatBytes(NetworkUsage.downloadSpeed ?? 0);
return fmt ? `${fmt.value.toFixed(1)} ${fmt.unit}` : "0.0 B/s";
}
}
}
// Upload row
RowLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.small
MaterialIcon {
color: Colors.palette.m3secondary
text: "upload"
}
CustomText {
color: Colors.palette.m3onSurfaceVariant
text: qsTr("Upload")
}
Item {
Layout.fillWidth: true
}
CustomText {
color: Colors.palette.m3secondary
text: {
const fmt = NetworkUsage.formatBytes(NetworkUsage.uploadSpeed ?? 0);
return fmt ? `${fmt.value.toFixed(1)} ${fmt.unit}` : "0.0 B/s";
}
}
}
// Session totals
RowLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.small
MaterialIcon {
color: Colors.palette.m3onSurfaceVariant
text: "history"
}
CustomText {
color: Colors.palette.m3onSurfaceVariant
text: qsTr("Total")
}
Item {
Layout.fillWidth: true
}
CustomText {
color: Colors.palette.m3onSurfaceVariant
text: {
const down = NetworkUsage.formatBytesTotal(NetworkUsage.downloadTotal ?? 0);
const up = NetworkUsage.formatBytesTotal(NetworkUsage.uploadTotal ?? 0);
return (down && up) ? `↓${down.value.toFixed(1)}${down.unit} ${up.value.toFixed(1)}${up.unit}` : "↓0.0B ↑0.0B";
}
}
}
}
}