* fix(plugin): Feed text encoding fix and panel UI improvements V1.0.2 * fix(plugin): Feed text encoding fix and panel UI improvements V1.0.2 * Add xdg-open dependency to plugin.toml Added 'xdg-open' as a dependency for the plugin.
154 lines
4.7 KiB
Luau
154 lines
4.7 KiB
Luau
-- 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.
|
|
|
|
local items = {}
|
|
local hoveredKey = nil
|
|
|
|
-- declaradas antes para permitir referencia cruzada entre elas
|
|
local render
|
|
local dismissItem
|
|
local itemRow
|
|
local emptyState
|
|
|
|
local function openLink(link)
|
|
if not link or link == "" then
|
|
return
|
|
end
|
|
-- escapa aspas simples pra evitar quebrar o comando do shell
|
|
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
|
|
for i, it in ipairs(items) do
|
|
if it == item then
|
|
table.remove(items, i)
|
|
break
|
|
end
|
|
end
|
|
render()
|
|
|
|
local id = item.id or item.link or item.title
|
|
if id then
|
|
local safe = tostring(id):gsub("'", "'\\''")
|
|
noctalia.runAsync("noctalia msg plugin nilsonlinux/rss-notifier:fetcher all dismiss '" .. safe .. "'")
|
|
end
|
|
end
|
|
|
|
itemRow = function(item)
|
|
local key = item.id or item.link or item.title
|
|
local hovered = hoveredKey == key
|
|
|
|
return ui.row({
|
|
key = key,
|
|
gap = 6,
|
|
padding = 10,
|
|
radius = 8,
|
|
fill = "surface_variant/0.4",
|
|
align = "center",
|
|
border = "outline",
|
|
borderWidth = hovered and 1 or 0,
|
|
onHover = function(isHovering)
|
|
hoveredKey = isHovering and key or nil
|
|
render()
|
|
end,
|
|
}, {
|
|
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,
|
|
}),
|
|
})
|
|
end
|
|
|
|
emptyState = function()
|
|
return ui.column({ gap = 10, align = "center", padding = 32, flexGrow = 1, justify = "center" }, {
|
|
ui.glyph({ name = "rss", size = 32, color = "outline" }),
|
|
ui.label({ text = "Nenhuma atualização", color = "outline" }),
|
|
})
|
|
end
|
|
|
|
render = function()
|
|
local body
|
|
|
|
if #items == 0 then
|
|
body = emptyState()
|
|
else
|
|
local rows = {}
|
|
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).
|
|
body = ui.scroll({ gap = 6, flexGrow = 1 }, rows)
|
|
end
|
|
|
|
local headerButtons = {}
|
|
if #items > 0 then
|
|
table.insert(headerButtons, ui.button({ glyph = "trash", variant = "outline", controlSize = "sm", tooltip = "Limpar tudo", onClick = "onClearAllClicked" }))
|
|
end
|
|
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 }, {
|
|
ui.row({ align = "center", justify = "space_between" }, {
|
|
ui.label({ text = "RSS/Atom Notifier", fontSize = 15, fontWeight = "bold" }),
|
|
ui.row({ gap = 4 }, headerButtons),
|
|
}),
|
|
ui.separator({}),
|
|
body,
|
|
}))
|
|
end
|
|
|
|
noctalia.state.watch("items", function(raw)
|
|
local ok, decoded = pcall(noctalia.json.decode, raw or "[]")
|
|
items = (ok and decoded) or {}
|
|
render()
|
|
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.
|
|
local ok, raw = pcall(noctalia.state.get, "items")
|
|
if ok and raw then
|
|
local decodeOk, decoded = pcall(noctalia.json.decode, raw)
|
|
if decodeOk and decoded then
|
|
items = decoded
|
|
end
|
|
end
|
|
|
|
render()
|
|
-- abrir o painel conta como "li as novidades": zera o badge no service
|
|
noctalia.runAsync("noctalia msg plugin nilsonlinux/rss-notifier:fetcher all mark-read")
|
|
end
|
|
|
|
function onRefreshClicked()
|
|
noctalia.runAsync("noctalia msg plugin nilsonlinux/rss-notifier:fetcher all refresh")
|
|
end
|
|
|
|
function onClearAllClicked()
|
|
items = {}
|
|
render()
|
|
noctalia.runAsync("noctalia msg plugin nilsonlinux/rss-notifier:fetcher all clear-all")
|
|
end
|
|
|
|
function onCloseClicked()
|
|
panel.close()
|
|
end
|