fix: sidetone slider commits on drag end, track and roll back control state
This commit is contained in:
1 parent
eb20480321
commit
b2364082f0
1 file changed
+75
-25
+75
-25
@@ -8,9 +8,15 @@ local state = {
|
||||
caps = {},
|
||||
equalizerPresets = 0,
|
||||
sidetone = nil,
|
||||
voicePrompts = false,
|
||||
volumeLimiter = false,
|
||||
eqPreset = 0,
|
||||
inactive = 0,
|
||||
}
|
||||
|
||||
local INACTIVE_VALUES = { 0, 1, 2, 5, 10, 15, 20, 30, 45, 60, 90 }
|
||||
local INACTIVE_LABELS = { noctalia.tr("panel.never"), "1", "2", "5", "10", "15", "20", "30", "45", "60", "90" }
|
||||
local committedSidetone = 64
|
||||
|
||||
local function syncState()
|
||||
local v = noctalia.state.get("device")
|
||||
@@ -24,12 +30,16 @@ local function syncState()
|
||||
v = noctalia.state.get("equalizerPresets")
|
||||
if v then state.equalizerPresets = v end
|
||||
v = noctalia.state.get("sidetone")
|
||||
if v ~= nil then state.sidetone = v end
|
||||
if v ~= nil then
|
||||
state.sidetone = v
|
||||
committedSidetone = v
|
||||
end
|
||||
end
|
||||
|
||||
local function send(flag, value, onOk)
|
||||
local function send(flag, value, onOk, onFail)
|
||||
hsc.sendCommand({ flag, value }, function(res)
|
||||
if res.exitCode ~= 0 then
|
||||
if onFail then onFail() end
|
||||
noctalia.notifyError(noctalia.tr("error.command_failed"), string.sub(res.stderr or "", 1, 200))
|
||||
return
|
||||
end
|
||||
@@ -44,33 +54,53 @@ function onSidetone(value) -- live drag update
|
||||
render()
|
||||
end
|
||||
|
||||
function onSidetoneEnd(value)
|
||||
local v = tonumber(value)
|
||||
if v then
|
||||
send("-s", tostring(v), function()
|
||||
noctalia.state.set("sidetone", v)
|
||||
end)
|
||||
end
|
||||
function onSidetoneEnd(_value)
|
||||
local v = state.sidetone
|
||||
if v == nil then return end
|
||||
local prev = committedSidetone
|
||||
send("-s", tostring(v), function()
|
||||
committedSidetone = v
|
||||
noctalia.state.set("sidetone", v)
|
||||
end, function()
|
||||
state.sidetone = prev
|
||||
render()
|
||||
end)
|
||||
end
|
||||
|
||||
function onSidetoneOff()
|
||||
local prev = committedSidetone
|
||||
send("-s", "0", function()
|
||||
state.sidetone = 0
|
||||
committedSidetone = 0
|
||||
noctalia.state.set("sidetone", 0)
|
||||
end, function()
|
||||
state.sidetone = prev
|
||||
render()
|
||||
end)
|
||||
end
|
||||
|
||||
function onEqPreset(idx)
|
||||
local i = tonumber(idx) or 0
|
||||
send("-p", tostring(i))
|
||||
local prev = state.eqPreset
|
||||
state.eqPreset = i
|
||||
render()
|
||||
send("-p", tostring(i), nil, function()
|
||||
state.eqPreset = prev
|
||||
render()
|
||||
end)
|
||||
end
|
||||
|
||||
function onInactive(idx)
|
||||
local i = tonumber(idx) or 0
|
||||
local value = INACTIVE_VALUES[i + 1]
|
||||
if value ~= nil then
|
||||
send("-i", tostring(value))
|
||||
end
|
||||
if value == nil then return end
|
||||
local prev = state.inactive
|
||||
state.inactive = i
|
||||
render()
|
||||
send("-i", tostring(value), nil, function()
|
||||
state.inactive = prev
|
||||
render()
|
||||
end)
|
||||
end
|
||||
|
||||
local function noiseButtons()
|
||||
@@ -115,7 +145,7 @@ local function render()
|
||||
end
|
||||
|
||||
if caps.sidetone then
|
||||
local st = state.sidetone or noctalia.getConfig("sidetone_default") or 64
|
||||
local st = state.sidetone or committedSidetone or 64
|
||||
table.insert(rows, ui.row({ gap = 8, align = "center" }, {
|
||||
ui.label({ text = noctalia.tr("panel.sidetone") .. ":", width = 120 }),
|
||||
ui.slider({
|
||||
@@ -134,15 +164,18 @@ local function render()
|
||||
end
|
||||
table.insert(rows, ui.row({ gap = 8, align = "center" }, {
|
||||
ui.label({ text = noctalia.tr("panel.equalizer") .. ":", width = 120 }),
|
||||
ui.select({ options = opts, selectedIndex = 0, flexGrow = 1, onChange = "onEqPreset" }),
|
||||
ui.select({ options = opts, selectedIndex = state.eqPreset, flexGrow = 1, onChange = "onEqPreset" }),
|
||||
}))
|
||||
end
|
||||
|
||||
if caps.inactive_time then
|
||||
local opts = { noctalia.tr("panel.never"), "1", "2", "5", "10", "15", "20", "30", "45", "60", "90" }
|
||||
local opts = {}
|
||||
for i, value in ipairs(INACTIVE_VALUES) do
|
||||
table.insert(opts, INACTIVE_LABELS[i] or tostring(value))
|
||||
end
|
||||
table.insert(rows, ui.row({ gap = 8, align = "center" }, {
|
||||
ui.label({ text = noctalia.tr("panel.inactive_time") .. ":", width = 120 }),
|
||||
ui.select({ options = opts, selectedIndex = 0, flexGrow = 1, onChange = "onInactive" }),
|
||||
ui.select({ options = opts, selectedIndex = state.inactive, flexGrow = 1, onChange = "onInactive" }),
|
||||
}))
|
||||
end
|
||||
|
||||
@@ -153,30 +186,40 @@ local function render()
|
||||
if caps.voice_prompts then
|
||||
table.insert(rows, ui.row({ gap = 8, align = "center", justify = "space_between" }, {
|
||||
ui.label({ text = noctalia.tr("panel.voice_prompts") }),
|
||||
ui.toggle({ checked = false, onChange = "onVoicePrompts" }),
|
||||
ui.toggle({ checked = state.voicePrompts, onChange = "onVoicePrompts" }),
|
||||
}))
|
||||
end
|
||||
|
||||
if caps.volume_limiter then
|
||||
table.insert(rows, ui.row({ gap = 8, align = "center", justify = "space_between" }, {
|
||||
ui.label({ text = noctalia.tr("panel.volume_limiter") }),
|
||||
ui.toggle({ checked = false, onChange = "onVolumeLimiter" }),
|
||||
ui.toggle({ checked = state.volumeLimiter, onChange = "onVolumeLimiter" }),
|
||||
}))
|
||||
end
|
||||
|
||||
if #rows == 0 then
|
||||
table.insert(rows, ui.label({ text = noctalia.tr("panel.no_caps"), opacity = 0.6 }))
|
||||
end
|
||||
|
||||
panel.render(ui.column({ gap = 12, padding = 16 }, rows))
|
||||
end
|
||||
|
||||
function onVoicePrompts(value)
|
||||
send("-v", value == "true" and "1" or "0")
|
||||
local newVal = value == "true"
|
||||
local prev = state.voicePrompts
|
||||
state.voicePrompts = newVal
|
||||
render()
|
||||
send("-v", newVal and "1" or "0", nil, function()
|
||||
state.voicePrompts = prev
|
||||
render()
|
||||
end)
|
||||
end
|
||||
|
||||
function onVolumeLimiter(value)
|
||||
send("--volume-limiter", value == "true" and "1" or "0")
|
||||
local newVal = value == "true"
|
||||
local prev = state.volumeLimiter
|
||||
state.volumeLimiter = newVal
|
||||
render()
|
||||
send("--volume-limiter", newVal and "1" or "0", nil, function()
|
||||
state.volumeLimiter = prev
|
||||
render()
|
||||
end)
|
||||
end
|
||||
|
||||
function onOpen(_context)
|
||||
@@ -197,3 +240,10 @@ noctalia.state.watch("chatmix", function() render() end)
|
||||
noctalia.state.watch("caps", function() render() end)
|
||||
noctalia.state.watch("equalizerPresets", function() render() end)
|
||||
noctalia.state.watch("device", function() render() end)
|
||||
noctalia.state.watch("sidetone", function(v)
|
||||
if v ~= nil then
|
||||
state.sidetone = v
|
||||
committedSidetone = v
|
||||
end
|
||||
render()
|
||||
end)
|
||||
Reference in new issue
Block a user