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" id = "apex077/eyecare"
name = "Eye-Care Reminders" name = "Eye-Care Reminders"
version = "1.0.1" version = "1.0.2"
plugin_api = 3 plugin_api = 3
author = "Apex077" author = "Apex077"
license = "MIT" license = "MIT"
+74 -68
View File
@@ -53,26 +53,20 @@ local function isSoundAllowed()
-- Check Noctalia global sound configuration options -- Check Noctalia global sound configuration options
local enableSounds = noctalia.getConfig("enable_sounds") local enableSounds = noctalia.getConfig("enable_sounds")
if enableSounds == false then if enableSounds == false or enableSounds == "false" then
return false return false
end end
local soundEnabled = noctalia.getConfig("sound_enabled") local soundEnabled = noctalia.getConfig("sound_enabled")
if soundEnabled == false then if soundEnabled == false or soundEnabled == "false" then
return false return false
end end
local audioEnableSounds = noctalia.getConfig("audio.enable_sounds") local audioEnableSounds = noctalia.getConfig("audio.enable_sounds")
if audioEnableSounds == false then if audioEnableSounds == false or audioEnableSounds == "false" then
return false return false
end 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 if getSoundVolume() <= 0 then
return false return false
end end
@@ -80,27 +74,26 @@ local function isSoundAllowed()
return true return true
end 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) local function playSound(soundName)
if not isSoundAllowed() then if not isSoundAllowed() then
return return
end end
local vol = getSoundVolume() local vol = getSoundVolume()
if vol <= 0 then
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)
return return
end end
local path = "/usr/share/sounds/freedesktop/stereo/" .. soundName .. ".oga" local path = "/usr/share/sounds/freedesktop/stereo/" .. soundName .. ".oga"
local paVol = math.floor(vol * 65536) local paVol = math.floor(vol * 65536)
local pwVol = string.format("%.2f", vol) 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 end
local lastLoggedIdle = nil local lastLoggedIdle = nil
@@ -124,6 +117,63 @@ end
local wasSystemIdle = false 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) -- Tick cycle actions (every 1 second)
function update() function update()
noctalia.setUpdateInterval(1000) noctalia.setUpdateInterval(1000)
@@ -154,20 +204,7 @@ function update()
end end
elseif breakTimer >= settings.break_duration_seconds then elseif breakTimer >= settings.break_duration_seconds then
-- Break completed successfully -- Break completed successfully
inBreak = false finishBreak()
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
end end
else else
-- Not in break -- Not in break
@@ -189,8 +226,8 @@ function update()
if settings.enable_notifications then if settings.enable_notifications then
noctalia.notify( noctalia.notify(
noctalia.tr("notifications.eyecare-break-title"), noctalia.tr("notifications.eyecare-break-title") or "Time for a break",
noctalia.tr("notifications.eyecare-break-body", { seconds = settings.break_duration_seconds }) 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 end
if settings.enable_sound then if settings.enable_sound then
@@ -203,39 +240,6 @@ function update()
updateState() updateState()
end 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 -- Listen to compositor IPC commands
function onIpc(event, payload) function onIpc(event, payload)
if event == "idled" then if event == "idled" then
@@ -244,7 +248,9 @@ function onIpc(event, payload)
isSystemIdle = false isSystemIdle = false
elseif event == "trigger-break" then elseif event == "trigger-break" then
triggerBreak() triggerBreak()
elseif event == "finish-break" or event == "abort-break" then elseif event == "finish-break" then
finishBreak()
elseif event == "abort-break" then
abortBreak() abortBreak()
elseif event == "reset" then elseif event == "reset" then
resetTimer() resetTimer()
+3 -1
View File
@@ -3,7 +3,9 @@
"eyecare-break-body": "Focus on an object 20 feet away for {seconds} seconds.", "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-body": "Your eyes are rested. You can return to your screen.",
"eyecare-break-finished-title": "Break finished", "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": { "settings": {
"eyecare-active-duration": { "eyecare-active-duration": {
-1
View File
@@ -94,7 +94,6 @@ end
function onRightClick() function onRightClick()
noctalia.state.set("eyecare-request", "reset") noctalia.state.set("eyecare-request", "reset")
noctalia.notify("Eye-Care", "Timer has been reset.")
end end
-- Initial render -- Initial render