Improve update widget

This commit is contained in:
Ryan Hughes
2026-06-04 18:38:25 -04:00
parent d0cac7346a
commit 20d79fe443
+153 -46
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Io import Quickshell.Io
import qs.Commons 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 stateHome: Quickshell.env("XDG_STATE_HOME") || (Quickshell.env("HOME") + "/.local/state")
readonly property string availableStatePath: stateHome + "/omarchy/updates/available" 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 } function close() { popupOpen = false }
@@ -39,10 +44,28 @@ BarWidget {
popupOpen = false popupOpen = false
} }
function runUpdate() {
if (root.bar) root.bar.run("omarchy-launch-floating-terminal-with-presentation omarchy-update")
}
function packageName(line) { function packageName(line) {
return String(line || "").trim().split(/\s+/)[0] || "" 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) { function isOmarchyPackage(line) {
var pkg = packageName(line) var pkg = packageName(line)
return pkg === "omarchy" || pkg.indexOf("omarchy-") === 0 return pkg === "omarchy" || pkg.indexOf("omarchy-") === 0
@@ -148,7 +171,7 @@ BarWidget {
text: root.updateAvailable ? "\uf021" : "" text: root.updateAvailable ? "\uf021" : ""
fontSize: Style.font.caption fontSize: Style.font.caption
tooltipText: "" tooltipText: ""
onPressed: function() { root.bar.run("omarchy-launch-floating-terminal-with-presentation omarchy-update") } onPressed: root.runUpdate()
} }
HoverHandler { HoverHandler {
@@ -165,7 +188,7 @@ BarWidget {
open: root.popupOpen && root.updateAvailable open: root.popupOpen && root.updateAvailable
triggerMode: "hover" triggerMode: "hover"
contentWidth: popup.fittedContentWidth(Style.space(460)) contentWidth: popup.fittedContentWidth(Style.space(460))
contentHeight: popup.fittedContentHeight(panelColumn.implicitHeight, Style.space(520)) contentHeight: popup.fittedContentHeight(panelColumn.implicitHeight, Style.space(640))
Flickable { Flickable {
id: updateFlick id: updateFlick
@@ -182,47 +205,52 @@ BarWidget {
width: updateFlick.width width: updateFlick.width
spacing: Style.space(12) spacing: Style.space(12)
Row { PanelHero {
width: parent.width width: parent.width
spacing: Style.space(8) title: "System update"
meta: countLabel(root.updateCount) + " available"
Text { foreground: root.foreground
text: "\uf021" fontFamily: root.fontFamily
color: root.bar ? root.bar.urgent : Color.urgent iconComponent: Component {
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)
Text { Text {
width: parent.width text: "\uf021"
text: countLabel(root.updateCount) + " available" color: root.foreground
color: Color.popups.text font.family: root.fontFamily
font.family: root.bar ? root.bar.fontFamily : Style.font.family font.pixelSize: Style.font.display
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
} }
} }
} }
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 { UpdateSection {
title: "Omarchy" title: "Omarchy"
lines: root.omarchyUpdateLines lines: root.omarchyUpdateLines
important: true
width: parent.width width: parent.width
} }
PanelSeparator {
visible: root.omarchyUpdateLines.length > 0 && root.otherUpdateLines.length > 0
foreground: root.foreground
}
UpdateSection { UpdateSection {
title: "Other packages" title: "Other packages"
lines: root.otherUpdateLines lines: root.otherUpdateLines
@@ -237,28 +265,107 @@ BarWidget {
property string title: "" property string title: ""
property var lines: [] property var lines: []
property bool important: false
visible: lines.length > 0 visible: lines.length > 0
spacing: Style.space(6) spacing: Style.space(8)
Text { PanelSectionHeader {
width: section.width width: section.width
text: section.title text: section.title.toUpperCase() + " (" + section.lines.length + ")"
color: root.bar ? root.bar.foreground : Color.foreground foreground: root.foreground
font.family: root.bar ? root.bar.fontFamily : Style.font.family fontFamily: root.fontFamily
font.pixelSize: Style.font.bodySmall
font.bold: true
} }
Repeater { Column {
model: section.lines width: section.width
spacing: Style.space(6)
delegate: Text { Repeater {
width: section.width model: section.lines
text: modelData
color: Color.popups.text delegate: UpdateRow {
font.family: root.bar ? root.bar.fontFamily : Style.font.family width: parent.width
font.pixelSize: Style.font.bodySmall 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 wrapMode: Text.WrapAnywhere
} }
} }