Make Applications a real app manager, and clean up storage without the racket
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
// What is on the disk, drawn as the disk.
|
||||
//
|
||||
// One bar whose segments add up to the whole filesystem, because the question
|
||||
// people bring to this page is "what is taking my space" and the only answer
|
||||
// that cannot mislead is one where the parts sum to the total. Four of the five
|
||||
// segments are measured; the fifth is what is left over, and it is labelled as
|
||||
// exactly that rather than being called "System" and quietly absorbing every
|
||||
// measurement error in the other four.
|
||||
//
|
||||
// The legend carries the numbers. A bar this wide can hold a 2% segment but it
|
||||
// cannot label one, and a segment nobody can name is decoration.
|
||||
|
||||
import QtQuick
|
||||
import qs.config
|
||||
import qs.services
|
||||
|
||||
Column {
|
||||
id: root
|
||||
|
||||
readonly property var breakdown: Disks.breakdown ?? null
|
||||
|
||||
readonly property var segments: {
|
||||
const source = root.breakdown?.segments ?? null;
|
||||
if (!source)
|
||||
return [];
|
||||
return [
|
||||
{
|
||||
key: "home",
|
||||
label: "Home",
|
||||
detail: "Your files, not counting caches",
|
||||
bytes: Number(source.home ?? 0),
|
||||
color: Theme.accent
|
||||
},
|
||||
{
|
||||
key: "applications",
|
||||
label: "Applications",
|
||||
detail: "Flatpak applications and the runtimes they share",
|
||||
bytes: Number(source.applications ?? 0),
|
||||
color: Theme.teal
|
||||
},
|
||||
{
|
||||
key: "caches",
|
||||
label: "Caches",
|
||||
detail: "~/.cache, rebuilt as applications run",
|
||||
bytes: Number(source.caches ?? 0),
|
||||
color: Theme.warn
|
||||
},
|
||||
{
|
||||
key: "system",
|
||||
label: "System & everything else",
|
||||
detail: "Whatever the measured segments do not account for",
|
||||
bytes: Number(source.system ?? 0),
|
||||
color: Theme.magenta
|
||||
},
|
||||
{
|
||||
key: "free",
|
||||
label: "Free",
|
||||
detail: "Reported by the filesystem",
|
||||
bytes: Number(source.free ?? 0),
|
||||
color: Theme.alpha(Theme.fg, 0.1)
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
readonly property real total: root.segments.reduce(
|
||||
(sum, segment) => sum + Math.max(0, segment.bytes), 0)
|
||||
|
||||
width: parent ? parent.width : 620
|
||||
spacing: 10
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: root.total <= 0
|
||||
text: Disks.measuringBreakdown
|
||||
? "Measuring what is on this disk…"
|
||||
: (Disks.lastError !== "" ? Disks.lastError : "Not measured yet.")
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
visible: root.total > 0
|
||||
height: 26
|
||||
radius: 8
|
||||
clip: true
|
||||
color: Theme.alpha(Theme.fg, 0.06)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.fg, 0.1)
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: root.segments
|
||||
|
||||
delegate: Rectangle {
|
||||
required property var modelData
|
||||
|
||||
// A measured segment always gets a sliver, so "1 GB of
|
||||
// caches" is visible as a fact rather than rounded away.
|
||||
width: root.total > 0 && modelData.bytes > 0
|
||||
? Math.max(parent.width * (modelData.bytes / root.total), 2)
|
||||
: 0
|
||||
height: parent.height
|
||||
color: modelData.color
|
||||
border.width: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
width: parent.width
|
||||
visible: root.total > 0
|
||||
spacing: 14
|
||||
|
||||
Repeater {
|
||||
model: root.segments
|
||||
|
||||
delegate: Row {
|
||||
required property var modelData
|
||||
|
||||
spacing: 6
|
||||
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 9
|
||||
height: 9
|
||||
radius: 3
|
||||
color: modelData.key === "free"
|
||||
? Theme.alpha(Theme.fg, 0.25)
|
||||
: modelData.color
|
||||
border.width: 0
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: modelData.label + " " + Disks.formatBytes(modelData.bytes)
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontFamily
|
||||
font.features: Theme.tabularFigures
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user