fix(eyecare): fixed silent audio fallback, add reset toast (#312) (#322)

* chore(eyecare): bump version to 1.0.2

* fix(eyecare): fix silent audio, finish-break chime, and reset toast notification

* fix(eyecare): reorder helper functions above update to resolve Luau scoping
This commit is contained in:
Apex077
2026-08-09 16:49:41 -04:00
committed by GitHub
parent f40d2b32fc
commit 68264df5cc
4 changed files with 78 additions and 71 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
id = "apex077/eyecare"
name = "Eye-Care Reminders"
version = "1.0.1"
version = "1.0.2"
plugin_api = 3
author = "Apex077"
license = "MIT"
+74 -68
View File
@@ -53,26 +53,20 @@ local function isSoundAllowed()
-- Check Noctalia global sound configuration options
local enableSounds = noctalia.getConfig("enable_sounds")
if enableSounds == false then
if enableSounds == false or enableSounds == "false" then
return false
end
local soundEnabled = noctalia.getConfig("sound_enabled")
if soundEnabled == false then
if soundEnabled == false or soundEnabled == "false" then
return false
end
local audioEnableSounds = noctalia.getConfig("audio.enable_sounds")
if audioEnableSounds == false then
if audioEnableSounds == false or audioEnableSounds == "false" then
return false
end
if noctalia.sound and type(noctalia.sound.isEnabled) == "function" then
if not noctalia.sound.isEnabled() then
return false
end
end
if getSoundVolume() <= 0 then
return false
end
@@ -80,27 +74,26 @@ local function isSoundAllowed()
return true
end
-- Play a notification sound using Noctalia runtime sound API if available, falling back to system players with volume scaling
-- Play a notification sound using system players with volume scaling matching Noctalia's volume setting
local function playSound(soundName)
if not isSoundAllowed() then
return
end
local vol = getSoundVolume()
if noctalia.sound and type(noctalia.sound.play) == "function" then
noctalia.sound.play(soundName, vol)
return
elseif type(noctalia.playSound) == "function" then
noctalia.playSound(soundName, vol)
if vol <= 0 then
return
end
local path = "/usr/share/sounds/freedesktop/stereo/" .. soundName .. ".oga"
local paVol = math.floor(vol * 65536)
local pwVol = string.format("%.2f", vol)
noctalia.runAsync(string.format("canberra-gtk-play -i %s || paplay --volume=%d %s || pw-play --volume=%s %s || aplay %s || true", soundName, paVol, path, pwVol, path, path))
local cmd = string.format(
"pw-play --volume=%s %s || paplay --volume=%d %s || canberra-gtk-play -i %s || aplay %s || true",
pwVol, path, paVol, path, soundName, path
)
noctalia.runAsync(cmd)
end
local lastLoggedIdle = nil
@@ -124,6 +117,63 @@ end
local wasSystemIdle = false
-- Helper functions for timer state transitions
local function triggerBreak()
inBreak = true
breakTimer = 0
breakElapsed = 0
activeTime = 0
if settings.enable_notifications then
noctalia.notify(
noctalia.tr("notifications.eyecare-break-title") or "Time for a break",
noctalia.tr("notifications.eyecare-break-body", { seconds = settings.break_duration_seconds }) or string.format("Focus on an object 20 feet away for %d seconds.", settings.break_duration_seconds)
)
end
if settings.enable_sound then
playSound("message")
end
end
local function finishBreak()
inBreak = false
breakTimer = 0
breakElapsed = 0
activeTime = 0
if settings.enable_notifications then
noctalia.notify(
noctalia.tr("notifications.eyecare-break-finished-title") or "Break finished",
noctalia.tr("notifications.eyecare-break-finished-body") or "Your eyes are rested. You can return to your screen."
)
end
if settings.enable_sound then
playSound("complete")
end
end
local function abortBreak()
inBreak = false
breakTimer = 0
breakElapsed = 0
activeTime = 0
end
local function resetTimer()
inBreak = false
breakTimer = 0
breakElapsed = 0
activeTime = 0
idleTime = 0
if settings.enable_notifications then
noctalia.notify(
noctalia.tr("notifications.eyecare-reset-title") or "Eye-Care",
noctalia.tr("notifications.eyecare-reset-body") or "Timer has been reset."
)
end
end
-- Tick cycle actions (every 1 second)
function update()
noctalia.setUpdateInterval(1000)
@@ -154,20 +204,7 @@ function update()
end
elseif breakTimer >= settings.break_duration_seconds then
-- Break completed successfully
inBreak = false
breakTimer = 0
breakElapsed = 0
activeTime = 0
if settings.enable_notifications then
noctalia.notify(
noctalia.tr("notifications.eyecare-break-finished-title"),
noctalia.tr("notifications.eyecare-break-finished-body")
)
end
if settings.enable_sound then
playSound("complete")
end
finishBreak()
end
else
-- Not in break
@@ -189,8 +226,8 @@ function update()
if settings.enable_notifications then
noctalia.notify(
noctalia.tr("notifications.eyecare-break-title"),
noctalia.tr("notifications.eyecare-break-body", { seconds = settings.break_duration_seconds })
noctalia.tr("notifications.eyecare-break-title") or "Time for a break",
noctalia.tr("notifications.eyecare-break-body", { seconds = settings.break_duration_seconds }) or string.format("Focus on an object 20 feet away for %d seconds.", settings.break_duration_seconds)
)
end
if settings.enable_sound then
@@ -203,39 +240,6 @@ function update()
updateState()
end
-- Helper functions for timer state transitions
local function triggerBreak()
inBreak = true
breakTimer = 0
breakElapsed = 0
activeTime = 0
if settings.enable_notifications then
noctalia.notify(
noctalia.tr("notifications.eyecare-break-title"),
noctalia.tr("notifications.eyecare-break-body", { seconds = settings.break_duration_seconds })
)
end
if settings.enable_sound then
playSound("message")
end
end
local function abortBreak()
inBreak = false
breakTimer = 0
breakElapsed = 0
activeTime = 0
end
local function resetTimer()
inBreak = false
breakTimer = 0
breakElapsed = 0
activeTime = 0
idleTime = 0
end
-- Listen to compositor IPC commands
function onIpc(event, payload)
if event == "idled" then
@@ -244,7 +248,9 @@ function onIpc(event, payload)
isSystemIdle = false
elseif event == "trigger-break" then
triggerBreak()
elseif event == "finish-break" or event == "abort-break" then
elseif event == "finish-break" then
finishBreak()
elseif event == "abort-break" then
abortBreak()
elseif event == "reset" then
resetTimer()
+3 -1
View File
@@ -3,7 +3,9 @@
"eyecare-break-body": "Focus on an object 20 feet away for {seconds} seconds.",
"eyecare-break-finished-body": "Your eyes are rested. You can return to your screen.",
"eyecare-break-finished-title": "Break finished",
"eyecare-break-title": "Time for a break"
"eyecare-break-title": "Time for a break",
"eyecare-reset-body": "Timer has been reset.",
"eyecare-reset-title": "Eye-Care"
},
"settings": {
"eyecare-active-duration": {
-1
View File
@@ -94,7 +94,6 @@ end
function onRightClick()
noctalia.state.set("eyecare-request", "reset")
noctalia.notify("Eye-Care", "Timer has been reset.")
end
-- Initial render