ed063ab1fe
Capture desktop-specific system, session, Noctalia, and Pi integration alongside shared laptop support. Retire obsolete X11 configuration and make package ownership explicit for repeatable Decman deployments.
103 lines
3.8 KiB
Lua
103 lines
3.8 KiB
Lua
local request_in_flight = false
|
|
|
|
local function shell_quote(value)
|
|
return "'" .. string.gsub(value, "'", "'\\\"'\\\"'") .. "'"
|
|
end
|
|
|
|
local function ui_binary()
|
|
local configured = noctalia.getenv("PI_STATUS_UI_BINARY")
|
|
if configured ~= nil and configured ~= "" then return configured end
|
|
return (noctalia.getenv("HOME") or "") .. "/projects/pi-status-bridge/ui/src-tauri/target/release/pi-status-ui"
|
|
end
|
|
|
|
local function bridge_client_binary()
|
|
local configured = noctalia.getenv("PI_STATUS_BRIDGE_CLIENT")
|
|
if configured ~= nil and configured ~= "" then return shell_quote(configured) end
|
|
return "pi-status-bridge-client"
|
|
end
|
|
|
|
local function socket_path()
|
|
local runtime = noctalia.getenv("XDG_RUNTIME_DIR")
|
|
if runtime == nil or runtime == "" then return nil end
|
|
return runtime .. "/pi-status-bridge/bridge.sock"
|
|
end
|
|
|
|
local bridge_start_in_flight = false
|
|
local pending_ui_open = false
|
|
|
|
local function open_ui()
|
|
local binary = shell_quote(ui_binary())
|
|
local command = "if test -x " .. binary .. "; then setsid -f env TMPDIR=/tmp "
|
|
.. binary .. " --toggle >/tmp/pi-status-ui.log 2>&1; else exit 1; fi"
|
|
noctalia.runAsync(command, function(result)
|
|
if result.exitCode ~= 0 then
|
|
barWidget.setGlyph("alert-triangle")
|
|
barWidget.setText("Pi UI unavailable")
|
|
barWidget.setTooltip("Build Pi Status UI or set PI_STATUS_UI_BINARY")
|
|
end
|
|
end)
|
|
end
|
|
|
|
local function start_bridge(open_after_start)
|
|
if open_after_start then pending_ui_open = true end
|
|
if bridge_start_in_flight then return end
|
|
bridge_start_in_flight = true
|
|
barWidget.setGlyph("terminal-2")
|
|
barWidget.setText("Pi starting")
|
|
barWidget.setTooltip("Bridge is starting")
|
|
noctalia.runAsync("systemctl --user start pi-status-bridge.service", function(result)
|
|
bridge_start_in_flight = false
|
|
if result.exitCode ~= 0 then
|
|
pending_ui_open = false
|
|
barWidget.setGlyph("alert-triangle")
|
|
barWidget.setText("Pi offline")
|
|
barWidget.setTooltip("Could not start pi-status-bridge.service")
|
|
return
|
|
end
|
|
if pending_ui_open then pending_ui_open = false; open_ui() end
|
|
end)
|
|
end
|
|
|
|
local function json_count(payload, key)
|
|
local value = string.match(payload, '"' .. key .. '":(%d+)')
|
|
return tonumber(value) or 0
|
|
end
|
|
|
|
local function update_summary(payload)
|
|
local open = json_count(payload, "openCount")
|
|
local working = json_count(payload, "workingCount")
|
|
local attention = json_count(payload, "attentionCount")
|
|
local recovering = json_count(payload, "recoveringCount")
|
|
local errors = json_count(payload, "errorCount")
|
|
local glyph = errors > 0 and "alert-triangle" or attention > 0 and "circle-alert" or working > 0 and "terminal-2" or recovering > 0 and "refresh-cw" or "terminal"
|
|
local text = errors > 0 and "Pi needs attention" or working > 0 and "Pi working" or recovering > 0 and "Pi recovering" or "Pi ready"
|
|
local detail = open .. " open · " .. working .. " working · " .. attention .. " attention · " .. recovering .. " recovering · " .. errors .. " errors"
|
|
barWidget.setGlyph(glyph)
|
|
barWidget.setText(text)
|
|
barWidget.setTooltip(detail .. "; click to open Pi Status UI")
|
|
end
|
|
|
|
function update()
|
|
noctalia.setUpdateInterval(2000)
|
|
local socket = socket_path()
|
|
if socket == nil then start_bridge(false); return end
|
|
if request_in_flight then return end
|
|
request_in_flight = true
|
|
local command = bridge_client_binary() .. " --socket \"" .. socket .. "\" request '{\"op\":\"get_workspace_summary\"}'"
|
|
noctalia.runAsync(command, function(result)
|
|
request_in_flight = false
|
|
if result.exitCode ~= 0 then
|
|
start_bridge(false)
|
|
barWidget.setGlyph("terminal-2")
|
|
barWidget.setText("Pi reconnecting")
|
|
barWidget.setTooltip("Refreshing Pi workspace summary")
|
|
return
|
|
end
|
|
update_summary(result.stdout)
|
|
end)
|
|
end
|
|
|
|
function onClick()
|
|
start_bridge(true)
|
|
end
|