From 848a11873903ec2dcd07546efab9f877ac5795ac Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Sun, 9 Aug 2026 15:36:51 -0300 Subject: [PATCH 01/24] Rename panel commands to link_ip_monitor.cmd --- link-ip-monitor/service.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/link-ip-monitor/service.luau b/link-ip-monitor/service.luau index bdec324a..e6bc4d1d 100644 --- a/link-ip-monitor/service.luau +++ b/link-ip-monitor/service.luau @@ -7,7 +7,7 @@ -- Persistence: pluginDataDir()/state.json ({ ips = { {ip=, label=}, ... } }) -- State: link_ip_monitor.statuses = { {ip=, label=, status=, latency_ms=}, ... } -- link_ip_monitor.down_count = number --- Panel commands: ip_monitor.cmd = +-- Panel commands: link_ip_monitor.cmd = -- { op = "add"|"remove"|"refresh"|"reorder", ip = "...", label? = "...", index? = N } local ipList = {} -- { {ip=, label=}, ... } — "ip" here is the already-normalized host (no scheme/port/path) From 5cf02d0d70ede1db9d06b59faae84f0a9839a3da Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Wed, 12 Aug 2026 18:03:38 -0300 Subject: [PATCH 02/24] Update nilsonlinux/link-ip-monitor v1.0.1 --- link-ip-monitor/README.md | 10 ++-- link-ip-monitor/panel.luau | 62 ++++++++++++-------- link-ip-monitor/plugin.toml | 11 +++- link-ip-monitor/service.luau | 18 +++--- link-ip-monitor/translations/en.json | 78 ++++++++++++------------- link-ip-monitor/translations/pt-BR.json | 78 ++++++++++++------------- link-ip-monitor/widget.luau | 17 +++--- 7 files changed, 147 insertions(+), 127 deletions(-) diff --git a/link-ip-monitor/README.md b/link-ip-monitor/README.md index 39cf6e44..9e6248f6 100644 --- a/link-ip-monitor/README.md +++ b/link-ip-monitor/README.md @@ -25,10 +25,11 @@ automatically, keeping only the host to ping). An optional description can be set alongside it. Each row in the panel shows the label (or the host, if no label was set), a -status pill, the response time in ms while online, a drag handle to -reorder the list, and a trash button to remove that entry (asks for -confirmation). Right-click the widget, or use the refresh button in the -panel, to force an immediate check. +status pill, the response time in ms while online — colored green under +100ms, yellow between 100 and 300ms, and red at 300ms or above — a drag +handle to reorder the list, and a trash button to remove that entry (asks +for confirmation). Right-click the widget, or use the refresh button in +the panel, to force an immediate check. Open the panel directly with: ```sh @@ -51,6 +52,7 @@ plugin API has no way to write settings back from a script. | `interval_seconds` | `int` | `30` | How often each host is checked. | | `timeout_seconds` | `int` | `1` | How long to wait for a ping reply before treating it as a failure. | | `notify_on_recovery` | `bool` | `true` | Send a notification when a host that was down responds again. | +| `colorize_latency` | `bool` | `true` | Colors the ms value by latency (green under 100ms, yellow 100-300ms, red 300ms+). Turn off to show it in a neutral color. | | `glyph` (widget) | `glyph` | `activity` | Icon shown in the bar for the `status` widget. | ## Notes diff --git a/link-ip-monitor/panel.luau b/link-ip-monitor/panel.luau index a01f3678..555e9e25 100644 --- a/link-ip-monitor/panel.luau +++ b/link-ip-monitor/panel.luau @@ -14,7 +14,7 @@ local draftError = "" local pendingDelete = nil local showAddForm = false -local DRAG_TYPE = "link-ip-monitor-host" +local DRAG_TYPE = "ip-monitor-host" local STATUS_COLORS = { up = { fill = "#2e7d32", text = "#ffffff" }, @@ -79,14 +79,24 @@ local function normalizeHost(raw) end local STATUS_TR_KEY = { - up = "panel.status_online", - down = "panel.status_offline", - checking = "panel.status_checking", + up = "status_online", + down = "status_offline", + checking = "status_checking", } +local function latencyColor(ms) + if ms < 100 then + return "#2e7d32" -- green + elseif ms < 300 then + return "#f2b705" -- yellow + else + return "#c62828" -- red + end +end + local function pill(status) local colors = STATUS_COLORS[status] or STATUS_COLORS.checking - local label = noctalia.tr(STATUS_TR_KEY[status] or "panel.status_checking") + local label = noctalia.tr(STATUS_TR_KEY[status] or "status_checking") return ui.row({ fill = colors.fill, radius = 8, @@ -119,7 +129,7 @@ function onIpDropped(payload, value) if type(payload) ~= "string" or payload == "" or insertAt == nil then return end - noctalia.state.set("link_ip_monitor.cmd", { op = "reorder", ip = payload, index = insertAt }) + noctalia.state.set("ip_monitor.cmd", { op = "reorder", ip = payload, index = insertAt }) end local function hostRow(item) @@ -133,9 +143,9 @@ local function hostRow(item) glyph = "check", variant = "destructive", controlSize = "sm", - tooltip = noctalia.tr("panel.tooltip_confirm_remove"), + tooltip = noctalia.tr("tooltip_confirm_remove"), onClick = function() - noctalia.state.set("link_ip_monitor.cmd", { op = "remove", ip = id }) + noctalia.state.set("ip_monitor.cmd", { op = "remove", ip = id }) pendingDelete = nil render() end, @@ -144,7 +154,7 @@ local function hostRow(item) glyph = "close", variant = "ghost", controlSize = "sm", - tooltip = noctalia.tr("panel.tooltip_cancel"), + tooltip = noctalia.tr("tooltip_cancel"), onClick = function() pendingDelete = nil render() @@ -156,7 +166,7 @@ local function hostRow(item) glyph = "trash", variant = "ghost", controlSize = "sm", - tooltip = noctalia.tr("panel.tooltip_remove"), + tooltip = noctalia.tr("tooltip_remove"), onClick = function() pendingDelete = id render() @@ -179,10 +189,14 @@ local function hostRow(item) -- and when the measurement exists). local statusChildren = { pill(item.status) } if item.status == "up" and item.latency_ms ~= nil then + local color = "on_surface_variant" + if noctalia.getConfig("colorize_latency") ~= false then + color = latencyColor(item.latency_ms) + end table.insert(statusChildren, ui.label({ - text = tostring(math.floor(item.latency_ms + 0.5)) .. " ms", + text = tostring(item.latency_ms) .. " ms", fontSize = 10, - color = "on_surface_variant", + color = color, })) end @@ -205,7 +219,7 @@ local function hostRow(item) height = 20, align = "center", justify = "center", - tooltip = noctalia.tr("panel.tooltip_drag"), + tooltip = noctalia.tr("tooltip_drag"), }, { ui.glyph({ name = "menu-2", size = 14, color = "on_surface_variant" }), }), @@ -218,7 +232,7 @@ end local function emptyState() return ui.column({ gap = 10, align = "center", padding = 32, flexGrow = 1, justify = "center" }, { ui.glyph({ name = "activity", size = 32, color = "outline" }), - ui.label({ text = noctalia.tr("panel.empty"), color = "outline" }), + ui.label({ text = noctalia.tr("empty"), color = "outline" }), }) end @@ -245,7 +259,7 @@ render = function() glyph = showAddForm and "minus" or "plus", variant = showAddForm and "primary" or "ghost", controlSize = "sm", - tooltip = showAddForm and noctalia.tr("panel.tooltip_close_form") or noctalia.tr("panel.tooltip_add_host"), + tooltip = showAddForm and noctalia.tr("tooltip_close_form") or noctalia.tr("tooltip_add_host"), onClick = function() showAddForm = not showAddForm if not showAddForm then @@ -261,8 +275,8 @@ render = function() glyph = "refresh", variant = "ghost", controlSize = "sm", - tooltip = noctalia.tr("panel.tooltip_check_now"), - onClick = function() noctalia.state.set("link_ip_monitor.cmd", { op = "refresh" }) end, + tooltip = noctalia.tr("tooltip_check_now"), + onClick = function() noctalia.state.set("ip_monitor.cmd", { op = "refresh" }) end, }), ui.button({ glyph = "close", @@ -284,20 +298,20 @@ render = function() ui.input({ key = "add-ip-" .. draftKey, value = draftIp, - placeholder = noctalia.tr("panel.add_placeholder"), + placeholder = noctalia.tr("add_placeholder"), onChange = function(value) draftIp = value; draftError = "" end, onSubmit = "onAdd", }), ui.input({ key = "add-label-" .. draftKey, value = draftLabel, - placeholder = noctalia.tr("panel.add_label_placeholder"), + placeholder = noctalia.tr("add_label_placeholder"), onChange = function(value) draftLabel = value end, onSubmit = "onAdd", }), (draftError ~= "" and ui.label({ text = draftError, color = "#e05252", fontSize = 11 }) or nil), }), - ui.button({ glyph = "plus", variant = "primary", controlSize = "sm", tooltip = noctalia.tr("panel.tooltip_add"), onClick = "onAdd" }), + ui.button({ glyph = "plus", variant = "primary", controlSize = "sm", tooltip = noctalia.tr("tooltip_add"), onClick = "onAdd" }), })) end @@ -312,7 +326,7 @@ function onAdd() return end if host == nil then - draftError = noctalia.tr("panel.invalid_format") + draftError = noctalia.tr("invalid_format") showAddForm = true render() return @@ -324,12 +338,12 @@ function onAdd() draftKey += 1 draftError = "" showAddForm = false - noctalia.state.set("link_ip_monitor.cmd", { op = "add", ip = host, label = label }) + noctalia.state.set("ip_monitor.cmd", { op = "add", ip = host, label = label }) render() end function onOpen(_context) - ips = noctalia.state.get("link_ip_monitor.statuses") or {} + ips = noctalia.state.get("ip_monitor.statuses") or {} pendingDelete = nil draftIp = "" draftLabel = "" @@ -339,7 +353,7 @@ function onOpen(_context) render() end -noctalia.state.watch("link_ip_monitor.statuses", function(value) +noctalia.state.watch("ip_monitor.statuses", function(value) ips = (type(value) == "table") and value or {} if pendingDelete ~= nil then diff --git a/link-ip-monitor/plugin.toml b/link-ip-monitor/plugin.toml index d8d31a76..dd41f6de 100644 --- a/link-ip-monitor/plugin.toml +++ b/link-ip-monitor/plugin.toml @@ -1,6 +1,6 @@ -id = "nilsonlinux/link-ip-monitor" +id = "nilsonlinux/link-ip-monitor" name = "Link/IP Monitor" -version = "1.0.0" +version = "1.0.1" plugin_api = 14 author = "Nilsonlinux" license = "MIT" @@ -39,6 +39,13 @@ label_key = "settings.notify_on_recovery.label" description_key = "settings.notify_on_recovery.description" default = true +[[setting]] +key = "colorize_latency" +type = "bool" +label_key = "settings.colorize_latency.label" +description_key = "settings.colorize_latency.description" +default = true + # --------------------------------------------------------------------------- # Service: runs in the background, pings hosts, and publishes state # --------------------------------------------------------------------------- diff --git a/link-ip-monitor/service.luau b/link-ip-monitor/service.luau index e6bc4d1d..ca70ee5f 100644 --- a/link-ip-monitor/service.luau +++ b/link-ip-monitor/service.luau @@ -7,7 +7,7 @@ -- Persistence: pluginDataDir()/state.json ({ ips = { {ip=, label=}, ... } }) -- State: link_ip_monitor.statuses = { {ip=, label=, status=, latency_ms=}, ... } -- link_ip_monitor.down_count = number --- Panel commands: link_ip_monitor.cmd = +-- Panel commands: ip_monitor.cmd = -- { op = "add"|"remove"|"refresh"|"reorder", ip = "...", label? = "...", index? = N } local ipList = {} -- { {ip=, label=}, ... } — "ip" here is the already-normalized host (no scheme/port/path) @@ -144,8 +144,8 @@ local function publishState() }) end - noctalia.state.set("link_ip_monitor.statuses", statuses) - noctalia.state.set("link_ip_monitor.down_count", downCount) + noctalia.state.set("ip_monitor.statuses", statuses) + noctalia.state.set("ip_monitor.down_count", downCount) end local function checkHost(entry) @@ -175,9 +175,9 @@ local function checkHost(entry) if wasUp ~= success then local display = (entry.label ~= "" and entry.label) or ip if success == false then - noctalia.notifyError(noctalia.tr("title"), noctalia.tr("notify.host_down", { host = display })) + noctalia.notifyError(noctalia.tr("title"), noctalia.tr("host_down", { host = display })) elseif wasUp == false and success == true and noctalia.getConfig("notify_on_recovery") then - noctalia.notify(noctalia.tr("title"), noctalia.tr("notify.host_up", { host = display })) + noctalia.notify(noctalia.tr("title"), noctalia.tr("host_up", { host = display })) end end @@ -252,7 +252,7 @@ end -- watches it, processes it, and clears it back to nil). -- --------------------------------------------------------------------------- -noctalia.state.watch("link_ip_monitor.cmd", function(cmd) +noctalia.state.watch("ip_monitor.cmd", function(cmd) if type(cmd) ~= "table" then return end @@ -262,9 +262,9 @@ noctalia.state.watch("link_ip_monitor.cmd", function(cmd) if not ok then local display = tostring(cmd.ip or "") if reason == "invalid" then - noctalia.notifyError(noctalia.tr("title"), noctalia.tr("notify.invalid_host", { host = display })) + noctalia.notifyError(noctalia.tr("title"), noctalia.tr("invalid_host", { host = display })) elseif reason == "duplicate" then - noctalia.notifyError(noctalia.tr("title"), noctalia.tr("notify.duplicate_host", { host = display })) + noctalia.notifyError(noctalia.tr("title"), noctalia.tr("duplicate_host", { host = display })) end end elseif op == "remove" then @@ -274,7 +274,7 @@ noctalia.state.watch("link_ip_monitor.cmd", function(cmd) elseif op == "refresh" then checkAll() end - noctalia.state.set("link_ip_monitor.cmd", nil) + noctalia.state.set("ip_monitor.cmd", nil) end) -- --------------------------------------------------------------------------- diff --git a/link-ip-monitor/translations/en.json b/link-ip-monitor/translations/en.json index 48688542..f0ebe010 100644 --- a/link-ip-monitor/translations/en.json +++ b/link-ip-monitor/translations/en.json @@ -1,49 +1,47 @@ { - "notify": { - "duplicate_host": "{host} is already in the list", - "host_down": "{host} is unreachable", - "host_up": "{host} is responding again", - "invalid_host": "{host} is not a valid IP, host or link" - }, - "panel": { - "add_label_placeholder": "Description (optional) — e.g. Router, Server", - "add_placeholder": "IP, host or link", - "empty": "No hosts configured yet", - "invalid_format": "Invalid — enter an IP (0.0.0.0), a host or a link", - "status_checking": "Checking…", - "status_offline": "Offline", - "status_online": "Online", - "tooltip_add": "Add", - "tooltip_add_host": "Add host", - "tooltip_cancel": "Cancel", - "tooltip_check_now": "Check now", - "tooltip_close_form": "Close", - "tooltip_confirm_remove": "Confirm removal", - "tooltip_drag": "Drag to reorder", - "tooltip_remove": "Remove" - }, + "title": "Link/IP Monitor", + "host_down": "{host} is unreachable", + "host_up": "{host} is responding again", + "invalid_host": "{host} is not a valid IP, host or link", + "duplicate_host": "{host} is already in the list", + "empty": "No hosts configured yet", + "add_placeholder": "IP, host or link", + "add_label_placeholder": "Description (optional) — e.g. Router, Server", + "invalid_format": "Invalid — enter an IP (0.0.0.0), a host or a link", + "status_online": "Online", + "status_offline": "Offline", + "status_checking": "Checking…", + "tooltip_check_now": "Check now", + "tooltip_add": "Add", + "tooltip_remove": "Remove", + "tooltip_confirm_remove": "Confirm removal", + "tooltip_cancel": "Cancel", + "tooltip_drag": "Drag to reorder", + "tooltip_close_form": "Close", + "tooltip_add_host": "Add host", + "tooltip_all_up": "All monitored hosts are responding", + "tooltip_down_prefix": "Down:", + "checking_now": "Checking now…", "settings": { - "glyph": { - "description": "Icon shown in the bar for this widget.", - "label": "Bar icon" - }, "interval_seconds": { - "description": "How often each host is checked.", - "label": "Check interval (s)" + "label": "Check interval (s)", + "description": "How often each host is checked." + }, + "timeout_seconds": { + "label": "Ping timeout (s)", + "description": "How long to wait for a reply before treating it as a failure." }, "notify_on_recovery": { - "description": "Send a notification when a host that was down responds again.", - "label": "Notify when a host comes back" + "label": "Notify when a host comes back", + "description": "Send a notification when a host that was down responds again." }, - "timeout_seconds": { - "description": "How long to wait for a reply before treating it as a failure.", - "label": "Ping timeout (s)" + "glyph": { + "label": "Bar icon", + "description": "Icon shown in the bar for this widget." + }, + "colorize_latency": { + "label": "Colorize response time", + "description": "Colors the ms value by latency (green under 100ms, yellow 100-300ms, red 300ms+). Turn off to show it in a neutral color." } - }, - "title": "Link/IP Monitor", - "widget": { - "checking_now": "Checking now…", - "tooltip_all_up": "All monitored hosts are responding", - "tooltip_down_prefix": "Down:" } } diff --git a/link-ip-monitor/translations/pt-BR.json b/link-ip-monitor/translations/pt-BR.json index 3ec354a8..5fbc3697 100644 --- a/link-ip-monitor/translations/pt-BR.json +++ b/link-ip-monitor/translations/pt-BR.json @@ -1,49 +1,47 @@ { - "notify": { - "duplicate_host": "{host} já está na lista", - "host_down": "{host} está inacessível", - "host_up": "{host} voltou a responder", - "invalid_host": "{host} não é um IP, host ou link válido" - }, - "panel": { - "add_label_placeholder": "Descrição (opcional) — ex: Roteador, Servidor", - "add_placeholder": "IP, host ou link", - "empty": "Nenhum host configurado ainda", - "invalid_format": "Inválido — informe um IP (0.0.0.0), um host ou um link", - "status_checking": "Checando…", - "status_offline": "Offline", - "status_online": "Online", - "tooltip_add": "Adicionar", - "tooltip_add_host": "Adicionar host", - "tooltip_cancel": "Cancelar", - "tooltip_check_now": "Checar agora", - "tooltip_close_form": "Fechar", - "tooltip_confirm_remove": "Confirmar remoção", - "tooltip_drag": "Arraste para reordenar", - "tooltip_remove": "Remover" - }, + "title": "Link/IP Monitor", + "host_down": "{host} está inacessível", + "host_up": "{host} voltou a responder", + "invalid_host": "{host} não é um IP, host ou link válido", + "duplicate_host": "{host} já está na lista", + "empty": "Nenhum host configurado ainda", + "add_placeholder": "IP, host ou link", + "add_label_placeholder": "Descrição (opcional) — ex: Roteador, Servidor", + "invalid_format": "Inválido — informe um IP (0.0.0.0), um host ou um link", + "status_online": "Online", + "status_offline": "Offline", + "status_checking": "Checando…", + "tooltip_check_now": "Checar agora", + "tooltip_add": "Adicionar", + "tooltip_remove": "Remover", + "tooltip_confirm_remove": "Confirmar remoção", + "tooltip_cancel": "Cancelar", + "tooltip_drag": "Arraste para reordenar", + "tooltip_close_form": "Fechar", + "tooltip_add_host": "Adicionar host", + "tooltip_all_up": "Todos os hosts monitorados estão respondendo", + "tooltip_down_prefix": "Fora do ar:", + "checking_now": "Checando agora…", "settings": { - "glyph": { - "description": "Ícone mostrado na barra para este widget.", - "label": "Ícone da barra" - }, "interval_seconds": { - "description": "Com que frequência cada host é checado.", - "label": "Intervalo entre checagens (s)" + "label": "Intervalo entre checagens (s)", + "description": "Com que frequência cada host é checado." + }, + "timeout_seconds": { + "label": "Timeout do ping (s)", + "description": "Quanto tempo esperar por resposta antes de considerar falha." }, "notify_on_recovery": { - "description": "Envia uma notificação quando um host que estava fora do ar volta a responder.", - "label": "Notificar quando o host volta" + "label": "Notificar quando o host volta", + "description": "Envia uma notificação quando um host que estava fora do ar volta a responder." }, - "timeout_seconds": { - "description": "Quanto tempo esperar por resposta antes de considerar falha.", - "label": "Timeout do ping (s)" + "glyph": { + "label": "Ícone da barra", + "description": "Ícone mostrado na barra para este widget." + }, + "colorize_latency": { + "label": "Colorir tempo de resposta", + "description": "Colore o valor em ms de acordo com a latência (verde abaixo de 100ms, amarelo entre 100-300ms, vermelho a partir de 300ms). Desmarque para mostrar sem coloração." } - }, - "title": "Link/IP Monitor", - "widget": { - "checking_now": "Checando agora…", - "tooltip_all_up": "Todos os hosts monitorados estão respondendo", - "tooltip_down_prefix": "Fora do ar:" } } diff --git a/link-ip-monitor/widget.luau b/link-ip-monitor/widget.luau index 9dc9fdeb..b720ba77 100644 --- a/link-ip-monitor/widget.luau +++ b/link-ip-monitor/widget.luau @@ -42,8 +42,9 @@ local function render() -- everything responding: green icon, no badge table.insert(children, ui.glyph({ name = glyphName, size = 14, color = COLOR_UP })) else - -- no hosts configured yet: neutral color (neither green nor red) - table.insert(children, ui.glyph({ name = glyphName, size = 14 })) + -- no hosts configured yet: neutral color (neither green nor red) — + -- must be set explicitly, omitting `color` renders the glyph blank. + table.insert(children, ui.glyph({ name = glyphName, size = 14, color = "on_surface" })) end local container = barWidget.isVertical() and ui.column or ui.row @@ -51,18 +52,18 @@ local function render() local down = downList() if #down > 0 then - barWidget.setTooltip(noctalia.tr("widget.tooltip_down_prefix") .. "\n" .. table.concat(down, "\n")) + barWidget.setTooltip(noctalia.tr("tooltip_down_prefix") .. "\n" .. table.concat(down, "\n")) else - barWidget.setTooltip(noctalia.tr("widget.tooltip_all_up")) + barWidget.setTooltip(noctalia.tr("tooltip_all_up")) end end -noctalia.state.watch("link_ip_monitor.down_count", function(value) +noctalia.state.watch("ip_monitor.down_count", function(value) downCount = value or 0 render() end) -noctalia.state.watch("link_ip_monitor.statuses", function(value) +noctalia.state.watch("ip_monitor.statuses", function(value) statuses = (type(value) == "table") and value or {} render() end) @@ -82,6 +83,6 @@ function onClick() end function onRightClick() - noctalia.state.set("link_ip_monitor.cmd", { op = "refresh" }) - noctalia.notify(noctalia.tr("title"), noctalia.tr("widget.checking_now")) + noctalia.state.set("ip_monitor.cmd", { op = "refresh" }) + noctalia.notify(noctalia.tr("title"), noctalia.tr("checking_now")) end From c8c6dba851974899d3651e9df43184bb1b80efbf Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Wed, 12 Aug 2026 18:09:33 -0300 Subject: [PATCH 03/24] eddit commit message --- link-ip-monitor/service.luau | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/link-ip-monitor/service.luau b/link-ip-monitor/service.luau index ca70ee5f..6cabd3af 100644 --- a/link-ip-monitor/service.luau +++ b/link-ip-monitor/service.luau @@ -5,8 +5,8 @@ -- on the up -> down transition (and, when enabled, down -> up). -- -- Persistence: pluginDataDir()/state.json ({ ips = { {ip=, label=}, ... } }) --- State: link_ip_monitor.statuses = { {ip=, label=, status=, latency_ms=}, ... } --- link_ip_monitor.down_count = number +-- State: ip_monitor.statuses = { {ip=, label=, status=, latency_ms=}, ... } +-- ip_monitor.down_count = number -- Panel commands: ip_monitor.cmd = -- { op = "add"|"remove"|"refresh"|"reorder", ip = "...", label? = "...", index? = N } From b99893e91f09e45bee6dd17b28b305d60e358cec Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Wed, 12 Aug 2026 18:13:22 -0300 Subject: [PATCH 04/24] Update nilsonlinux/link-ip-monitor v1.0.1 From 07f015ec95d3981269ab20ea2757d0e09121ee96 Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Thu, 13 Aug 2026 07:16:03 -0300 Subject: [PATCH 05/24] Update Portuguese translations for notifications and panel Added new notification and panel sections with relevant translations. --- link-ip-monitor/translations/pt-BR.json | 82 +++++++++++++------------ 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/link-ip-monitor/translations/pt-BR.json b/link-ip-monitor/translations/pt-BR.json index 5fbc3697..74122fdf 100644 --- a/link-ip-monitor/translations/pt-BR.json +++ b/link-ip-monitor/translations/pt-BR.json @@ -1,47 +1,53 @@ { - "title": "Link/IP Monitor", - "host_down": "{host} está inacessível", - "host_up": "{host} voltou a responder", - "invalid_host": "{host} não é um IP, host ou link válido", - "duplicate_host": "{host} já está na lista", - "empty": "Nenhum host configurado ainda", - "add_placeholder": "IP, host ou link", - "add_label_placeholder": "Descrição (opcional) — ex: Roteador, Servidor", - "invalid_format": "Inválido — informe um IP (0.0.0.0), um host ou um link", - "status_online": "Online", - "status_offline": "Offline", - "status_checking": "Checando…", - "tooltip_check_now": "Checar agora", - "tooltip_add": "Adicionar", - "tooltip_remove": "Remover", - "tooltip_confirm_remove": "Confirmar remoção", - "tooltip_cancel": "Cancelar", - "tooltip_drag": "Arraste para reordenar", - "tooltip_close_form": "Fechar", - "tooltip_add_host": "Adicionar host", - "tooltip_all_up": "Todos os hosts monitorados estão respondendo", - "tooltip_down_prefix": "Fora do ar:", - "checking_now": "Checando agora…", + "notify": { + "duplicate_host": "{host} já está na lista", + "host_down": "{host} está inacessível", + "host_up": "{host} voltou a responder", + "invalid_host": "{host} não é um IP, host ou link válido" + }, + "panel": { + "add_label_placeholder": "Descrição (opcional) — ex: Roteador, Servidor", + "add_placeholder": "IP, host ou link", + "empty": "Nenhum host configurado ainda", + "invalid_format": "Inválido — informe um IP (0.0.0.0), um host ou um link", + "status_checking": "Checando…", + "status_offline": "Offline", + "status_online": "Online", + "tooltip_add": "Adicionar", + "tooltip_add_host": "Adicionar host", + "tooltip_cancel": "Cancelar", + "tooltip_check_now": "Checar agora", + "tooltip_close_form": "Fechar", + "tooltip_confirm_remove": "Confirmar remoção", + "tooltip_drag": "Arraste para reordenar", + "tooltip_remove": "Remover" + }, "settings": { - "interval_seconds": { - "label": "Intervalo entre checagens (s)", - "description": "Com que frequência cada host é checado." + "colorize_latency": { + "description": "Colore o valor em ms de acordo com a latência (verde abaixo de 100ms, amarelo entre 100-300ms, vermelho a partir de 300ms). Desmarque para mostrar sem coloração.", + "label": "Colorir tempo de resposta" }, - "timeout_seconds": { - "label": "Timeout do ping (s)", - "description": "Quanto tempo esperar por resposta antes de considerar falha." + "glyph": { + "description": "Ícone mostrado na barra para este widget.", + "label": "Ícone da barra" }, - "notify_on_recovery": { - "label": "Notificar quando o host volta", - "description": "Envia uma notificação quando um host que estava fora do ar volta a responder." + "interval_seconds": { + "description": "Com que frequência cada host é checado.", + "label": "Intervalo entre checagens (s)" }, - "glyph": { - "label": "Ícone da barra", - "description": "Ícone mostrado na barra para este widget." + "notify_on_recovery": { + "description": "Envia uma notificação quando um host que estava fora do ar volta a responder.", + "label": "Notificar quando o host volta" }, - "colorize_latency": { - "label": "Colorir tempo de resposta", - "description": "Colore o valor em ms de acordo com a latência (verde abaixo de 100ms, amarelo entre 100-300ms, vermelho a partir de 300ms). Desmarque para mostrar sem coloração." + "timeout_seconds": { + "description": "Quanto tempo esperar por resposta antes de considerar falha.", + "label": "Timeout do ping (s)" } + }, + "title": "Link/IP Monitor", + "widget": { + "checking_now": "Checando agora…", + "tooltip_all_up": "Todos os hosts monitorados estão respondendo", + "tooltip_down_prefix": "Fora do ar:" } } From 016e6c345f01c1633909a838a3cbdd16e4c44bb5 Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Thu, 13 Aug 2026 07:16:33 -0300 Subject: [PATCH 06/24] Enhance translation file with notifications and panel details Added new notification and panel structures to the translation file. --- link-ip-monitor/translations/en.json | 82 +++++++++++++++------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/link-ip-monitor/translations/en.json b/link-ip-monitor/translations/en.json index f0ebe010..2868cc6c 100644 --- a/link-ip-monitor/translations/en.json +++ b/link-ip-monitor/translations/en.json @@ -1,47 +1,53 @@ { - "title": "Link/IP Monitor", - "host_down": "{host} is unreachable", - "host_up": "{host} is responding again", - "invalid_host": "{host} is not a valid IP, host or link", - "duplicate_host": "{host} is already in the list", - "empty": "No hosts configured yet", - "add_placeholder": "IP, host or link", - "add_label_placeholder": "Description (optional) — e.g. Router, Server", - "invalid_format": "Invalid — enter an IP (0.0.0.0), a host or a link", - "status_online": "Online", - "status_offline": "Offline", - "status_checking": "Checking…", - "tooltip_check_now": "Check now", - "tooltip_add": "Add", - "tooltip_remove": "Remove", - "tooltip_confirm_remove": "Confirm removal", - "tooltip_cancel": "Cancel", - "tooltip_drag": "Drag to reorder", - "tooltip_close_form": "Close", - "tooltip_add_host": "Add host", - "tooltip_all_up": "All monitored hosts are responding", - "tooltip_down_prefix": "Down:", - "checking_now": "Checking now…", + "notify": { + "duplicate_host": "{host} is already in the list", + "host_down": "{host} is unreachable", + "host_up": "{host} is responding again", + "invalid_host": "{host} is not a valid IP, host or link" + }, + "panel": { + "add_label_placeholder": "Description (optional) — e.g. Router, Server", + "add_placeholder": "IP, host or link", + "empty": "No hosts configured yet", + "invalid_format": "Invalid — enter an IP (0.0.0.0), a host or a link", + "status_checking": "Checking…", + "status_offline": "Offline", + "status_online": "Online", + "tooltip_add": "Add", + "tooltip_add_host": "Add host", + "tooltip_cancel": "Cancel", + "tooltip_check_now": "Check now", + "tooltip_close_form": "Close", + "tooltip_confirm_remove": "Confirm removal", + "tooltip_drag": "Drag to reorder", + "tooltip_remove": "Remove" + }, "settings": { - "interval_seconds": { - "label": "Check interval (s)", - "description": "How often each host is checked." + "colorize_latency": { + "description": "Colors the ms value by latency (green under 100ms, yellow 100-300ms, red 300ms+). Turn off to show it in a neutral color.", + "label": "Colorize response time" }, - "timeout_seconds": { - "label": "Ping timeout (s)", - "description": "How long to wait for a reply before treating it as a failure." + "glyph": { + "description": "Icon shown in the bar for this widget.", + "label": "Bar icon" }, - "notify_on_recovery": { - "label": "Notify when a host comes back", - "description": "Send a notification when a host that was down responds again." + "interval_seconds": { + "description": "How often each host is checked.", + "label": "Check interval (s)" }, - "glyph": { - "label": "Bar icon", - "description": "Icon shown in the bar for this widget." + "notify_on_recovery": { + "description": "Send a notification when a host that was down responds again.", + "label": "Notify when a host comes back" }, - "colorize_latency": { - "label": "Colorize response time", - "description": "Colors the ms value by latency (green under 100ms, yellow 100-300ms, red 300ms+). Turn off to show it in a neutral color." + "timeout_seconds": { + "description": "How long to wait for a reply before treating it as a failure.", + "label": "Ping timeout (s)" } + }, + "title": "Link/IP Monitor", + "widget": { + "checking_now": "Checking now…", + "tooltip_all_up": "All monitored hosts are responding", + "tooltip_down_prefix": "Down:" } } From 2bda2f116e8fa9eea4a0ee707af59de690ee5fa3 Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Thu, 13 Aug 2026 07:28:06 -0300 Subject: [PATCH 07/24] fix translation --- link-ip-monitor/panel.luau | 30 +++++++++++++++--------------- link-ip-monitor/service.luau | 8 ++++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/link-ip-monitor/panel.luau b/link-ip-monitor/panel.luau index 555e9e25..f164aaa4 100644 --- a/link-ip-monitor/panel.luau +++ b/link-ip-monitor/panel.luau @@ -79,9 +79,9 @@ local function normalizeHost(raw) end local STATUS_TR_KEY = { - up = "status_online", - down = "status_offline", - checking = "status_checking", + up = "panel.status_online", + down = "panel.status_offline", + checking = "panel.status_checking", } local function latencyColor(ms) @@ -96,7 +96,7 @@ end local function pill(status) local colors = STATUS_COLORS[status] or STATUS_COLORS.checking - local label = noctalia.tr(STATUS_TR_KEY[status] or "status_checking") + local label = noctalia.tr(STATUS_TR_KEY[status] or "panel.status_checking") return ui.row({ fill = colors.fill, radius = 8, @@ -143,7 +143,7 @@ local function hostRow(item) glyph = "check", variant = "destructive", controlSize = "sm", - tooltip = noctalia.tr("tooltip_confirm_remove"), + tooltip = noctalia.tr("panel.tooltip_confirm_remove"), onClick = function() noctalia.state.set("ip_monitor.cmd", { op = "remove", ip = id }) pendingDelete = nil @@ -154,7 +154,7 @@ local function hostRow(item) glyph = "close", variant = "ghost", controlSize = "sm", - tooltip = noctalia.tr("tooltip_cancel"), + tooltip = noctalia.tr("panel.tooltip_cancel"), onClick = function() pendingDelete = nil render() @@ -166,7 +166,7 @@ local function hostRow(item) glyph = "trash", variant = "ghost", controlSize = "sm", - tooltip = noctalia.tr("tooltip_remove"), + tooltip = noctalia.tr("panel.tooltip_remove"), onClick = function() pendingDelete = id render() @@ -219,7 +219,7 @@ local function hostRow(item) height = 20, align = "center", justify = "center", - tooltip = noctalia.tr("tooltip_drag"), + tooltip = noctalia.tr("panel.tooltip_drag"), }, { ui.glyph({ name = "menu-2", size = 14, color = "on_surface_variant" }), }), @@ -232,7 +232,7 @@ end local function emptyState() return ui.column({ gap = 10, align = "center", padding = 32, flexGrow = 1, justify = "center" }, { ui.glyph({ name = "activity", size = 32, color = "outline" }), - ui.label({ text = noctalia.tr("empty"), color = "outline" }), + ui.label({ text = noctalia.tr("panel.empty"), color = "outline" }), }) end @@ -259,7 +259,7 @@ render = function() glyph = showAddForm and "minus" or "plus", variant = showAddForm and "primary" or "ghost", controlSize = "sm", - tooltip = showAddForm and noctalia.tr("tooltip_close_form") or noctalia.tr("tooltip_add_host"), + tooltip = showAddForm and noctalia.tr("panel.tooltip_close_form") or noctalia.tr("panel.tooltip_add_host"), onClick = function() showAddForm = not showAddForm if not showAddForm then @@ -275,7 +275,7 @@ render = function() glyph = "refresh", variant = "ghost", controlSize = "sm", - tooltip = noctalia.tr("tooltip_check_now"), + tooltip = noctalia.tr("panel.tooltip_check_now"), onClick = function() noctalia.state.set("ip_monitor.cmd", { op = "refresh" }) end, }), ui.button({ @@ -298,20 +298,20 @@ render = function() ui.input({ key = "add-ip-" .. draftKey, value = draftIp, - placeholder = noctalia.tr("add_placeholder"), + placeholder = noctalia.tr("panel.add_placeholder"), onChange = function(value) draftIp = value; draftError = "" end, onSubmit = "onAdd", }), ui.input({ key = "add-label-" .. draftKey, value = draftLabel, - placeholder = noctalia.tr("add_label_placeholder"), + placeholder = noctalia.tr("panel.add_label_placeholder"), onChange = function(value) draftLabel = value end, onSubmit = "onAdd", }), (draftError ~= "" and ui.label({ text = draftError, color = "#e05252", fontSize = 11 }) or nil), }), - ui.button({ glyph = "plus", variant = "primary", controlSize = "sm", tooltip = noctalia.tr("tooltip_add"), onClick = "onAdd" }), + ui.button({ glyph = "plus", variant = "primary", controlSize = "sm", tooltip = noctalia.tr("panel.tooltip_add"), onClick = "onAdd" }), })) end @@ -326,7 +326,7 @@ function onAdd() return end if host == nil then - draftError = noctalia.tr("invalid_format") + draftError = noctalia.tr("panel.invalid_format") showAddForm = true render() return diff --git a/link-ip-monitor/service.luau b/link-ip-monitor/service.luau index 6cabd3af..00d134d5 100644 --- a/link-ip-monitor/service.luau +++ b/link-ip-monitor/service.luau @@ -175,9 +175,9 @@ local function checkHost(entry) if wasUp ~= success then local display = (entry.label ~= "" and entry.label) or ip if success == false then - noctalia.notifyError(noctalia.tr("title"), noctalia.tr("host_down", { host = display })) + noctalia.notifyError(noctalia.tr("title"), noctalia.tr("notify.host_down", { host = display })) elseif wasUp == false and success == true and noctalia.getConfig("notify_on_recovery") then - noctalia.notify(noctalia.tr("title"), noctalia.tr("host_up", { host = display })) + noctalia.notify(noctalia.tr("title"), noctalia.tr("notify.host_up", { host = display })) end end @@ -262,9 +262,9 @@ noctalia.state.watch("ip_monitor.cmd", function(cmd) if not ok then local display = tostring(cmd.ip or "") if reason == "invalid" then - noctalia.notifyError(noctalia.tr("title"), noctalia.tr("invalid_host", { host = display })) + noctalia.notifyError(noctalia.tr("title"), noctalia.tr("notify.invalid_host", { host = display })) elseif reason == "duplicate" then - noctalia.notifyError(noctalia.tr("title"), noctalia.tr("duplicate_host", { host = display })) + noctalia.notifyError(noctalia.tr("title"), noctalia.tr("notify.duplicate_host", { host = display })) end end elseif op == "remove" then From 43661567105965eb6991654ba5084e7905a06aba Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Thu, 13 Aug 2026 07:28:55 -0300 Subject: [PATCH 08/24] fix translation --- link-ip-monitor/widget.luau | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/link-ip-monitor/widget.luau b/link-ip-monitor/widget.luau index b720ba77..f8a2e4a2 100644 --- a/link-ip-monitor/widget.luau +++ b/link-ip-monitor/widget.luau @@ -52,9 +52,9 @@ local function render() local down = downList() if #down > 0 then - barWidget.setTooltip(noctalia.tr("tooltip_down_prefix") .. "\n" .. table.concat(down, "\n")) + barWidget.setTooltip(noctalia.tr("widget.tooltip_down_prefix") .. "\n" .. table.concat(down, "\n")) else - barWidget.setTooltip(noctalia.tr("tooltip_all_up")) + barWidget.setTooltip(noctalia.tr("widget.tooltip_all_up")) end end @@ -84,5 +84,5 @@ end function onRightClick() noctalia.state.set("ip_monitor.cmd", { op = "refresh" }) - noctalia.notify(noctalia.tr("title"), noctalia.tr("checking_now")) + noctalia.notify(noctalia.tr("title"), noctalia.tr("widget.checking_now")) end From 8ec9c73a1746bd487a57d6f5c39c6586c64e8a70 Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Fri, 14 Aug 2026 18:40:59 -0300 Subject: [PATCH 09/24] Updated README.md with new information about the link-ip-monitor project. --- link-ip-monitor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/link-ip-monitor/README.md b/link-ip-monitor/README.md index 9e6248f6..a2145e1f 100644 --- a/link-ip-monitor/README.md +++ b/link-ip-monitor/README.md @@ -1,5 +1,5 @@ -# link-ip-monitor -link-ip-monitor pings a list of IPs, hostnames or links on an interval, tracks +# Link/IP Monitor +pings a list of IPs, hostnames or links on an interval, tracks each host's online/offline status and response time, and notifies when one goes down or comes back up. From a6c1ad706c952751563610f4e7663ee97303b3bd Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Sun, 16 Aug 2026 16:58:13 -0300 Subject: [PATCH 10/24] update plugin.toml and widget.luau to fix the panel id and improve comments --- link-ip-monitor/README.md | 2 +- rss-notifier/README.md | 5 +- rss-notifier/panel.luau | 35 ++-- rss-notifier/plugin.toml | 22 +-- rss-notifier/service.luau | 352 ++++++++++++++++++++++++++++---------- rss-notifier/widget.luau | 22 +-- 6 files changed, 306 insertions(+), 132 deletions(-) diff --git a/link-ip-monitor/README.md b/link-ip-monitor/README.md index a2145e1f..8d82ccf7 100644 --- a/link-ip-monitor/README.md +++ b/link-ip-monitor/README.md @@ -1,5 +1,5 @@ # Link/IP Monitor -pings a list of IPs, hostnames or links on an interval, tracks +Pings a list of IPs, hostnames or links on an interval, tracks each host's online/offline status and response time, and notifies when one goes down or comes back up. diff --git a/rss-notifier/README.md b/rss-notifier/README.md index f635e85d..14a8901c 100644 --- a/rss-notifier/README.md +++ b/rss-notifier/README.md @@ -12,11 +12,11 @@ Monitor RSS/Atom feeds and get notifications for new items. **Entries:** - **Service:** `fetcher` - Background service that fetches and parses feeds - **Widget:** `badge` - Shows unread count on the bar -- **Panel:** `list` - Displays feed items in a list +- **Panel:** `panel` - Displays feed items in a panel **IPC Command:** -noctalia msg panel-toggle nilsonlinux/rss-notifier:list +noctalia msg panel-toggle nilsonlinux/rss-notifier:panel text @@ -28,6 +28,7 @@ text | `refresh_minutes` | int | `30` | How often to check for new items (1-1440 minutes) | | `notify_new` | bool | `true` | Display notifications when new items arrive | | `max_notifications_per_cycle` | int | `5` | Maximum notifications shown per check (1-50) | +| `glyph` (widget) | `glyph` | `rss` | Icon shown in the bar for the `status` widget. | ## Installation diff --git a/rss-notifier/panel.luau b/rss-notifier/panel.luau index 471da1eb..c691892c 100644 --- a/rss-notifier/panel.luau +++ b/rss-notifier/panel.luau @@ -1,11 +1,11 @@ -- panel.luau --- Janela pop-up mostrada ao clicar no widget da barra: lista os itens mais --- recentes, ou um estado vazio com icone quando nao ha nada novo. +-- Popup shown when clicking the bar widget: lists the most recent items, or +-- an empty state with an icon when there's nothing new. local items = {} local hoveredKey = nil --- declaradas antes para permitir referencia cruzada entre elas +-- declared upfront to allow cross-referencing between them local render local dismissItem local itemRow @@ -15,14 +15,14 @@ local function openLink(link) if not link or link == "" then return end - -- escapa aspas simples pra evitar quebrar o comando do shell + -- escape single quotes so we don't break the shell command local safe = link:gsub("'", "'\\''") noctalia.runAsync("xdg-open '" .. safe .. "'") end dismissItem = function(item) - -- remove localmente (resposta imediata) e avisa o service pra nao - -- reaparecer nas proximas atualizacoes + -- remove locally (immediate feedback) and tell the service so it doesn't + -- reappear on future updates for i, it in ipairs(items) do if it == item then table.remove(items, i) @@ -56,6 +56,11 @@ itemRow = function(item) render() end, }, { + (item.image and item.image ~= "") + and ui.image({ path = item.image, width = 56, height = 56, radius = 10, fit = "cover" }) + or ui.row({ width = 56, height = 56, radius = 10, fill = "surface_variant/0.7", align = "center", justify = "center" }, { + ui.glyph({ name = "rss", size = 20, color = "outline" }), + }), ui.column({ gap = 2, flexGrow = 1, @@ -91,8 +96,8 @@ render = function() for _, item in ipairs(items) do table.insert(rows, itemRow(item)) end - -- flexGrow preenche o espaco que sobrar dentro da coluna raiz - so - -- funciona se essa coluna tiver uma altura definida (ver abaixo). + -- flexGrow fills the leftover space inside the root column - only works + -- if that column has a defined height (see below). body = ui.scroll({ gap = 6, flexGrow = 1 }, rows) end @@ -103,9 +108,9 @@ render = function() table.insert(headerButtons, ui.button({ glyph = "refresh", variant = "outline", controlSize = "sm", tooltip = "Atualizar agora", onClick = "onRefreshClicked" })) table.insert(headerButtons, ui.button({ glyph = "close", variant = "outline", controlSize = "sm", onClick = "onCloseClicked" })) - -- um pouco menor que os 415 do painel (ver plugin.toml) para sobrar uma - -- margem de seguranca antes da borda arredondada, em vez de encostar nela - panel.render(ui.column({ gap = 10, padding = 12, height = 415 }, { + -- 560 (panel height, see plugin.toml) minus a 30px safety margin before + -- the rounded edge, instead of touching it + panel.render(ui.column({ gap = 10, padding = 12, height = 530 }, { ui.row({ align = "center", justify = "space_between" }, { ui.label({ text = "RSS/Atom Notifier", fontSize = 15, fontWeight = "bold" }), ui.row({ gap = 4 }, headerButtons), @@ -122,9 +127,9 @@ noctalia.state.watch("items", function(raw) end) function onOpen(_context) - -- o painel so e criado na primeira vez que e aberto - se o service ja - -- tinha publicado itens antes disso (ex: na checagem de boot), o watch() - -- sozinho nao pega esse valor antigo. Busca o estado atual na abertura. + -- the panel is only created the first time it's opened - if the service + -- had already published items before that (e.g. on the boot-time check), + -- watch() alone won't pick up that old value. Fetch the current state on open. local ok, raw = pcall(noctalia.state.get, "items") if ok and raw then local decodeOk, decoded = pcall(noctalia.json.decode, raw) @@ -134,7 +139,7 @@ function onOpen(_context) end render() - -- abrir o painel conta como "li as novidades": zera o badge no service + -- opening the panel counts as "read the news": resets the badge on the service noctalia.runAsync("noctalia msg plugin nilsonlinux/rss-notifier:fetcher all mark-read") end diff --git a/rss-notifier/plugin.toml b/rss-notifier/plugin.toml index 4cf1ae72..e3270c87 100644 --- a/rss-notifier/plugin.toml +++ b/rss-notifier/plugin.toml @@ -1,6 +1,6 @@ id = "nilsonlinux/rss-notifier" name = "RSS/Atom Notifier" -version = "1.0.2" +version = "1.0.3" plugin_api = 14 author = "Nilsonlinux" license = "MIT" @@ -63,22 +63,22 @@ entry = "service.luau" id = "badge" entry = "widget.luau" -[[widget.setting]] -key = "glyph" -type = "glyph" -label_key = "settings.glyph.label" -description_key = "settings.glyph.description" -default = "rss" + [[widget.setting]] + key = "glyph" + type = "glyph" + label_key = "settings.glyph.label" + description_key = "settings.glyph.description" + default = "rss" # --------------------------------------------------------------------------- # Panel: small window with the list of items, opened by clicking on the widget # --------------------------------------------------------------------------- [[panel]] -id = "list" +id = "panel" entry = "panel.luau" -width = 360 -height = 440 -placement = "attached" +width = 420 +height = 560 +placement = "attached" # attached to the bar, near the widget position = "auto" open_near_click = true diff --git a/rss-notifier/service.luau b/rss-notifier/service.luau index a31563e1..6425cf7c 100644 --- a/rss-notifier/service.luau +++ b/rss-notifier/service.luau @@ -1,41 +1,42 @@ -- service.luau --- Servico headless: busca cada feed configurado, extrai itens (RSS ou --- Atom ), compara com o que ja foi visto, notifica o que for novo e --- publica a contagem de nao-lidos em noctalia.state para o widget consumir. +-- Headless service: fetches each configured feed, extracts items (RSS +-- or Atom ), compares against what's already been seen, notifies on +-- new items, and publishes the unread count in noctalia.state for the widget. local seen = {} -- { [feedUrl] = { ids = { [itemId]=true, ... }, order = { id1, id2, ... } } } local unread = 0 -local recentItems = {} -- lista dos itens mais recentes, mais novo primeiro +local recentItems = {} -- list of the most recent items, newest first +local faviconCache = {} -- { [domain] = localFilePath } - avoids re-downloading the same site's favicon local dataPath = nil local MAX_RECENT_ITEMS = 50 -local MAX_SEEN_PER_FEED = 300 -- limite de ids "ja vistos" guardados por feed (evita crescer sem fim) +local MAX_SEEN_PER_FEED = 300 -- cap on "already seen" ids kept per feed (prevents unbounded growth) --- Limites para manter o parsing rapido o suficiente para o orcamento de CPU --- (muito apertado) do callback assincrono. -local MAX_BODY_BYTES = 8000 -- so olhamos os primeiros ~8KB do corpo do feed -local MAX_ITEM_BYTES = 400 -- corta cada bloco / antes de extrair tags -local MAX_ITEMS = 8 -- para de processar itens depois desse tanto +-- Limits to keep parsing fast enough for the (very tight) CPU budget of the +-- async callback. +local MAX_BODY_BYTES = 8000 -- only look at the first ~8KB of the feed body +local MAX_ITEM_BYTES = 700 -- trim each / block before extracting tags (raised to fit enclosure/media:thumbnail) +local MAX_ITEMS = 8 -- stop processing items after this many local function isUtf8Continuation(b) return b ~= nil and b >= 0x80 and b < 0xC0 end --- Corta a string em ate n bytes, mas nunca no meio de um caractere UTF-8 --- multibyte (acentos, aspas curvas, emoji, etc.) - cortar assim gera bytes --- invalidos que o renderizador de texto (Pango) rejeita, deixando labels --- (e por tabela o painel inteiro) sem aparecer. +-- Cuts the string to at most n bytes, but never in the middle of a multibyte +-- UTF-8 character (accents, curly quotes, emoji, etc.) - cutting there +-- produces invalid bytes that the text renderer (Pango) rejects, leaving +-- labels (and by extension the whole panel) blank. local function truncate(s, n) if not s or #s <= n then return s end local cut = n - -- recua enquanto o byte da posicao for byte de continuacao (0x80-0xBF) + -- back off while the byte at this position is a continuation byte (0x80-0xBF) while cut > 0 and isUtf8Continuation(s:byte(cut)) do cut = cut - 1 end - -- se o byte que sobrou for o inicio de uma sequencia multibyte, so mantem - -- se ela couber inteira dentro do limite n; senao descarta ele tambem + -- if the remaining byte is the start of a multibyte sequence, only keep it + -- if the whole sequence fits within the limit n; otherwise drop it too local b = cut > 0 and s:byte(cut) or nil if b and b >= 0xC0 then local seqLen = (b >= 0xF0 and 4) or (b >= 0xE0 and 3) or 2 @@ -46,10 +47,9 @@ local function truncate(s, n) return s:sub(1, cut) end --- Mesma logica de "nao corte no meio de UTF-8", mas trabalhando so com --- indices/bytes individuais (sem materializar substrings gigantes) - usado --- para limitar o tamanho de um bloco sem copiar o conteudo inteiro --- antes de cortar. +-- Same "don't cut mid-UTF-8" logic, but working only with individual +-- indices/bytes (without materializing giant substrings) - used to bound the +-- size of an block without copying the whole content before cutting. local function safeCutEnd(xml, endPos, minPos) local pos = endPos while pos > minPos do @@ -58,23 +58,23 @@ local function safeCutEnd(xml, endPos, minPos) break end if b < 0x80 then - break -- ascii, seguro + break -- ascii, safe elseif b >= 0xC0 then local seqLen = (b >= 0xF0 and 4) or (b >= 0xE0 and 3) or 2 if pos + seqLen - 1 <= endPos then - break -- sequencia cabe inteira ate endPos, seguro + break -- the whole sequence fits up to endPos, safe end - pos = pos - 1 -- nao cabe inteira, descarta o lead byte tambem + pos = pos - 1 -- doesn't fit whole, drop the lead byte too else - pos = pos - 1 -- byte de continuacao, ainda no meio da sequencia + pos = pos - 1 -- continuation byte, still mid-sequence end end return pos end --- Testa se um item ja foi visto e, se nao, marca como visto - com limite de --- tamanho por feed (descarta o mais antigo quando passa do limite), para --- nunca deixar a estrutura "seen" crescer sem fim (e estourar o encode/save). +-- Checks whether an item has already been seen and, if not, marks it as +-- seen - with a per-feed size cap (drops the oldest once over the limit), so +-- the "seen" structure never grows without bound (and blows up encode/save). local function markSeen(url, id) local bucket = seen[url] if not bucket or not bucket.ids then @@ -82,7 +82,7 @@ local function markSeen(url, id) seen[url] = bucket end if bucket.ids[id] then - return false -- ja visto + return false -- already seen end bucket.ids[id] = true table.insert(bucket.order, id) @@ -90,7 +90,7 @@ local function markSeen(url, id) local oldest = table.remove(bucket.order, 1) bucket.ids[oldest] = nil end - return true -- era novo + return true -- was new end local function isFirstRunForFeed(url) @@ -98,7 +98,7 @@ local function isFirstRunForFeed(url) return not bucket or not bucket.order or #bucket.order == 0 end --- Converte um codepoint Unicode para a sequencia de bytes UTF-8 equivalente. +-- Converts a Unicode codepoint to the equivalent UTF-8 byte sequence. local function codepointToUtf8(cp) if not cp or cp < 0 then return "" @@ -122,9 +122,9 @@ local function codepointToUtf8(cp) end end --- CP-1252 diverge de Latin-1 exatamente nos bytes 0x80-0x9F: em Latin-1 sao --- codigos de controle inuteis, mas em CP-1252 (o padrao de fato mais comum --- em feeds mal-marcados) sao aspas curvas, travessao, reticencias etc. +-- CP-1252 diverges from Latin-1 exactly in the 0x80-0x9F byte range: in +-- Latin-1 those are useless control codes, but in CP-1252 (the de-facto more +-- common charset in mislabeled feeds) they're curly quotes, dashes, ellipsis, etc. local CP1252_HIGH = { [0x80] = 0x20AC, [0x82] = 0x201A, [0x83] = 0x0192, [0x84] = 0x201E, [0x85] = 0x2026, [0x86] = 0x2020, [0x87] = 0x2021, [0x88] = 0x02C6, @@ -135,17 +135,17 @@ local CP1252_HIGH = { [0x9C] = 0x0153, [0x9E] = 0x017E, [0x9F] = 0x0178, } --- Converte um unico byte Latin-1/CP-1252 (0x80-0xFF) para a sequencia UTF-8 --- equivalente - usado como fallback quando um byte nao forma UTF-8 valido. +-- Converts a single Latin-1/CP-1252 byte (0x80-0xFF) to the equivalent UTF-8 +-- sequence - used as a fallback when a byte doesn't form valid UTF-8. local function latin1ByteToUtf8(b) - local cp = CP1252_HIGH[b] or b -- 0xA0-0xFF: Latin-1 e CP-1252 coincidem + local cp = CP1252_HIGH[b] or b -- 0xA0-0xFF: Latin-1 and CP-1252 match return codepointToUtf8(cp) end --- Corrige/normaliza texto para UTF-8 valido. Quando um byte nao forma uma --- sequencia UTF-8 valida, assume Latin-1/CP-1252 (charset errado e comum --- de feeds mais antigos, como sites de noticia brasileiros) e CONVERTE em --- vez de descartar - assim o acento aparece certo em vez de sumir. +-- Fixes/normalizes text to valid UTF-8. When a byte doesn't form a valid +-- UTF-8 sequence, assumes Latin-1/CP-1252 (a wrong-charset case common in +-- older feeds, like Brazilian news sites) and CONVERTS instead of dropping - +-- so the accent shows up correctly instead of vanishing. local function sanitizeUtf8(s) if not s then return s @@ -167,7 +167,7 @@ local function sanitizeUtf8(s) elseif b >= 0xC2 then seqLen = 2 else - seqLen = 0 -- lead byte invalido (0x80-0xC1) + seqLen = 0 -- invalid lead byte (0x80-0xC1) end local valid = seqLen > 0 and (i + seqLen - 1) <= len @@ -185,7 +185,7 @@ local function sanitizeUtf8(s) out[#out + 1] = s:sub(i, i + seqLen - 1) i = i + seqLen else - out[#out + 1] = latin1ByteToUtf8(b) -- converte em vez de descartar + out[#out + 1] = latin1ByteToUtf8(b) -- convert instead of dropping i = i + 1 end end @@ -194,7 +194,7 @@ local function sanitizeUtf8(s) end -- --------------------------------------------------------------------------- --- Persistencia (sobrevive a restarts do plugin/shell) +-- Persistence (survives plugin/shell restarts) -- --------------------------------------------------------------------------- local function loadState() @@ -211,9 +211,10 @@ local function loadState() seen = decoded.seen or {} recentItems = decoded.recentItems or {} unread = decoded.unread or 0 + faviconCache = decoded.faviconCache or {} - -- migra formato antigo ({ [id]=true, ... } direto) para o novo - -- ({ ids=..., order=... }), se necessario + -- migrate the old format ({ [id]=true, ... } directly) to the new one + -- ({ ids=..., order=... }), if needed for url, bucket in pairs(seen) do if type(bucket) == "table" and not bucket.ids then local migrated = { ids = {}, order = {} } @@ -227,8 +228,8 @@ local function loadState() end end - -- sanitiza itens ja persistidos (podem ter sido salvos com UTF-8 - -- quebrado por versoes anteriores deste plugin, antes deste fix) + -- sanitize already-persisted items (may have been saved with broken + -- UTF-8 by earlier versions of this plugin, before this fix) for _, item in ipairs(recentItems) do if item.title then item.title = sanitizeUtf8(item.title) @@ -241,23 +242,24 @@ local function loadState() end end --- Nunca deixa uma falha de encode/escrita derrubar o entry (isso ja causou o --- service ser desativado apos varios erros seguidos no update()). +-- Never let an encode/write failure take down the entry (this already +-- caused the service to be disabled after several consecutive update() errors). local function saveState() if not dataPath then return end local ok, encoded = pcall(noctalia.json.encode, { - seen = seen, - recentItems = recentItems, - unread = unread, + seen = seen, + recentItems = recentItems, + unread = unread, + faviconCache = faviconCache, }) if ok and type(encoded) == "string" then pcall(noctalia.writeFile, dataPath, encoded) end end --- Idem para publicar em noctalia.state: nunca propaga erro pra cima. +-- Same idea for publishing to noctalia.state: never propagate an error upward. local function publishItems() local ok, encoded = pcall(noctalia.json.encode, recentItems) if ok and type(encoded) == "string" then @@ -266,15 +268,107 @@ local function publishItems() end -- --------------------------------------------------------------------------- --- Parsing minimo de RSS 2.0 / Atom 1.0 usando SO busca literal (string.find --- com plain=true) - evita o motor de padroes do Lua (".-", "[^>]", etc.), --- que parece caro demais para o orcamento de CPU deste ambiente. +-- Thumbnail download: ui.image only accepts a LOCAL file 'path', not a +-- remote URL (confirmed in the official Wallhaven plugin). So we download +-- the image into the plugin's cache and only then fill item.image with the +-- local path. Queue with a concurrency cap, same pattern as Wallhaven, to +-- avoid exceeding the host's simultaneous async operation limit. -- --------------------------------------------------------------------------- --- (codepointToUtf8 ja foi definida mais acima, perto de sanitizeUtf8 - reusada aqui) +local THUMB_DIR = nil +local thumbQueue = {} +local thumbActive = 0 +local MAX_THUMB_CONCURRENT = 2 --- Entidades nomeadas de acento mais comuns em portugues (nao sao XML puro, --- mas alguns feeds mal-formados usam mesmo assim). +local function shellQuote(s) + return "'" .. s:gsub("'", "'\\''") .. "'" +end + +local function sanitizeFilename(s) + return (tostring(s):gsub("[^%w%-]", "_")):sub(1, 80) +end + +local function ensureThumbDir() + local dir = noctalia.pluginDataDir() + if not dir then + return + end + THUMB_DIR = dir .. "/thumbs" + noctalia.runAsync("mkdir -p " .. shellQuote(THUMB_DIR)) +end + +local pumpThumbQueue + +pumpThumbQueue = function() + while thumbActive < MAX_THUMB_CONCURRENT and #thumbQueue > 0 do + local job = table.remove(thumbQueue, 1) + thumbActive = thumbActive + 1 + noctalia.download(job.url, job.dest, function(ok) + thumbActive = thumbActive - 1 + if ok then + if job.domain then + faviconCache[job.domain] = job.dest -- cache so other items from the same site reuse it + end + for _, item in ipairs(recentItems) do + if item.id == job.id then + item.image = job.dest + break + end + end + publishItems() + saveState() + else + noctalia.log("rss-notifier: thumbnail download failed for " .. job.url) + end + pumpThumbQueue() + end) + end +end + +-- Downloads a feed item's own cover image (enclosure/media). One file per +-- item, since these URLs are essentially unique per item. +local function queueThumbDownload(id, url) + if not THUMB_DIR or not url or url == "" then + return + end + local dest = THUMB_DIR .. "/" .. sanitizeFilename(id) .. ".img" + table.insert(thumbQueue, { id = id, url = url, dest = dest }) + pumpThumbQueue() +end + +-- Resolves a site favicon for an item, reusing the cache when another item +-- from the same domain already downloaded it (favicons are per-SITE, not +-- per-item, so there's no reason to fetch the same one over and over). +local function queueFaviconDownload(id, domain, faviconUrl) + if not THUMB_DIR or not domain then + return + end + local cached = faviconCache[domain] + if cached then + for _, item in ipairs(recentItems) do + if item.id == id then + item.image = cached + break + end + end + publishItems() + return + end + local dest = THUMB_DIR .. "/favicon-" .. sanitizeFilename(domain) .. ".img" + table.insert(thumbQueue, { id = id, url = faviconUrl, dest = dest, domain = domain }) + pumpThumbQueue() +end + +-- --------------------------------------------------------------------------- +-- Minimal RSS 2.0 / Atom 1.0 parsing using ONLY literal search (string.find +-- with plain=true) - avoids Lua's pattern engine (".-", "[^>]", etc.), which +-- turned out to be too expensive for this environment's CPU budget. +-- --------------------------------------------------------------------------- + +-- (codepointToUtf8 was already defined above, near sanitizeUtf8 - reused here) + +-- Most common named accent entities in Portuguese (not strict XML, but some +-- malformed feeds use them anyway). local NAMED_ENTITIES = { aacute = 0xE1, eacute = 0xE9, iacute = 0xED, oacute = 0xF3, uacute = 0xFA, Aacute = 0xC1, Eacute = 0xC9, Iacute = 0xCD, Oacute = 0xD3, Uacute = 0xDA, @@ -295,20 +389,20 @@ local function decodeEntities(s) s = s:gsub(">", ">") s = s:gsub(""", '"') s = s:gsub("'", "'") - -- numericas decimais: ô + -- decimal numeric refs: ô s = s:gsub("&#(%d+);", function(digits) return codepointToUtf8(tonumber(digits)) end) - -- numericas hexadecimais: ô ou ô + -- hex numeric refs: ô or ô s = s:gsub("&#[xX](%x+);", function(hex) return codepointToUtf8(tonumber(hex, 16)) end) - -- nomeadas comuns de acento (feeds nao-XML-estritos) + -- common named accent entities (non-strict-XML feeds) s = s:gsub("&(%a+);", function(name) local cp = NAMED_ENTITIES[name] return cp and codepointToUtf8(cp) or ("&" .. name .. ";") end) - s = s:gsub("&", "&") -- por ultimo, senao "&lt;" viraria "<" errado + s = s:gsub("&", "&") -- last, otherwise "&lt;" would wrongly become "<" return sanitizeUtf8(noctalia.string.trim(s)) end @@ -322,7 +416,7 @@ local function stripCdata(s) return s end --- Extrai o conteudo de ... usando so find() literal. +-- Extracts the content of ... using only literal find(). local function findTagContent(s, tag) local openStart = s:find("<" .. tag, 1, true) if not openStart then @@ -339,7 +433,7 @@ local function findTagContent(s, tag) return decodeEntities(stripCdata(s:sub(openEnd + 1, closeStart - 1))) end --- Extrai um valor de atributo de dentro da PRIMEIRA ocorrencia de . +-- Extracts an attribute value from inside the FIRST occurrence of . local function findAttr(s, tag, attr) local openStart = s:find("<" .. tag, 1, true) if not openStart then @@ -374,10 +468,73 @@ local function extractId(block) return findTagContent(block, "guid") or findTagContent(block, "id") or extractLink(block) end --- Encontra o PROXIMO bloco ... a partir de fromPos, usando so --- find() literal. Retorna o conteudo do bloco (ja cortado) e a posicao onde --- parar na proxima chamada - permite processar um item por vez, em ticks --- separados, em vez de tudo de uma vez dentro do callback http. +-- Tries to find a cover image for the item: , +-- , or , in that order. +local function extractImage(block) + local encUrl = findAttr(block, "enclosure", "url") + if encUrl then + local encType = findAttr(block, "enclosure", "type") + if not encType or encType:find("image", 1, true) then + return encUrl + end + end + + local thumbUrl = findAttr(block, "media:thumbnail", "url") + if thumbUrl then + return thumbUrl + end + + local mediaUrl = findAttr(block, "media:content", "url") + if mediaUrl then + local medium = findAttr(block, "media:content", "medium") + local mtype = findAttr(block, "media:content", "type") + if (not medium and not mtype) or (medium == "image") or (mtype and mtype:find("image", 1, true)) then + return mediaUrl + end + end + + return nil +end + +-- Extracts the host from a URL (e.g. "https://example.com/path" -> "example.com"), +-- using only literal find()/sub() - no pattern engine. +local function extractDomain(url) + if not url or url == "" then + return nil + end + local schemeEnd = url:find("://", 1, true) + local start = schemeEnd and (schemeEnd + 3) or 1 + local slashPos = url:find("/", start, true) + local domain = slashPos and url:sub(start, slashPos - 1) or url:sub(start) + + local atPos = domain:find("@", 1, true) + if atPos then + domain = domain:sub(atPos + 1) -- strip a possible "user:pass@" prefix + end + local colonPos = domain:find(":", 1, true) + if colonPos then + domain = domain:sub(1, colonPos - 1) -- strip a possible ":port" suffix + end + + if domain == "" then + return nil + end + return domain +end + +-- Fallback favicon URL for a site, used when the feed item has no image of +-- its own. Uses Google's favicon service instead of guessing /favicon.ico +-- paths or downloading+parsing the site's HTML, which would be much heavier. +local function faviconUrlFor(domain) + return "https://www.google.com/s2/favicons?sz=64&domain=" .. domain +end + + +-- Finds the NEXT ... block starting at fromPos, using only +-- literal find(). Returns the (already trimmed) block content and the +-- position to resume at on the next call - lets us process one item at a +-- time, across separate ticks, instead of everything at once inside the +-- http callback. local function findNextBlock(xml, tag, fromPos, maxItemBytes) local openStart = xml:find("<" .. tag, fromPos, true) if not openStart then @@ -394,8 +551,8 @@ local function findNextBlock(xml, tag, fromPos, maxItemBytes) end local contentEnd = math.min(closeStart - 1, openEnd + maxItemBytes) if contentEnd < closeStart - 1 then - -- so precisa corrigir a fronteira UTF-8 quando o corte foi mesmo pelo - -- limite de bytes (nao pela tag de fechamento, que ja e uma fronteira segura) + -- only need to fix the UTF-8 boundary when the cut was actually caused + -- by the byte limit (not by the closing tag, which is already a safe boundary) contentEnd = safeCutEnd(xml, contentEnd, openEnd) end local block = xml:sub(openEnd + 1, contentEnd) @@ -403,13 +560,13 @@ local function findNextBlock(xml, tag, fromPos, maxItemBytes) end -- --------------------------------------------------------------------------- --- Fila de processamento incremental: o callback http so guarda o corpo (ja --- cortado) na fila; o parsing de verdade acontece aos poucos, um item por --- tick de update(), porque o orcamento de CPU do callback assincrono e --- pequeno demais para processar um feed inteiro de uma vez. +-- Incremental processing queue: the http callback only stores the (already +-- trimmed) body in the queue; the actual parsing happens gradually, one item +-- per update() tick, because the async callback's CPU budget is too small +-- to process a whole feed at once. -- --------------------------------------------------------------------------- -local queue = {} -- lista de { url=, body=, pos=, tag=, feedTitle=, items=, notifyBudget= } +local queue = {} -- list of { url=, body=, pos=, tag=, feedTitle=, items=, notifyBudget= } local function enqueueFeed(url, body, notifyBudget) table.insert(queue, { @@ -424,9 +581,9 @@ local function enqueueFeed(url, body, notifyBudget) }) end --- Finaliza um feed da fila: compara com o que ja foi visto, notifica o que --- for novo e publica o estado. E um passo isolado (nao mistura com a --- extracao de itens) para manter cada callback pequeno. +-- Finalizes a feed from the queue: compares against what's already been +-- seen, notifies on new items, and publishes state. This is an isolated +-- step (not mixed with item extraction) to keep each callback small. local function finalizeFeed(f) local url = f.url local firstRun = isFirstRunForFeed(url) @@ -444,7 +601,16 @@ local function finalizeFeed(f) title = item.title, link = item.link, feedTitle = f.feedTitle, + image = nil, -- filled in later with the LOCAL path, once the download finishes }) + if item.image and item.image ~= "" then + queueThumbDownload(id, item.image) + else + local domain = extractDomain(item.link) or extractDomain(url) + if domain then + queueFaviconDownload(id, domain, faviconUrlFor(domain)) + end + end if notifyEnabled and f.notifyBudget.count < f.notifyBudget.max then f.notifyBudget.count = f.notifyBudget.count + 1 noctalia.notify(item.title, f.feedTitle) @@ -466,8 +632,8 @@ local function finalizeFeed(f) saveState() end --- Processa UM pequeno passo da fila: extrai no maximo um item do feed que --- esta na frente da fila. Chamado uma vez por tick de update(). +-- Processes ONE small step of the queue: extracts at most one item from the +-- feed at the front of the queue. Called once per update() tick. local function processQueueStep() local f = queue[1] if not f then @@ -476,7 +642,7 @@ local function processQueueStep() if not f.feedTitle then f.feedTitle = findTagContent(truncate(f.body, 300), "title") or f.url - return -- um passo por tick: so o titulo desta vez + return -- one step per tick: just the title this time end if #f.items >= MAX_ITEMS then @@ -489,13 +655,13 @@ local function processQueueStep() if not block then if f.tag == "item" and not f.triedEntry then - -- RSS nao encontrado: tenta Atom () a partir do comeco + -- no RSS found: try Atom () from the start f.tag = "entry" f.pos = 1 f.triedEntry = true return end - -- acabaram os itens (ou nao achou nenhum) - finaliza + -- ran out of items (or found none) - finalize table.remove(queue, 1) finalizeFeed(f) return @@ -506,16 +672,17 @@ local function processQueueStep() title = findTagContent(block, "title") or "(sem titulo)", link = extractLink(block), id = extractId(block), + image = extractImage(block), }) end -- --------------------------------------------------------------------------- --- Ciclo de busca +-- Fetch cycle -- --------------------------------------------------------------------------- local function checkFeed(url, notifyBudget) - -- o callback http faz o MINIMO possivel: so guarda o corpo na fila. - -- Todo o parsing de verdade acontece depois, aos poucos, em processQueueStep(). + -- the http callback does the BARE MINIMUM: just stores the body in the + -- queue. All the real parsing happens later, gradually, in processQueueStep(). noctalia.http({ url = url, headers = { "Accept: application/rss+xml, application/atom+xml, application/xml, text/xml" } }, function(res) if not res.ok or not res.body or res.body == "" then return @@ -535,7 +702,7 @@ local function fetchAll() end end -local REFRESH_TICK_MS = 1000 -- update() roda a cada segundo: drena a fila aos poucos +local REFRESH_TICK_MS = 1000 -- update() runs every second: drains the queue gradually local ticksUntilFetch = 1 local function applyInterval() @@ -548,17 +715,18 @@ local function applyInterval() end -- --------------------------------------------------------------------------- --- Ciclo de vida +-- Lifecycle -- --------------------------------------------------------------------------- loadState() +ensureThumbDir() applyInterval() noctalia.state.set("unread", unread) publishItems() -fetchAll() -- primeira leitura: so marca como "vistos", sem notificar (firstRun) +fetchAll() -- first read: just marks items as "seen", without notifying (firstRun) function update() - processQueueStep() -- sempre drena um pedacinho da fila, se houver algo + processQueueStep() -- always drains a little bit of the queue, if there's anything ticksUntilFetch = ticksUntilFetch - 1 if ticksUntilFetch <= 0 then diff --git a/rss-notifier/widget.luau b/rss-notifier/widget.luau index 37ffe2b7..9688ce58 100644 --- a/rss-notifier/widget.luau +++ b/rss-notifier/widget.luau @@ -1,6 +1,6 @@ -- widget.luau --- Widget de barra: icone RSS com uma pilula colorida (badge) de itens nao --- lidos encostada no lado esquerdo, publicada pelo service via noctalia.state. +-- Bar widget: RSS glyph with a colored pill (badge) of unread items next to +-- it on the left side, published by the service via noctalia.state. local unread = 0 @@ -8,8 +8,8 @@ local function render() local children = {} if unread > 0 then - -- pilula: um container com fundo colorido e cantos arredondados, com o - -- numero dentro - o mais perto que a API declarativa chega de um "badge" + -- pill: a container with a colored background and rounded corners, with + -- the number inside - the closest the declarative API gets to a "badge" table.insert(children, ui.row({ fill = "primary", radius = 8, @@ -38,22 +38,22 @@ end) render() function update() - noctalia.setUpdateInterval(5000) -- so mantem o widget "vivo"; os dados reais vem do state + noctalia.setUpdateInterval(5000) -- just keeps the widget "alive"; real data comes from state end function onConfigChanged() - render() -- pega o novo glyph quando o usuario troca o icone nas settings do widget + render() -- picks up the new glyph when the user changes the icon in the widget settings end function onClick() - -- abre/fecha a janelinha com a lista de itens; o proprio painel marca - -- como lido (zera o badge) quando e aberto, via IPC pro service - noctalia.togglePanel("nilsonlinux/rss-notifier:list") + -- opens/closes the item list popup; the panel itself marks everything as + -- read (resets the badge) when it's opened, via IPC to the service + noctalia.togglePanel("nilsonlinux/rss-notifier:panel") end function onRightClick() - -- clique direito: forca uma nova checagem imediata dos feeds, - -- enviando um evento IPC para a entry [[service]] (que e um singleton, alvo "all") + -- right click: forces an immediate feed check by sending an IPC event to + -- the [[service]] entry (which is a singleton, target "all") noctalia.runAsync("noctalia msg plugin nilsonlinux/rss-notifier:fetcher all refresh") noctalia.notify("RSS/Atom Notifier", "Atualizando feeds...") end From 2bb21a892472e4c2bb0a8390a4c0f3d18d6ef2a8 Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Sun, 16 Aug 2026 17:04:04 -0300 Subject: [PATCH 11/24] update plugin.toml and widget.luau to fix the panel id and improve comments. From 5eb6a506b20908f946b67f2db2ba9af651f20e9a Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Sun, 16 Aug 2026 21:49:47 -0300 Subject: [PATCH 12/24] update rss-notifier/service.luau to fix the issue with the notification system. --- rss-notifier/service.luau | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/rss-notifier/service.luau b/rss-notifier/service.luau index 6425cf7c..9603c7ea 100644 --- a/rss-notifier/service.luau +++ b/rss-notifier/service.luau @@ -319,6 +319,10 @@ pumpThumbQueue = function() saveState() else noctalia.log("rss-notifier: thumbnail download failed for " .. job.url) + if job.domain then + faviconCache[job.domain] = false -- remember the failure so we stop retrying this domain + saveState() + end end pumpThumbQueue() end) @@ -339,11 +343,16 @@ end -- Resolves a site favicon for an item, reusing the cache when another item -- from the same domain already downloaded it (favicons are per-SITE, not -- per-item, so there's no reason to fetch the same one over and over). +-- faviconCache[domain] can be: nil (never tried), false (tried and failed - +-- don't retry), or a string (local path, ready to use). local function queueFaviconDownload(id, domain, faviconUrl) if not THUMB_DIR or not domain then return end local cached = faviconCache[domain] + if cached == false then + return -- already know this domain has no favicon, don't hammer it again + end if cached then for _, item in ipairs(recentItems) do if item.id == id then @@ -606,7 +615,11 @@ local function finalizeFeed(f) if item.image and item.image ~= "" then queueThumbDownload(id, item.image) else - local domain = extractDomain(item.link) or extractDomain(url) + -- prefer the FEED's own domain: item links often go through + -- redirect/tracking subdomains (e.g. redir.example.com) that have + -- no favicon of their own, while the feed's domain is reliably the + -- real site + local domain = extractDomain(url) or extractDomain(item.link) if domain then queueFaviconDownload(id, domain, faviconUrlFor(domain)) end From 86b6507a550f211a3bf9dca510fe97a730a378c2 Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Mon, 17 Aug 2026 20:22:07 -0300 Subject: [PATCH 13/24] update translations and fix widget --- rss-notifier/panel.luau | 61 ++++++++++++++++++---------- rss-notifier/plugin.toml | 18 +++++++- rss-notifier/translations/en.json | 4 ++ rss-notifier/translations/pt-BR.json | 4 ++ rss-notifier/widget.luau | 2 +- 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/rss-notifier/panel.luau b/rss-notifier/panel.luau index c691892c..c59f9855 100644 --- a/rss-notifier/panel.luau +++ b/rss-notifier/panel.luau @@ -42,6 +42,40 @@ itemRow = function(item) local key = item.id or item.link or item.title local hovered = hoveredKey == key + local showImages = noctalia.getConfig("show_feed_images") + if showImages == nil then + showImages = true -- default enabled + end + + local rowChildren = {} + + if showImages then + if item.image and item.image ~= "" then + table.insert(rowChildren, ui.image({ path = item.image, width = 56, height = 56, radius = 10, fit = "cover" })) + else + table.insert(rowChildren, ui.row({ width = 56, height = 56, radius = 10, fill = "surface_variant/0.7", align = "center", justify = "center" }, { + ui.glyph({ name = "rss", size = 20, color = "outline" }), + })) + end + end + + table.insert(rowChildren, ui.column({ + gap = 2, + flexGrow = 1, + onClick = function() openLink(item.link) end, + }, { + ui.label({ text = item.title or "(sem titulo)", fontWeight = "bold", maxLines = 2 }), + ui.label({ text = item.feedTitle or "", fontSize = 12, color = "outline" }), + })) + + table.insert(rowChildren, ui.button({ + glyph = "close", + variant = "outline", + controlSize = "sm", + tooltip = "Dispensar", + onClick = function() dismissItem(item) end, + })) + return ui.row({ key = key, gap = 6, @@ -55,28 +89,7 @@ itemRow = function(item) hoveredKey = isHovering and key or nil render() end, - }, { - (item.image and item.image ~= "") - and ui.image({ path = item.image, width = 56, height = 56, radius = 10, fit = "cover" }) - or ui.row({ width = 56, height = 56, radius = 10, fill = "surface_variant/0.7", align = "center", justify = "center" }, { - ui.glyph({ name = "rss", size = 20, color = "outline" }), - }), - ui.column({ - gap = 2, - flexGrow = 1, - onClick = function() openLink(item.link) end, - }, { - ui.label({ text = item.title or "(sem titulo)", fontWeight = "bold", maxLines = 2 }), - ui.label({ text = item.feedTitle or "", fontSize = 12, color = "outline" }), - }), - ui.button({ - glyph = "close", - variant = "outline", - controlSize = "sm", - tooltip = "Dispensar", - onClick = function() dismissItem(item) end, - }), - }) + }, rowChildren) end emptyState = function() @@ -156,3 +169,7 @@ end function onCloseClicked() panel.close() end + +function onConfigChanged() + render() -- picks up show_feed_images (or other setting) changes immediately +end diff --git a/rss-notifier/plugin.toml b/rss-notifier/plugin.toml index e3270c87..d8077330 100644 --- a/rss-notifier/plugin.toml +++ b/rss-notifier/plugin.toml @@ -47,6 +47,13 @@ min = 1 max = 50 advanced = true +[[setting]] +key = "show_feed_images" +type = "bool" +label_key = "settings.show_feed_images.label" +description_key = "settings.show_feed_images.description" +default = true + # --------------------------------------------------------------------------- # Service: runs in the background, without UI, searches and parses feeds # --------------------------------------------------------------------------- @@ -70,12 +77,19 @@ entry = "widget.luau" description_key = "settings.glyph.description" default = "rss" + [[widget.setting]] + key = "show_feed_images" + type = "bool" + label_key = "settings.show_feed_images.label" + description_key = "settings.show_feed_images.description" + default = true + # --------------------------------------------------------------------------- -# Panel: small window with the list of items, opened by clicking on the widget +# Panel: popup with the item list, opened by clicking the widget # --------------------------------------------------------------------------- [[panel]] -id = "panel" +id = "Panel" entry = "panel.luau" width = 420 height = 560 diff --git a/rss-notifier/translations/en.json b/rss-notifier/translations/en.json index 3d756f3e..5e646b80 100644 --- a/rss-notifier/translations/en.json +++ b/rss-notifier/translations/en.json @@ -4,6 +4,10 @@ "description": "One RSS or Atom feed URL per entry (e.g. https://example.com/feed.xml).", "label": "Feed URLs" }, + "show_feed_images": { + "label": "Show feed images", + "description": "Show each item's cover image (or the site's favicon as a fallback) in the item list." + }, "glyph": { "description": "Icon shown in the bar for this widget.", "label": "Icon" diff --git a/rss-notifier/translations/pt-BR.json b/rss-notifier/translations/pt-BR.json index 01c7c049..4dcd83b6 100644 --- a/rss-notifier/translations/pt-BR.json +++ b/rss-notifier/translations/pt-BR.json @@ -19,6 +19,10 @@ "refresh_minutes": { "description": "Frequência com que os feeds são checados em busca de novidades.", "label": "Intervalo de atualização (minutos)" + }, + "show_feed_images": { + "label": "Mostrar imagens dos feeds", + "description": "Mostra a imagem de capa de cada item (ou o favicon do site como alternativa) na lista de itens." } } } diff --git a/rss-notifier/widget.luau b/rss-notifier/widget.luau index 9688ce58..4a1eaca8 100644 --- a/rss-notifier/widget.luau +++ b/rss-notifier/widget.luau @@ -48,7 +48,7 @@ end function onClick() -- opens/closes the item list popup; the panel itself marks everything as -- read (resets the badge) when it's opened, via IPC to the service - noctalia.togglePanel("nilsonlinux/rss-notifier:panel") + noctalia.togglePanel("nilsonlinux/rss-notifier:Panel") end function onRightClick() From ee7ebf72bcb7f821005f39b6745536a869d153f2 Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Mon, 17 Aug 2026 20:25:53 -0300 Subject: [PATCH 14/24] update e fix images rss From 66681b71712fb31ae46b29cda70bdffa347549eb Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Mon, 17 Aug 2026 20:35:17 -0300 Subject: [PATCH 15/24] corrected typo in the translation file --- rss-notifier/translations/en.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rss-notifier/translations/en.json b/rss-notifier/translations/en.json index 5e646b80..5cbc9682 100644 --- a/rss-notifier/translations/en.json +++ b/rss-notifier/translations/en.json @@ -4,10 +4,6 @@ "description": "One RSS or Atom feed URL per entry (e.g. https://example.com/feed.xml).", "label": "Feed URLs" }, - "show_feed_images": { - "label": "Show feed images", - "description": "Show each item's cover image (or the site's favicon as a fallback) in the item list." - }, "glyph": { "description": "Icon shown in the bar for this widget.", "label": "Icon" @@ -23,6 +19,10 @@ "refresh_minutes": { "description": "How often feeds are checked for new items.", "label": "Refresh interval (minutes)" + }, + "show_feed_images": { + "label": "Show feed images", + "description": "Show each item's cover image (or the site's favicon as a fallback) in the item list." } } } From b1604a61728d4febcd615286db5ba4d26af3f067 Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Mon, 17 Aug 2026 20:43:57 -0300 Subject: [PATCH 16/24] corrected typo in the translation file --- rss-notifier/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rss-notifier/README.md b/rss-notifier/README.md index 14a8901c..ed49ae8a 100644 --- a/rss-notifier/README.md +++ b/rss-notifier/README.md @@ -16,7 +16,7 @@ Monitor RSS/Atom feeds and get notifications for new items. **IPC Command:** -noctalia msg panel-toggle nilsonlinux/rss-notifier:panel +noctalia msg panel-toggle nilsonlinux/rss-notifier:Panel text @@ -28,6 +28,7 @@ text | `refresh_minutes` | int | `30` | How often to check for new items (1-1440 minutes) | | `notify_new` | bool | `true` | Display notifications when new items arrive | | `max_notifications_per_cycle` | int | `5` | Maximum notifications shown per check (1-50) | +| `show_feed_images` | bool | `true` | Show each item's cover image (or the site's favicon as a fallback) in the item list. | | `glyph` (widget) | `glyph` | `rss` | Icon shown in the bar for the `status` widget. | ## Installation From be258a14decf861a1bdcdd622cc2ab00f68dbf55 Mon Sep 17 00:00:00 2001 From: nilsonlinux Date: Mon, 17 Aug 2026 20:57:06 -0300 Subject: [PATCH 17/24] update thumbnail --- rss-notifier/thumbnail.webp | Bin 76704 -> 79670 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/rss-notifier/thumbnail.webp b/rss-notifier/thumbnail.webp index da2ff6ace6dc4bf2a54b572eca48196153a3932c..e039d86353b8249950b5eafad02718daa466c50a 100644 GIT binary patch literal 79670 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�n`Nxn@Sgl2^IvM|_k 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 literal 76704 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 From 3c6423c9a83fb5d9ef3e7ba00680cd0f977f0aa0 Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Mon, 17 Aug 2026 21:50:18 -0300 Subject: [PATCH 18/24] Revise README for link-ip-monitor Updated title and improved description in README. --- link-ip-monitor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/link-ip-monitor/README.md b/link-ip-monitor/README.md index 8d82ccf7..9e6248f6 100644 --- a/link-ip-monitor/README.md +++ b/link-ip-monitor/README.md @@ -1,5 +1,5 @@ -# Link/IP Monitor -Pings a list of IPs, hostnames or links on an interval, tracks +# link-ip-monitor +link-ip-monitor pings a list of IPs, hostnames or links on an interval, tracks each host's online/offline status and response time, and notifies when one goes down or comes back up. From cf29e0d564e71e6190a6ce7405be1f009f1b882d Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Mon, 17 Aug 2026 22:02:15 -0300 Subject: [PATCH 19/24] Correct capitalization in README entries section --- rss-notifier/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rss-notifier/README.md b/rss-notifier/README.md index ed49ae8a..e2fd8f38 100644 --- a/rss-notifier/README.md +++ b/rss-notifier/README.md @@ -7,7 +7,7 @@ Monitor RSS/Atom feeds and get notifications for new items. | Field | Value | | --- | --- | | ID | `nilsonlinux/rss-notifier` | -| Entries | Bar widget: `indicator`; panel: `panel`| +| Entries | Bar widget: `indicator`; Panel: `Panel`| **Entries:** - **Service:** `fetcher` - Background service that fetches and parses feeds From 33f3ec32a6436b8f643f7d235b28ed3a497db78e Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Thu, 20 Aug 2026 18:17:04 -0300 Subject: [PATCH 20/24] Update notification label in Portuguese translation --- rss-notifier/translations/pt-BR.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rss-notifier/translations/pt-BR.json b/rss-notifier/translations/pt-BR.json index 4dcd83b6..46bbe1f9 100644 --- a/rss-notifier/translations/pt-BR.json +++ b/rss-notifier/translations/pt-BR.json @@ -14,7 +14,7 @@ }, "notify_new": { "description": "Mostra uma notificação para cada item novo encontrado nos feeds.", - "label": "Notificar novos itens" + "label": "Notificar sobre novos itens" }, "refresh_minutes": { "description": "Frequência com que os feeds são checados em busca de novidades.", From 23b7d5babd8d4cf7f4572e2ccaf9a2fd2330fb4d Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Thu, 20 Aug 2026 18:26:23 -0300 Subject: [PATCH 21/24] Fix JSON formatting in pt-BR translation --- rss-notifier/translations/pt-BR.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rss-notifier/translations/pt-BR.json b/rss-notifier/translations/pt-BR.json index 46bbe1f9..f58da037 100644 --- a/rss-notifier/translations/pt-BR.json +++ b/rss-notifier/translations/pt-BR.json @@ -21,8 +21,8 @@ "label": "Intervalo de atualização (minutos)" }, "show_feed_images": { - "label": "Mostrar imagens dos feeds", - "description": "Mostra a imagem de capa de cada item (ou o favicon do site como alternativa) na lista de itens." + "description": "Mostra a imagem de capa de cada item (ou o favicon do site como alternativa) na lista de itens." + "label": "Mostrar imagens dos feeds", } } } From cd8a5dafec6a38bea941c19315f09b9abc91ad0d Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Thu, 20 Aug 2026 18:26:50 -0300 Subject: [PATCH 22/24] Fix formatting in en.json for feed images section --- rss-notifier/translations/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rss-notifier/translations/en.json b/rss-notifier/translations/en.json index 5cbc9682..4aa79f78 100644 --- a/rss-notifier/translations/en.json +++ b/rss-notifier/translations/en.json @@ -21,8 +21,8 @@ "label": "Refresh interval (minutes)" }, "show_feed_images": { - "label": "Show feed images", - "description": "Show each item's cover image (or the site's favicon as a fallback) in the item list." + "description": "Show each item's cover image (or the site's favicon as a fallback) in the item list." + "label": "Show feed images", } } } From 301e9bec6e21335c9f4969df17c9aac508d1812e Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Fri, 21 Aug 2026 07:10:26 -0300 Subject: [PATCH 23/24] Update plugin.toml --- rss-notifier/plugin.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rss-notifier/plugin.toml b/rss-notifier/plugin.toml index d8077330..46f2ee68 100644 --- a/rss-notifier/plugin.toml +++ b/rss-notifier/plugin.toml @@ -6,7 +6,7 @@ author = "Nilsonlinux" license = "MIT" icon = "rss" description = "Monitors RSS/Atom feeds and notifies you when new items appear." -tags = ["utility", "indicator"] +tags = ["utility", "indicator", "panel", "bar", "service"] dependencies = ["xdg-open"] # --------------------------------------------------------------------------- From c3b0dc4782bf222b5e7376a9bb2ebd8809b55663 Mon Sep 17 00:00:00 2001 From: Nilsonlinux Date: Fri, 21 Aug 2026 10:15:41 -0300 Subject: [PATCH 24/24] Fix formatting in en.json for feed images section --- rss-notifier/translations/en.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rss-notifier/translations/en.json b/rss-notifier/translations/en.json index 88a06eb8..b4e04d68 100644 --- a/rss-notifier/translations/en.json +++ b/rss-notifier/translations/en.json @@ -21,8 +21,8 @@ "label": "Refresh interval (minutes)" }, "show_feed_images": { - "description": "Show each item's cover image (or the site's favicon as a fallback) in the item list." - "label": "Show feed images", + "description": "Show each item's cover image (or the site's favicon as a fallback) in the item list.", + "label": "Show feed images" } } -} \ No newline at end of file +}