feat: bar widget shows battery with scroll-sidetone control
This commit is contained in:
1 parent
d77dc7eff4
commit
1011d43b2e
1 file changed
+128
@@ -0,0 +1,128 @@
|
||||
local hsc = require("./lib/hsc.luau")
|
||||
|
||||
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 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)
|
||||
hsc.sendCommand({ "-s", tostring(value) }, function(res)
|
||||
if res.exitCode ~= 0 then
|
||||
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
|
||||
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()
|
||||
Reference in new issue
Block a user