diff --git a/shell/plugins/bar/widgets/SystemUpdate.qml b/shell/plugins/bar/widgets/SystemUpdate.qml index f93c4fa8..71c3199f 100644 --- a/shell/plugins/bar/widgets/SystemUpdate.qml +++ b/shell/plugins/bar/widgets/SystemUpdate.qml @@ -1,5 +1,6 @@ import QtQuick import QtQuick.Controls +import QtQuick.Layouts import Quickshell import Quickshell.Io import qs.Commons @@ -21,6 +22,10 @@ BarWidget { readonly property string stateHome: Quickshell.env("XDG_STATE_HOME") || (Quickshell.env("HOME") + "/.local/state") readonly property string availableStatePath: stateHome + "/omarchy/updates/available" + readonly property color foreground: root.bar ? root.bar.foreground : Color.foreground + readonly property color urgent: root.bar ? root.bar.urgent : Color.urgent + readonly property color dim: Qt.darker(foreground, 1.55) + readonly property string fontFamily: root.bar ? root.bar.fontFamily : Style.font.family function close() { popupOpen = false } @@ -39,10 +44,28 @@ BarWidget { popupOpen = false } + function runUpdate() { + if (root.bar) root.bar.run("omarchy-launch-floating-terminal-with-presentation omarchy-update") + } + function packageName(line) { return String(line || "").trim().split(/\s+/)[0] || "" } + function versionMatch(line) { + return String(line || "").trim().match(/^\S+\s+(.+?)\s+->\s+(.+)$/) + } + + function versionFrom(line) { + var match = versionMatch(line) + return match ? match[1] : "" + } + + function versionTo(line) { + var match = versionMatch(line) + return match ? match[2] : "" + } + function isOmarchyPackage(line) { var pkg = packageName(line) return pkg === "omarchy" || pkg.indexOf("omarchy-") === 0 @@ -148,7 +171,7 @@ BarWidget { text: root.updateAvailable ? "\uf021" : "" fontSize: Style.font.caption tooltipText: "" - onPressed: function() { root.bar.run("omarchy-launch-floating-terminal-with-presentation omarchy-update") } + onPressed: root.runUpdate() } HoverHandler { @@ -165,7 +188,7 @@ BarWidget { open: root.popupOpen && root.updateAvailable triggerMode: "hover" contentWidth: popup.fittedContentWidth(Style.space(460)) - contentHeight: popup.fittedContentHeight(panelColumn.implicitHeight, Style.space(520)) + contentHeight: popup.fittedContentHeight(panelColumn.implicitHeight, Style.space(640)) Flickable { id: updateFlick @@ -182,47 +205,52 @@ BarWidget { width: updateFlick.width spacing: Style.space(12) - Row { + PanelHero { width: parent.width - spacing: Style.space(8) - - Text { - text: "\uf021" - color: root.bar ? root.bar.urgent : Color.urgent - font.family: root.bar ? root.bar.fontFamily : Style.font.family - font.pixelSize: Style.font.title - verticalAlignment: Text.AlignVCenter - } - - Column { - width: parent.width - Style.space(28) - spacing: Style.space(2) - + title: "System update" + meta: countLabel(root.updateCount) + " available" + foreground: root.foreground + fontFamily: root.fontFamily + iconComponent: Component { Text { - width: parent.width - text: countLabel(root.updateCount) + " available" - color: Color.popups.text - font.family: root.bar ? root.bar.fontFamily : Style.font.family - font.pixelSize: Style.font.body - font.bold: true - } - - Text { - width: parent.width - text: "Click to run omarchy update" - color: Qt.darker(Color.popups.text, 1.35) - font.family: root.bar ? root.bar.fontFamily : Style.font.family - font.pixelSize: Style.font.bodySmall + text: "\uf021" + color: root.foreground + font.family: root.fontFamily + font.pixelSize: Style.font.display } } } + Button { + width: parent.width + text: "Run omarchy update" + iconText: "\uf021" + foreground: root.foreground + accent: root.urgent + fontFamily: root.fontFamily + fontSize: Style.font.bodySmall + iconSize: Style.font.body + bordered: true + onClicked: root.runUpdate() + } + + PanelSeparator { + visible: root.updateLines.length > 0 + foreground: root.foreground + } + UpdateSection { title: "Omarchy" lines: root.omarchyUpdateLines + important: true width: parent.width } + PanelSeparator { + visible: root.omarchyUpdateLines.length > 0 && root.otherUpdateLines.length > 0 + foreground: root.foreground + } + UpdateSection { title: "Other packages" lines: root.otherUpdateLines @@ -237,28 +265,107 @@ BarWidget { property string title: "" property var lines: [] + property bool important: false visible: lines.length > 0 - spacing: Style.space(6) + spacing: Style.space(8) - Text { + PanelSectionHeader { width: section.width - text: section.title - color: root.bar ? root.bar.foreground : Color.foreground - font.family: root.bar ? root.bar.fontFamily : Style.font.family - font.pixelSize: Style.font.bodySmall - font.bold: true + text: section.title.toUpperCase() + " (" + section.lines.length + ")" + foreground: root.foreground + fontFamily: root.fontFamily } - Repeater { - model: section.lines + Column { + width: section.width + spacing: Style.space(6) - delegate: Text { - width: section.width - text: modelData - color: Color.popups.text - font.family: root.bar ? root.bar.fontFamily : Style.font.family - font.pixelSize: Style.font.bodySmall + Repeater { + model: section.lines + + delegate: UpdateRow { + width: parent.width + line: modelData + important: section.important + } + } + } + } + + component UpdateRow: CursorSurface { + id: row + + property string line: "" + property bool important: false + readonly property string packageTitle: root.packageName(line) + readonly property string fromVersion: root.versionFrom(line) + readonly property string toVersion: root.versionTo(line) + readonly property bool hasVersions: fromVersion !== "" && toVersion !== "" + + foreground: root.foreground + accent: root.urgent + implicitHeight: Math.max(Style.spacing.popupRowHeight, rowContent.implicitHeight + Style.spacing.rowPaddingX) + + ColumnLayout { + id: rowContent + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Style.spacing.rowPaddingX + anchors.rightMargin: Style.spacing.rowPaddingX + spacing: Style.space(1) + + Text { + Layout.fillWidth: true + text: row.packageTitle + color: root.foreground + font.family: root.fontFamily + font.pixelSize: Style.font.body + font.bold: true + elide: Text.ElideRight + } + + RowLayout { + visible: row.hasVersions + Layout.fillWidth: true + spacing: Style.space(7) + + Text { + Layout.fillWidth: true + text: row.fromVersion + color: root.dim + font.family: root.fontFamily + font.pixelSize: Style.font.caption + elide: Text.ElideRight + } + + Text { + text: "\u2192" + color: row.important ? root.urgent : root.dim + font.family: root.fontFamily + font.pixelSize: Style.font.bodySmall + font.bold: true + } + + Text { + Layout.fillWidth: true + text: row.toVersion + color: row.important ? root.urgent : root.foreground + font.family: root.fontFamily + font.pixelSize: Style.font.caption + font.bold: true + elide: Text.ElideRight + } + } + + Text { + visible: !row.hasVersions + Layout.fillWidth: true + text: row.line + color: root.dim + font.family: root.fontFamily + font.pixelSize: Style.font.caption wrapMode: Text.WrapAnywhere } }