diff --git a/tailscalectl/TailscaleWidget.qml b/tailscalectl/TailscaleWidget.qml index 01d88f3..0c9e844 100644 --- a/tailscalectl/TailscaleWidget.qml +++ b/tailscalectl/TailscaleWidget.qml @@ -3,21 +3,94 @@ import qs.Common import qs.Services import qs.Widgets import qs.Modules.Plugins +import Quickshell.Io PluginComponent { id: root + property bool isConnected: false + + Process { + id: toggleProcess + + onExited: (code, status) => { + statusCheck.running = true + } + } + + Process { + id: statusCheck + + command: ["tailscale", "status", "--json"] + + stdout: StdioCollector { + onStreamFinished: { + try { + const data = JSON.parse(this.text) + root.isConnected = data.BackendState === "Running" + } catch (e) { + root.isConnected = false + } + } + } + + onExited: (code, status) => { + if (code !== 0) { + root.isConnected = false + } + } + } + + function toggleTailscale() { + if (root.isConnected) { + toggleProcess.command = ["tailscale", "down"] + } else { + toggleProcess.command = ["tailscale", "up"] + } + toggleProcess.running = true + } + horizontalBarPill: Component { - StyledText { - text: "TS" - color: Theme.surfaceText + MouseArea { + implicitWidth: contentRow.implicitWidth + implicitHeight: contentRow.implicitHeight + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.RightButton + onClicked: toggleTailscale() + + Row { + id: contentRow + spacing: Theme.spacingS + + DankIcon { + name: root.isConnected ? "vpn_key" : "vpn_key_off" + size: Theme.iconSize + color: root.isConnected ? Theme.primary : Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + } } } verticalBarPill: Component { - StyledText { - text: "TS" - color: Theme.surfaceText + MouseArea { + implicitWidth: contentColumn.implicitWidth + implicitHeight: contentColumn.implicitHeight + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.RightButton + onClicked: toggleTailscale() + + Column { + id: contentColumn + spacing: Theme.spacingXS + + DankIcon { + name: root.isConnected ? "vpn_key" : "vpn_key_off" + size: Theme.iconSize + color: root.isConnected ? Theme.primary : Theme.surfaceText + anchors.horizontalCenter: parent.horizontalCenter + } + } } } }