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:
Gabriel Brown
2026-08-24 17:18:14 -04:00
parent b30bf40407
commit 5a0643357f
29 changed files with 5024 additions and 314 deletions
+34 -1
View File
@@ -44,6 +44,26 @@ Singleton {
// inside the handler that changes it. See DefaultApps.qml.
readonly property bool busy: query.running || mutation.running
// How many snapshots a horizon may keep. The page offers a dropdown rather
// than a number field, and this is what fills it; the helper refuses
// anything above it too. 999 hourly snapshots is not a retention policy,
// it is a typo that fills a drive.
//
// The monthly and yearly limits are not editable here and are never
// written, so a configuration with longer horizons keeps them.
readonly property int retentionMax: 50
readonly property var retentionChoices: {
const values = [];
for (let index = 0; index <= root.retentionMax; index += 1)
values.push(index);
return values;
}
// The card the browser lives in is not the card it was opened from: the
// browse state below is independent of any config row's expanded state, so
// opening a snapshot from a collapsed row still shows the files.
readonly property bool browserOpen: root.browsingConfig !== ""
function labelFor(config: var): string {
const subvolume = String(config?.subvolume ?? "");
if (subvolume === "/")
@@ -128,8 +148,21 @@ Singleton {
root.run(["delete", config, String(number)]);
}
// Three horizons, each a whole number the dropdown offered. Checked here as
// well as in the helper because the caller is a page that can be wrong, and
// a keep count that arrives as "5.5" or "-1" would be written straight into
// snapper's config file.
function setRetention(config: string, hourly: int, daily: int, weekly: int): void {
root.run(["set-retention", config, String(hourly), String(daily), String(weekly)]);
const values = [hourly, daily, weekly];
for (const value of values) {
const number = Number(value);
if (!Number.isInteger(number) || number < 0 || number > root.retentionMax) {
root.lastError = "Keep counts go from 0 to " + root.retentionMax + ".";
return;
}
}
root.run(["set-retention", config,
String(values[0]), String(values[1]), String(values[2])]);
}
function setTimeline(config: string, enabled: bool): void {