Files
Panama/config/dot/quickshell/services/SettingsSync.qml
T

81 lines
2.9 KiB
QML

pragma Singleton
// Carrying settings to another machine.
//
// Distinct from SettingsBackup, which snapshots this machine so it can be put
// back exactly as it was. This produces something meant to travel: the
// preferences that describe taste rather than hardware.
//
// The helper exports by allow-list from the preference schema, so a key added
// later that happens to hold a token cannot leak into a file somebody emails to
// themselves, and validates everything again on arrival.
import Quickshell
import Quickshell.Io
import QtQuick
Singleton {
id: root
readonly property string helperPath: Quickshell.shellDir + "/scripts/panama-settings-sync"
// Where an export lands by default. Somewhere a person will find it again.
readonly property string defaultPath:
(Quickshell.env("HOME") ?? "") + "/panama-settings.json"
property string lastError: ""
property string lastAction: ""
property int carried: 0
property int applied: 0
// What an import would do, one setting per row, with both values already
// rendered as text by the helper. Capped for display; changeCount is how
// many there really are, so the page can say what it is not showing.
property var changes: []
property int changeCount: 0
property var skipped: []
property string exportedFrom: ""
property bool previewed: false
readonly property bool busy: worker.running
function run(action: string, path: string): void {
if (worker.running)
return;
root.lastError = "";
root.lastAction = action;
worker.command = [root.helperPath, action, path];
worker.running = true;
}
function exportTo(path: string): void { root.run("export", path); }
function preview(path: string): void { root.run("preview", path); }
function importFrom(path: string): void { root.run("import", path); }
function absorb(text: string): void {
try {
const parsed = JSON.parse(text);
root.lastError = String(parsed.error ?? "");
root.carried = Number(parsed.carried ?? 0);
root.applied = Number(parsed.applied ?? 0);
root.changes = Array.isArray(parsed.changes) ? parsed.changes : [];
root.changeCount = Number(parsed.changeCount ?? root.changes.length);
root.skipped = Array.isArray(parsed.skipped) ? parsed.skipped : [];
root.exportedFrom = String(parsed.exportedFrom ?? "");
root.previewed = root.lastAction === "preview" && root.lastError === "";
} catch (error) {
root.lastError = "Could not read the result.";
console.warn("SettingsSync: could not parse helper output:", error);
}
}
Process {
id: worker
stdout: StdioCollector { onStreamFinished: root.absorb(this.text) }
stderr: StdioCollector {
onStreamFinished: if (this.text.trim() !== "") root.lastError = this.text.trim()
}
}
}