144 lines
4.4 KiB
Luau
144 lines
4.4 KiB
Luau
local hsc = require("./lib/hsc.luau")
|
|
|
|
hsc.init({
|
|
device = noctalia.getConfig("device"),
|
|
mock = noctalia.getConfig("mock"),
|
|
wake_sink = noctalia.getConfig("wake_sink"),
|
|
})
|
|
|
|
local battery = { status = "BATTERY_UNAVAILABLE", level = -1 }
|
|
local chatmix = 0
|
|
local caps = {}
|
|
local device = nil
|
|
local errorState = ""
|
|
local sidetoneValue = nil
|
|
local sidetoneFlashUntil = 0
|
|
|
|
local function statusKey(status)
|
|
if status == "BATTERY_CHARGING" then return "status.charging" end
|
|
if status == "BATTERY_FULL" then return "status.full" end
|
|
if status == "BATTERY_DISCHARGING" then return "status.discharging" end
|
|
return "status.normal"
|
|
end
|
|
|
|
local function batteryGlyph()
|
|
if battery.status == "BATTERY_CHARGING" then return "battery-charging" end
|
|
if battery.level < 0 then return "battery-off" end
|
|
if battery.level <= 25 then return "battery-1" end
|
|
if battery.level <= 50 then return "battery-2" end
|
|
if battery.level <= 75 then return "battery-3" end
|
|
return "battery-4"
|
|
end
|
|
|
|
local function batteryColor()
|
|
local low = noctalia.getConfig("battery_low") or 20
|
|
if battery.level < 0 then return "#6e7681" end
|
|
if battery.level <= low then return "#e5484d" end
|
|
if battery.status == "BATTERY_CHARGING" then return "#3fb950" end
|
|
return "#7ee787"
|
|
end
|
|
|
|
local function render()
|
|
if not barWidget then return end
|
|
if errorState == "no_binary" then
|
|
barWidget.setGlyph("alert-triangle")
|
|
barWidget.setColor("#e5484d")
|
|
barWidget.setGlyphColor("#e5484d")
|
|
barWidget.setText("")
|
|
barWidget.setTooltip(noctalia.tr("error.no_binary"))
|
|
return
|
|
end
|
|
|
|
if noctalia.nowMs() < sidetoneFlashUntil and sidetoneValue ~= nil then
|
|
barWidget.setGlyph("music")
|
|
barWidget.setColor("#e6edf3")
|
|
barWidget.setGlyphColor("#e6edf3")
|
|
barWidget.setText(tostring(sidetoneValue))
|
|
else
|
|
barWidget.setGlyph(batteryGlyph())
|
|
local col = batteryColor()
|
|
barWidget.setColor(col)
|
|
barWidget.setGlyphColor(col)
|
|
if battery.level < 0 then
|
|
barWidget.setText("--")
|
|
else
|
|
barWidget.setText(tostring(battery.level) .. "%")
|
|
end
|
|
end
|
|
|
|
local parts = {}
|
|
if device and device.name then
|
|
table.insert(parts, device.name)
|
|
end
|
|
if battery.level >= 0 then
|
|
table.insert(parts, noctalia.tr(statusKey(battery.status)) .. " " .. battery.level .. "%")
|
|
elseif errorState == "unavailable" then
|
|
table.insert(parts, noctalia.tr("status.unavailable"))
|
|
end
|
|
if caps.chatmix then
|
|
table.insert(parts, noctalia.tr("widget.chatmix") .. ": " .. hsc.chatmixText(chatmix))
|
|
end
|
|
barWidget.setTooltip(table.concat(parts, " "))
|
|
end
|
|
|
|
local function sendSidetone(value)
|
|
value = math.clamp(value, 0, 128)
|
|
local previous = sidetoneValue
|
|
hsc.sendCommand({ "-s", tostring(value) }, function(res)
|
|
if res.exitCode ~= 0 then
|
|
if previous ~= nil then
|
|
sidetoneValue = previous
|
|
end
|
|
sidetoneFlashUntil = 0
|
|
render()
|
|
noctalia.notifyError(noctalia.tr("error.command_failed"), string.sub(res.stderr or "", 1, 200))
|
|
return
|
|
end
|
|
noctalia.state.set("sidetone", value)
|
|
end)
|
|
sidetoneValue = value
|
|
sidetoneFlashUntil = noctalia.nowMs() + 2000
|
|
render()
|
|
end
|
|
|
|
function onScroll(axis, steps)
|
|
if axis ~= "vertical" then return end
|
|
if not caps.sidetone or errorState ~= "" then return end
|
|
local current = sidetoneValue or noctalia.getConfig("sidetone_default") or 64
|
|
sendSidetone(current + steps * 4)
|
|
end
|
|
|
|
function onClick()
|
|
noctalia.togglePanel("loki/headsetcontrol:control")
|
|
end
|
|
|
|
function update()
|
|
noctalia.setUpdateInterval(1000)
|
|
render()
|
|
end
|
|
|
|
local function syncState()
|
|
local v = noctalia.state.get("battery")
|
|
if v then battery = v end
|
|
v = noctalia.state.get("chatmix")
|
|
if v ~= nil then chatmix = v end
|
|
v = noctalia.state.get("caps")
|
|
if v then caps = v end
|
|
v = noctalia.state.get("device")
|
|
if v then device = v end
|
|
v = noctalia.state.get("error")
|
|
if v ~= nil then errorState = v end
|
|
v = noctalia.state.get("sidetone")
|
|
if v ~= nil then sidetoneValue = v end
|
|
end
|
|
|
|
noctalia.state.watch("battery", function(v) battery = v or battery; render() end)
|
|
noctalia.state.watch("chatmix", function(v) chatmix = v or 0; render() end)
|
|
noctalia.state.watch("caps", function(v) caps = v or {}; render() end)
|
|
noctalia.state.watch("device", function(v) device = v; render() end)
|
|
noctalia.state.watch("error", function(v) errorState = v or ""; render() end)
|
|
noctalia.state.watch("sidetone", function(v) if v ~= nil then sidetoneValue = v end end)
|
|
|
|
syncState()
|
|
render()
|