local function loadLinks() local raw = noctalia.getConfig("links") local links = {} if type(raw) ~= "table" then return links end for _, line in ipairs(raw) do local name, url = line:match("^([^|]+)|(.+)$") if name and url then table.insert(links, { name = noctalia.string.trim(name), url = noctalia.string.trim(url), }) else noctalia.log("web-launcher: skipped malformed line (expected Name|https://url): " .. tostring(line)) end end return links end local links = loadLinks() local function extractDomain(url) local domain = url:match("^https?://([^/]+)") return domain end local function faviconUrl(domain) return "https://www.google.com/s2/favicons?sz=64&domain=" .. noctalia.string.urlEncode(domain) end local function faviconCachePath(domain) local dir = noctalia.pluginDir() .. "/cache" local safe = domain:gsub("[^%w%.%-]", "_") local path = dir .. "/" .. safe .. ".png" return path, dir end local function downloadFavicon(domain, onDone) local path, dir = faviconCachePath(domain) if noctalia.fileExists(path) then onDone(path) return end noctalia.mkdirAll(dir) noctalia.download(faviconUrl(domain), path, function(ok) if ok then onDone(path) end end) end function onQuery(query) local text = noctalia.string.trim(query) local results = {} for _, link in ipairs(links) do local domain = extractDomain(link.url) local iconPath = faviconCachePath(domain) local hasIcon = noctalia.fileExists(iconPath) local glyphValue = hasIcon and nil or "world" local iconValue = hasIcon and iconPath or nil if not hasIcon then downloadFavicon(domain, function() end) end if text == "" then table.insert(results, { id = link.url, title = link.name, subtitle = link.url, glyph = glyphValue, icon = iconValue }) else local score = noctalia.fuzzyScore(text, link.name) if score ~= nil then table.insert(results, { id = link.url, title = link.name, subtitle = link.url, glyph = glyphValue, icon = iconValue, score = score }) end end end launcher.setResults(query, results) end function onActivate(id) noctalia.runAsync("xdg-open '" .. id .. "'") if noctalia.getConfig("notify") then noctalia.notify("Websites", "Opening " .. id) end end