1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-30 01:22:06 -04:00
Files
DankMaterialShell/quickshell/Services/SystemUpdateService.qml
2026-04-29 14:56:54 -04:00

209 lines
5.9 KiB
QML

pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Common
Singleton {
id: root
property int refCount: 0
property bool sysupdateAvailable: false
property var availableUpdates: []
property bool isChecking: false
property bool isUpgrading: false
property bool hasError: false
property string errorMessage: ""
property string errorCode: ""
property var backends: []
property string distribution: ""
property string distributionPretty: ""
property string pkgManager: ""
property bool distributionSupported: false
property var recentLog: []
property int intervalSeconds: 1800
property int lastCheckUnix: 0
property int nextCheckUnix: 0
readonly property int updateCount: availableUpdates.length
readonly property bool helperAvailable: sysupdateAvailable && backends.length > 0
Connections {
target: DMSService
function onCapabilitiesReceived() {
root.checkCapabilities();
}
function onConnectionStateChanged() {
if (DMSService.isConnected) {
root.checkCapabilities();
} else {
root.sysupdateAvailable = false;
}
}
function onSysupdateStateUpdate(data) {
root._applyState(data);
}
}
Component.onCompleted: {
if (DMSService.dmsAvailable) {
checkCapabilities();
}
}
function checkCapabilities() {
if (!DMSService.capabilities || !Array.isArray(DMSService.capabilities)) {
sysupdateAvailable = false;
return;
}
const has = DMSService.capabilities.includes("sysupdate");
if (has && !sysupdateAvailable) {
sysupdateAvailable = true;
requestState();
} else if (!has) {
sysupdateAvailable = false;
}
}
function requestState() {
if (!DMSService.isConnected || !sysupdateAvailable) {
return;
}
DMSService.sysupdateGetState(resp => {
if (resp && resp.result) {
_applyState(resp.result);
}
});
}
function _applyState(data) {
if (!data) {
return;
}
availableUpdates = data.packages || [];
backends = data.backends || [];
distribution = data.distro || "";
distributionPretty = data.distroPretty || "";
distributionSupported = (backends.length > 0);
recentLog = data.recentLog || [];
intervalSeconds = data.intervalSeconds || 1800;
lastCheckUnix = data.lastCheckUnix || 0;
nextCheckUnix = data.nextCheckUnix || 0;
const phase = data.phase || "idle";
switch (phase) {
case "refreshing":
isChecking = true;
isUpgrading = false;
break;
case "upgrading":
isChecking = false;
isUpgrading = true;
break;
default:
isChecking = false;
isUpgrading = false;
}
if (data.error) {
hasError = true;
errorMessage = data.error.message || "";
errorCode = data.error.code || "";
} else {
hasError = false;
errorMessage = "";
errorCode = "";
}
if (backends.length > 0) {
const sys = backends.find(b => b.repo === "system" || b.repo === "ostree");
pkgManager = sys ? sys.id : backends[0].id;
} else {
pkgManager = "";
}
}
function checkForUpdates() {
DMSService.sysupdateRefresh(false, null);
}
function runUpdates(opts) {
const params = opts || {};
if (SettingsData.updaterUseCustomCommand && SettingsData.updaterCustomCommand.length > 0) {
_runCustomTerminalCommand();
return;
}
DMSService.sysupdateUpgrade(params, null);
}
function cancelUpdates() {
DMSService.sysupdateCancel(null);
}
function setInterval(seconds) {
DMSService.sysupdateSetInterval(seconds, null);
}
function _runCustomTerminalCommand() {
const terminal = SessionData.resolveTerminal();
if (!terminal || terminal.length === 0) {
ToastService.showError(I18n.tr("No terminal configured"), I18n.tr("Pick a terminal in Settings → Launcher (or set $TERMINAL)."));
return;
}
const updateCommand = `${SettingsData.updaterCustomCommand} && echo -n "Updates complete! " ; echo "Press Enter to close..." && read`;
const termClass = SettingsData.updaterTerminalAdditionalParams || "";
var argv = [terminal];
if (termClass.length > 0) {
argv = argv.concat(termClass.split(" "));
}
argv.push("-e");
argv.push("sh");
argv.push("-c");
argv.push(updateCommand);
customRunner.command = argv;
customRunner.running = true;
}
Process {
id: customRunner
onExited: root.checkForUpdates()
}
onRefCountChanged: _syncAcquire()
onSysupdateAvailableChanged: _syncAcquire()
property bool _acquired: false
function _syncAcquire() {
const want = refCount > 0 && sysupdateAvailable;
if (want === _acquired) {
return;
}
_acquired = want;
if (want) {
DMSService.sysupdateAcquire(null);
return;
}
DMSService.sysupdateRelease(null);
}
IpcHandler {
target: "systemupdater"
function updatestatus(): string {
if (root.isChecking) {
return "ERROR: already checking";
}
if (root.backends.length === 0) {
return "ERROR: no package manager available";
}
root.checkForUpdates();
return "SUCCESS: Now checking...";
}
}
}