* Add ip-monitor plugin * fix: removed typo * feat: increase default refresh interval to 60 seconds * fix: prevent shell injection in IP monitor gateway lookup. * docs: fix author casing in README * feat: add configurable click actions * feat: add desktop widget support and refactor core logic - Extracted IP fetching and data parsing into a shared `utils.luau` module to prevent code duplication. - Created `desktop.luau` to display network details explicitly in a tabulated UI. - Added specific configuration options for font sizes and colors for the new desktop widget * feat: add hidden_fields configuration to allow filtering tooltip and desktop widget details * fix: remove raw HTML from README * refactor(utils): use bit32 and fix glob pattern escaping & gateway parsing * refactor(utils): centralize shared UI builder and display name resolution * refactor(widget): use shared utils helpers and clean up duplicate logic * refactor(desktop): use shared utils helpers and add IPC click action parity * docs: update README with desktop widget settings * feat: remove unused IPC copy actions from widget logic
158 lines
5.6 KiB
Luau
158 lines
5.6 KiB
Luau
-------------------------------------------------------------------------------
|
|
-- IP Monitor Desktop Widget for Noctalia
|
|
--
|
|
-- Monitors network IP addresses and displays details on the desktop.
|
|
-------------------------------------------------------------------------------
|
|
|
|
local utils = require("./utils.luau")
|
|
|
|
-- Current runtime state
|
|
local currentIp = ""
|
|
local currentIpcName = ""
|
|
local currentTooltip = nil
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- HELPER FUNCTIONS
|
|
-------------------------------------------------------------------------------
|
|
|
|
--- Resolves the active display name according to active mode and IPC state.
|
|
local function getDisplayName()
|
|
return utils.getDisplayName(noctalia.getConfig("mode"), currentIpcName, noctalia.getConfig("name"))
|
|
end
|
|
|
|
local function copyNotifyAndLog(text, optionKey, logMessage)
|
|
if text and text ~= "" then
|
|
noctalia.copyToClipboard(text, "text/plain")
|
|
noctalia.notify(noctalia.tr("name"), noctalia.tr(optionKey) .. ": " .. text)
|
|
noctalia.log("ip-monitor: " .. logMessage .. ": " .. text)
|
|
end
|
|
end
|
|
|
|
local function applyAction(action)
|
|
if action == "copy_ip" then
|
|
copyNotifyAndLog(currentIp, "settings.click.options.copy_ip", "copied IP to clipboard")
|
|
elseif action == "copy_name" then
|
|
copyNotifyAndLog(getDisplayName(), "settings.click.options.copy_name", "copied name to clipboard")
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- UI RENDERING
|
|
-------------------------------------------------------------------------------
|
|
|
|
--- Renders the desktop widget UI based on current state and user settings.
|
|
local function render()
|
|
local hideOnEmpty = noctalia.getConfig("hide_on_empty")
|
|
if hideOnEmpty == nil then hideOnEmpty = true end
|
|
|
|
-- Omit rendering completely if no IP is present and hide_on_empty is active
|
|
if hideOnEmpty and (not currentIp or currentIp == "") then
|
|
desktopWidget.render(ui.row({}, {}))
|
|
return
|
|
end
|
|
|
|
local ipFontSize = noctalia.getConfig("ip_font_size") or 32
|
|
local detailsFontSize = noctalia.getConfig("details_font_size") or 16
|
|
|
|
local displayName = getDisplayName()
|
|
local topRowContent = utils.buildTopRow(currentIp, displayName, ipFontSize)
|
|
|
|
local content = {}
|
|
table.insert(content, ui.row({ gap = 8, align = "center", justify = "center" }, topRowContent))
|
|
|
|
-- Add Details
|
|
if currentTooltip then
|
|
local hiddenConfig = noctalia.getConfig("hidden_fields")
|
|
local hiddenFields = utils.parseHiddenFields(hiddenConfig)
|
|
|
|
local colKeys = {}
|
|
local colValues = {}
|
|
local fields = { "iface", "ip", "network", "gateway", "mask", "broadcast" }
|
|
for _, field in ipairs(fields) do
|
|
if not hiddenFields[field] then
|
|
local val = currentTooltip[field]
|
|
if val and val ~= "" then
|
|
table.insert(colKeys, ui.label({
|
|
text = noctalia.tr("tooltip." .. field),
|
|
fontSize = detailsFontSize,
|
|
color = noctalia.getConfig("details_key_color") or "primary"
|
|
}))
|
|
table.insert(colValues, ui.label({
|
|
text = val,
|
|
fontSize = detailsFontSize,
|
|
color = noctalia.getConfig("details_value_color") or "on_surface"
|
|
}))
|
|
end
|
|
end
|
|
end
|
|
|
|
if #colKeys > 0 then
|
|
table.insert(content, ui.row({ gap = 12, align = "center", justify = "center" }, {
|
|
ui.column({ gap = 4, align = "start" }, colKeys),
|
|
ui.column({ gap = 4, align = "start" }, colValues)
|
|
}))
|
|
end
|
|
end
|
|
|
|
desktopWidget.render(ui.column({ gap = 12, align = "center" }, content))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- LIFECYCLE HOOKS
|
|
-------------------------------------------------------------------------------
|
|
|
|
--- Handler for IPC messages dispatched to this widget.
|
|
function onIpc(event, payload)
|
|
if noctalia.getConfig("mode") ~= "ipc" then return end
|
|
|
|
if event == "set" then
|
|
local myId = noctalia.getConfig("ipc_id") or "default"
|
|
local data = utils.handleIpcPayload(payload, myId)
|
|
if data then
|
|
currentIp = data.ip
|
|
currentIpcName = data.name
|
|
currentTooltip = data.tooltip
|
|
render()
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Primary update entry point called periodically by Noctalia script runtime.
|
|
function update()
|
|
local mode = noctalia.getConfig("mode")
|
|
if mode == "interface" then
|
|
utils.fetchInterfaceIp(noctalia.getConfig("iface"), function(ip, tooltip)
|
|
currentIp = ip
|
|
currentTooltip = tooltip
|
|
render()
|
|
end)
|
|
elseif mode == "custom_command" then
|
|
utils.fetchCustomCommandIp(noctalia.getConfig("custom_command"), function(ip, tooltip)
|
|
currentIp = ip
|
|
currentTooltip = tooltip
|
|
render()
|
|
end)
|
|
end
|
|
end
|
|
|
|
--- Config change handler called automatically when user alters widget settings.
|
|
function onConfigChanged()
|
|
local mode = noctalia.getConfig("mode")
|
|
currentIp = ""
|
|
currentIpcName = ""
|
|
currentTooltip = nil
|
|
|
|
if mode == "interface" or mode == "custom_command" then
|
|
local interval = noctalia.getConfig("refresh_interval") or 60
|
|
noctalia.setUpdateInterval(interval * 1000)
|
|
update()
|
|
else
|
|
-- IPC mode doesn't need periodic updates
|
|
noctalia.setUpdateInterval(0)
|
|
render()
|
|
end
|
|
end
|
|
|
|
-- Initial setup upon loading widget
|
|
onConfigChanged()
|