From 64536fe531f5582d878039938473c9a026dcbc8d Mon Sep 17 00:00:00 2001 From: rickpeters Date: Sun, 27 Sep 2026 12:49:49 +0200 Subject: [PATCH] feat: New badge for default sub-options added in this version --- AGENTS.md | 3 ++- lib/backend.sh | 1 + lib/menu.sh | 13 ++++++++----- steamify.sh | 4 +++- ui/qml/Main.qml | 12 +++++++----- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 63aa7f1..14e0ca6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,7 +33,8 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine `VERSION` whenever what `_enable` sets up changes (a new component gets one too): installs recorded with an older version are ticked and re-applied ("update" in the plan and the app). New default - sub-options are ticked for installs whose parent is on (`feature_new`). + sub-options are ticked for installs whose parent is on (`feature_new`, + shown as "new"). Status still comes from the system; don't add ad-hoc `_repair` checks for new changes. - **Reversibility.** Every per-user KDE setting a component changes goes diff --git a/lib/backend.sh b/lib/backend.sh index fdd0241..76d0177 100644 --- a/lib/backend.sh +++ b/lib/backend.sh @@ -63,6 +63,7 @@ backend_status() { items+=",\"on\":$( [[ "$now" == 1 ]] && echo true || echo false)" items+=",\"wanted\":$( [[ "${WANTED[$c]:-0}" == 1 ]] && echo true || echo false)" items+=",\"update\":$(feature_outdated "$c" && echo true || echo false)" + items+=",\"new\":$(feature_new "$c" && echo true || echo false)" items+=",\"selectable\":$(component_selectable "$c" && echo true || echo false)}" done local cec="" f diff --git a/lib/menu.sh b/lib/menu.sh index 1202536..9c053eb 100644 --- a/lib/menu.sh +++ b/lib/menu.sh @@ -90,11 +90,14 @@ feature_outdated() { menu_label() { # The label, with "(update)" after the name when a newer version of it - # will be applied. - local l="${LABEL[$1]}" - if feature_outdated "$1"; then - if [[ "$l" == *:* ]]; then l="${l%%:*} ${c_yellow}(update)${c_reset}:${l#*:}" - else l+=" ${c_yellow}(update)${c_reset}"; fi + # will be applied, "(new)" for a default sub-option added since the + # last run. + local l="${LABEL[$1]}" b="" + if feature_outdated "$1"; then b="${c_yellow}(update)${c_reset}" + elif feature_new "$1"; then b="${c_green}(new)${c_reset}"; fi + if [[ -n "$b" ]]; then + if [[ "$l" == *:* ]]; then l="${l%%:*} $b:${l#*:}" + else l+=" $b"; fi fi printf '%s' "$l" } diff --git a/steamify.sh b/steamify.sh index 971b826..b34ef37 100755 --- a/steamify.sh +++ b/steamify.sh @@ -140,7 +140,9 @@ while true; do if [[ "$c" == boot ]]; then echo " - boot into: desktop (from the next boot)" elif is_action "$c"; then echo " - run: ${LABEL[$c]%%:*} at your own risk (checks, then asks twice more)" elif feature_outdated "$c"; then echo " - update: ${LABEL[$c]} (changed in this version)" - elif [[ "${CURRENT[$c]}" == 1 ]]; then echo " - re-apply: ${LABEL[$c]}"; else echo " - turn on: ${LABEL[$c]}"; fi + elif [[ "${CURRENT[$c]}" == 1 ]]; then echo " - re-apply: ${LABEL[$c]}" + elif feature_new "$c"; then echo " - turn on: ${LABEL[$c]} (new in this version)" + else echo " - turn on: ${LABEL[$c]}"; fi done ask_yn "Go ahead?" y || { info "Nothing changed."; continue; } diff --git a/ui/qml/Main.qml b/ui/qml/Main.qml index 4f3d0dd..2ca5d8b 100644 --- a/ui/qml/Main.qml +++ b/ui/qml/Main.qml @@ -268,7 +268,7 @@ ApplicationWindow { var it = items[i]; if (it.kind !== "toggle") continue; if (it.parent && !want[it.parent]) { if (it.on) p.push({ id: it.id, action: "off" }); continue; } - if (want[it.id] && !it.on) p.push({ id: it.id, action: "on" }); + if (want[it.id] && !it.on) p.push({ id: it.id, action: "on", isNew: !!it["new"] }); else if (!want[it.id] && it.on) p.push({ id: it.id, action: "off" }); else if (want[it.id] && (reapply || it.update)) p.push({ id: it.id, action: reapply ? "again" : "update" }); } @@ -631,11 +631,12 @@ ApplicationWindow { x: row.modelData.parent ? 46 : 16 width: controls.x - x - 16 opacity: row.modelData.kind === "action" && !(bios && bios.selectable) ? 0.6 : 1 - // The name, with an Update badge when a newer version of it will be applied. + // The name, with an Update badge when a newer version of it will be + // applied, New for a default sub-option added since the last run. Row { width: parent.width; spacing: 10 Text { text: label(row.modelData); color: t.textHi; font.family: t.body; font.pixelSize: 17; font.weight: Font.DemiBold; elide: Text.ElideRight width: Math.min(implicitWidth, parent.width - (upd.visible ? upd.width + parent.spacing : 0)) } - Chip { id: upd; visible: !!row.modelData.update; text: "Update"; fg: t.warn; bgc: t.warnBg; height: 20; anchors.verticalCenter: parent.verticalCenter } } + Chip { id: upd; visible: !!row.modelData.update || !!row.modelData["new"]; text: row.modelData.update ? "Update" : "New"; fg: row.modelData.update ? t.warn : t.good; bgc: row.modelData.update ? t.warnBg : t.goodBg; height: 20; anchors.verticalCenter: parent.verticalCenter } } Text { text: row.modelData.id === "bios" ? biosHint() : ((row.modelData.id === "hdmi" && hdmiRowHint()) || (texts[row.modelData.id] && texts[row.modelData.id].hint) || row.modelData.hint); color: t.mute; font.family: t.body; font.pixelSize: 13; elide: Text.ElideRight; width: parent.width } } // Right: every control ends on the same edge @@ -767,6 +768,7 @@ ApplicationWindow { Row { anchors.fill: parent; anchors.leftMargin: 18; spacing: 14 Chip { text: parent.parent.st[0]; fg: parent.parent.st[1]; bgc: parent.parent.st[2]; width: 84; anchors.verticalCenter: parent.verticalCenter } Text { text: (texts[parent.parent.modelData.id] || {}).label || parent.parent.modelData.id; color: t.textHi; font.family: t.body; font.pixelSize: 17; font.weight: Font.DemiBold; anchors.verticalCenter: parent.verticalCenter } + Chip { visible: !!parent.parent.modelData.isNew; text: "New"; fg: t.good; bgc: t.goodBg; height: 20; anchors.verticalCenter: parent.verticalCenter } } } } @@ -862,7 +864,7 @@ ApplicationWindow { border.width: parent.parent.st === "wait" || parent.parent.st === "run" ? 2 : 0; border.color: parent.parent.st === "run" ? t.accent : "#343f50" Text { anchors.centerIn: parent; text: parent.parent.parent.st === "ok" ? "✓" : (parent.parent.parent.st === "fail" ? "!" : ""); color: parent.parent.parent.st === "ok" ? t.good : t.bad; font.pixelSize: 13; font.weight: Font.Bold } RotationAnimator on rotation { running: parent.parent.parent.st === "run"; from: 0; to: 360; duration: 1000; loops: Animation.Infinite } } - // The step; an update shows the name with an Update badge, like the menu. + // The step; an update or new sub-option shows its badge, like the menu. Item { width: 380; height: parent.height readonly property var step: parent.parent.modelData readonly property bool update: step.action === "update" @@ -870,7 +872,7 @@ ApplicationWindow { Text { text: (({ on: "Turn on ", off: "Turn off ", again: "Re-apply ", desktop: "Boot into ", gaming: "Boot into ", check: "Download and check the ", flash: "Hand to fwupd: the " })[parent.parent.step.action] || "") + ((texts[parent.parent.step.id] || {}).label || parent.parent.step.id) color: parent.parent.parent.parent.st === "wait" ? t.faint : t.textHi; font.family: t.body; font.pixelSize: 16; font.weight: Font.DemiBold; anchors.verticalCenter: parent.verticalCenter; elide: Text.ElideRight width: Math.min(implicitWidth, parent.width - (stepUpd.visible ? stepUpd.width + parent.spacing : 0)) } - Chip { id: stepUpd; visible: parent.parent.update; text: "Update"; fg: t.warn; bgc: t.warnBg; height: 20; anchors.verticalCenter: parent.verticalCenter } } } + Chip { id: stepUpd; visible: parent.parent.update || !!parent.parent.step.isNew; text: parent.parent.update ? "Update" : "New"; fg: parent.parent.update ? t.warn : t.good; bgc: parent.parent.update ? t.warnBg : t.goodBg; height: 20; anchors.verticalCenter: parent.verticalCenter } } } Text { text: ({ wait: "Waiting", run: "Working…", ok: "Done", fail: "Problem" })[parent.parent.st]; color: parent.parent.st === "ok" ? t.good : (parent.parent.st === "fail" ? t.bad : "#b8c3d1"); font.family: t.body; font.pixelSize: 13; anchors.verticalCenter: parent.verticalCenter } } }