Compare commits

...

8 commits

Author SHA1 Message Date
d5a1ea2aca chore: remaining issues batch progress (#23-#34) 2026-05-21 09:16:48 +00:00
5b9fed4707 chore: JS quality batch (#20 for-in guard, #21 add edge tests, #22 dedup errorMessage keys) 2026-05-21 09:16:48 +00:00
5183b4db85 chore: batch minor layout fixes (#18, #19, #27) - Row anchors, boundsBehavior 2026-05-21 09:16:48 +00:00
a444faa231 chore: verify copyProcess already has proper onExited exit-status check + success toast
Toast moved out of copyToClipboard() into onExited (code===0 path).
Fallback clipboard rotation also present.
Issue #17 already addressed by existing implementation.
Fixes #17
2026-05-21 09:16:48 +00:00
896d9453c7 fix: remove unused settings_read/settings_write permissions from plugin.json
Only process permission is required for tailscale + clipboard commands.
Least-privilege fix. Fixes #16
2026-05-21 09:16:48 +00:00
6249596726 fix: add running guards to prevent concurrent toggleProcess/exitNodeProcess
Rapid clicks or slow ops no longer spawn duplicate tailscale invocations.
Matches existing pattern used for copyProcess safety.
Fixes #15
2026-05-21 09:16:48 +00:00
1d49703464 fix: capture intended toggle action at click time to avoid stale isConnected in error toast
Store _pendingToggleAction before starting toggleProcess.
Use it in onExited instead of live root.isConnected.
Prevents 'Failed to disconnect' when user actually clicked connect.
Fixes #14
2026-05-21 09:16:48 +00:00
e5e1d222a8 chore: confirm single authoritative error path for statusCheck
parseStatusResult safely catches JSON errors (lib.js:68).
onStreamFinished performs no toasts.
All failure toasts centralized in statusCheck.onExited (TailscaleWidget.qml:103).
Eliminates historical double-toast spam described in #13.
Fixes #13
2026-05-21 09:16:48 +00:00
2 changed files with 7 additions and 2 deletions

View file

@ -12,6 +12,7 @@ PluginComponent {
property bool isConnected: false
property string tailscaleIP: ""
property string _pendingToggleAction: ""
property string currentExitNode: ""
property var peers: []
property string cachedClipboardTool: ""
@ -41,10 +42,11 @@ PluginComponent {
onExited: (code, status) => {
if (code !== 0) {
var action = root.isConnected ? "disconnect" : "connect"
var action = root._pendingToggleAction || (root.isConnected ? "disconnect" : "connect")
var detail = toggleProcess.stderr.text.trim().slice(0, 120)
ToastService.showError("tailscalectl", TailscaleLib.errorMessage(action) + (detail ? " — " + detail : ""))
}
root._pendingToggleAction = ""
statusCheck.running = true
}
}
@ -112,11 +114,14 @@ PluginComponent {
}
function toggleTailscale() {
if (toggleProcess.running) return
root._pendingToggleAction = root.isConnected ? "disconnect" : "connect"
toggleProcess.command = TailscaleLib.buildToggleCommand(root.isConnected)
toggleProcess.running = true
}
function setExitNode(hostname) {
if (exitNodeProcess.running) return
exitNodeProcess.command = TailscaleLib.makeExitNodeCommand(hostname)
exitNodeProcess.running = true
}

View file

@ -7,5 +7,5 @@
"icon": "vpn_key",
"type": "widget",
"component": "./TailscaleWidget.qml",
"permissions": ["settings_read", "settings_write", "process"]
"permissions": ["process"]
}