Krolyxon
Commit bfdf41e

Branches

Refs →

aurora.configquickshellauroraSysPage.qml

190 lines · 7.5 KB · QML

1import QtQuick
2import QtQuick.Layouts
3import Quickshell.Services.UPower
4
5Flickable {
6 id: flick
7 clip: true
8 contentWidth: width
9 contentHeight: col.implicitHeight
10 boundsBehavior: Flickable.StopAtBounds
11
12 // GiB -> "812G" / "1.8T"
13 function size(v) { return v >= 1000 ? (v / 1024).toFixed(1) + "T" : (v >= 100 ? Math.round(v) : v.toFixed(1)) + "G" }
14
15 // pick up drives plugged in since the last poll
16 onVisibleChanged: if (visible) { SysStats.refreshDisks(); Updates.check(false) }
17
18 ColumnLayout {
19 id: col
20 width: flick.width
21 spacing: 8
22
23 SectionLabel { text: "cpu" }
24 RowLayout {
25 Layout.fillWidth: true
26 spacing: 10
27 Text {
28 text: Theme.iChip + " " + Math.round(SysStats.cpu * 100) + "%"
29 Layout.preferredWidth: 80
30 color: Theme.fg
31 font.family: Theme.font
32 font.pixelSize: Theme.fontSize + 2
33 font.bold: true
34 }
35 Spark { Layout.fillWidth: true; values: SysStats.history }
36 }
37
38 SectionLabel { text: "memory & storage"; Layout.topMargin: 6 }
39 StatBar {
40 label: "memory"
41 frac: SysStats.memTotal > 0 ? SysStats.memUsed / SysStats.memTotal : 0
42 valueText: flick.size(SysStats.memUsed) + " / " + flick.size(SysStats.memTotal)
43 }
44 Repeater {
45 model: SysStats.disks
46 delegate: StatBar {
47 required property var modelData
48 label: modelData.label
49 frac: modelData.used / modelData.size
50 fill: frac > 0.9 ? Theme.err : Theme.accent
51 valueText: flick.size(modelData.used) + " / " + flick.size(modelData.size)
52 }
53 }
54
55 // removable drives + phones (Devices): mount / open / unmount, power-off once the disk is idle
56 SectionLabel { text: "removable"; Layout.topMargin: 6; visible: Devices.drives.length + Devices.phones.length > 0 }
57 Repeater {
58 model: Devices.drives.concat(Devices.phones)
59 delegate: ListRow {
60 id: dr
61 required property var modelData
62 required property int index
63 readonly property bool phone: modelData.uri !== undefined
64 readonly property bool mounted: phone ? modelData.mounted : modelData.mount !== ""
65 // first row of its disk carries the power-off button
66 readonly property bool firstOfDisk: !phone && (index === 0 || Devices.drives[index - 1].disk !== modelData.disk)
67 icon: phone ? Theme.iPhone : (modelData.locked ? Theme.iLock : Theme.iUsb)
68 title: phone ? modelData.name : Devices.title(modelData)
69 subtitle: phone ? (mounted ? modelData.path : "not mounted")
70 : modelData.size + " " + modelData.fstype + " " + (mounted ? modelData.mount : (modelData.locked ? "locked" : "not mounted"))
71 current: mounted
72 onClicked: if (mounted) Devices.open(modelData.key); else Devices.mount(modelData.key, true)
73 IconBtn {
74 icon: Theme.iFolderOpen
75 onClicked: if (dr.mounted) Devices.open(dr.modelData.key); else Devices.mount(dr.modelData.key, true)
76 }
77 IconBtn {
78 icon: Theme.iEject
79 visible: dr.mounted || (!dr.phone && dr.modelData.luksParent !== "")
80 onClicked: Devices.eject(dr.modelData.key)
81 }
82 IconBtn {
83 icon: Theme.iPower
84 visible: dr.firstOfDisk && !Devices.diskBusy(dr.modelData.disk)
85 onClicked: Devices.powerOff(dr.modelData.disk)
86 }
87 }
88 }
89
90 BatteryInfo { Layout.topMargin: 6 }
91
92 ColumnLayout {
93 visible: Battery.hasProfiles
94 Layout.fillWidth: true
95 Layout.topMargin: 6
96 spacing: 8
97 SectionLabel { text: "power profile" }
98 RowLayout {
99 Layout.fillWidth: true
100 spacing: 6
101 IconBtn {
102 Layout.fillWidth: true
103 icon: Theme.iLeaf
104 label: "saver"
105 active: Battery.profile === "saver"
106 onClicked: Battery.setProfile("saver")
107 }
108 IconBtn {
109 Layout.fillWidth: true
110 icon: Theme.iBalance
111 label: "balanced"
112 active: Battery.profile === "balanced"
113 onClicked: Battery.setProfile("balanced")
114 }
115 IconBtn {
116 Layout.fillWidth: true
117 visible: Battery.hasPerf
118 icon: Theme.iSpeed
119 label: "perf"
120 active: Battery.profile === "performance"
121 onClicked: Battery.setProfile("performance")
122 }
123 IconBtn {
124 Layout.fillWidth: true
125 visible: Battery.hasBat
126 icon: Theme.iAuto
127 label: "auto"
128 active: Battery.profile === "auto"
129 onClicked: Battery.setProfile("auto")
130 }
131 }
132 }
133
134 GpuSwitch { Layout.topMargin: 6 }
135
136 // pending pacman + AUR updates (Updates)
137 SectionLabel { text: "updates"; Layout.topMargin: 6; visible: Updates.available }
138 RowLayout {
139 visible: Updates.available
140 Layout.fillWidth: true
141 spacing: 6
142 Text {
143 Layout.fillWidth: true
144 text: Updates.checking ? "checking..."
145 : Updates.error !== "" ? Updates.error
146 : (Updates.count === 0 ? "up to date" : Updates.repo + " repo, " + Updates.aur + " aur")
147 + (Updates.lastCheck.getTime() > 0 ? " · " + Qt.formatDateTime(Updates.lastCheck, "HH:mm") : "")
148 color: Updates.error !== "" ? Theme.err : Theme.fg
149 font.family: Theme.font
150 font.pixelSize: Theme.fontSize
151 elide: Text.ElideRight
152 }
153 IconBtn { icon: Theme.iRefresh; label: "check"; onClicked: Updates.check(true) }
154 IconBtn {
155 visible: Updates.count > 0
156 icon: Theme.iUpdate
157 label: Updates.upgrading ? "running" : "upgrade"
158 active: Updates.upgrading
159 onClicked: Updates.upgrade()
160 }
161 }
162 Repeater {
163 model: Updates.available ? Updates.list.slice(0, 6) : []
164 delegate: ListRow {
165 required property var modelData
166 icon: Theme.iUpdate
167 title: modelData.name
168 subtitle: modelData.from + " → " + modelData.to
169 trailing: modelData.aur ? "aur" : ""
170 }
171 }
172 Text {
173 visible: Updates.available && Updates.list.length > 6
174 text: "+ " + (Updates.list.length - 6) + " more"
175 color: Theme.dim
176 font.family: Theme.font
177 font.pixelSize: Theme.fontSize - 2
178 }
179
180 Text {
181 Layout.topMargin: 10
182 Layout.alignment: Qt.AlignRight
183 text: "up " + Theme.fmtTime(SysStats.uptime)
184 color: Theme.dim
185 font.family: Theme.font
186 font.pixelSize: Theme.fontSize - 2
187 }
188 Item { Layout.preferredHeight: 6 }
189 }
190}