1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -05:00
Files
DankMaterialShell/Services/DMSService.qml
2025-10-08 14:51:38 -04:00

240 lines
6.5 KiB
QML

pragma Singleton
pragma ComponentBehavior: Bound
import QtCore
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Common
Singleton {
id: root
property bool dmsAvailable: false
property var capabilities: []
property var availablePlugins: []
property var installedPlugins: []
property bool isConnected: false
property bool isConnecting: false
readonly property string socketPath: Quickshell.env("DMS_SOCKET")
property var pendingRequests: ({})
property int requestIdCounter: 0
signal pluginsListReceived(var plugins)
signal installedPluginsReceived(var plugins)
signal searchResultsReceived(var plugins)
signal operationSuccess(string message)
signal operationError(string error)
signal connectionStateChanged()
Component.onCompleted: {
if (socketPath && socketPath.length > 0) {
testProcess.running = true
}
}
Process {
id: testProcess
command: ["test", "-S", root.socketPath]
onExited: exitCode => {
if (exitCode === 0) {
root.dmsAvailable = true
connectSocket()
} else {
root.dmsAvailable = false
}
}
}
function connectSocket() {
if (!dmsAvailable || isConnected || isConnecting) {
return
}
isConnecting = true
socket.connected = true
}
DankSocket {
id: socket
path: root.socketPath
connected: false
onConnectionStateChanged: {
if (connected) {
root.isConnected = true
root.isConnecting = false
root.connectionStateChanged()
} else {
root.isConnected = false
root.isConnecting = false
root.connectionStateChanged()
}
}
parser: SplitParser {
onRead: line => {
if (!line || line.length === 0) {
return
}
try {
const response = JSON.parse(line)
if (response.capabilities) {
root.capabilities = response.capabilities
return
}
handleResponse(response)
} catch (e) {
console.warn("DMSService: Failed to parse response:", line, e)
}
}
}
}
function sendRequest(method, params, callback) {
if (!isConnected) {
if (callback) {
callback({
"error": "not connected to DMS socket"
})
}
return
}
requestIdCounter++
const id = Date.now() + requestIdCounter
const request = {
"id": id,
"method": method
}
if (params) {
request.params = params
}
if (callback) {
pendingRequests[id] = callback
}
socket.send(request)
}
property var networkUpdateCallback: null
function handleResponse(response) {
if (response.id === undefined && response.result) {
if (response.result.type === "state_changed" && response.result.data) {
if (networkUpdateCallback) {
networkUpdateCallback(response.result.data)
}
}
return
}
const callback = pendingRequests[response.id]
if (callback) {
delete pendingRequests[response.id]
callback(response)
}
}
function ping(callback) {
sendRequest("ping", null, callback)
}
function listPlugins(callback) {
sendRequest("plugins.list", null, response => {
if (response.result) {
availablePlugins = response.result
pluginsListReceived(response.result)
}
if (callback) {
callback(response)
}
})
}
function listInstalled(callback) {
sendRequest("plugins.listInstalled", null, response => {
if (response.result) {
installedPlugins = response.result
installedPluginsReceived(response.result)
}
if (callback) {
callback(response)
}
})
}
function search(query, category, compositor, capability, callback) {
const params = {
"query": query
}
if (category) {
params.category = category
}
if (compositor) {
params.compositor = compositor
}
if (capability) {
params.capability = capability
}
sendRequest("plugins.search", params, response => {
if (response.result) {
searchResultsReceived(response.result)
}
if (callback) {
callback(response)
}
})
}
function install(pluginName, callback) {
sendRequest("plugins.install", {
"name": pluginName
}, response => {
if (callback) {
callback(response)
}
if (!response.error) {
listInstalled()
}
})
}
function uninstall(pluginName, callback) {
sendRequest("plugins.uninstall", {
"name": pluginName
}, response => {
if (callback) {
callback(response)
}
if (!response.error) {
listInstalled()
}
})
}
function update(pluginName, callback) {
sendRequest("plugins.update", {
"name": pluginName
}, response => {
if (callback) {
callback(response)
}
if (!response.error) {
listInstalled()
}
})
}
}