Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

quickshell/nuguland/Usage.qml

Raw
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io

// Persistent widget-usage tracker: counts how often each bar widget is
// opened and exposes a usage-sorted layout order. The order is snapshotted
// at file load so the bar stays stable within a session and re-sorts across
// restarts, while counts keep accumulating live and persist to disk.
Item {
    id: root

    // Canonical widget set; array order is the tie-break for equal counts.
    // "clock" is intentionally absent: it is pinned at a constant bar-center
    // position by Bar.qml, so it must never drift in the usage-sorted order.
    readonly property var widgets: ["launcher", "media", "noko", "system", "clipboard", "vault", "audio", "brightness", "connectivity", "power", "notifications", "tray", "idle"]

    // Snapshotted once at load (see FileView.onLoaded); the bar binds to this.
    property var layoutOrder: widgets
    property bool snapshotted: false
    property alias usageStore: usageStoreObject

    function snapshot() {
        if (root.snapshotted)
            return;

        root.snapshotted = true;
        root.layoutOrder = root.ordered();
    }

    function countFor(name) {
        const counts = root.usageStore.counts || ({});
        return Number(counts[String(name)] || 0);
    }

    // widgets sorted by usage desc, ties broken by canonical order
    function ordered() {
        return root.widgets.slice().map((name, index) => {
            return {
                "name": name,
                "index": index,
                "count": root.countFor(name)
            };
        }).sort((a, b) => {
            return (b.count - a.count) || (a.index - b.index);
        }).map(entry => {
            return entry.name;
        });
    }

    function record(name) {
        const key = String(name);
        if (root.widgets.indexOf(key) < 0)
            return root.stateJson();

        const next = Object.assign({}, root.usageStore.counts);
        next[key] = (Number(next[key]) || 0) + 1;
        root.usageStore.counts = next;
        root.saveCounts();
        return root.stateJson();
    }

    function stateJson() {
        return JSON.stringify({
            "backend": "Usage.qml",
            "path": usageFile.path,
            "counts": root.usageStore.counts || ({}),
            "layoutOrder": root.layoutOrder,
            "liveOrder": root.ordered()
        });
    }

    function loadCounts() {
        let data = {};
        try {
            data = JSON.parse(usageFile.text() || "{}");
        } catch (error) {
            data = {};
        }
        root.usageStore.counts = data.counts || {};
        root.snapshot();
    }

    function saveCounts() {
        usageFile.setText(JSON.stringify({
            "counts": root.usageStore.counts || {}
        }, null, 2));
    }

    QtObject {
        id: usageStoreObject

        property var counts: ({})
    }

    FileView {
        id: usageFile

        // Single writer (this shell), so no watchChanges: a reload on our own
        // write would re-snapshot layoutOrder mid-session.
        path: Quickshell.statePath("nuguland-widget-usage.json")
        printErrors: false
        onLoaded: root.loadCounts()
        onLoadFailed: root.snapshot()
    }
}