1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-13 00:42:49 -05:00

make system updater widget more generic

This commit is contained in:
bbedward
2025-09-15 11:55:15 -04:00
parent e4f86abda9
commit 903ef0cc72
6 changed files with 86 additions and 61 deletions

View File

@@ -164,11 +164,11 @@ Item {
"icon": "palette", "icon": "palette",
"enabled": true "enabled": true
}, { }, {
"id": "archUpdater", "id": "systemUpdate",
"text": "Arch Updater", "text": "System Update",
"description": "Check for updates in Arch-based systems", "description": "Check for system updates",
"icon": "update", "icon": "update",
"enabled": true "enabled": SystemUpdateService.distributionSupported
}] }]
property var defaultLeftWidgets: [{ property var defaultLeftWidgets: [{
"id": "launcherButton", "id": "launcherButton",

View File

@@ -9,7 +9,7 @@ import qs.Services
import qs.Widgets import qs.Widgets
DankPopout { DankPopout {
id: archUpdaterPopout id: systemUpdatePopout
property var parentWidget: null property var parentWidget: null
property string triggerSection: "right" property string triggerSection: "right"
@@ -35,8 +35,8 @@ DankPopout {
onShouldBeVisibleChanged: { onShouldBeVisibleChanged: {
if (shouldBeVisible) { if (shouldBeVisible) {
if (ArchUpdaterService.updateCount === 0 && !ArchUpdaterService.isChecking) { if (SystemUpdateService.updateCount === 0 && !SystemUpdateService.isChecking) {
ArchUpdaterService.checkForUpdates() SystemUpdateService.checkForUpdates()
} }
} }
} }
@@ -103,14 +103,14 @@ DankPopout {
StyledText { StyledText {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: { text: {
if (ArchUpdaterService.isChecking) return "Checking..."; if (SystemUpdateService.isChecking) return "Checking...";
if (ArchUpdaterService.hasError) return "Error"; if (SystemUpdateService.hasError) return "Error";
if (ArchUpdaterService.updateCount === 0) return "Up to date"; if (SystemUpdateService.updateCount === 0) return "Up to date";
return ArchUpdaterService.updateCount + " updates"; return SystemUpdateService.updateCount + " updates";
} }
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
color: { color: {
if (ArchUpdaterService.hasError) return Theme.error; if (SystemUpdateService.hasError) return Theme.error;
return Theme.surfaceText; return Theme.surfaceText;
} }
} }
@@ -122,10 +122,10 @@ DankPopout {
iconSize: 18 iconSize: 18
z: 15 z: 15
iconColor: Theme.surfaceText iconColor: Theme.surfaceText
enabled: !ArchUpdaterService.isChecking enabled: !SystemUpdateService.isChecking
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
onClicked: { onClicked: {
ArchUpdaterService.checkForUpdates() SystemUpdateService.checkForUpdates()
} }
RotationAnimation { RotationAnimation {
@@ -134,7 +134,7 @@ DankPopout {
from: 0 from: 0
to: 360 to: 360
duration: 1000 duration: 1000
running: ArchUpdaterService.isChecking running: SystemUpdateService.isChecking
loops: Animation.Infinite loops: Animation.Infinite
onRunningChanged: { onRunningChanged: {
@@ -168,39 +168,39 @@ DankPopout {
id: statusText id: statusText
width: parent.width width: parent.width
text: { text: {
if (ArchUpdaterService.hasError) { if (SystemUpdateService.hasError) {
return "Failed to check for updates:\n" + ArchUpdaterService.errorMessage; return "Failed to check for updates:\n" + SystemUpdateService.errorMessage;
} }
if (!ArchUpdaterService.helperAvailable) { if (!SystemUpdateService.helperAvailable) {
return "No AUR helper found. Please install 'paru' or 'yay' to check for updates."; return "No package manager found. Please install 'paru' or 'yay' to check for updates.";
} }
if (ArchUpdaterService.isChecking) { if (SystemUpdateService.isChecking) {
return "Checking for updates..."; return "Checking for updates...";
} }
if (ArchUpdaterService.updateCount === 0) { if (SystemUpdateService.updateCount === 0) {
return "Your system is up to date!"; return "Your system is up to date!";
} }
return `Found ${ArchUpdaterService.updateCount} packages to update:`; return `Found ${SystemUpdateService.updateCount} packages to update:`;
} }
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
color: { color: {
if (ArchUpdaterService.hasError) return Theme.errorText; if (SystemUpdateService.hasError) return Theme.errorText;
return Theme.surfaceText; return Theme.surfaceText;
} }
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
visible: ArchUpdaterService.updateCount === 0 || ArchUpdaterService.hasError || ArchUpdaterService.isChecking visible: SystemUpdateService.updateCount === 0 || SystemUpdateService.hasError || SystemUpdateService.isChecking
} }
DankListView { DankListView {
id: packagesList id: packagesList
width: parent.width width: parent.width
height: parent.height - (ArchUpdaterService.updateCount === 0 || ArchUpdaterService.hasError || ArchUpdaterService.isChecking ? statusText.height + Theme.spacingM : 0) height: parent.height - (SystemUpdateService.updateCount === 0 || SystemUpdateService.hasError || SystemUpdateService.isChecking ? statusText.height + Theme.spacingM : 0)
visible: ArchUpdaterService.updateCount > 0 && !ArchUpdaterService.isChecking && !ArchUpdaterService.hasError visible: SystemUpdateService.updateCount > 0 && !SystemUpdateService.isChecking && !SystemUpdateService.hasError
clip: true clip: true
spacing: Theme.spacingXS spacing: Theme.spacingXS
model: ArchUpdaterService.availableUpdates model: SystemUpdateService.availableUpdates
delegate: Rectangle { delegate: Rectangle {
width: ListView.view.width - Theme.spacingM width: ListView.view.width - Theme.spacingM
@@ -265,7 +265,7 @@ DankPopout {
height: parent.height height: parent.height
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: updateMouseArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover color: updateMouseArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover
opacity: ArchUpdaterService.updateCount > 0 ? 1.0 : 0.5 opacity: SystemUpdateService.updateCount > 0 ? 1.0 : 0.5
Behavior on color { Behavior on color {
ColorAnimation { duration: Theme.shortDuration } ColorAnimation { duration: Theme.shortDuration }
@@ -296,10 +296,10 @@ DankPopout {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
enabled: ArchUpdaterService.updateCount > 0 enabled: SystemUpdateService.updateCount > 0
onClicked: { onClicked: {
ArchUpdaterService.runUpdates() SystemUpdateService.runUpdates()
archUpdaterPopout.close() systemUpdatePopout.close()
} }
} }
} }
@@ -341,7 +341,7 @@ DankPopout {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
archUpdaterPopout.close() systemUpdatePopout.close()
} }
} }
} }

View File

@@ -13,8 +13,8 @@ Rectangle {
property real widgetHeight: 30 property real widgetHeight: 30
property real barHeight: 48 property real barHeight: 48
readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30))
readonly property bool hasUpdates: ArchUpdaterService.updateCount > 0 readonly property bool hasUpdates: SystemUpdateService.updateCount > 0
readonly property bool isChecking: ArchUpdaterService.isChecking readonly property bool isChecking: SystemUpdateService.isChecking
signal clicked() signal clicked()
@@ -42,13 +42,13 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
name: { name: {
if (isChecking) return "refresh"; if (isChecking) return "refresh";
if (ArchUpdaterService.hasError) return "error"; if (SystemUpdateService.hasError) return "error";
if (hasUpdates) return "system_update_alt"; if (hasUpdates) return "system_update_alt";
return "check_circle"; return "check_circle";
} }
size: Theme.iconSize - 6 size: Theme.iconSize - 6
color: { color: {
if (ArchUpdaterService.hasError) return Theme.error; if (SystemUpdateService.hasError) return Theme.error;
if (hasUpdates) return Theme.primary; if (hasUpdates) return Theme.primary;
return (updaterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText); return (updaterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText);
} }
@@ -75,7 +75,7 @@ Rectangle {
id: countText id: countText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: ArchUpdaterService.updateCount.toString() text: SystemUpdateService.updateCount.toString()
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.surfaceText color: Theme.surfaceText

View File

@@ -184,7 +184,7 @@ PanelWindow {
"loader": clipboardHistoryModalPopup, "loader": clipboardHistoryModalPopup,
"prop": "visible" "prop": "visible"
}, { }, {
"loader": archUpdaterLoader, "loader": systemUpdateLoader,
"prop": "shouldBeVisible" "prop": "shouldBeVisible"
}] }]
return notepadInstanceVisible || loaders.some(item => { return notepadInstanceVisible || loaders.some(item => {
@@ -377,7 +377,7 @@ PanelWindow {
"vpn": vpnComponent, "vpn": vpnComponent,
"notepadButton": notepadButtonComponent, "notepadButton": notepadButtonComponent,
"colorPicker": colorPickerComponent, "colorPicker": colorPickerComponent,
"archUpdater": archUpdaterComponent "systemUpdate": systemUpdateComponent
}) })
function getWidgetComponent(widgetId) { function getWidgetComponent(widgetId) {
@@ -1022,21 +1022,21 @@ PanelWindow {
} }
Component { Component {
id: archUpdaterComponent id: systemUpdateComponent
ArchUpdater { SystemUpdate {
isActive: archUpdaterLoader.item ? archUpdaterLoader.item.shouldBeVisible : false isActive: systemUpdateLoader.item ? systemUpdateLoader.item.shouldBeVisible : false
widgetHeight: root.widgetHeight widgetHeight: root.widgetHeight
barHeight: root.effectiveBarHeight barHeight: root.effectiveBarHeight
section: topBarContent.getWidgetSection(parent) || "right" section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: { popupTarget: {
archUpdaterLoader.active = true systemUpdateLoader.active = true
return archUpdaterLoader.item return systemUpdateLoader.item
} }
parentScreen: root.screen parentScreen: root.screen
onClicked: { onClicked: {
archUpdaterLoader.active = true systemUpdateLoader.active = true
archUpdaterLoader.item?.toggle() systemUpdateLoader.item?.toggle()
} }
} }
} }

View File

@@ -14,23 +14,48 @@ Singleton {
property bool isChecking: false property bool isChecking: false
property bool hasError: false property bool hasError: false
property string errorMessage: "" property string errorMessage: ""
property string aurHelper: "" property string pkgManager: ""
property string distribution: ""
property bool distributionSupported: false
readonly property list<string> supportedDistributions: ["arch", "cachyos", "manjaro", "endeavouros"]
readonly property int updateCount: availableUpdates.length readonly property int updateCount: availableUpdates.length
readonly property bool helperAvailable: aurHelper !== "" readonly property bool helperAvailable: pkgManager !== "" && distributionSupported
Process { Process {
id: helperDetection id: distributionDetection
command: ["sh", "-c", "which paru || which yay"] command: ["sh", "-c", "cat /etc/os-release | grep '^ID=' | cut -d'=' -f2 | tr -d '\"'"]
running: true running: true
onExited: (exitCode) => {
if (exitCode === 0) {
distribution = stdout.text.trim().toLowerCase()
distributionSupported = supportedDistributions.includes(distribution)
if (distributionSupported) {
helperDetection.running = true
} else {
console.warn("SystemUpdate: Unsupported distribution:", distribution)
}
} else {
console.warn("SystemUpdate: Failed to detect distribution")
}
}
stdout: StdioCollector {}
}
Process {
id: helperDetection
command: ["sh", "-c", "which paru || which yay"]
onExited: (exitCode) => { onExited: (exitCode) => {
if (exitCode === 0) { if (exitCode === 0) {
const helperPath = stdout.text.trim() const helperPath = stdout.text.trim()
aurHelper = helperPath.split('/').pop() pkgManager = helperPath.split('/').pop()
checkForUpdates() checkForUpdates()
} else { } else {
console.warn("ArchUpdater: No AUR helper found") console.warn("SystemUpdate: No package manager found")
} }
} }
@@ -50,7 +75,7 @@ Singleton {
} else { } else {
hasError = true hasError = true
errorMessage = "Failed to check for updates" errorMessage = "Failed to check for updates"
console.warn("ArchUpdater: Update check failed with code:", exitCode) console.warn("SystemUpdate: Update check failed with code:", exitCode)
} }
} }
@@ -65,11 +90,11 @@ Singleton {
} }
function checkForUpdates() { function checkForUpdates() {
if (!helperAvailable || isChecking) return if (!distributionSupported || !pkgManager || isChecking) return
isChecking = true isChecking = true
hasError = false hasError = false
updateChecker.command = [aurHelper, "-Qu"] updateChecker.command = [pkgManager, "-Qu"]
updateChecker.running = true updateChecker.running = true
} }
@@ -93,10 +118,10 @@ Singleton {
} }
function runUpdates() { function runUpdates() {
if (!helperAvailable || updateCount === 0) return if (!distributionSupported || !pkgManager || updateCount === 0) return
const terminal = Quickshell.env("TERMINAL") || "xterm" const terminal = Quickshell.env("TERMINAL") || "xterm"
const updateCommand = `${aurHelper} -Syu && echo "Updates complete! Press Enter to close..." && read` const updateCommand = `${pkgManager} -Syu && echo "Updates complete! Press Enter to close..." && read`
updater.command = [terminal, "-e", "sh", "-c", updateCommand] updater.command = [terminal, "-e", "sh", "-c", updateCommand]
updater.running = true updater.running = true
@@ -105,7 +130,7 @@ Singleton {
Timer { Timer {
interval: 30 * 60 * 1000 interval: 30 * 60 * 1000
repeat: true repeat: true
running: helperAvailable running: distributionSupported && pkgManager
onTriggered: checkForUpdates() onTriggered: checkForUpdates()
} }
} }

View File

@@ -274,12 +274,12 @@ ShellRoot {
} }
LazyLoader { LazyLoader {
id: archUpdaterLoader id: systemUpdateLoader
active: false active: false
ArchUpdaterPopout { SystemUpdatePopout {
id: archUpdaterPopout id: systemUpdatePopout
} }
} }