diff --git a/web-launcher/launcher.luau b/web-launcher/launcher.luau new file mode 100644 index 0000000..c335315 --- /dev/null +++ b/web-launcher/launcher.luau @@ -0,0 +1,89 @@ +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 .. "'") + noctalia.notify("Websites", "Opening " .. id) +end diff --git a/web-launcher/plugin.toml b/web-launcher/plugin.toml new file mode 100644 index 0000000..f791e4b --- /dev/null +++ b/web-launcher/plugin.toml @@ -0,0 +1,28 @@ +id = "yocraft/web-launcher" +name = "Web launcher" +version = "1.0.0" +plugin_api = 3 +author = "yocraft" +description = "Quickly open your favorite websites from the launcher." +tags = ["web", "bookmarks"] + +[[launcher_provider]] +id = "web-launcher" +entry = "launcher.luau" +prefix = "web" +glyph = "world" +include_in_global_search = false + +[[setting]] +key = "links" +type = "string_list" +label_key = "settings.links.label" +description_key = "settings.links.description" +default = [ + "GitHub|https://github.com", + "GitLab|https://gitlab.com", + "Codeberg|https://codeberg.org", + "Reddit|https://reddit.com", + "YouTube|https://youtube.com", + "Gmail|https://mail.google.com", +] diff --git a/web-launcher/translations/en.json b/web-launcher/translations/en.json new file mode 100644 index 0000000..66d655e --- /dev/null +++ b/web-launcher/translations/en.json @@ -0,0 +1,8 @@ +{ + "settings": { + "links": { + "label": "Links", + "description": "Format: Name|https://url" + } + } +}