From 7140e2fe7dfb8fd6aeb39929508de52dd776a24f Mon Sep 17 00:00:00 2001 From: h465855hgg <3382198490@qq.com> Date: Fri, 17 Jul 2026 05:40:37 +0800 Subject: [PATCH 01/34] feat: add lyrics plugin --- lyrics/README.md | 86 +++++++ lyrics/krc_decode.py | 91 +++++++ lyrics/lrclib_lyric.py | 81 ++++++ lyrics/lyrics.luau | 457 +++++++++++++++++++++++++++++++++ lyrics/lyrics_service.luau | 486 ++++++++++++++++++++++++++++++++++++ lyrics/plugin.toml | 152 +++++++++++ lyrics/thumbnail.webp | Bin 0 -> 13748 bytes lyrics/translations/en.json | 85 +++++++ 8 files changed, 1438 insertions(+) create mode 100644 lyrics/README.md create mode 100644 lyrics/krc_decode.py create mode 100644 lyrics/lrclib_lyric.py create mode 100644 lyrics/lyrics.luau create mode 100644 lyrics/lyrics_service.luau create mode 100644 lyrics/plugin.toml create mode 100644 lyrics/thumbnail.webp create mode 100644 lyrics/translations/en.json diff --git a/lyrics/README.md b/lyrics/README.md new file mode 100644 index 0000000..58dd762 --- /dev/null +++ b/lyrics/README.md @@ -0,0 +1,86 @@ +# Lyrics + +Lyrics adds a synchronized status-bar lyric display with album artwork, karaoke +highlighting, animated line changes, and configurable online or local sources. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `h465855hgg/lyrics` | +| Entries | Bar widget: `lyrics`; service: `service` | + +## Requirements + +Install `playerctl`, `python3`, `curl`, and `cp` on `PATH`. The active media +player must expose MPRIS metadata for automatic track and playback detection. + +## Usage + +Enable `h465855hgg/lyrics`, then add the `lyrics` bar widget in Noctalia's bar +settings. The background `service` detects the active MPRIS player, resolves +lyrics, downloads or caches album artwork, and publishes playback state to the +widget. + +Left-click the widget to switch between lyrics and track information. Right-click +to pause or resume the active player. Paused content is dimmed and all lyric, +transition, and marquee animation stops until playback resumes. + +When synchronized lyrics are unavailable, the widget displays +`track title + artist`. Long lines pause at each end while scrolling. Intro and +instrumental gaps can show a configurable cue such as `•••••`. + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `lyrics_source` | `select` | `auto` | Selects automatic fallback, LRCLIB, public NetEase, MPRIS text, custom HTTP, or external IPC. | +| `custom_url` | `string` | empty | HTTP URL template with `{title}`, `{artist}`, `{album}`, and `{duration}` placeholders. | +| `custom_json_field` | `string` | `syncedLyrics` | Dotted field path containing an LRC string or timed-lines array in a JSON response. | +| `cue_text` | `string` | `•••••` | Characters highlighted through long intro or instrumental gaps. | +| `scroll_mode` | `select` | `auto` | Enables automatic marquee, forced marquee, or static truncation. | +| `marquee_speed` | `int` | `30` | Approximate long-line scroll speed in logical pixels per second. | +| `max_lines` | `int` | `1` | Number of lines shown on a vertical bar, from 1 to 3. | +| `gradient` | `bool` | `true` | Enables progressive per-character highlighting. | +| `animation` | `select` | `karaoke` | Chooses karaoke, cascade, wave, fade-only, or no line transition. | +| `max_chars` | `int` | `24` | Number of visible Unicode characters before marquee scrolling starts. | +| `char_width` | `int` | `9` | Estimated logical-pixel character width used for scroll timing and minimum layout width. | +| `glyph` | `glyph` | `music` | Fallback icon shown when album artwork is unavailable. | +| `show_artist` | `bool` | `true` | Includes the artist in track-information mode. | +| `hide_when_paused` | `bool` | `false` | Hides the widget instead of dimming it while paused. | +| `show_cover` | `bool` | `true` | Shows circular album artwork beside the lyrics. | + +## IPC + +External players can set `lyrics_source` to `external` and address the singleton +service with: + +```sh +noctalia msg plugin h465855hgg/lyrics:service all '' +``` + +Supported events: + +- `push-lrc`: accepts synchronized or plain LRC text. +- `push-json`: accepts JSON with a `lines` timed array or a `lyrics` LRC string. +- `push-state`: also accepts `track`, `position`, `playing`, and `cover` fields. +- `clear`: clears the currently published lyrics. + +Line timestamps and character timestamps are milliseconds. MPRIS track duration +and playback position are microseconds: + +```json +{"lines":[{"time":1200,"duration":1800,"text":"Hello","chars":[1200,1500,1800,2100,2400]}]} +``` + +## Notes + +Automatic mode requests LRCLIB first, then the public NetEase Music API. Custom +HTTP mode contacts only the configured endpoint. The plugin never reads browser +cookies or player credentials. + +The service runs `playerctl` to read and control MPRIS playback, `python3` for the +LRCLIB helper and dynamic-lyric parser, `curl` for the public NetEase API, and +`cp` to preserve temporary local cover files. Query scratch files and downloaded +cover images are written inside the plugin runtime directory. Remote code is +never downloaded or executed. diff --git a/lyrics/krc_decode.py b/lyrics/krc_decode.py new file mode 100644 index 0000000..fc2ab34 --- /dev/null +++ b/lyrics/krc_decode.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# Decode NetEase KRC ("klyric") dynamic lyrics into per-character timings. +# Reads the klyric field (base64 of "krc1" + zlib stream) from argv[1], +# writes JSON: {"type":"krc","lines":[{"time":ms,"text":"...","chars":[ms,...]}]} +import sys, json, base64, zlib, re + +def find_zlib(buf): + for i in range(len(buf) - 1): + if buf[i] == 0x78 and buf[i + 1] in (0x01, 0x9c, 0xda): + try: + return zlib.decompress(buf[i:]) + except Exception: + continue + return None + +def decode_krc(raw): + if isinstance(raw, str) and re.search(r"^\[\d+,\d+\]", raw, re.MULTILINE): + return raw + data = None + if isinstance(raw, str): + try: + data = base64.b64decode(raw) + except Exception: + data = raw.encode("latin-1") + else: + data = raw + if data[:4] == b"krc1": + data = data[4:] + dec = find_zlib(data) + if dec is None: + return None + try: + return dec.decode("utf-8") + except Exception: + return dec.decode("utf-8", "ignore") + +LINE_RE = re.compile(r"^\[(\d+),(\d+)\](.*)$") +PREFIX_SYL_RE = re.compile(r"(?:<|\()(\d+),(\d+)(?:,\d+)?(?:>|\))([^<(]*)") +SUFFIX_SYL_RE = re.compile(r"(.*?)<(\d+),(\d+)(?:,\d+)?>") + +def parse_krc(text): + out = [] + for line in text.splitlines(): + m = LINE_RE.match(line) + if not m: + continue + start = int(m.group(1)) + dur = int(m.group(2)) + body = m.group(3) + # NetEase has shipped both `(offset,duration,0)word` and + # `word` variants of its word-synced format. + prefixed = PREFIX_SYL_RE.findall(body) if re.match(r"^[<(]\d+,", body) else [] + if prefixed: + syl = [(word, int(offset), int(duration)) + for offset, duration, word in prefixed] + else: + syl = [(word, int(offset), int(duration)) + for word, offset, duration in SUFFIX_SYL_RE.findall(body)] + if not syl and body.strip() != "": + syl = [(body, 0, dur)] + chars = [] + full = "" + for (word, so, sd) in syl: + n = len(word) + if n == 0: + continue + for j in range(n): + chars.append(start + so + (j * sd) // n) + full += word[j] + if full.strip() != "": + out.append({"time": start, "duration": dur, "text": full, "chars": chars}) + return out + +def main(): + if len(sys.argv) < 2: + print(json.dumps({"type": "none"})) + return + try: + with open(sys.argv[1], "r", encoding="utf-8") as f: + raw = f.read() + except Exception: + print(json.dumps({"type": "none"})) + return + text = decode_krc(raw) + if text is None: + print(json.dumps({"type": "none"})) + return + print(json.dumps({"type": "krc", "lines": parse_krc(text)}, ensure_ascii=False)) + +if __name__ == "__main__": + main() diff --git a/lyrics/lrclib_lyric.py b/lyrics/lrclib_lyric.py new file mode 100644 index 0000000..9c953fb --- /dev/null +++ b/lyrics/lrclib_lyric.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +import sys, os, json, urllib.request, urllib.parse + +LRCLIB = "https://lrclib.net/api/search" + + +def norm(s): + return "".join(ch for ch in (s or "") if ch.isalnum() or "\u4e00" <= ch <= "\u9fff").lower() + + +def http_get(url): + req = urllib.request.Request(url, headers={ + "User-Agent": "lyrics-plugin/1.0", + "Accept": "application/json", + }) + with urllib.request.urlopen(req, timeout=15) as r: + return r.read().decode("utf-8", "ignore") + + +def main(): + raw = sys.argv[1] if len(sys.argv) > 1 else "" + title, artist, album = "test", "", "" + if raw and os.path.isfile(raw): + try: + with open(raw, encoding="utf-8") as f: + lines = [l.strip() for l in f.read().splitlines()] + title = lines[0] if lines else "test" + artist = lines[1] if len(lines) > 1 else "" + album = lines[2] if len(lines) > 2 else "" + except Exception as e: + out = {"type": "none", "lines": [], "lrc": "", "diag": [f"query_file_read_err={e!r}"]} + print(json.dumps(out, ensure_ascii=False)) + return + else: + title = raw or "test" + + out = {"type": "none", "lines": [], "lrc": "", "diag": []} + try: + q = urllib.parse.urlencode({"track_name": title, "artist_name": artist or title}) + s = json.loads(http_get(LRCLIB + "?" + q)) + if not s: + out["diag"].append("lrclib: no results") + print(json.dumps(out, ensure_ascii=False)) + return + + nart = norm(artist) + nalb = norm(album) + ntitle = norm(title) + best = None + for c in s: + cn = norm(c.get("trackName", "")) + ca = norm(c.get("artistName", "")) + if ntitle and cn != ntitle and ntitle not in cn and cn not in ntitle: + continue + if nart and ca and (nart in ca or ca in nart): + best = c + break + if nalb and norm(c.get("albumName", "")) == nalb: + best = c + break + if best is None: + best = c + if best is None: + best = s[0] + + lrc = best.get("syncedLyrics") or best.get("plainLyrics") or "" + if not lrc: + out["diag"].append("lrclib: empty lyrics") + print(json.dumps(out, ensure_ascii=False)) + return + out["lrc"] = lrc + out["type"] = "lrc" + out["diag"].append(f"lrclib: {best.get('trackName')} / {best.get('artistName')} synced={bool(best.get('syncedLyrics'))}") + print(json.dumps(out, ensure_ascii=False)) + except Exception as e: + out["diag"].append(f"lrclib ERR: {e!r}") + print(json.dumps(out, ensure_ascii=False)) + + +if __name__ == "__main__": + main() diff --git a/lyrics/lyrics.luau b/lyrics/lyrics.luau new file mode 100644 index 0000000..bb9a4cd --- /dev/null +++ b/lyrics/lyrics.luau @@ -0,0 +1,457 @@ +--!nonstrict +-- Synchronized lyrics bar widget with karaoke highlighting and long-line scrolling. + +noctalia.setUpdateInterval(33) + +local glyph = noctalia.getConfig("glyph") +local showArtist = noctalia.getConfig("show_artist") +local hideWhenPaused = noctalia.getConfig("hide_when_paused") +local showCover = noctalia.getConfig("show_cover") +if showCover == nil then showCover = true end + +-- These are plugin settings, not per-widget settings. +local scrollMode = noctalia.getConfig("scroll_mode") or "auto" +local marqueeSpeed = tonumber(noctalia.getConfig("marquee_speed")) or 30 +local maxLines = tonumber(noctalia.getConfig("max_lines")) or 1 +local maxChars = tonumber(noctalia.getConfig("max_chars")) or 24 +local charWidth = tonumber(noctalia.getConfig("char_width")) or 9 +local gradientOn = noctalia.getConfig("gradient") +if gradientOn == nil then gradientOn = true end +local animation = noctalia.getConfig("animation") or "karaoke" +local cueText = noctalia.getConfig("cue_text") or "•••••" +if cueText == "" then cueText = "•••••" end + +local track = nil +local lyrics = nil +local cover = nil +local playing = false +local showMode = "auto" +local rendered = false + +local baselinePosition = 0 +local baselineClock = os.clock() +local lastClock = 0 +local displayKey = "" +local displayedLine = nil +local outgoingLine = nil +local transitionElapsed = 0 +local marqueeElapsed = 0 +local smoothProgress = 0 + +local FADE_OUT_MS = 130 +local FADE_IN_MS = 260 +local MARQUEE_HOLD = 1.1 +local BLEND_MS = 350 +local INTERLUDE_GAP_MS = 7000 +local INTRO_MIN_MS = 6000 +local INTERLUDE_MIN_MS = 8000 + +local function clamp(value, low, high) + return math.min(high, math.max(low, value)) +end + +local function easeOutCubic(t) + local u = 1 - clamp(t, 0, 1) + return 1 - u * u * u +end + +local function toChars(text) + local chars = {} + local i = 1 + while i <= #text do + local byte = text:byte(i) + local length = 1 + if byte >= 0xF0 then length = 4 + elseif byte >= 0xE0 then length = 3 + elseif byte >= 0xC0 then length = 2 end + chars[#chars + 1] = text:sub(i, i + length - 1) + i = i + length + end + return chars +end + +local function getProgressMs() + local elapsed = playing and (os.clock() - baselineClock) * 1000 or 0 + return baselinePosition / 1000 + elapsed +end + +local function getLineInfo() + if not lyrics or #lyrics == 0 or not track then return nil end + + local position = getProgressMs() + local synced = lyrics[1].time >= 0 + if not synced then + return { key = "plain", index = 1, line = lyrics[1], progress = 0, synced = false } + end + + local firstTime = lyrics[1].time + if firstTime >= INTRO_MIN_MS and position < firstTime then + return { + key = "intro", + index = 0, + line = { text = cueText }, + progress = clamp(position / firstTime, 0, 1), + synced = true, + position = position, + cue = true, + } + end + + local index = 1 + for i = #lyrics, 1, -1 do + if lyrics[i].time <= position then + index = i + break + end + end + + local line = lyrics[index] + local startTime = line.time + local durationMs = track.duration and track.duration > 0 and track.duration / 1000 or nil + local nextLine = lyrics[index + 1] + local nextTime = nextLine and nextLine.time + or durationMs + or (startTime + 4000) + local lineEnd = nextTime + + if line.duration and line.duration > 0 then + lineEnd = math.min(nextTime, startTime + line.duration) + elseif nextTime - startTime >= INTERLUDE_GAP_MS then + -- LRC only marks line starts. Do not stretch a lyric across a long instrumental gap. + local estimatedDuration = clamp(#toChars(line.text) * 320, 3200, 6000) + lineEnd = math.min(nextTime, startTime + estimatedDuration) + end + + -- Only show an interlude between two real lyric lines. The final lyric stays + -- visible through the outro instead of turning the whole song ending into dots. + if nextLine and nextTime - lineEnd >= INTERLUDE_MIN_MS and position >= lineEnd then + return { + key = "interlude-" .. tostring(index), + index = index, + line = { text = cueText }, + progress = clamp((position - lineEnd) / (nextTime - lineEnd), 0, 1), + synced = true, + position = position, + cue = true, + } + end + + local progress = lineEnd > startTime and clamp((position - startTime) / (lineEnd - startTime), 0, 1) or 1 + + return { + key = "line-" .. tostring(index), + index = index, + line = line, + progress = progress, + synced = true, + position = position, + } +end + +local function getTrackLabel() + if not track then return "--" end + if not showArtist then return track.title end + if track.artist and track.artist ~= "" then + return track.artist .. " - " .. track.title + end + return track.title +end + +local function getFallbackLabel() + if not track then return "--" end + if track.artist and track.artist ~= "" then + return track.title .. " + " .. track.artist + end + return track.title +end + +local function shouldMarquee(text) + return scrollMode ~= "static" and #toChars(text) > maxChars +end + +local function getMarqueeOffset(length) + local distance = math.max(0, length - maxChars) + if distance == 0 then return 0 end + + -- The setting is pixels per second; convert it to character cells per second. + local charsPerSecond = math.max(0.5, marqueeSpeed / math.max(1, charWidth)) + local travelTime = distance / charsPerSecond + local cycle = MARQUEE_HOLD * 2 + travelTime * 2 + local phase = marqueeElapsed % cycle + + if phase < MARQUEE_HOLD then return 0 end + phase = phase - MARQUEE_HOLD + if phase < travelTime then return distance * (phase / travelTime) end + phase = phase - travelTime + if phase < MARQUEE_HOLD then return distance end + phase = phase - MARQUEE_HOLD + return distance * (1 - phase / travelTime) +end + +local function karaokeColor(charTime, charProgress, position, useGradient) + if not playing then return "on_surface_variant" end + local active = noctalia.isDarkMode() and "primary" or "on_surface" + local inactive = "on_surface_variant" + if charTime and position then + if not useGradient then + return position >= charTime and active or inactive + end + if position >= charTime then return active end + local distance = charTime - position + if distance >= BLEND_MS then return inactive end + local alpha = 1 - distance / BLEND_MS + if alpha <= 0.5 then return inactive end + return active .. "/" .. string.format("%.2f", math.max(0.72, alpha)) + end + + if not useGradient then + return smoothProgress >= charProgress and active or inactive + end + local distance = charProgress - smoothProgress + if distance <= 0 then return active end + if distance >= 0.16 then return inactive end + local alpha = 1 - distance / 0.16 + if alpha <= 0.5 then return inactive end + return active .. "/" .. string.format("%.2f", math.max(0.72, alpha)) +end + +local function buildLineRow(line, opts) + opts = opts or {} + local text = type(line) == "table" and line.text or line + local times = type(line) == "table" and line.chars or nil + local chars = toChars(text or "") + if #chars == 0 then chars = { " " } end + + local exactOffset = opts.marquee and getMarqueeOffset(#chars) or 0 + local offset = math.floor(exactOffset) + local fraction = exactOffset - offset + local first = offset + 1 + local last = math.min(#chars, first + maxChars) + local labels = {} + + for sourceIndex = first, last do + local active = playing and (noctalia.isDarkMode() and "primary" or "on_surface") or "on_surface_variant" + local color = opts.dim and "on_surface_variant" or active + if not opts.solid and not opts.dim then + local progress = #chars > 1 and (sourceIndex - 1) / (#chars - 1) or 0 + color = karaokeColor(times and times[sourceIndex], progress, opts.position, opts.useGradient) + end + + -- Soft viewport edges make cell-by-cell marquee movement less abrupt. + local alpha = 1 + local edgeAlpha = noctalia.isDarkMode() and 0.5 or 0.72 + if opts.marquee and offset > 0 and sourceIndex == first then alpha = edgeAlpha end + if opts.marquee and last < #chars and sourceIndex == last then alpha = edgeAlpha end + if opts.cascade then + local charProgress = (sourceIndex - first) / math.max(1, last - first) + local cascadeProgress = clamp((transitionElapsed - FADE_OUT_MS) / 420, 0, 1) + alpha = alpha * clamp((cascadeProgress - charProgress * 0.45) * 2.4, 0.08, 1) + end + if opts.wave then + local waveProgress = clamp((transitionElapsed - FADE_OUT_MS) / 650, 0, 1) + local wave = 0.55 + 0.45 * math.sin(waveProgress * math.pi * 2 - sourceIndex * 0.78) + alpha = alpha * (wave * (1 - waveProgress) + waveProgress) + end + + -- Bar labels elide glyphs when constrained below their natural width, so + -- animate the viewport edges with opacity without clipping CJK characters. + if opts.marquee and fraction > 0 then + if sourceIndex == first then + alpha = alpha * (1 - fraction) + elseif sourceIndex == first + maxChars then + alpha = alpha * fraction + end + elseif sourceIndex == first + maxChars then + alpha = 0 + end + + labels[#labels + 1] = ui.label({ + key = "char-" .. tostring(sourceIndex), + text = chars[sourceIndex], + color = color, + opacity = alpha, + maxLines = 1, + }) + end + + if opts.marquee then + while #labels < maxChars + 1 do + labels[#labels + 1] = ui.label({ text = " ", opacity = 0, maxLines = 1 }) + end + end + + return ui.row({ + key = opts.key or "line", + gap = 0, + align = "center", + minWidth = maxChars * charWidth, + opacity = opts.opacity or 1, + }, labels) +end + +local function currentTransitionLine(info) + if animation == "none" or transitionElapsed >= FADE_OUT_MS then + local opacity = animation == "none" and 1 + or easeOutCubic((transitionElapsed - FADE_OUT_MS) / FADE_IN_MS) + return info and info.line or nil, opacity + end + return outgoingLine, 1 - easeOutCubic(transitionElapsed / FADE_OUT_MS) +end + +local function render() + if hideWhenPaused and not playing then + barWidget.setVisible(false) + return + end + barWidget.setVisible(true) + + local vertical = barWidget.isVertical() + local useGradient = (animation == "karaoke" or animation == "cascade" or animation == "wave") and gradientOn + local position = getProgressMs() + local prefix = {} + local coverPath = showCover and cover and cover ~= "" and noctalia.fileExists(cover) and cover or nil + if coverPath then + prefix[#prefix + 1] = ui.image({ path = coverPath, width = 18, height = 18, radius = 9, fit = "cover" }) + else + prefix[#prefix + 1] = ui.glyph({ + name = glyph, + size = 14, + color = playing and (noctalia.isDarkMode() and "primary" or "on_surface") or "on_surface_variant", + }) + end + + local lineNodes = {} + if showMode == "track" then + local label = getTrackLabel() + lineNodes[1] = buildLineRow(label, { + key = "track", + marquee = shouldMarquee(label), + solid = true, + }) + else + local info = getLineInfo() + if info then + local shownLine, opacity = currentTransitionLine(info) + if shownLine then + lineNodes[#lineNodes + 1] = buildLineRow(shownLine, { + key = "current-" .. tostring(info.index), + marquee = shownLine == info.line and shouldMarquee(shownLine.text), + position = position, + useGradient = shownLine == info.line and info.synced and useGradient, + solid = not info.synced or (animation ~= "karaoke" and animation ~= "cascade" and animation ~= "wave"), + cascade = shownLine == info.line and animation == "cascade", + wave = shownLine == info.line and animation == "wave", + opacity = opacity, + }) + end + + if vertical and maxLines > 1 and shownLine == info.line then + for i = 1, maxLines - 1 do + local nextLine = lyrics[info.index + i] + if not nextLine then break end + lineNodes[#lineNodes + 1] = buildLineRow(nextLine, { + key = "next-" .. tostring(info.index + i), + dim = true, + opacity = math.max(0.25, 0.58 - (i - 1) * 0.16), + }) + end + end + else + local label = getFallbackLabel() + lineNodes[1] = buildLineRow(label, { + key = "fallback", + marquee = shouldMarquee(label), + solid = true, + }) + end + end + + if vertical then + barWidget.render(ui.column({ gap = 3, align = "start", opacity = playing and 1 or 0.58 }, { + ui.row({ gap = 6, align = "center" }, prefix), + ui.column({ gap = 2, align = "start" }, lineNodes), + })) + else + local children = {} + for _, node in ipairs(prefix) do children[#children + 1] = node end + children[#children + 1] = lineNodes[1] + barWidget.render(ui.row({ gap = 6, align = "center", opacity = playing and 1 or 0.58 }, children)) + end + + barWidget.setTooltip(getTrackLabel()) + rendered = true +end + +function onClick() + showMode = showMode == "auto" and "track" or "auto" + marqueeElapsed = 0 + if rendered then render() end +end + +function onRightClick() + noctalia.runAsync("playerctl play-pause", function(result) + if result.exitCode == 0 then + local wasPlaying = playing + if wasPlaying then baselinePosition = getProgressMs() * 1000 end + playing = not wasPlaying + noctalia.state.set("playing", playing) + baselineClock = os.clock() + render() + end + end) +end + +function update() + local now = os.clock() + local delta = lastClock > 0 and now - lastClock or 0 + lastClock = now + + track = noctalia.state.get("track") + lyrics = noctalia.state.get("lyrics") + cover = noctalia.state.get("cover") + playing = noctalia.state.get("playing") == true + + local info = getLineInfo() + local nextKey = info and info.key or "fallback" + if nextKey ~= displayKey then + outgoingLine = displayedLine + displayKey = nextKey + transitionElapsed = animation == "none" and FADE_OUT_MS + FADE_IN_MS or 0 + marqueeElapsed = 0 + smoothProgress = info and info.progress or 0 + else + local target = info and info.progress or 0 + smoothProgress = smoothProgress + (target - smoothProgress) * math.min(1, delta * 8) + end + displayedLine = info and info.line or nil + + if playing then + transitionElapsed = transitionElapsed + delta * 1000 + local text = showMode == "track" and getTrackLabel() or (info and info.line.text or "") + if shouldMarquee(text) then marqueeElapsed = marqueeElapsed + delta end + end + + render() +end + +noctalia.state.watch("position", function(value) + baselinePosition = tonumber(value) or 0 + baselineClock = os.clock() +end) + +noctalia.state.watch("lyrics", function(value) + lyrics = value + displayKey = "" + displayedLine = nil + outgoingLine = nil + marqueeElapsed = 0 +end) + +noctalia.state.watch("playing", function(value) + -- Preserve the interpolated position when pausing between service polls. + if playing and value ~= true then + baselinePosition = getProgressMs() * 1000 + end + playing = value == true + baselineClock = os.clock() +end) diff --git a/lyrics/lyrics_service.luau b/lyrics/lyrics_service.luau new file mode 100644 index 0000000..3368540 --- /dev/null +++ b/lyrics/lyrics_service.luau @@ -0,0 +1,486 @@ +--!nonstrict +-- Lyrics — headless service. +-- Polls MPRIS metadata via playerctl, fetches lyrics from NetEase Cloud Music +-- via /api endpoints, publishes state. No polling delay. + +noctalia.setUpdateInterval(250) + +local cache = {} +local coverCache = {} +local lastTrackKey = "" +local inFlight = nil +local coverInFlight = nil +local krcTmp = (noctalia.pluginDir() or "/tmp") .. "/.krc_cache.tmp" +local lyricsSource = noctalia.getConfig("lyrics_source") or "auto" +local customUrl = noctalia.getConfig("custom_url") or "" +local customJsonField = noctalia.getConfig("custom_json_field") or "syncedLyrics" +local currentTrack = nil +local currentEmbeddedLyrics = "" + +local function coverPathFor(track) + local safe = (track.artist .. "_" .. track.album .. "_" .. track.title):gsub("[^%w]+", "_") + return noctalia.pluginDir() .. "/cover_" .. safe .. ".jpg" +end + +local function shellQuote(value) + return "'" .. tostring(value):gsub("'", "'\\''") .. "'" +end + +local function parseLRC(lrcText) + local lines = {} + for line in lrcText:gmatch("[^\n]+") do + local mins, secs = line:match("%[(%d+):(%d+%.?%d*)%]") + if mins and secs then + local ms = math.floor(tonumber(mins) * 60000 + tonumber(secs) * 1000) + local text = line:gsub("%[%d+:%d+%.?%d*%]", ""):gsub("^%s+", ""):gsub("%s+$", "") + if text ~= "" then + local isMeta = ms < 5000 and (text:find(":") or text:find(":")) + if not isMeta then + lines[#lines + 1] = { time = ms, text = text } + end + end + end + end + if #lines == 0 then return nil end + return lines +end + +local function parsePlain(text) + local lines = {} + local seenLyric = false + for line in text:gmatch("[^\n]+") do + local trimmed = line:gsub("^%s+", ""):gsub("%s+$", "") + if trimmed ~= "" then + if seenLyric then + lines[#lines + 1] = { time = -1, text = trimmed } + elseif trimmed:find(":") or trimmed:find(":") then + -- skip metadata header line + else + seenLyric = true + lines[#lines + 1] = { time = -1, text = trimmed } + end + end + end + if #lines == 0 then return nil end + return lines +end + +local function evictCache() + local keys = {} + for k, _ in pairs(cache) do keys[#keys + 1] = k end + if #keys > 30 then + table.sort(keys) + for i = 1, #keys - 30 do cache[keys[i]] = nil end + end +end + +local function fetchLyricsNetEase(track, embeddedLyrics) + if inFlight then return end + inFlight = track + + local tk = track.title .. "|" .. track.artist .. "|" .. track.album + + local function tryFetch(query, fallback) + local searchUrl = "https://music.163.com/api/search/get?type=1&s=" .. noctalia.string.urlEncode(query) .. "&limit=5" + local cmd = 'curl -s --max-time 10 --connect-timeout 5 "' .. searchUrl .. '" -H "Referer: https://music.163.com"' + + noctalia.runAsync(cmd, function(r1) + if not inFlight then return end + if tk ~= lastTrackKey then inFlight = nil; return end + + if r1.exitCode ~= 0 or not r1.stdout or #r1.stdout == 0 then + if fallback then fallback() + else inFlight = nil; noctalia.state.set("lyrics", nil) end + return + end + + local data = noctalia.json.decode(r1.stdout) + if not data or not data.result or not data.result.songs or #data.result.songs == 0 then + if fallback then fallback() + else inFlight = nil; noctalia.state.set("lyrics", nil) end + return + end + + local function songArtist(s) + if s.artists and #s.artists > 0 then + return (s.artists[1].name or ""):lower() + end + return "" + end + + local bestMatch = nil + local trackArtist = track.artist:lower() + for _, s in ipairs(data.result.songs) do + if songArtist(s):find(trackArtist, 1, true) then + bestMatch = s + break + end + end + if not bestMatch then + bestMatch = data.result.songs[1] + end + + local songId = bestMatch.id + local lyricUrl = "https://music.163.com/api/song/lyric?id=" .. songId .. "&lv=1&kv=1&tv=-1" + local lCmd = 'curl -s --max-time 10 --connect-timeout 5 "' .. lyricUrl .. '" -H "Referer: https://music.163.com"' + + noctalia.runAsync(lCmd, function(r2) + if not inFlight then return end + if tk ~= lastTrackKey then inFlight = nil; return end + + local lyrics = nil + if r2.exitCode == 0 and r2.stdout and #r2.stdout > 0 then + local ldata = noctalia.json.decode(r2.stdout) + local klyricStr = "" + if ldata and ldata.klyric then + local k = ldata.klyric + if type(k) == "string" then + klyricStr = k + elseif type(k) == "table" then + klyricStr = (k.lyric and type(k.lyric) == "string") and k.lyric or "" + end + end + if klyricStr ~= "" then + local ok = pcall(noctalia.writeFile, krcTmp, klyricStr) + if not ok then klyricStr = "" end + end + if klyricStr ~= "" then + local py = 'python3 "' .. noctalia.pluginDir() .. '/krc_decode.py" "' .. krcTmp .. '"' + noctalia.runAsync(py, function(r3) + if not inFlight then return end + if tk ~= lastTrackKey then inFlight = nil; return end + local ok, parsed = pcall(noctalia.json.decode, r3.stdout or "") + if ok and parsed and parsed.type == "krc" and parsed.lines then + cache[tk] = parsed.lines + evictCache() + inFlight = nil + noctalia.state.set("lyrics", parsed.lines) + return + end + local lrc = (ldata.lrc and ldata.lrc.lyric) or "" + local lyr = parseLRC(lrc) + if not lyr then lyr = parsePlain(lrc) end + if lyr then + cache[tk] = lyr + evictCache() + inFlight = nil + noctalia.state.set("lyrics", lyr) + elseif fallback then + fallback() + else + inFlight = nil + noctalia.state.set("lyrics", nil) + end + end) + return + end + if ldata and ldata.lrc and ldata.lrc.lyric and ldata.lrc.lyric ~= "" then + lyrics = parseLRC(ldata.lrc.lyric) + if not lyrics then + lyrics = parsePlain(ldata.lrc.lyric) + end + end + end + + if lyrics then + cache[tk] = lyrics + evictCache() + inFlight = nil + noctalia.state.set("lyrics", lyrics) + elseif fallback then + fallback() + else + inFlight = nil + noctalia.state.set("lyrics", nil) + end + end) + end) + end + + local query = track.title .. "\n" .. track.artist .. "\n" .. (track.album or "") + local qTmp = (noctalia.pluginDir() or "/tmp") .. "/.query_cache.tmp" + noctalia.writeFile(qTmp, query) + local dir = noctalia.pluginDir() or "/tmp" + + local function applyParsed(parsed) + if parsed and parsed.type == "krc" and parsed.lines then + cache[tk] = parsed.lines + evictCache() + noctalia.state.set("lyrics", parsed.lines) + return true + end + if parsed and parsed.type == "lrc" and parsed.lrc and parsed.lrc ~= "" then + local lyr = parseLRC(parsed.lrc) + if not lyr then lyr = parsePlain(parsed.lrc) end + if lyr then + cache[tk] = lyr + evictCache() + noctalia.state.set("lyrics", lyr) + return true + end + end + return false + end + + local function runPy(script, cb) + local py = 'python3 "' .. dir .. "/" .. script .. '" "' .. qTmp .. '"' + noctalia.runAsync(py, function(r) + if not inFlight then return end + if tk ~= lastTrackKey then inFlight = nil; return end + local ok, parsed = pcall(noctalia.json.decode, r.stdout or "") + cb(ok and parsed or nil) + end) + end + + local function applyText(text) + if not text or text == "" then return false end + local parsed = parseLRC(text) + if not parsed then parsed = parsePlain(text) end + if not parsed then return false end + cache[tk] = parsed + evictCache() + noctalia.state.set("lyrics", parsed) + return true + end + + local function fetchCustom() + if customUrl == "" then + inFlight = nil + noctalia.state.set("lyrics", nil) + return + end + + local replacements = { + title = track.title, + artist = track.artist, + album = track.album, + duration = tostring(math.floor((track.duration or 0) / 1000000)), + } + local url = customUrl:gsub("{([%w_]+)}", function(key) + return noctalia.string.urlEncode(replacements[key] or "") + end) + + noctalia.http({ url = url, headers = { "Accept: application/json, text/plain" } }, function(response) + if tk ~= lastTrackKey then inFlight = nil; return end + local text = response.ok and response.body or "" + if text ~= "" and customJsonField ~= "" then + local decoded = noctalia.json.decode(text) + for part in customJsonField:gmatch("[^.]+") do + decoded = type(decoded) == "table" and decoded[part] or nil + end + if type(decoded) == "table" then + cache[tk] = decoded + evictCache() + noctalia.state.set("lyrics", decoded) + inFlight = nil + return + end + text = type(decoded) == "string" and decoded or "" + end + applyText(text) + inFlight = nil + end) + end + + if lyricsSource == "external" then + inFlight = nil + return + elseif lyricsSource == "mpris" then + applyText(embeddedLyrics) + inFlight = nil + return + elseif lyricsSource == "custom" then + fetchCustom() + return + elseif lyricsSource == "netease" then + tryFetch(track.title .. " " .. track.artist, function() + tryFetch(track.title, nil) + end) + return + end + + -- Auto: LRCLIB, then the public NetEase API. + runPy("lrclib_lyric.py", function(parsed) + if applyParsed(parsed) then inFlight = nil; return end + if lyricsSource == "lrclib" then + inFlight = nil + noctalia.state.set("lyrics", nil) + return + end + tryFetch(track.title .. " " .. track.artist, function() + tryFetch(track.title, nil) + end) + end) +end + +local function fetchCover(track, artUrl) + if coverInFlight then return end + coverInFlight = track.title .. "|" .. track.artist .. "|" .. track.album + + local dest = coverPathFor(track) + + local apply = function(path) + local tk = track.title .. "|" .. track.artist .. "|" .. track.album + coverInFlight = nil + if tk ~= lastTrackKey then return end + coverCache[tk] = path + noctalia.state.set("cover", path) + end + + if not artUrl or artUrl == "" then + noctalia.state.set("cover", nil) + coverInFlight = nil + return + end + + if artUrl:sub(1, 7) == "file://" then + local source = noctalia.string.urlDecode(artUrl:sub(8)) + if not noctalia.fileExists(source) then + apply(nil) + return + end + noctalia.runAsync("cp -- " .. shellQuote(source) .. " " .. shellQuote(dest), function(result) + if result.exitCode == 0 then apply(dest) else apply(source) end + end) + return + end + + noctalia.download(artUrl, dest, function(ok) + if ok then apply(dest) else apply(nil) end + end) +end + +local function poll() + local cmd = [[playerctl metadata --format $'{{lc(status)}}\x1f{{title}}\x1f{{artist}}\x1f{{album}}\x1f{{position}}\x1f{{mpris:length}}\x1f{{mpris:artUrl}}\x1f{{xesam:asText}}' 2>/dev/null]] + + noctalia.runAsync(cmd, function(r) + if r.exitCode ~= 0 or not r.stdout or r.stdout == "" then + noctalia.state.set("track", nil) + noctalia.state.set("lyrics", nil) + noctalia.state.set("cover", nil) + noctalia.state.set("playing", false) + return + end + + local parts = {} + local separator = string.char(31) + for field in (r.stdout .. separator):gmatch("(.-)" .. separator) do + parts[#parts + 1] = field:gsub("^%s+", ""):gsub("%s+$", "") + end + + local status = parts[1] or "stopped" + local title = parts[2] or "" + local artist = parts[3] or "" + local album = parts[4] or "" + local artUrl = parts[7] or "" + local embeddedLyrics = parts[8] or "" + + if title == "" and artist == "" then + noctalia.state.set("track", nil) + noctalia.state.set("lyrics", nil) + noctalia.state.set("playing", status == "playing") + return + end + + local playing = status == "playing" + local tk = title .. "|" .. artist .. "|" .. album + + local t = { + title = title, + artist = artist, + album = album, + status = status, + position = tonumber(parts[5]) or 0, + duration = tonumber(parts[6]) or 0, + } + currentTrack = t + currentEmbeddedLyrics = embeddedLyrics + + noctalia.state.set("position", t.position) + + if tk ~= lastTrackKey then + lastTrackKey = tk + noctalia.state.set("track", t) + noctalia.state.set("playing", playing) + + local cached = cache[tk] + if cached then + noctalia.state.set("lyrics", cached) + else + noctalia.state.set("lyrics", nil) + fetchLyricsNetEase(t, embeddedLyrics) + end + + local cachedCover = coverCache[tk] + if cachedCover then + noctalia.state.set("cover", cachedCover) + else + noctalia.state.set("cover", nil) + fetchCover(t, artUrl) + end + else + noctalia.state.set("track", t) + noctalia.state.set("playing", playing) + end + end) +end + +local pollTick = 0 + +function update() + if lyricsSource == "external" then return end + pollTick = pollTick + 1 + if pollTick % 2 == 0 then + poll() + end + +end + +function onConfigChanged() + local nextSource = noctalia.getConfig("lyrics_source") or "auto" + local nextUrl = noctalia.getConfig("custom_url") or "" + local nextField = noctalia.getConfig("custom_json_field") or "syncedLyrics" + local sourceChanged = nextSource ~= lyricsSource or nextUrl ~= customUrl or nextField ~= customJsonField + lyricsSource = nextSource + customUrl = nextUrl + customJsonField = nextField + if sourceChanged and currentTrack then + inFlight = nil + cache = {} + noctalia.state.set("lyrics", nil) + fetchLyricsNetEase(currentTrack, currentEmbeddedLyrics) + end +end + +local function applyPushedLyrics(payload) + local decoded = noctalia.json.decode(payload or "") + if type(decoded) == "table" then + if decoded.track then + currentTrack = decoded.track + lastTrackKey = (decoded.track.title or "") .. "|" .. (decoded.track.artist or "") .. "|" .. (decoded.track.album or "") + noctalia.state.set("track", decoded.track) + end + if decoded.lines then noctalia.state.set("lyrics", decoded.lines) end + if decoded.lyrics then + local parsed = parseLRC(decoded.lyrics) or parsePlain(decoded.lyrics) + noctalia.state.set("lyrics", parsed) + end + if decoded.position ~= nil then noctalia.state.set("position", decoded.position) end + if decoded.playing ~= nil then noctalia.state.set("playing", decoded.playing == true) end + if decoded.cover ~= nil then noctalia.state.set("cover", decoded.cover) end + return true + end + return false +end + +function onIpc(event, payload) + if event == "push-lrc" then + noctalia.state.set("lyrics", parseLRC(payload or "") or parsePlain(payload or "")) + elseif event == "push-json" or event == "push-state" then + applyPushedLyrics(payload) + elseif event == "clear" then + noctalia.state.set("lyrics", nil) + end +end + +if lyricsSource ~= "external" then poll() end diff --git a/lyrics/plugin.toml b/lyrics/plugin.toml new file mode 100644 index 0000000..70689ac --- /dev/null +++ b/lyrics/plugin.toml @@ -0,0 +1,152 @@ +id = "h465855hgg/lyrics" +name = "Lyrics" +version = "1.0.0" +plugin_api = 3 +author = "h465855hgg" +license = "MIT" +dependencies = ["playerctl", "python3", "curl", "cp"] +tags = ["bar", "service", "music", "media", "animation"] +icon = "music" +description = "Synchronized lyrics with karaoke highlighting, animated transitions, and flexible lyric sources." + +[[setting]] +key = "lyrics_source" +type = "select" +label_key = "settings.lyrics_source.label" +description_key = "settings.lyrics_source.description" +default = "auto" +options = [ + { value = "auto", label_key = "settings.lyrics_source.options.auto" }, + { value = "lrclib", label_key = "settings.lyrics_source.options.lrclib" }, + { value = "netease", label_key = "settings.lyrics_source.options.netease" }, + { value = "mpris", label_key = "settings.lyrics_source.options.mpris" }, + { value = "custom", label_key = "settings.lyrics_source.options.custom" }, + { value = "external", label_key = "settings.lyrics_source.options.external" }, +] + +[[setting]] +key = "custom_url" +type = "string" +label_key = "settings.custom_url.label" +description_key = "settings.custom_url.description" +default = "" +visible_when = { key = "lyrics_source", values = ["custom"] } + +[[setting]] +key = "custom_json_field" +type = "string" +label_key = "settings.custom_json_field.label" +description_key = "settings.custom_json_field.description" +default = "syncedLyrics" +visible_when = { key = "lyrics_source", values = ["custom"] } + +[[setting]] +key = "cue_text" +type = "string" +label_key = "settings.cue_text.label" +description_key = "settings.cue_text.description" +default = "•••••" + +[[setting]] +key = "scroll_mode" +type = "select" +label_key = "settings.scroll_mode.label" +default = "auto" +description_key = "settings.scroll_mode.description" +options = [ + { value = "auto", label_key = "settings.scroll_mode.options.auto" }, + { value = "marquee", label_key = "settings.scroll_mode.options.marquee" }, + { value = "static", label_key = "settings.scroll_mode.options.static" }, +] + +[[setting]] +key = "marquee_speed" +type = "int" +label_key = "settings.marquee_speed.label" +default = 30 +min = 10 +max = 120 +description_key = "settings.marquee_speed.description" + +[[setting]] +key = "max_lines" +type = "int" +label_key = "settings.max_lines.label" +default = 1 +min = 1 +max = 3 +description_key = "settings.max_lines.description" + +[[setting]] +key = "gradient" +type = "bool" +label_key = "settings.gradient.label" +default = true +description_key = "settings.gradient.description" + +[[setting]] +key = "animation" +type = "select" +label_key = "settings.animation.label" +default = "karaoke" +description_key = "settings.animation.description" +options = [ + { value = "karaoke", label_key = "settings.animation.options.karaoke" }, + { value = "cascade", label_key = "settings.animation.options.cascade" }, + { value = "wave", label_key = "settings.animation.options.wave" }, + { value = "fade", label_key = "settings.animation.options.fade" }, + { value = "none", label_key = "settings.animation.options.none" }, +] + +[[setting]] +key = "max_chars" +type = "int" +label_key = "settings.max_chars.label" +default = 24 +min = 8 +max = 80 +description_key = "settings.max_chars.description" + +[[setting]] +key = "char_width" +type = "int" +label_key = "settings.char_width.label" +default = 9 +min = 4 +max = 24 +description_key = "settings.char_width.description" + +# Headless background service: polls MPRIS metadata, fetches lyrics, publishes state. +[[service]] +id = "service" +entry = "lyrics_service.luau" + +# Bar widget: thin presentation that mirrors the published lyrics state. +[[widget]] +id = "lyrics" +entry = "lyrics.luau" + + [[widget.setting]] + key = "glyph" + type = "glyph" + label_key = "settings.glyph.label" + default = "music" + + [[widget.setting]] + key = "show_artist" + type = "bool" + label_key = "settings.show_artist.label" + default = true + + [[widget.setting]] + key = "hide_when_paused" + type = "bool" + label_key = "settings.hide_when_paused.label" + default = false + + [[widget.setting]] + key = "show_cover" + type = "bool" + label_key = "settings.show_cover.label" + description_key = "settings.show_cover.description" + default = true diff --git a/lyrics/thumbnail.webp b/lyrics/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..dd51510f4d93d68ae5e6836458144830e607dad5 GIT binary patch literal 13748 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 a866NPk^q-sEQ}ru3|xy=*&hINkqH2C1d{Fm literal 0 HcmV?d00001 diff --git a/lyrics/translations/en.json b/lyrics/translations/en.json new file mode 100644 index 0000000..6c0a6d5 --- /dev/null +++ b/lyrics/translations/en.json @@ -0,0 +1,85 @@ +{ + "title": "Lyrics", + "no_lyrics": "♪ No lyrics available", + "intro": "Intro", + "instrumental": "Instrumental", + "settings": { + "glyph": { + "label": "Glyph" + }, + "show_artist": { + "label": "Show artist" + }, + "hide_when_paused": { + "label": "Hide when paused" + }, + "show_cover": { + "label": "Show album cover", + "description": "Display the song's album art next to the lyrics." + }, + "lyrics_source": { + "label": "Lyrics source", + "description": "Choose a preset source, local-player lyrics, a custom endpoint, or external push protocol.", + "options": { + "auto": "Automatic fallback", + "lrclib": "LRCLIB", + "netease": "NetEase Music (public API)", + "mpris": "Local player (MPRIS)", + "custom": "Custom HTTP endpoint", + "external": "External IPC push" + } + }, + "custom_url": { + "label": "Custom endpoint URL", + "description": "Supports {title}, {artist}, {album}, and {duration} placeholders. Text responses may contain LRC directly." + }, + "custom_json_field": { + "label": "JSON lyrics field", + "description": "Lyrics field in a JSON response, with dotted paths such as data.lyric. Leave empty for plain LRC." + }, + "cue_text": { + "label": "Intro/interlude characters", + "description": "Text or characters highlighted during intros and interludes." + }, + "scroll_mode": { + "label": "Scroll mode", + "description": "How lyrics scroll in the bar.", + "options": { + "auto": "Auto (synced)", + "marquee": "Marquee", + "static": "Static" + } + }, + "marquee_speed": { + "label": "Marquee speed", + "description": "Pixels per second for long-line scrolling." + }, + "max_lines": { + "label": "Max lines", + "description": "Maximum lyric lines to show at once." + }, + "gradient": { + "label": "Per-character gradient", + "description": "Light up each character as the song progresses (karaoke style)." + }, + "animation": { + "label": "Animation", + "description": "How lyrics animate on line change.", + "options": { + "karaoke": "Karaoke gradient + fade", + "cascade": "Character cascade", + "wave": "Character wave reveal", + "fade": "Fade only", + "none": "No animation" + } + }, + "max_chars": { + "label": "Max characters", + "description": "Visible width before a long lyric line scrolls (marquee)." + }, + "char_width": { + "label": "Character width (px)", + "description": "Approximate pixel width per character, used to fix the widget width and clip scrolling." + } + } +} From 0d2adc1939ecd85bdc8c53b2a58fe80e6e64a779 Mon Sep 17 00:00:00 2001 From: h465855hgg <3382198490@qq.com> Date: Fri, 17 Jul 2026 05:57:13 +0800 Subject: [PATCH 02/34] docs: add plugin screenshots --- lyrics/README.md | 10 ++++++++++ lyrics/screenshots/settings.webp | Bin 0 -> 47850 bytes lyrics/screenshots/widget.webp | Bin 0 -> 8910 bytes lyrics/thumbnail.webp | Bin 13748 -> 7560 bytes 4 files changed, 10 insertions(+) create mode 100644 lyrics/screenshots/settings.webp create mode 100644 lyrics/screenshots/widget.webp diff --git a/lyrics/README.md b/lyrics/README.md index 58dd762..6baaaf5 100644 --- a/lyrics/README.md +++ b/lyrics/README.md @@ -30,6 +30,16 @@ When synchronized lyrics are unavailable, the widget displays `track title + artist`. Long lines pause at each end while scrolling. Intro and instrumental gaps can show a configurable cue such as `•••••`. +## Screenshots + +Status-bar widget: + +![Lyrics bar widget](screenshots/widget.webp) + +Plugin settings: + +![Lyrics settings](screenshots/settings.webp) + ## Settings | Setting | Type | Default | Description | diff --git a/lyrics/screenshots/settings.webp b/lyrics/screenshots/settings.webp new file mode 100644 index 0000000000000000000000000000000000000000..fd049ad2dc306c4a69622102818cd1fe9d877b8d GIT binary patch literal 47850 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 Mi@J$gO92A|0HniL2LJ#7 literal 0 HcmV?d00001 diff --git a/lyrics/screenshots/widget.webp b/lyrics/screenshots/widget.webp new file mode 100644 index 0000000000000000000000000000000000000000..f85b7840fd7fe929651e8e1bdb723cc83e93d1c9 GIT binary patch literal 8910 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 literal 13748 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 a866NPk^q-sEQ}ru3|xy=*&hINkqH2C1d{Fm From cf3a93b2fb9bc3726b8e64b128b3ee000b23a87d Mon Sep 17 00:00:00 2001 From: h465855hgg <3382198490@qq.com> Date: Fri, 17 Jul 2026 06:21:54 +0800 Subject: [PATCH 03/34] docs: use generated plugin thumbnail --- lyrics/thumbnail.webp | Bin 7560 -> 41594 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lyrics/thumbnail.webp b/lyrics/thumbnail.webp index f2269ed9464792ca86e4cc154d1b0f691b7bfd43..cf876db65e015f8c943b9f529b71a1436d372ff4 100644 GIT binary patch literal 41594 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 From 9eb698403110cbba09aea23ec012a06316f7772f Mon Sep 17 00:00:00 2001 From: h465855hgg <3382198490@qq.com> Date: Fri, 17 Jul 2026 07:20:42 +0800 Subject: [PATCH 04/34] docs: add lyrics dependency setup helper --- lyrics/README.md | 11 +++ lyrics/scripts/setup-deps.sh | 149 +++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100755 lyrics/scripts/setup-deps.sh diff --git a/lyrics/README.md b/lyrics/README.md index 6baaaf5..a7dc19d 100644 --- a/lyrics/README.md +++ b/lyrics/README.md @@ -15,6 +15,17 @@ highlighting, animated line changes, and configurable online or local sources. Install `playerctl`, `python3`, `curl`, and `cp` on `PATH`. The active media player must expose MPRIS metadata for automatic track and playback detection. +Noctalia installs the plugin files; it does not install system packages for you. +To check or install the runtime packages automatically, run: + +```sh +sh scripts/setup-deps.sh --check +sh scripts/setup-deps.sh +``` + +Use `--yes` for unattended installs. The script supports `apt`, `dnf`, +`pacman`, `zypper`, `apk`, and `xbps-install`. + ## Usage Enable `h465855hgg/lyrics`, then add the `lyrics` bar widget in Noctalia's bar diff --git a/lyrics/scripts/setup-deps.sh b/lyrics/scripts/setup-deps.sh new file mode 100755 index 0000000..5493be4 --- /dev/null +++ b/lyrics/scripts/setup-deps.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env sh +set -eu + +usage() { + cat <<'EOF' +Usage: scripts/setup-deps.sh [--check] [--yes] + +Install or check runtime dependencies for the Noctalia Lyrics plugin. + +Options: + --check Only report missing commands; do not install anything. + --yes Skip the confirmation prompt before installing packages. + --help Show this help text. +EOF +} + +CHECK_ONLY=0 +ASSUME_YES=0 + +while [ "$#" -gt 0 ]; do + case "$1" in + --check) + CHECK_ONLY=1 + ;; + -y|--yes) + ASSUME_YES=1 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" >&2 + usage >&2 + exit 2 + ;; + esac + shift +done + +need_command() { + command -v "$1" >/dev/null 2>&1 || MISSING_COMMANDS="$MISSING_COMMANDS $1" +} + +MISSING_COMMANDS="" +need_command playerctl +need_command python3 +need_command curl +need_command cp + +if [ -z "$MISSING_COMMANDS" ]; then + echo "All runtime commands are installed: playerctl python3 curl cp" + exit 0 +fi + +echo "Missing runtime command(s):$MISSING_COMMANDS" + +if [ "$CHECK_ONLY" -eq 1 ]; then + exit 1 +fi + +if [ "$(id -u)" -eq 0 ]; then + SUDO="" +elif command -v sudo >/dev/null 2>&1; then + SUDO="sudo" +else + echo "sudo is required to install packages as a non-root user." >&2 + exit 1 +fi + +detect_pm() { + if command -v apt-get >/dev/null 2>&1; then + echo apt + elif command -v dnf >/dev/null 2>&1; then + echo dnf + elif command -v pacman >/dev/null 2>&1; then + echo pacman + elif command -v zypper >/dev/null 2>&1; then + echo zypper + elif command -v apk >/dev/null 2>&1; then + echo apk + elif command -v xbps-install >/dev/null 2>&1; then + echo xbps + else + echo unknown + fi +} + +PM="$(detect_pm)" + +case "$PM" in + apt) + INSTALL_CMD="$SUDO apt-get update && $SUDO apt-get install -y playerctl python3 curl coreutils" + ;; + dnf) + INSTALL_CMD="$SUDO dnf install -y playerctl python3 curl coreutils" + ;; + pacman) + INSTALL_CMD="$SUDO pacman -S --needed playerctl python curl coreutils" + ;; + zypper) + INSTALL_CMD="$SUDO zypper install -y playerctl python3 curl coreutils" + ;; + apk) + INSTALL_CMD="$SUDO apk add playerctl python3 curl coreutils" + ;; + xbps) + INSTALL_CMD="$SUDO xbps-install -Sy playerctl python3 curl coreutils" + ;; + *) + cat >&2 <<'EOF' +Could not detect a supported package manager. +Install these packages manually with your distribution package manager: + playerctl python3 curl coreutils +EOF + exit 1 + ;; +esac + +echo "Detected package manager: $PM" +echo "Install command: $INSTALL_CMD" + +if [ "$ASSUME_YES" -ne 1 ]; then + printf "Proceed with installation? [y/N] " + read -r answer + case "$answer" in + y|Y|yes|YES) + ;; + *) + echo "Cancelled." + exit 1 + ;; + esac +fi + +sh -c "$INSTALL_CMD" + +MISSING_COMMANDS="" +need_command playerctl +need_command python3 +need_command curl +need_command cp + +if [ -n "$MISSING_COMMANDS" ]; then + echo "Still missing after installation:$MISSING_COMMANDS" >&2 + exit 1 +fi + +echo "Dependencies installed successfully." From 681e8ee0576211ce3d1f6bb1de8cb2244bfc20bd Mon Sep 17 00:00:00 2001 From: goodroot <9484709+goodroot@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:16:39 -0700 Subject: [PATCH 05/34] feat: add noctwhspr plugin --- noctwhspr/README.md | 72 +++++++++++++++++++ noctwhspr/plugin.toml | 21 ++++++ noctwhspr/thumbnail.webp | Bin 0 -> 25222 bytes noctwhspr/translations/en.json | 5 ++ noctwhspr/widget.luau | 125 +++++++++++++++++++++++++++++++++ 5 files changed, 223 insertions(+) create mode 100644 noctwhspr/README.md create mode 100644 noctwhspr/plugin.toml create mode 100644 noctwhspr/thumbnail.webp create mode 100644 noctwhspr/translations/en.json create mode 100644 noctwhspr/widget.luau diff --git a/noctwhspr/README.md b/noctwhspr/README.md new file mode 100644 index 0000000..fef78f3 --- /dev/null +++ b/noctwhspr/README.md @@ -0,0 +1,72 @@ +# noctwhspr + +Noctalia companion for [hyprwhspr](https://github.com/goodroot/hyprwhspr) — +native speech-to-text for Linux. hyprwhspr is fast, accurate, private, +system-wide dictation: press a hotkey, talk, and your words land in whatever +you were typing — transcribed by local in-memory models (Whisper, Parakeet) +that never leave your machine, or by top cloud APIs if you point it there. +Its visuals even theme themselves to match your Noctalia theme. + +This plugin puts hyprwhspr on your bar: the widget shows the dictation state +at a glance, left-click starts or stops a recording, and right-click restarts +the hyprwhspr service if it ever gets stuck. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `goodroot/noctwhspr` | +| Entries | Bar widget: `status` | + +## Requirements + +Install [`hyprwhspr`](https://github.com/goodroot/hyprwhspr) and set it up so +its `hyprwhspr.service` systemd user service exists. The widget drives +hyprwhspr's own tray script (`hyprwhspr-tray.sh`), which it looks up under the +install root — `/usr/lib/hyprwhspr` for the Arch/AUR package. Nothing else is +needed; the widget has no network access of its own. + +## Usage + +Enable the plugin in Settings → Plugins, then add the `status` widget to your +bar in Settings → Bar. + +The glyph tracks the dictation state reported by hyprwhspr: + +| Glyph | State | +| --- | --- | +| Filled record dot (error color) | Recording — dictation is capturing audio | +| Microphone (primary color) | Ready — service is up, waiting for a hotkey or click | +| Zzz | Model unloaded — first recording will load it | +| Microphone off | Service stopped | +| Warning triangle | Error — the tooltip explains what is wrong | + +Interactions: + +- **Left-click** — toggle recording (same as the hyprwhspr hotkey). If the + service is stopped, this starts it first. +- **Right-click** — restart the `hyprwhspr.service` systemd user service. +- **Hover** — the tooltip shows the detailed status line, including error + reasons when something is wrong. + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `root` | `string` | `/usr/lib/hyprwhspr` | Directory hyprwhspr is installed under. Leave at the default unless hyprwhspr lives at a non-standard prefix; `HYPRWHSPR_ROOT` in Noctalia's environment is also honored. | + +## Notes + +- The widget is a thin shim over hyprwhspr's tray script — the same script + that backs its Waybar module — so state detection stays in one place. It + polls `/config/hyprland/hyprwhspr-tray.sh status` every 2 seconds and + renders the returned JSON. +- Spawned processes: the tray script on every poll and click; the script in + turn queries `systemctl --user` and hyprwhspr's runtime state files. + Right-click runs `systemctl --user restart hyprwhspr.service` through the + script. No network calls and no filesystem writes are made by the plugin + itself. +- If the widget shows "hyprwhspr not found", hyprwhspr is not installed at + the configured root — point the `root` setting at your install prefix. +- Works on any compositor Noctalia runs on; the `hyprland` in the script path + is historical, hyprwhspr itself supports Hyprland, Niri and friends. diff --git a/noctwhspr/plugin.toml b/noctwhspr/plugin.toml new file mode 100644 index 0000000..ebfe1f6 --- /dev/null +++ b/noctwhspr/plugin.toml @@ -0,0 +1,21 @@ +id = "goodroot/noctwhspr" +name = "noctwhspr" +version = "1.0.0" +plugin_api = 3 +author = "goodroot" +license = "MIT" +icon = "microphone" +description = "Noctalia companion for hyprwhspr: shows dictation state, click to record, right-click to restart." +dependencies = ["hyprwhspr"] +tags = ["audio", "bar", "recording", "utility"] + +[[widget]] +id = "status" +entry = "widget.luau" + + [[widget.setting]] + key = "root" + type = "string" + label_key = "settings.root.label" + description_key = "settings.root.description" + default = "/usr/lib/hyprwhspr" diff --git a/noctwhspr/thumbnail.webp b/noctwhspr/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..f0a11ce8327310bc454124edf9ce7a1facaf8aa1 GIT binary patch literal 25222 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 KYL*KF0|Nk9b^d1n literal 0 HcmV?d00001 diff --git a/noctwhspr/translations/en.json b/noctwhspr/translations/en.json new file mode 100644 index 0000000..a141050 --- /dev/null +++ b/noctwhspr/translations/en.json @@ -0,0 +1,5 @@ +{ + "title": "noctwhspr", + "settings.root.label": "hyprwhspr install root", + "settings.root.description": "Directory hyprwhspr is installed under. Leave at the default unless hyprwhspr lives at a non-standard prefix." +} diff --git a/noctwhspr/widget.luau b/noctwhspr/widget.luau new file mode 100644 index 0000000..f0c326e --- /dev/null +++ b/noctwhspr/widget.luau @@ -0,0 +1,125 @@ +--!nonstrict +-- hyprwhspr bar widget for Noctalia. +-- +-- Thin shim over the existing tray script (single source of truth for state +-- detection, shared with the Waybar module): polls `hyprwhspr-tray.sh status` +-- and renders its JSON (class + tooltip) as a glyph. Clicks invoke the same +-- script actions the Waybar module binds. + +local TRAY_REL = "/config/hyprland/hyprwhspr-tray.sh" + +-- state class (from the tray script's JSON) -> glyph + palette color +local STATES = { + recording = { glyph = "player-record-filled", color = "error" }, + ready = { glyph = "microphone", color = "primary" }, + unloaded = { glyph = "zzz", color = "outline" }, + stopped = { glyph = "microphone-off", color = "outline" }, + error = { glyph = "alert-triangle", color = "error" }, +} + +local function applyState(state, tooltip) + barWidget.setGlyph(state.glyph) + barWidget.setGlyphColor(state.color) + if tooltip ~= nil and tooltip ~= "" then + barWidget.setTooltip(tooltip) + end +end + +local function applyError(tooltip) + applyState(STATES.error, tooltip) +end + +-- Resolve the tray script lazily and cache the hit. Noctalia's process is +-- spawned by the compositor, so HYPRWHSPR_ROOT is usually absent from its +-- environment — the widget "root" setting is the override for non-standard +-- install prefixes. +local trayCached = nil +local function trayPath() + if trayCached ~= nil and noctalia.fileExists(trayCached) then + return trayCached + end + trayCached = nil + local candidates = {} + local cfg = noctalia.getConfig("root") + if type(cfg) == "string" and cfg ~= "" then + table.insert(candidates, cfg) + end + local env = noctalia.getenv("HYPRWHSPR_ROOT") + if env ~= nil and env ~= "" then + table.insert(candidates, env) + end + table.insert(candidates, "/usr/lib/hyprwhspr") + for _, root in ipairs(candidates) do + local path = root .. TRAY_REL + if noctalia.fileExists(path) then + trayCached = path + return path + end + end + return nil +end + +local function trayCommand(action) + local path = trayPath() + if path == nil then + return nil + end + -- Single-quote the path: install roots may contain spaces. + return "'" .. path .. "' " .. action +end + +local function render(json) + if type(json) ~= "string" or json == "" then + applyError("hyprwhspr: tray script returned no status") + return + end + local class = json:match('"class":"([^"]*)"') or "error" + local tooltip = json:match('"tooltip":"([^"]*)"') or "" + + -- Strip the Waybar cache-buster line, unescape \n + tooltip = tooltip:gsub("\\n_ts:%d+", "") + tooltip = tooltip:gsub("\\n", "\n") + + applyState(STATES[class] or STATES.error, tooltip) +end + +local function refresh() + local cmd = trayCommand("status") + if cmd == nil then + applyError("hyprwhspr not found\nInstall hyprwhspr or set this widget's root setting") + return + end + noctalia.runAsync(cmd, function(result) + if type(result) ~= "table" then + applyError("hyprwhspr: status query failed") + return + end + render(result.stdout) + end) +end + +function update() + -- The tray script re-derives state via many subprocesses per call; 2s is + -- responsive enough (the recording overlay gives immediate feedback). + noctalia.setUpdateInterval(2000) + refresh() +end + +function onClick() + local cmd = trayCommand("record") + if cmd ~= nil then + noctalia.runAsync(cmd, function() refresh() end) + end +end + +function onRightClick() + local cmd = trayCommand("restart") + if cmd ~= nil then + noctalia.runAsync(cmd, function() refresh() end) + end +end + +-- Honest placeholder until the first poll lands. +barWidget.setGlyph("microphone") +barWidget.setGlyphColor("outline") +barWidget.setTooltip("hyprwhspr: waiting for status…") From 6d7efe757784d55f17e6cc8be8fa50622025e415 Mon Sep 17 00:00:00 2001 From: goodroot <9484709+goodroot@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:38:44 -0700 Subject: [PATCH 06/34] noctwhspr: full-bleed thumbnail screenshot --- noctwhspr/thumbnail.webp | Bin 25222 -> 33234 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/noctwhspr/thumbnail.webp b/noctwhspr/thumbnail.webp index f0a11ce8327310bc454124edf9ce7a1facaf8aa1..a94a3a36732cec724b04019f53b4ceab23d1d5f7 100644 GIT binary patch literal 33234 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 KYL*KF0|Nk9b^d1n From 4a44228965a7b0af38ff11da9d3508d26ae65727 Mon Sep 17 00:00:00 2001 From: goodroot <9484709+goodroot@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:40:36 -0700 Subject: [PATCH 07/34] noctwhspr: clarify thumbnail description --- noctwhspr/thumbnail.webp | Bin 33234 -> 35624 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/noctwhspr/thumbnail.webp b/noctwhspr/thumbnail.webp index a94a3a36732cec724b04019f53b4ceab23d1d5f7..1f109e06609fa216a98e5072fc83eca700c2fda8 100644 GIT binary patch literal 35624 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 literal 33234 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 jaUR2wO}z28^{Y51?EJfJg6qF`4FZc6v Date: Fri, 17 Jul 2026 14:49:39 +0800 Subject: [PATCH 08/34] feat(lyrics): add customizable colors --- lyrics/README.md | 2 ++ lyrics/lyrics.luau | 14 ++++++++------ lyrics/plugin.toml | 16 +++++++++++++++- lyrics/translations/en.json | 8 ++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lyrics/README.md b/lyrics/README.md index a7dc19d..3cd29c9 100644 --- a/lyrics/README.md +++ b/lyrics/README.md @@ -70,6 +70,8 @@ Plugin settings: | `show_artist` | `bool` | `true` | Includes the artist in track-information mode. | | `hide_when_paused` | `bool` | `false` | Hides the widget instead of dimming it while paused. | | `show_cover` | `bool` | `true` | Shows circular album artwork beside the lyrics. | +| `active_color` | `color` | `primary` | Colors the current and already-sung lyric characters. | +| `inactive_color` | `color` | `on_surface_variant` | Colors upcoming lyrics, paused playback, and secondary lines. | ## IPC diff --git a/lyrics/lyrics.luau b/lyrics/lyrics.luau index bb9a4cd..c352031 100644 --- a/lyrics/lyrics.luau +++ b/lyrics/lyrics.luau @@ -8,6 +8,8 @@ local showArtist = noctalia.getConfig("show_artist") local hideWhenPaused = noctalia.getConfig("hide_when_paused") local showCover = noctalia.getConfig("show_cover") if showCover == nil then showCover = true end +local activeColor = noctalia.getConfig("active_color") or "primary" +local inactiveColor = noctalia.getConfig("inactive_color") or "on_surface_variant" -- These are plugin settings, not per-widget settings. local scrollMode = noctalia.getConfig("scroll_mode") or "auto" @@ -189,9 +191,9 @@ local function getMarqueeOffset(length) end local function karaokeColor(charTime, charProgress, position, useGradient) - if not playing then return "on_surface_variant" end - local active = noctalia.isDarkMode() and "primary" or "on_surface" - local inactive = "on_surface_variant" + if not playing then return inactiveColor end + local active = activeColor + local inactive = inactiveColor if charTime and position then if not useGradient then return position >= charTime and active or inactive @@ -230,8 +232,8 @@ local function buildLineRow(line, opts) local labels = {} for sourceIndex = first, last do - local active = playing and (noctalia.isDarkMode() and "primary" or "on_surface") or "on_surface_variant" - local color = opts.dim and "on_surface_variant" or active + local active = playing and activeColor or inactiveColor + local color = opts.dim and inactiveColor or active if not opts.solid and not opts.dim then local progress = #chars > 1 and (sourceIndex - 1) / (#chars - 1) or 0 color = karaokeColor(times and times[sourceIndex], progress, opts.position, opts.useGradient) @@ -316,7 +318,7 @@ local function render() prefix[#prefix + 1] = ui.glyph({ name = glyph, size = 14, - color = playing and (noctalia.isDarkMode() and "primary" or "on_surface") or "on_surface_variant", + color = playing and activeColor or inactiveColor, }) end diff --git a/lyrics/plugin.toml b/lyrics/plugin.toml index 70689ac..37eb261 100644 --- a/lyrics/plugin.toml +++ b/lyrics/plugin.toml @@ -1,6 +1,6 @@ id = "h465855hgg/lyrics" name = "Lyrics" -version = "1.0.0" +version = "1.1.0" plugin_api = 3 author = "h465855hgg" license = "MIT" @@ -150,3 +150,17 @@ entry = "lyrics.luau" label_key = "settings.show_cover.label" description_key = "settings.show_cover.description" default = true + + [[widget.setting]] + key = "active_color" + type = "color" + label_key = "settings.active_color.label" + description_key = "settings.active_color.description" + default = "primary" + + [[widget.setting]] + key = "inactive_color" + type = "color" + label_key = "settings.inactive_color.label" + description_key = "settings.inactive_color.description" + default = "on_surface_variant" diff --git a/lyrics/translations/en.json b/lyrics/translations/en.json index 6c0a6d5..ac28055 100644 --- a/lyrics/translations/en.json +++ b/lyrics/translations/en.json @@ -17,6 +17,14 @@ "label": "Show album cover", "description": "Display the song's album art next to the lyrics." }, + "active_color": { + "label": "Active lyric color", + "description": "Color used for the current and already-sung lyric characters." + }, + "inactive_color": { + "label": "Inactive lyric color", + "description": "Color used for upcoming lyrics, paused playback, and secondary lines." + }, "lyrics_source": { "label": "Lyrics source", "description": "Choose a preset source, local-player lyrics, a custom endpoint, or external push protocol.", From f50a65d125fee8fc074715e9b57f250f849af230 Mon Sep 17 00:00:00 2001 From: princearia Date: Fri, 17 Jul 2026 14:29:26 +0200 Subject: [PATCH 09/34] Feature: Added support for PrismLauncher forks, notably FreesmLauncher --- prismlauncher-instances/plugin.toml | 11 +++++++++-- prismlauncher-instances/prismlauncher-instances.luau | 11 +++++++++-- prismlauncher-instances/translations/en.json | 4 ++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/prismlauncher-instances/plugin.toml b/prismlauncher-instances/plugin.toml index 75fa0b8..8986efd 100644 --- a/prismlauncher-instances/plugin.toml +++ b/prismlauncher-instances/plugin.toml @@ -1,13 +1,13 @@ id = "radimous/prismlauncher-instances" name = "PrismLauncher Instances" -version = "1.0.0" +version = "1.0.1" plugin_api = 3 author = "radimous" license = "MIT" dependencies = ["prismlauncher"] icon = "nut" deprecated = false -description = "A launcher provider that adds PrismLauncher instances to the noctalia launcher." +description = "A launcher provider that adds PrismLauncher and PrismLauncher fork instances to the noctalia launcher." tags = ["gaming", "launcher"] [[launcher_provider]] @@ -24,3 +24,10 @@ type = "string" label_key = "settings.prismlauncher_path.label" description_key = "settings.prismlauncher_path.description" default = "~/.local/share/PrismLauncher" + +[[setting]] +key = "launcher_exec_command" +type = "string" +label_key = "settings.launcher_exec_command.label" +description_key = "settings.launcher_exec_command.description" +default = "prismlauncher" \ No newline at end of file diff --git a/prismlauncher-instances/prismlauncher-instances.luau b/prismlauncher-instances/prismlauncher-instances.luau index 59331c0..865c885 100644 --- a/prismlauncher-instances/prismlauncher-instances.luau +++ b/prismlauncher-instances/prismlauncher-instances.luau @@ -5,10 +5,15 @@ local function getPrismPath() return noctalia.expandPath(prismPath) end +local function getLauncherCommand() + local launcherCommand = noctalia.getConfig("launcher_exec_command") + return noctalia.expandPath(launcherCommand) +end + local function getInstancesDir() local prismPath = getPrismPath() - local configuredInstanceDir = getCfgValue(prismPath .. "/prismlauncher.cfg", "InstanceDir") + local configuredInstanceDir = getCfgValue(prismPath .. "/*.cfg", "InstanceDir") local instances if configuredInstanceDir == nil then -- default path @@ -91,8 +96,10 @@ local function shellQuote(s) end function onActivate(id) + local launcherCommand = getLauncherCommand() + if id == "" then return end - noctalia.runAsync(string.format("prismlauncher --launch %s &>/dev/null", shellQuote(id))) + noctalia.runAsync(string.format(launcherCommand .. " --launch %s &>/dev/null", shellQuote(id))) end -- doesn't handle icons that were changed to different default icon, rest is fine diff --git a/prismlauncher-instances/translations/en.json b/prismlauncher-instances/translations/en.json index b8e4959..087c092 100644 --- a/prismlauncher-instances/translations/en.json +++ b/prismlauncher-instances/translations/en.json @@ -3,6 +3,10 @@ "prismlauncher_path": { "label": "PrismLauncher path", "description": "Path to PrismLauncher" + }, + "launcher_exec_command": { + "label": "Prism Executable", + "description": "Start Prismlauncher or fork of choice" } }, "no_instances": { From 82524c1bc0b246bc432ca37c0f151cb9f232065d Mon Sep 17 00:00:00 2001 From: Ian Ribeiro <133624505+oldirtty@users.noreply.github.com> Date: Fri, 17 Jul 2026 10:25:27 -0300 Subject: [PATCH 10/34] refactor: adopt noctalia.pluginDataDir() (#29) --- color_picker/plugin.toml | 2 +- color_picker/service.luau | 48 +++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/color_picker/plugin.toml b/color_picker/plugin.toml index 713b2bc..63e1823 100644 --- a/color_picker/plugin.toml +++ b/color_picker/plugin.toml @@ -3,7 +3,7 @@ id = "oldirtty/color_picker" name = "Color Picker" description = "Pick a color from your screen with hyprpicker." license = "MIT" -version = "1.0.2" +version = "1.0.3" plugin_api = 3 icon = "palette" dependencies = ["hyprpicker"] diff --git a/color_picker/service.luau b/color_picker/service.luau index f0a0d77..f289836 100644 --- a/color_picker/service.luau +++ b/color_picker/service.luau @@ -9,9 +9,9 @@ -- CONSTANTS --============================================== local MAX_HISTORY = 6 -local STATE_DIR = "~/.local/state/noctalia/plugin-cache/community/color_picker" -local HISTORY_FILE = STATE_DIR .. "/history.json" -local SELECTED_FILE = STATE_DIR .. "/selected.json" +local PERSISTENT_DIR = noctalia.pluginDataDir() +local HISTORY_FILE = PERSISTENT_DIR .. "/history.json" +local SELECTED_FILE = PERSISTENT_DIR .. "/selected.json" local tr_color_picker = noctalia.tr("color_picker") --============================================== @@ -101,11 +101,9 @@ end --============================================== -- STATE MODEL -- --- selectedColor / selectedOpacity: ephemeral, what the panel is currently --- showing. Set here on every successful pick; also updated by the panel --- itself for pure-UI interactions (history swatch click, field edit, --- opacity slider) that don't touch hyprpicker or disk. --- +-- selectedColor / selectedOpacity: persisted color, state is saved once +-- per panel session when closed. + -- colorHistory: persisted list. -- Only mutated by pushCurrentColor(), called on immediate-commit picks -- (widget right-click) and on "commit" (panel close). @@ -139,37 +137,37 @@ local function pushCurrentColor(hex: string, opacity: number) end local function loadHistoryFromDisk() - local content = noctalia.readFile(HISTORY_FILE) - if content == nil or content == "" then return end + local raw = noctalia.readFile(HISTORY_FILE) + if raw == nil or raw == "" then return end - local decoded = noctalia.json.decode(content) - if type(decoded) ~= "table" then return end + local decoded = noctalia.json.decode(raw) + if type(decoded) ~= "table" then return end - noctalia.state.set("colorHistory", decoded) + noctalia.state.set("colorHistory", decoded) end local function saveHistoryToDisk() - local history = noctalia.state.get("colorHistory") or {} - local encoded = noctalia.json.encode(history) - if encoded ~= nil then - noctalia.writeFile(HISTORY_FILE, encoded) - end + local history = noctalia.state.get("colorHistory") or {} + local encoded = noctalia.json.encode(history) + if encoded ~= nil then + noctalia.writeFile(HISTORY_FILE, encoded) + end end local function loadSelectedFromDisk() - local content = noctalia.readFile(SELECTED_FILE) - if content == nil or content == "" then return end - - local decoded = noctalia.json.decode(content) + local raw = noctalia.readFile(SELECTED_FILE) + if raw == nil or raw == "" then return end + + local decoded = noctalia.json.decode(raw) if type(decoded) ~= "table" or decoded.hex == nil then return end - + setSelected(decoded.hex, decoded.opacity or 1) end local function saveSelectedToDisk() local hex = noctalia.state.get("selectedColor") if hex == nil then return end - + local opacity = tonumber(noctalia.state.get("selectedOpacity")) or 1 local encoded = noctalia.json.encode({ hex = hex, opacity = opacity }) if encoded ~= nil then @@ -291,7 +289,7 @@ end --============================================== function load() - noctalia.mkdirAll(STATE_DIR) + noctalia.mkdirAll(PERSISTENT_DIR) loadHistoryFromDisk() loadSelectedFromDisk() end From f1b69842eb88243f1e77b2d1c1b2606f921ca509 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 17 Jul 2026 13:25:39 +0000 Subject: [PATCH 11/34] chore: update plugin catalog [skip ci] --- catalog.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog.toml b/catalog.toml index 277e90f..acc35a3 100644 --- a/catalog.toml +++ b/catalog.toml @@ -77,7 +77,7 @@ tags = ["bar", "mangowc"] [[plugin]] id = "oldirtty/color_picker" name = "Color Picker" -version = "1.0.2" +version = "1.0.3" author = "oldirtty" license = "MIT" icon = "palette" From 88b7af63780f3b58db99d5b84b455b12a8280308 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 17 Jul 2026 13:27:24 +0000 Subject: [PATCH 12/34] chore: update plugin catalog [skip ci] --- catalog.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/catalog.toml b/catalog.toml index acc35a3..d8b5d10 100644 --- a/catalog.toml +++ b/catalog.toml @@ -99,11 +99,11 @@ tags = ["hyprland", "sway", "desktop", "utility"] [[plugin]] id = "radimous/prismlauncher-instances" name = "PrismLauncher Instances" -version = "1.0.0" +version = "1.0.1" author = "radimous" license = "MIT" icon = "nut" -description = "A launcher provider that adds PrismLauncher instances to the noctalia launcher." +description = "A launcher provider that adds PrismLauncher and PrismLauncher fork instances to the noctalia launcher." deprecated = false plugin_api = 3 tags = ["gaming", "launcher"] From da237fe43b640574a59d26271cbfbd11e320e4d1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 17 Jul 2026 13:48:41 +0000 Subject: [PATCH 13/34] chore: update plugin catalog [skip ci] --- catalog.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/catalog.toml b/catalog.toml index d8b5d10..6c9d6f4 100644 --- a/catalog.toml +++ b/catalog.toml @@ -173,3 +173,14 @@ icon = "device-laptop" description = "Toggles battery conservation mode via the ideapad_acpi driver, on Lenovo IdeaPad and Legion laptops." plugin_api = 3 tags = ["hardware", "shortcut", "system"] + +[[plugin]] +id = "goodroot/noctwhspr" +name = "noctwhspr" +version = "1.0.0" +author = "goodroot" +license = "MIT" +icon = "microphone" +description = "Noctalia companion for hyprwhspr: shows dictation state, click to record, right-click to restart." +plugin_api = 3 +tags = ["audio", "bar", "recording", "utility"] From c71ec003543d431f5a61b30c47f64e9713ecd653 Mon Sep 17 00:00:00 2001 From: nightwatch75 <30896720+nightwatch75@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:49:12 +0200 Subject: [PATCH 14/34] =?UTF-8?q?Add=20nightwatch75/file-search=200.0.9=20?= =?UTF-8?q?=E2=80=94=20fuzzy=20file=20search=20(bar=20widget=20+=20panel?= =?UTF-8?q?=20+=20launcher=20provider)=20(#26)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add nightwatch75/file-search 0.0.7 Co-Authored-By: Claude Fable 5 * file-search: backtick dependency names in Requirements (CI check) Co-Authored-By: Claude Fable 5 * file-search 0.0.8: address review — safe index records, atomic cache writes, command dependencies, index fingerprint Co-Authored-By: Claude Fable 5 * file-search 0.0.8: min_noctalia → plugin_api = 3 (manifest format change) Co-Authored-By: Claude Fable 5 * file-search 0.0.9: move index to noctalia.pluginDataDir() Co-Authored-By: Claude Fable 5 --------- Co-authored-by: Massimiliano Co-authored-by: Claude Fable 5 Co-authored-by: nightwatch75 --- file-search/README.md | 130 +++++++++++ file-search/file-search.luau | 70 ++++++ file-search/launcher.luau | 278 ++++++++++++++++++++++ file-search/panel.luau | 387 +++++++++++++++++++++++++++++++ file-search/plugin.toml | 78 +++++++ file-search/thumbnail.webp | Bin 0 -> 57884 bytes file-search/translations/en.json | 30 +++ 7 files changed, 973 insertions(+) create mode 100644 file-search/README.md create mode 100644 file-search/file-search.luau create mode 100644 file-search/launcher.luau create mode 100644 file-search/panel.luau create mode 100644 file-search/plugin.toml create mode 100644 file-search/thumbnail.webp create mode 100644 file-search/translations/en.json diff --git a/file-search/README.md b/file-search/README.md new file mode 100644 index 0000000..2117ea3 --- /dev/null +++ b/file-search/README.md @@ -0,0 +1,130 @@ +# File Search + +A [noctalia](https://github.com/noctalia-dev/noctalia) v5 bar plugin: fuzzy +search files and folders as you type, with [fzf](https://github.com/junegunn/fzf) +as the matching subsystem. Click the bar glyph to open a search panel; picking +a result opens it with the system MIME association (`xdg-open`) — directories +open in your file manager. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `nightwatch75/file-search` | +| Entries | Bar widget: `file-search`; panel: `panel`; launcher provider: `launcher` | +| Launcher Prefix | `/fs` | + +## Usage + +Add the `file-search` widget from Noctalia's widget picker and click it to +open the search panel. You can also open the panel directly or bind it in +your compositor: + +```sh +noctalia msg panel-toggle nightwatch75/file-search:panel +``` + +| Action | Effect | +|--------------|-------------------------------------------------| +| Left click | Open/close the search panel | +| Right click | Open the search folder in the file manager | +| Middle click | Copy the search folder path to the clipboard | + +In the panel: + +| Key | Action | +|---------|-------------------------------------| +| `Enter` | Open the top match | +| `Esc` | Close the panel (noctalia default) | + +In the noctalia launcher (keyboard-first flow, native navigation): + +| Key | Action | +|-------------|-------------------------------------------| +| `/fs `| Fuzzy search files and folders | +| `↑` / `↓` | Move through the results | +| `Enter` | Open the selected result (MIME/xdg-open) | + +With an empty `/fs` query the list also offers *Rebuild search index*; the +index is shared with the panel and built on demand when missing. + +## Features + +- Live results while you type: the search folder is walked once with `find` + into a cache, then every keystroke is fuzzy-matched through + `fzf --filter`, so typing stays responsive even on large trees +- Configurable bar glyph, search folder (defaults to `~`), excluded folder + names (`.git, node_modules, .cache, .venv` by default, matched anywhere in + the tree), hidden entries on/off, max results +- `Enter` opens the top match; every result row opens on click via the + system MIME association — files in their default app, folders in the file + manager +- Launcher provider for a keyboard-first flow: type `/fs ` in the + noctalia launcher and navigate the results with the native arrow keys + + `Enter` (plugin panels cannot receive arrow keys in the current Luau API, + so the launcher is the keyboard way to browse results) +- Folder results are marked with a trailing `/` and a folder glyph +- Index rebuilds automatically when the relevant settings change, and on + demand via the panel's refresh button (external file changes are picked up + on rebuild) +- Panel placement (attached/floating), position and open-near-click are the + standard per-panel settings noctalia exposes in Settings → Plugins + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `search_folder` | `folder` | *(empty)* | Root folder the search indexes. Empty = your home folder. | +| `exclude_dirs` | `string` | `.git, node_modules, .cache, .venv` | Folder names skipped while indexing, separated by `,` or `;`, matched anywhere in the tree. | +| `show_hidden` | `bool` | `false` | Index files and folders whose name starts with a dot. | +| `max_results` | `int` | `50` | How many matches the panel lists at most (10–200). | +| `glyph` (widget) | `glyph` | `search` | Icon shown on the bar. | + +## Requirements + +- noctalia ≥ 5.0.0 +- [`fzf`](https://github.com/junegunn/fzf) — the fuzzy matcher +- `find` (GNU findutils) — walks the search folder into the index +- `xdg-open` (xdg-utils) — opens results with the MIME association +- `mktemp`, `mv`, `wc`, `head`, `rm` — GNU coreutils, standard on any Linux + desktop + +## Install + +Install **File Search** from Noctalia's plugin store (*Settings → Plugins*), +then add the widget to a bar from *Settings → Bar*. Plugin options live in +*Settings → Plugins*. + +For local development, add your working copy as a path source instead +(`.luau` edits hot-reload): + +```sh +noctalia msg plugins source add dev path /path/to/plugins +noctalia msg plugins enable nightwatch75/file-search +``` + +## Notes + +- The index lives in the plugin's private data directory + (`noctalia.pluginDataDir()`, by default + `~/.local/state/noctalia/plugins/data/nightwatch75/file-search/` — honors + `NOCTALIA_STATE_HOME`/`XDG_STATE_HOME`): `index.list` is a plain list of + paths relative to the search folder, and `index.meta` records which folder + and exclusions built it, so both the panel and the launcher rebuild + automatically after a settings change. +- Both files are written to `mktemp`-created private files and renamed into + place, so a rebuild never writes through a symlink planted at the cache + path. +- Names containing a newline are excluded from the index (they would break + the one-record-per-line format), and every record is validated against + the search root before being opened. +- Excluded entries match by folder/file *name* (`find -name`), not by path; + entries containing `/` are skipped and logged. +- With hidden entries off, anything starting with a dot is pruned — both + hidden folders (not descended into) and hidden files. +- Unreadable subtrees are silently skipped (permission errors don't fail the + index). + +## License + +MIT. diff --git a/file-search/file-search.luau b/file-search/file-search.luau new file mode 100644 index 0000000..86d1127 --- /dev/null +++ b/file-search/file-search.luau @@ -0,0 +1,70 @@ +--!nonstrict +-- file-search — bar widget that toggles the fuzzy search panel. +-- +-- The panel (panel.luau) publishes its open state on the shared +-- "file_search_open" state key; the glyph lights up while it is open. +-- +-- Click mapping: +-- Left click — open/close the search panel +-- Right click — open the search folder in the file manager +-- Middle click — copy the search folder path to the clipboard + +local PANEL_ID = "nightwatch75/file-search:panel" + +local open = false + +local function shellQuote(value) + return "'" .. value:gsub("'", "'\\''") .. "'" +end + +local function searchRoot() + local dir = noctalia.getConfig("search_folder") + if dir == nil or dir == "" then + dir = noctalia.getenv("HOME") or "/tmp" + else + dir = noctalia.expandPath(dir) + end + dir = dir:gsub("/+$", "") + if dir == "" then + dir = "/" + end + return dir +end + +local function render() + barWidget.setGlyph(noctalia.getConfig("glyph")) + local root = searchRoot() + if open then + barWidget.setGlyphColor("primary") + barWidget.setTooltip(noctalia.tr("tooltip_open", { path = root })) + else + barWidget.setGlyphColor("on_surface") + barWidget.setTooltip(noctalia.tr("tooltip_closed", { path = root })) + end +end + +noctalia.state.watch("file_search_open", function(value) + open = value == true + render() +end) + +-- Periodic re-render keeps the glyph and tooltip in sync with settings changes. +function update() + render() +end + +function onClick() + noctalia.togglePanel(PANEL_ID) +end + +function onRightClick() + noctalia.runAsync("xdg-open " .. shellQuote(searchRoot()) .. " >/dev/null 2>&1") +end + +function onMiddleClick() + noctalia.copyToClipboard(searchRoot(), "text/plain") + noctalia.notify(noctalia.tr("title"), noctalia.tr("copied_path")) +end + +noctalia.setUpdateInterval(1000) +render() diff --git a/file-search/launcher.luau b/file-search/launcher.luau new file mode 100644 index 0000000..cb591dd --- /dev/null +++ b/file-search/launcher.luau @@ -0,0 +1,278 @@ +--!nonstrict +-- file-search — launcher provider: the same fuzzy search with the native +-- keyboard flow of the noctalia launcher (type, arrows, Enter). +-- +-- `/fs ` fuzzy-matches over the index file the panel builds; when the +-- index is missing it is built here on demand. Activating a result opens it +-- with the system MIME association (xdg-open) — directories open in the +-- file manager. Late async results map back through the query echo of +-- launcher.setResults, so fzf can answer out of band. + +local MAX_RESULTS = 9 + +local searching = false +local indexing = false +local pendingQuery = nil -- latest query typed while a search/index ran + +local runQuery + +local function tr(key, args) + return noctalia.tr(key, args) +end + +local function trim(value) + return (value:gsub("^%s+", ""):gsub("%s+$", "")) +end + +local function shellQuote(value) + return "'" .. value:gsub("'", "'\\''") .. "'" +end + +-- Private per-plugin storage (XDG state); the host creates the directory on +-- every call. nil (with a log line) when no state directory resolves. +local function dataDir() + local dir, err = noctalia.pluginDataDir() + if dir == nil then + noctalia.log("file-search: pluginDataDir failed: " .. tostring(err)) + return nil + end + return dir +end + +-- Shell header shared by every cache command. The .meta sidecar holds the +-- settings fingerprint the cache was built with, so the panel and the +-- launcher can both tell a stale index apart. +local function cacheSh(dir) + return "CACHE_DIR=" .. shellQuote(dir) + .. '\nCACHE="$CACHE_DIR/index.list"\nMETA="$CACHE_DIR/index.meta"' +end + +local function searchRoot() + local dir = noctalia.getConfig("search_folder") + if dir == nil or dir == "" then + dir = noctalia.getenv("HOME") or "/tmp" + else + dir = noctalia.expandPath(dir) + end + dir = dir:gsub("/+$", "") + if dir == "" then + dir = "/" + end + return dir +end + + +-- Same exclusion set as the panel: names from the setting plus hidden +-- entries unless enabled. +local function excludeNames() + local raw = noctalia.getConfig("exclude_dirs") + if type(raw) ~= "string" then + raw = "" + end + local names = {} + for entry in raw:gmatch("[^,;]+") do + local name = trim(entry) + if name ~= "" and not name:find("/") then + table.insert(names, name) + end + end + if noctalia.getConfig("show_hidden") ~= true then + table.insert(names, ".*") + end + return names +end + +-- Must build the same string as the panel's indexKey(): the fingerprint in +-- the .meta sidecar is how the two entries recognize each other's index. +local function indexKey() + return searchRoot() .. "\n" .. table.concat(excludeNames(), "\n") +end + +-- The cache on disk is current when its fingerprint matches the settings, +-- whether the panel or the launcher built it. +local function cacheFresh(dir) + return noctalia.readFile(dir .. "/index.meta") == indexKey() +end + +-- One cache record, about to be joined to the search root. The cache is a +-- plain user-editable file, so records are untrusted: reject anything that +-- could resolve outside the root. +local function safeRel(rel) + if rel == "" or rel:sub(1, 1) == "/" or rel:find("\n", 1, true) then + return false + end + for part in rel:gmatch("[^/]+") do + if part == ".." then + return false + end + end + return true +end + +local function noopRow(titleKey) + return { id = "noop", title = tr(titleKey), glyph = "info-circle" } +end + +local function buildIndex(query) + if indexing then + pendingQuery = query + return + end + local dir = dataDir() + if dir == nil then + launcher.setResults(query, { noopRow("err_index") }) + return + end + indexing = true + pendingQuery = query + + local key = indexKey() + -- Names containing a newline would each forge extra one-per-fragment + -- records (a crafted name can smuggle '..' lines into the index), so + -- they are pruned unconditionally, before the user's exclusions. + local names = { "-name " .. shellQuote("*\n*") } + for _, name in ipairs(excludeNames()) do + table.insert(names, "-name " .. shellQuote(name)) + end + local prune = "\\( " .. table.concat(names, " -o ") .. " \\) -prune -o " + -- find's own exit status is ignored, so permission errors inside the + -- tree don't fail the build. Cache and fingerprint are written to + -- mktemp-created private files and renamed into place: rename replaces + -- a planted symlink at the destination instead of following it. The + -- host guarantees $CACHE_DIR exists (created by pluginDataDir above). + local cmd = cacheSh(dir) + .. '\nTMP=$(mktemp "$CACHE_DIR/index.list.XXXXXX") || exit 1\n' + .. "find " .. shellQuote(searchRoot()) .. " -mindepth 1 " .. prune + .. "-type d -printf '%P/\\n' -o -printf '%P\\n' > \"$TMP\" 2>/dev/null\n" + .. 'mv -f "$TMP" "$CACHE" || exit 1\n' + .. 'TMPM=$(mktemp "$CACHE_DIR/index.meta.XXXXXX") || exit 1\n' + .. "printf '%s' " .. shellQuote(key) .. ' > "$TMPM"\n' + .. 'mv -f "$TMPM" "$META" || exit 1' + + launcher.setResults(query, { noopRow("launcher.indexing") }) + local ok = noctalia.runAsync(cmd, function(result) + indexing = false + local queued = pendingQuery + pendingQuery = nil + if result.exitCode == 0 and not result.timedOut then + runQuery(queued or query) + else + launcher.setResults(queued or query, { noopRow("err_index") }) + end + end, 180000) + if not ok then + indexing = false + launcher.setResults(query, { noopRow("err_spawn") }) + end +end + +runQuery = function(query) + if indexing then + pendingQuery = query + return + end + if searching then + pendingQuery = query + return + end + local dir = dataDir() + if dir == nil then + launcher.setResults(query, { noopRow("err_index") }) + return + end + searching = true + local text = trim(query) + local cmd + if text == "" then + cmd = cacheSh(dir) .. '\nhead -n ' .. MAX_RESULTS .. ' "$CACHE" 2>/dev/null' + else + cmd = cacheSh(dir) .. "\nfzf --filter=" .. shellQuote(text) + .. ' < "$CACHE" 2>/dev/null | head -n ' .. MAX_RESULTS + end + local ok = noctalia.runAsync(cmd, function(result) + searching = false + local rows = {} + if not result.timedOut then + for line in (result.stdout or ""):gmatch("[^\n]+") do + local isDir = line:sub(-1) == "/" + local rel = line:gsub("/+$", "") + table.insert(rows, { + id = "open:" .. line, + title = rel:match("[^/]+$") or rel, + subtitle = line, + glyph = isDir and "folder" or "file", + }) + end + end + if #rows == 0 and text ~= "" then + table.insert(rows, noopRow("launcher.no_results")) + end + if text == "" then + table.insert(rows, { + id = "reindex", + title = tr("launcher.reindex_title"), + subtitle = searchRoot(), + glyph = "refresh", + }) + end + launcher.setResults(query, rows) + if pendingQuery ~= nil and pendingQuery ~= query then + local nextQuery = pendingQuery + pendingQuery = nil + runQuery(nextQuery) + end + end, 15000) + if not ok then + searching = false + end +end + +function onQuery(query) + if not noctalia.commandExists("fzf") then + launcher.setResults(query, { noopRow("err_no_fzf") }) + return + end + local dir = dataDir() + if dir == nil then + launcher.setResults(query, { noopRow("err_index") }) + return + end + -- A missing or stale index (no meta, or built with a different root or + -- exclusion set) is rebuilt before searching: stale relative paths + -- joined to a new root could resolve to unrelated files. + if not cacheFresh(dir) then + buildIndex(query) + return + end + runQuery(query) +end + +function onActivate(id) + if id == "reindex" then + local dir = dataDir() + if dir == nil then + return + end + -- Drop cache and fingerprint so the next keystroke rebuilds against + -- fresh disk state (a surviving .meta would read as a fresh index). + noctalia.runAsync(cacheSh(dir) .. '\nrm -f "$CACHE" "$META"', function(_result) + noctalia.notify(tr("title"), tr("launcher.reindex_done")) + end) + return + end + local rel = id:match("^open:(.+)$") + if rel == nil then + return + end + if not safeRel(rel) then + noctalia.log("file-search: refusing unsafe index record: " .. rel) + noctalia.notify(tr("title"), tr("err_bad_record")) + return + end + local path = searchRoot() + if path ~= "/" then + path = path .. "/" + end + path = path .. rel:gsub("/+$", "") + noctalia.runAsync("xdg-open " .. shellQuote(path) .. " >/dev/null 2>&1") +end diff --git a/file-search/panel.luau b/file-search/panel.luau new file mode 100644 index 0000000..55a97bf --- /dev/null +++ b/file-search/panel.luau @@ -0,0 +1,387 @@ +--!nonstrict +-- file-search — fuzzy search panel, fzf as the matching subsystem. +-- +-- On open the search folder is walked once with `find` into a cache file +-- (excluded directory names are pruned, hidden entries too unless enabled); +-- after that every keystroke runs `fzf --filter=` over the cache, so +-- typing stays responsive even on large trees. Results update live; picking +-- one opens it with the system MIME association (xdg-open) — directories +-- open in the file manager. Enter opens the top match. +-- +-- The index is rebuilt when the panel opens with changed settings, or on +-- demand via the refresh button. The bar widget mirrors the panel's open +-- state through the shared "file_search_open" state key. + +local query = "" +local results = {} -- relative paths; directories keep a trailing "/" +local total = nil -- entries in the index, shown in the footer +local indexing = false +local searching = false +local errMsg = nil +local fzfMissing = false +local inputRev = 0 -- bumped to reseed the query input on open +local haveIndex = false -- the cache on disk matches the current settings + +local render +local runSearch +local buildIndex + +-- Per-row callbacks need distinct global names; the reconciler dispatches +-- callbacks by name only. getfenv() is the script environment lua_getglobal +-- reads from, so assigning into it defines the callback the host will find. +local env = getfenv() +local function rowCallback(prefix, index, fn) + local name = prefix .. "_" .. index + env[name] = fn + return name +end + +local function tr(key, args) + return noctalia.tr(key, args) +end + +local function trim(value) + return (value:gsub("^%s+", ""):gsub("%s+$", "")) +end + +local function shellQuote(value) + return "'" .. value:gsub("'", "'\\''") .. "'" +end + +-- Private per-plugin storage (XDG state); the host creates the directory on +-- every call. nil (with a log line) when no state directory resolves. +local function dataDir() + local dir, err = noctalia.pluginDataDir() + if dir == nil then + noctalia.log("file-search: pluginDataDir failed: " .. tostring(err)) + return nil + end + return dir +end + +-- Shell header shared by every cache command. The .meta sidecar holds the +-- settings fingerprint the cache was built with, so the panel and the +-- launcher can both tell a stale index apart. +local function cacheSh(dir) + return "CACHE_DIR=" .. shellQuote(dir) + .. '\nCACHE="$CACHE_DIR/index.list"\nMETA="$CACHE_DIR/index.meta"' +end + +local function searchRoot() + local dir = noctalia.getConfig("search_folder") + if dir == nil or dir == "" then + dir = noctalia.getenv("HOME") or "/tmp" + else + dir = noctalia.expandPath(dir) + end + dir = dir:gsub("/+$", "") + if dir == "" then + dir = "/" + end + return dir +end + +local function maxResults() + return math.max(10, math.min(200, tonumber(noctalia.getConfig("max_results")) or 50)) +end + +-- Excluded directory names from the setting, split on ',' or ';'. Matching +-- is by basename (find -name), so entries containing '/' are skipped and +-- logged. Hidden entries are folded in as an extra '.*' pattern. +local function excludeNames() + local raw = noctalia.getConfig("exclude_dirs") + if type(raw) ~= "string" then + raw = "" + end + local names = {} + for entry in raw:gmatch("[^,;]+") do + local name = trim(entry) + if name:find("/") then + noctalia.log("file-search: ignoring exclude entry with '/': '" .. name .. "'") + elseif name ~= "" then + table.insert(names, name) + end + end + if noctalia.getConfig("show_hidden") ~= true then + table.insert(names, ".*") + end + return names +end + +local function indexKey() + return searchRoot() .. "\n" .. table.concat(excludeNames(), "\n") +end + +-- The cache on disk is current when its fingerprint matches the settings, +-- whether the panel or the launcher built it. +local function cacheFresh(dir) + return noctalia.readFile(dir .. "/index.meta") == indexKey() +end + +-- One cache record, about to be joined to the search root. The cache is a +-- plain user-editable file, so records are untrusted: reject anything that +-- could resolve outside the root. +local function safeRel(rel) + if rel == "" or rel:sub(1, 1) == "/" or rel:find("\n", 1, true) then + return false + end + for part in rel:gmatch("[^/]+") do + if part == ".." then + return false + end + end + return true +end + +buildIndex = function() + if fzfMissing or indexing then + return + end + local dir = dataDir() + if dir == nil then + errMsg = tr("err_index") + render() + return + end + indexing = true + errMsg = nil + local key = indexKey() + + -- Names containing a newline would each forge extra one-per-fragment + -- records (a crafted name can smuggle '..' lines into the index), so + -- they are pruned unconditionally, before the user's exclusions. + local names = { "-name " .. shellQuote("*\n*") } + for _, name in ipairs(excludeNames()) do + table.insert(names, "-name " .. shellQuote(name)) + end + local prune = "\\( " .. table.concat(names, " -o ") .. " \\) -prune -o " + -- %P prints paths relative to the root; the trailing '/' marks + -- directories so rows get the right glyph. find's own exit status is + -- ignored, so permission errors inside the tree don't fail the build. + -- Cache and fingerprint are written to mktemp-created private files and + -- renamed into place: rename replaces a planted symlink at the + -- destination instead of following it. The host guarantees $CACHE_DIR + -- exists (created by pluginDataDir above). + local cmd = cacheSh(dir) + .. '\nTMP=$(mktemp "$CACHE_DIR/index.list.XXXXXX") || exit 1\n' + .. "find " .. shellQuote(searchRoot()) .. " -mindepth 1 " .. prune + .. "-type d -printf '%P/\\n' -o -printf '%P\\n' > \"$TMP\" 2>/dev/null\n" + .. 'mv -f "$TMP" "$CACHE" || exit 1\n' + .. 'TMPM=$(mktemp "$CACHE_DIR/index.meta.XXXXXX") || exit 1\n' + .. "printf '%s' " .. shellQuote(key) .. ' > "$TMPM"\n' + .. 'mv -f "$TMPM" "$META" || exit 1\n' + .. 'wc -l < "$CACHE"' + + render() + local ok = noctalia.runAsync(cmd, function(result) + indexing = false + if result.exitCode == 0 and not result.timedOut then + haveIndex = true + total = tonumber(trim(result.stdout or "")) or 0 + if indexKey() ~= key then + buildIndex() -- settings changed while the walk was running + else + runSearch() + end + else + haveIndex = false + errMsg = tr("err_index") + end + render() + end, 180000) + if not ok then + indexing = false + errMsg = tr("err_spawn") + render() + end +end + +runSearch = function() + if fzfMissing or indexing or searching or not haveIndex then + return + end + local dir = dataDir() + if dir == nil then + return + end + searching = true + local q = query + local limit = maxResults() + local cmd + if trim(q) == "" then + cmd = cacheSh(dir) .. '\nhead -n ' .. limit .. ' "$CACHE" 2>/dev/null' + else + -- head closes the pipe early; the pipeline status stays head's (0). + cmd = cacheSh(dir) .. "\nfzf --filter=" .. shellQuote(q) + .. ' < "$CACHE" 2>/dev/null | head -n ' .. limit + end + local ok = noctalia.runAsync(cmd, function(result) + searching = false + if not result.timedOut then + results = {} + for line in (result.stdout or ""):gmatch("[^\n]+") do + table.insert(results, line) + end + end + -- The query moved on while this search ran: chase it. The stale + -- rows rendered below are overwritten as soon as it completes. + if query ~= q then + runSearch() + end + render() + end, 15000) + if not ok then + searching = false + end +end + +local function openEntry(rel) + if not safeRel(rel) then + noctalia.log("file-search: refusing unsafe index record: " .. rel) + noctalia.notify(tr("title"), tr("err_bad_record")) + return + end + local path = searchRoot() + if path ~= "/" then + path = path .. "/" + end + path = path .. rel:gsub("/+$", "") + noctalia.runAsync("xdg-open " .. shellQuote(path) .. " >/dev/null 2>&1") + panel.close() +end + +local function resultRow(rel, index) + local isDir = rel:sub(-1) == "/" + return ui.button({ + key = "hit-" .. index, + glyph = isDir and "folder" or "file", + text = rel, + variant = "ghost", + contentAlign = "start", + onClick = rowCallback("openHit", index, function() + openEntry(rel) + end), + }) +end + +local function statusFooter() + if indexing then + return ui.label({ text = tr("status_indexing", { path = searchRoot() }), fontSize = 11, color = "secondary" }) + end + local shown = #results + return ui.label({ + text = tr("counts", { shown = shown, total = total or 0 }), + fontSize = 11, + color = "on_surface_variant", + }) +end + +render = function() + local children = { + ui.row({ gap = 6, align = "center" }, { + ui.label({ + text = tr("title"), + fontSize = 16, + fontWeight = "bold", + color = "on_surface", + flexGrow = 1, + }), + ui.button({ glyph = "refresh", variant = "ghost", tooltip = tr("tip_refresh"), onClick = "onRefreshIndex" }), + ui.button({ glyph = "close", variant = "ghost", tooltip = tr("tip_close"), onClick = "onClosePanel" }), + }), + ui.input({ + key = "query-" .. inputRev, + value = query, + focus = true, + placeholder = tr("search_placeholder"), + onChange = "onQueryChanged", + onSubmit = "onOpenFirst", + }), + } + + if fzfMissing then + table.insert(children, ui.label({ text = tr("err_no_fzf"), color = "error" })) + elseif errMsg ~= nil then + table.insert(children, ui.label({ text = errMsg, color = "error" })) + else + if #results == 0 and not indexing and trim(query) ~= "" then + table.insert(children, ui.label({ + text = tr("no_results", { query = query }), + color = "on_surface_variant", + flexGrow = 1, + })) + else + local rows = {} + for index, rel in ipairs(results) do + table.insert(rows, resultRow(rel, index)) + end + table.insert(children, ui.scroll({ flexGrow = 1, gap = 2 }, rows)) + end + table.insert(children, statusFooter()) + end + + panel.render(ui.column({ flexGrow = 1, gap = 12, align = "stretch" }, children)) +end + +function onOpen(_context) + fzfMissing = not noctalia.commandExists("fzf") + query = "" + results = {} + inputRev += 1 + noctalia.state.set("file_search_open", true) + if not fzfMissing then + local dir = dataDir() + if dir == nil then + errMsg = tr("err_index") + else + haveIndex = cacheFresh(dir) + if not haveIndex then + buildIndex() + else + runSearch() + end + end + end + render() +end + +function onClose() + noctalia.state.set("file_search_open", false) +end + +function onConfigChanged() + if fzfMissing or indexing then + return + end + local dir = dataDir() + if dir == nil then + return + end + haveIndex = cacheFresh(dir) + if not haveIndex then + buildIndex() + else + runSearch() + end +end + +function onQueryChanged(value) + query = value + runSearch() +end + +function onOpenFirst(value) + query = value + if results[1] ~= nil then + openEntry(results[1]) + end +end + +function onRefreshIndex() + haveIndex = false + buildIndex() +end + +function onClosePanel() + panel.close() +end diff --git a/file-search/plugin.toml b/file-search/plugin.toml new file mode 100644 index 0000000..1d690c6 --- /dev/null +++ b/file-search/plugin.toml @@ -0,0 +1,78 @@ +# File Search — fuzzy file & folder search from the bar, powered by fzf. +# The bar glyph toggles a search panel: the search folder is indexed with +# `find` (honoring the excluded directories), every keystroke is matched +# through `fzf --filter`, and picking a result opens it with the system +# MIME association (xdg-open). + +id = "nightwatch75/file-search" +name = "File Search" +version = "0.0.9" +plugin_api = 3 +author = "nightwatch75" +license = "MIT" +# The exact commands the plugin spawns (fzf aside, findutils + coreutils + +# xdg-utils on any Linux desktop). +dependencies = ["fzf", "find", "mktemp", "mv", "wc", "head", "rm", "xdg-open"] +tags = ["bar", "launcher", "panel", "utility", "productivity"] +icon = "search" +description = "Search files and folders as you type, fuzzy-matched with fzf; open results with the system MIME association." + +# Plugin-level settings: shared by the bar widget (tooltip, folder actions) +# and the panel (index + search). + +[[setting]] +key = "search_folder" +type = "folder" +label_key = "settings.search_folder.label" +description_key = "settings.search_folder.description" + +[[setting]] +key = "exclude_dirs" +type = "string" +label_key = "settings.exclude_dirs.label" +description_key = "settings.exclude_dirs.description" +default = ".git, node_modules, .cache, .venv" + +[[setting]] +key = "show_hidden" +type = "bool" +label_key = "settings.show_hidden.label" +description_key = "settings.show_hidden.description" +default = false + +[[setting]] +key = "max_results" +type = "int" +label_key = "settings.max_results.label" +description_key = "settings.max_results.description" +default = 50 +min = 10 +max = 200 + +# Keyboard-first flow: the noctalia launcher provides native arrows + Enter +# navigation, which plugin panels cannot receive from the current Luau API. +[[launcher_provider]] +id = "launcher" +entry = "launcher.luau" +prefix = "fs" +glyph = "search" +include_in_global_search = false + +[[panel]] +id = "panel" +entry = "panel.luau" +width = 520 +height = 480 +placement = "attached" +open_near_click = true + +[[widget]] +id = "file-search" +entry = "file-search.luau" + + [[widget.setting]] + key = "glyph" + type = "glyph" + label_key = "settings.glyph.label" + description_key = "settings.glyph.description" + default = "search" diff --git a/file-search/thumbnail.webp b/file-search/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..5cd5a93e1f5f5b095048e1056db24860ee64730d GIT binary patch literal 57884 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 literal 0 HcmV?d00001 diff --git a/dropwall/translations/en.json b/dropwall/translations/en.json new file mode 100644 index 0000000..18025db --- /dev/null +++ b/dropwall/translations/en.json @@ -0,0 +1,27 @@ +{ + "title": "DropWall", + "settings.per_monitor.label": "Per-monitor drop", + "settings.per_monitor.description": "Set the wallpaper only on the monitor the image was dropped on. When off, apply it to every output.", + "settings.copy_to_wallpaper_dir.label": "Copy into wallpaper directory", + "settings.copy_to_wallpaper_dir.description": "Copy the dropped image into the system wallpaper directory before applying. Existing files are never replaced; a numeric suffix is added when needed.", + "settings.notify_on_set.label": "Notify on set", + "settings.notify_on_set.description": "Show a notification when a dropped image is applied.", + "settings.layer.label": "Drop surface layer", + "settings.layer.description": "Layer-shell layer for the invisible drop surface. \"Background\" is the least intrusive; use \"Bottom\" if drops don't register.", + "settings.layer.options.background": "Background", + "settings.layer.options.bottom": "Bottom", + "notify.set_title": "Wallpaper set", + "notify.invalid_title": "Not an image (jpg, png, webp, bmp, gif)", + "notify.missing_title": "Dropped file not found", + "notify.output_error_title": "Could not identify the target monitor", + "notify.helper_error_title": "DropWall helper error", + "notify.python_missing": "python3 is not available on PATH.", + "notify.plugin_dir_missing": "Noctalia did not provide the plugin directory.", + "notify.helper_file_missing": "The DropWall supervisor file is missing.", + "notify.helper_start_failed": "Noctalia could not open the helper stream.", + "notify.helper_busy": "Another DropWall helper is still running. The plugin will keep retrying.", + "notify.no_outputs": "The helper could not create a drop target for any output.", + "notify.copy_dir_title": "Wallpaper was not copied", + "notify.copy_dir_missing": "No wallpaper directory is configured; the original file will be used.", + "notify.copy_failed": "The safe copy failed; the original file will be used." +} From 0c87f534ba421f00b9fb006081f29493cace832b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 17 Jul 2026 22:33:36 +0000 Subject: [PATCH 19/34] chore: update plugin catalog [skip ci] --- catalog.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/catalog.toml b/catalog.toml index 225754a..817ab85 100644 --- a/catalog.toml +++ b/catalog.toml @@ -206,3 +206,14 @@ icon = "music" description = "Synchronized lyrics with karaoke highlighting, animated transitions, and flexible lyric sources." plugin_api = 3 tags = ["bar", "service", "music", "media", "animation"] + +[[plugin]] +id = "whyoolw/dropwall" +name = "DropWall" +version = "1.0.0" +author = "whyoolw" +license = "MIT" +icon = "image" +description = "Drag and drop an image onto the desktop to set it as wallpaper using Noctalia's wallpaper settings." +plugin_api = 3 +tags = ["desktop", "wallpaper"] From 203aaef232cb47ba37c9b32af82f27225ea1916e Mon Sep 17 00:00:00 2001 From: nightwatch75 <30896720+nightwatch75@users.noreply.github.com> Date: Sat, 18 Jul 2026 01:54:05 +0200 Subject: [PATCH 20/34] Update nightwatch75/file-search to 0.0.10 (#39) Co-authored-by: nightwatch75 Co-authored-by: Claude Fable 5 --- file-search/launcher.luau | 10 +++++++++- file-search/plugin.toml | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/file-search/launcher.luau b/file-search/launcher.luau index cb591dd..f73e88a 100644 --- a/file-search/launcher.luau +++ b/file-search/launcher.luau @@ -155,7 +155,15 @@ local function buildIndex(query) local queued = pendingQuery pendingQuery = nil if result.exitCode == 0 and not result.timedOut then - runQuery(queued or query) + if indexKey() ~= key then + -- Settings changed while the walk was running: the cache + -- holds paths relative to the old root, and activation + -- would join them to the new one. Rebuild instead of + -- searching stale records (mirrors the panel). + buildIndex(queued or query) + else + runQuery(queued or query) + end else launcher.setResults(queued or query, { noopRow("err_index") }) end diff --git a/file-search/plugin.toml b/file-search/plugin.toml index 1d690c6..f887d12 100644 --- a/file-search/plugin.toml +++ b/file-search/plugin.toml @@ -6,7 +6,7 @@ id = "nightwatch75/file-search" name = "File Search" -version = "0.0.9" +version = "0.0.10" plugin_api = 3 author = "nightwatch75" license = "MIT" From 54ac3ed0d699a6947fb2622f21e191022879749b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 17 Jul 2026 23:54:13 +0000 Subject: [PATCH 21/34] chore: update plugin catalog [skip ci] --- catalog.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog.toml b/catalog.toml index 817ab85..6212781 100644 --- a/catalog.toml +++ b/catalog.toml @@ -188,7 +188,7 @@ tags = ["audio", "bar", "recording", "utility"] [[plugin]] id = "nightwatch75/file-search" name = "File Search" -version = "0.0.9" +version = "0.0.10" author = "nightwatch75" license = "MIT" icon = "search" From d80bdf0190f5583ec37e37d10d426500dfdb658e Mon Sep 17 00:00:00 2001 From: rrzt <124551348+h465855hgg@users.noreply.github.com> Date: Sat, 18 Jul 2026 07:55:31 +0800 Subject: [PATCH 22/34] feat(lyrics): improve player and interlude controls (#42) * feat(lyrics): support multiple MPRIS players * feat(lyrics): add interlude font options --- lyrics/README.md | 15 ++- lyrics/lyrics.luau | 23 ++++- lyrics/lyrics_service.luau | 198 +++++++++++++++++++++++++++--------- lyrics/plugin.toml | 41 +++++++- lyrics/translations/en.json | 22 +++- 5 files changed, 240 insertions(+), 59 deletions(-) diff --git a/lyrics/README.md b/lyrics/README.md index 86ce6e7..faf4729 100644 --- a/lyrics/README.md +++ b/lyrics/README.md @@ -33,6 +33,11 @@ settings. The background `service` detects the active MPRIS player, resolves lyrics, downloads or caches album artwork, and publishes playback state to the widget. +When several players are available, the service prefers a playing player, then +a paused player, and keeps the current player when priorities are equal. The +optional allowlist and blocklist match player names or instances and support +`*` wildcards. + Left-click the widget to switch between lyrics and track information. Right-click to pause or resume the active player. Paused content is dimmed and all lyric, transition, and marquee animation stops until playback resumes. @@ -55,22 +60,26 @@ Plugin settings: | Setting | Type | Default | Description | | --- | --- | --- | --- | +| `player_allowlist` | `string_list` | empty | Only uses matching MPRIS player names or instances; supports `*` wildcards. | +| `player_blocklist` | `string_list` | empty | Ignores matching MPRIS player names or instances; takes priority over the allowlist. | | `lyrics_source` | `select` | `auto` | Selects automatic fallback, LRCLIB, public NetEase, MPRIS text, custom HTTP, or external IPC. | | `custom_url` | `string` | empty | HTTP URL template with `{title}`, `{artist}`, `{album}`, and `{duration}` placeholders. | | `custom_json_field` | `string` | `syncedLyrics` | Dotted field path containing an LRC string or timed-lines array in a JSON response. | | `cue_text` | `string` | `•••••` | Characters highlighted through long intro or instrumental gaps. | +| `cue_font_mode` | `select` | `follow` | Follows Noctalia's interface font or uses a custom installed font for intro/interlude characters. | +| `cue_font_family` | `string` | `sans-serif` | Installed font family used for intro/interlude characters in custom-font mode. | | `scroll_mode` | `select` | `auto` | Enables automatic marquee, forced marquee, or static truncation. | | `marquee_speed` | `int` | `30` | Approximate long-line scroll speed in logical pixels per second. | | `max_lines` | `int` | `1` | Number of lines shown on a vertical bar, from 1 to 3. | | `gradient` | `bool` | `true` | Enables progressive per-character highlighting. | | `animation` | `select` | `karaoke` | Chooses karaoke, cascade, wave, fade-only, or no line transition. | -| `max_chars` | `int` | `24` | Number of visible Unicode characters before marquee scrolling starts. | +| `max_chars` | `int` | `15` | Number of visible Unicode characters before marquee scrolling starts. | | `char_width` | `int` | `9` | Estimated logical-pixel character width used for scroll timing and minimum layout width. | | `glyph` | `glyph` | `music` | Fallback icon shown when album artwork is unavailable. | | `show_artist` | `bool` | `true` | Includes the artist in track-information mode. | | `hide_when_paused` | `bool` | `false` | Hides the widget instead of dimming it while paused. | | `show_cover` | `bool` | `true` | Shows circular album artwork beside the lyrics. | -| `active_color` | `color` | `primary` | Colors the current and already-sung lyric characters. | +| `active_color` | `color` | `on_surface` | Colors the current and already-sung lyric characters. | | `inactive_color` | `color` | `on_surface_variant` | Colors upcoming lyrics, paused playback, and secondary lines. | ## IPC @@ -102,7 +111,7 @@ Automatic mode requests LRCLIB first, then the public NetEase Music API. Custom HTTP mode contacts only the configured endpoint. The plugin never reads browser cookies or player credentials. -The service runs `playerctl` to read and control MPRIS playback, `python3` for the +The service runs `playerctl` to select, read, and control MPRIS playback, `python3` for the LRCLIB helper and dynamic-lyric parser, and `cp` to preserve temporary local cover files. Public NetEase requests use Noctalia's HTTP API. Query scratch files and downloaded cover images are written inside the plugin runtime directory. Remote diff --git a/lyrics/lyrics.luau b/lyrics/lyrics.luau index c352031..6458607 100644 --- a/lyrics/lyrics.luau +++ b/lyrics/lyrics.luau @@ -8,20 +8,23 @@ local showArtist = noctalia.getConfig("show_artist") local hideWhenPaused = noctalia.getConfig("hide_when_paused") local showCover = noctalia.getConfig("show_cover") if showCover == nil then showCover = true end -local activeColor = noctalia.getConfig("active_color") or "primary" +local activeColor = noctalia.getConfig("active_color") or "on_surface" local inactiveColor = noctalia.getConfig("inactive_color") or "on_surface_variant" -- These are plugin settings, not per-widget settings. local scrollMode = noctalia.getConfig("scroll_mode") or "auto" local marqueeSpeed = tonumber(noctalia.getConfig("marquee_speed")) or 30 local maxLines = tonumber(noctalia.getConfig("max_lines")) or 1 -local maxChars = tonumber(noctalia.getConfig("max_chars")) or 24 +local maxChars = tonumber(noctalia.getConfig("max_chars")) or 15 local charWidth = tonumber(noctalia.getConfig("char_width")) or 9 local gradientOn = noctalia.getConfig("gradient") if gradientOn == nil then gradientOn = true end local animation = noctalia.getConfig("animation") or "karaoke" local cueText = noctalia.getConfig("cue_text") or "•••••" if cueText == "" then cueText = "•••••" end +local cueFontMode = noctalia.getConfig("cue_font_mode") or "follow" +local cueFontFamily = noctalia.getConfig("cue_font_family") or "sans-serif" +if cueFontFamily == "" then cueFontFamily = "sans-serif" end local track = nil local lyrics = nil @@ -29,6 +32,7 @@ local cover = nil local playing = false local showMode = "auto" local rendered = false +local playerInstance = "" local baselinePosition = 0 local baselineClock = os.clock() @@ -48,6 +52,10 @@ local INTERLUDE_GAP_MS = 7000 local INTRO_MIN_MS = 6000 local INTERLUDE_MIN_MS = 8000 +local function shellQuote(value) + return "'" .. tostring(value):gsub("'", "'\\''") .. "'" +end + local function clamp(value, low, high) return math.min(high, math.max(low, value)) end @@ -91,7 +99,7 @@ local function getLineInfo() return { key = "intro", index = 0, - line = { text = cueText }, + line = { text = cueText, cue = true }, progress = clamp(position / firstTime, 0, 1), synced = true, position = position, @@ -130,7 +138,7 @@ local function getLineInfo() return { key = "interlude-" .. tostring(index), index = index, - line = { text = cueText }, + line = { text = cueText, cue = true }, progress = clamp((position - lineEnd) / (nextTime - lineEnd), 0, 1), synced = true, position = position, @@ -221,6 +229,7 @@ local function buildLineRow(line, opts) opts = opts or {} local text = type(line) == "table" and line.text or line local times = type(line) == "table" and line.chars or nil + local isCue = opts.cue or (type(line) == "table" and line.cue == true) local chars = toChars(text or "") if #chars == 0 then chars = { " " } end @@ -273,6 +282,7 @@ local function buildLineRow(line, opts) color = color, opacity = alpha, maxLines = 1, + fontFamily = isCue and cueFontMode == "custom" and cueFontFamily or nil, }) end @@ -344,6 +354,7 @@ local function render() cascade = shownLine == info.line and animation == "cascade", wave = shownLine == info.line and animation == "wave", opacity = opacity, + cue = shownLine == info.line and info.cue == true, }) end @@ -391,7 +402,8 @@ function onClick() end function onRightClick() - noctalia.runAsync("playerctl play-pause", function(result) + if playerInstance == "" then return end + noctalia.runAsync("playerctl --player " .. shellQuote(playerInstance) .. " play-pause", function(result) if result.exitCode == 0 then local wasPlaying = playing if wasPlaying then baselinePosition = getProgressMs() * 1000 end @@ -412,6 +424,7 @@ function update() lyrics = noctalia.state.get("lyrics") cover = noctalia.state.get("cover") playing = noctalia.state.get("playing") == true + playerInstance = noctalia.state.get("player_instance") or "" local info = getLineInfo() local nextKey = info and info.key or "fallback" diff --git a/lyrics/lyrics_service.luau b/lyrics/lyrics_service.luau index 119add0..4953c47 100644 --- a/lyrics/lyrics_service.luau +++ b/lyrics/lyrics_service.luau @@ -10,16 +10,85 @@ local coverCache = {} local lastTrackKey = "" local inFlight = nil local coverInFlight = nil -local krcTmp = (noctalia.pluginDir() or "/tmp") .. "/.krc_cache.tmp" +local pluginDir = noctalia.pluginDir() or "/tmp" +local cacheDir = pluginDir .. "/.cache" +noctalia.mkdirAll(cacheDir) +local krcTmp = cacheDir .. "/krc.tmp" local lyricsSource = noctalia.getConfig("lyrics_source") or "auto" local customUrl = noctalia.getConfig("custom_url") or "" local customJsonField = noctalia.getConfig("custom_json_field") or "syncedLyrics" local currentTrack = nil local currentEmbeddedLyrics = "" +local currentPlayerInstance = "" + +local function normalizePatterns(value) + if type(value) ~= "table" then return {} end + local patterns = {} + for _, pattern in ipairs(value) do + pattern = tostring(pattern):lower():gsub("^%s+", ""):gsub("%s+$", "") + if pattern ~= "" then patterns[#patterns + 1] = pattern end + end + table.sort(patterns) + return patterns +end + +local playerAllowlist = normalizePatterns(noctalia.getConfig("player_allowlist")) +local playerBlocklist = normalizePatterns(noctalia.getConfig("player_blocklist")) + +local function trackKey(track) + return (track.playerInstance or "") .. "|" .. track.title .. "|" .. track.artist .. "|" .. track.album +end + +local function patternMatches(value, pattern) + local luaPattern = "^" .. pattern:gsub("([%%%^%$%(%)%.%[%]%+%-%?])", "%%%1"):gsub("%*", ".*") .. "$" + return value:lower():match(luaPattern) ~= nil +end + +local function matchesAny(player, patterns) + for _, pattern in ipairs(patterns) do + if patternMatches(player.name, pattern) or patternMatches(player.instance, pattern) then return true end + end + return false +end + +local function playerAllowed(player) + if #playerAllowlist > 0 and not matchesAny(player, playerAllowlist) then return false end + return not matchesAny(player, playerBlocklist) +end + +local function selectPlayer(players) + local best = nil + local bestRank = -1 + for _, player in ipairs(players) do + if playerAllowed(player) then + local rank = player.status == "playing" and 2 or (player.status == "paused" and 1 or 0) + if rank > bestRank or (rank == bestRank and player.instance == currentPlayerInstance) then + best = player + bestRank = rank + end + end + end + return best +end + +local function clearPlayerState() + currentPlayerInstance = "" + currentTrack = nil + currentEmbeddedLyrics = "" + lastTrackKey = "" + inFlight = nil + coverInFlight = nil + noctalia.state.set("player_instance", nil) + noctalia.state.set("player_name", nil) + noctalia.state.set("track", nil) + noctalia.state.set("lyrics", nil) + noctalia.state.set("cover", nil) + noctalia.state.set("playing", false) +end local function coverPathFor(track) local safe = (track.artist .. "_" .. track.album .. "_" .. track.title):gsub("[^%w]+", "_") - return noctalia.pluginDir() .. "/cover_" .. safe .. ".jpg" + return cacheDir .. "/cover_" .. safe .. ".jpg" end local function shellQuote(value) @@ -75,16 +144,15 @@ local function evictCache() end local function fetchLyricsNetEase(track, embeddedLyrics) - if inFlight then return end - inFlight = track - - local tk = track.title .. "|" .. track.artist .. "|" .. track.album + local tk = trackKey(track) + if inFlight == tk then return end + inFlight = tk local function tryFetch(query, fallback) local searchUrl = "https://music.163.com/api/search/get?type=1&s=" .. noctalia.string.urlEncode(query) .. "&limit=5" noctalia.http({ url = searchUrl, headers = { "Referer: https://music.163.com" } }, function(r1) - if not inFlight then return end + if inFlight ~= tk then return end if tk ~= lastTrackKey then inFlight = nil; return end if not r1.ok or r1.status < 200 or r1.status >= 300 or not r1.body or #r1.body == 0 then @@ -128,7 +196,7 @@ local function fetchLyricsNetEase(track, embeddedLyrics) local lyricUrl = "https://music.163.com/api/song/lyric?id=" .. noctalia.string.urlEncode(songId) .. "&lv=1&kv=1&tv=-1" noctalia.http({ url = lyricUrl, headers = { "Referer: https://music.163.com" } }, function(r2) - if not inFlight then return end + if inFlight ~= tk then return end if tk ~= lastTrackKey then inFlight = nil; return end local lyrics = nil @@ -150,7 +218,7 @@ local function fetchLyricsNetEase(track, embeddedLyrics) if klyricStr ~= "" then local py = 'python3 "' .. noctalia.pluginDir() .. '/krc_decode.py" "' .. krcTmp .. '"' noctalia.runAsync(py, function(r3) - if not inFlight then return end + if inFlight ~= tk then return end if tk ~= lastTrackKey then inFlight = nil; return end local ok, parsed = pcall(noctalia.json.decode, r3.stdout or "") if ok and parsed and parsed.type == "krc" and parsed.lines then @@ -201,7 +269,7 @@ local function fetchLyricsNetEase(track, embeddedLyrics) end local query = track.title .. "\n" .. track.artist .. "\n" .. (track.album or "") - local qTmp = (noctalia.pluginDir() or "/tmp") .. "/.query_cache.tmp" + local qTmp = cacheDir .. "/query.tmp" noctalia.writeFile(qTmp, query) local dir = noctalia.pluginDir() or "/tmp" @@ -228,7 +296,7 @@ local function fetchLyricsNetEase(track, embeddedLyrics) local function runPy(script, cb) local py = 'python3 "' .. dir .. "/" .. script .. '" "' .. qTmp .. '"' noctalia.runAsync(py, function(r) - if not inFlight then return end + if inFlight ~= tk then return end if tk ~= lastTrackKey then inFlight = nil; return end local ok, parsed = pcall(noctalia.json.decode, r.stdout or "") cb(ok and parsed or nil) @@ -317,13 +385,14 @@ local function fetchLyricsNetEase(track, embeddedLyrics) end local function fetchCover(track, artUrl) - if coverInFlight then return end - coverInFlight = track.title .. "|" .. track.artist .. "|" .. track.album + local tk = trackKey(track) + if coverInFlight == tk then return end + coverInFlight = tk local dest = coverPathFor(track) local apply = function(path) - local tk = track.title .. "|" .. track.artist .. "|" .. track.album + if coverInFlight ~= tk then return end coverInFlight = nil if tk ~= lastTrackKey then return end coverCache[tk] = path @@ -354,50 +423,69 @@ local function fetchCover(track, artUrl) end local function poll() - local cmd = [[playerctl metadata --format $'{{lc(status)}}\x1f{{title}}\x1f{{artist}}\x1f{{album}}\x1f{{position}}\x1f{{mpris:length}}\x1f{{mpris:artUrl}}\x1f{{xesam:asText}}' 2>/dev/null]] + local cmd = [[playerctl --all-players metadata --format $'{{playerInstance}}\x1f{{playerName}}\x1f{{lc(status)}}\x1f{{title}}\x1f{{artist}}\x1f{{album}}\x1f{{position}}\x1f{{mpris:length}}\x1f{{mpris:artUrl}}\x1f{{xesam:asText}}\x1e' 2>/dev/null]] noctalia.runAsync(cmd, function(r) if r.exitCode ~= 0 or not r.stdout or r.stdout == "" then - noctalia.state.set("track", nil) - noctalia.state.set("lyrics", nil) - noctalia.state.set("cover", nil) - noctalia.state.set("playing", false) + clearPlayerState() return end - local parts = {} - local separator = string.char(31) - for field in (r.stdout .. separator):gmatch("(.-)" .. separator) do - parts[#parts + 1] = field:gsub("^%s+", ""):gsub("%s+$", "") + local players = {} + local fieldSeparator = string.char(31) + local recordSeparator = string.char(30) + for record in (r.stdout .. recordSeparator):gmatch("(.-)" .. recordSeparator) do + if record ~= "" then + local parts = {} + for field in (record .. fieldSeparator):gmatch("(.-)" .. fieldSeparator) do + parts[#parts + 1] = field:gsub("^%s+", ""):gsub("%s+$", "") + end + local player = { + instance = parts[1] or "", + name = parts[2] or "", + status = parts[3] or "stopped", + title = parts[4] or "", + artist = parts[5] or "", + album = parts[6] or "", + position = tonumber(parts[7]) or 0, + duration = tonumber(parts[8]) or 0, + artUrl = parts[9] or "", + embeddedLyrics = parts[10] or "", + } + if player.instance ~= "" or player.name ~= "" then players[#players + 1] = player end + end end - local status = parts[1] or "stopped" - local title = parts[2] or "" - local artist = parts[3] or "" - local album = parts[4] or "" - local artUrl = parts[7] or "" - local embeddedLyrics = parts[8] or "" - - if title == "" and artist == "" then - noctalia.state.set("track", nil) - noctalia.state.set("lyrics", nil) - noctalia.state.set("playing", status == "playing") + local selected = selectPlayer(players) + if not selected then + clearPlayerState() return end - local playing = status == "playing" - local tk = title .. "|" .. artist .. "|" .. album + currentPlayerInstance = selected.instance + noctalia.state.set("player_instance", selected.instance) + noctalia.state.set("player_name", selected.name) + if selected.title == "" and selected.artist == "" then + noctalia.state.set("track", nil) + noctalia.state.set("lyrics", nil) + noctalia.state.set("playing", selected.status == "playing") + return + end + + local playing = selected.status == "playing" local t = { - title = title, - artist = artist, - album = album, - status = status, - position = tonumber(parts[5]) or 0, - duration = tonumber(parts[6]) or 0, + title = selected.title, + artist = selected.artist, + album = selected.album, + status = selected.status, + position = selected.position, + duration = selected.duration, + playerInstance = selected.instance, } + local tk = trackKey(t) currentTrack = t - currentEmbeddedLyrics = embeddedLyrics + currentEmbeddedLyrics = selected.embeddedLyrics noctalia.state.set("position", t.position) @@ -411,7 +499,7 @@ local function poll() noctalia.state.set("lyrics", cached) else noctalia.state.set("lyrics", nil) - fetchLyricsNetEase(t, embeddedLyrics) + fetchLyricsNetEase(t, selected.embeddedLyrics) end local cachedCover = coverCache[tk] @@ -419,7 +507,7 @@ local function poll() noctalia.state.set("cover", cachedCover) else noctalia.state.set("cover", nil) - fetchCover(t, artUrl) + fetchCover(t, selected.artUrl) end else noctalia.state.set("track", t) @@ -443,11 +531,22 @@ function onConfigChanged() local nextSource = noctalia.getConfig("lyrics_source") or "auto" local nextUrl = noctalia.getConfig("custom_url") or "" local nextField = noctalia.getConfig("custom_json_field") or "syncedLyrics" + local nextAllowlist = normalizePatterns(noctalia.getConfig("player_allowlist")) + local nextBlocklist = normalizePatterns(noctalia.getConfig("player_blocklist")) local sourceChanged = nextSource ~= lyricsSource or nextUrl ~= customUrl or nextField ~= customJsonField + local playersChanged = table.concat(nextAllowlist, "\n") ~= table.concat(playerAllowlist, "\n") + or table.concat(nextBlocklist, "\n") ~= table.concat(playerBlocklist, "\n") lyricsSource = nextSource customUrl = nextUrl customJsonField = nextField - if sourceChanged and currentTrack then + playerAllowlist = nextAllowlist + playerBlocklist = nextBlocklist + if playersChanged then + currentPlayerInstance = "" + inFlight = nil + poll() + end + if sourceChanged and currentTrack and not playersChanged then inFlight = nil cache = {} noctalia.state.set("lyrics", nil) @@ -460,7 +559,12 @@ local function applyPushedLyrics(payload) if type(decoded) == "table" then if decoded.track then currentTrack = decoded.track - lastTrackKey = (decoded.track.title or "") .. "|" .. (decoded.track.artist or "") .. "|" .. (decoded.track.album or "") + lastTrackKey = trackKey({ + playerInstance = decoded.track.playerInstance or "", + title = decoded.track.title or "", + artist = decoded.track.artist or "", + album = decoded.track.album or "", + }) noctalia.state.set("track", decoded.track) end if decoded.lines then noctalia.state.set("lyrics", decoded.lines) end diff --git a/lyrics/plugin.toml b/lyrics/plugin.toml index 6f7837b..ec8f2bc 100644 --- a/lyrics/plugin.toml +++ b/lyrics/plugin.toml @@ -1,6 +1,6 @@ id = "h465855hgg/lyrics" name = "Lyrics" -version = "1.1.0" +version = "1.3.0" plugin_api = 3 author = "h465855hgg" license = "MIT" @@ -9,6 +9,22 @@ tags = ["bar", "service", "music", "media", "animation"] icon = "music" description = "Synchronized lyrics with karaoke highlighting, animated transitions, and flexible lyric sources." +[[setting]] +key = "player_allowlist" +type = "string_list" +label_key = "settings.player_allowlist.label" +description_key = "settings.player_allowlist.description" +default = [] +advanced = true + +[[setting]] +key = "player_blocklist" +type = "string_list" +label_key = "settings.player_blocklist.label" +description_key = "settings.player_blocklist.description" +default = [] +advanced = true + [[setting]] key = "lyrics_source" type = "select" @@ -47,6 +63,25 @@ label_key = "settings.cue_text.label" description_key = "settings.cue_text.description" default = "•••••" +[[setting]] +key = "cue_font_mode" +type = "select" +label_key = "settings.cue_font_mode.label" +description_key = "settings.cue_font_mode.description" +default = "follow" +options = [ + { value = "follow", label_key = "settings.cue_font_mode.options.follow" }, + { value = "custom", label_key = "settings.cue_font_mode.options.custom" }, +] + +[[setting]] +key = "cue_font_family" +type = "string" +label_key = "settings.cue_font_family.label" +description_key = "settings.cue_font_family.description" +default = "sans-serif" +visible_when = { key = "cue_font_mode", values = ["custom"] } + [[setting]] key = "scroll_mode" type = "select" @@ -102,7 +137,7 @@ options = [ key = "max_chars" type = "int" label_key = "settings.max_chars.label" -default = 24 +default = 15 min = 8 max = 80 description_key = "settings.max_chars.description" @@ -156,7 +191,7 @@ entry = "lyrics.luau" type = "color" label_key = "settings.active_color.label" description_key = "settings.active_color.description" - default = "primary" + default = "on_surface" [[widget.setting]] key = "inactive_color" diff --git a/lyrics/translations/en.json b/lyrics/translations/en.json index ac28055..ed3f66c 100644 --- a/lyrics/translations/en.json +++ b/lyrics/translations/en.json @@ -4,6 +4,14 @@ "intro": "Intro", "instrumental": "Instrumental", "settings": { + "player_allowlist": { + "label": "Allowed players", + "description": "Only use matching MPRIS player names or instances. Supports * wildcards; leave empty to allow all players." + }, + "player_blocklist": { + "label": "Blocked players", + "description": "Ignore matching MPRIS player names or instances. Supports * wildcards and takes priority over the allowlist." + }, "glyph": { "label": "Glyph" }, @@ -19,7 +27,7 @@ }, "active_color": { "label": "Active lyric color", - "description": "Color used for the current and already-sung lyric characters." + "description": "Color used for the current and already-sung lyric characters. Defaults to the interface text color." }, "inactive_color": { "label": "Inactive lyric color", @@ -49,6 +57,18 @@ "label": "Intro/interlude characters", "description": "Text or characters highlighted during intros and interludes." }, + "cue_font_mode": { + "label": "Intro/interlude font mode", + "description": "Choose whether intro and interlude characters follow Noctalia's interface font or use another installed font.", + "options": { + "follow": "Follow interface font", + "custom": "Custom font" + } + }, + "cue_font_family": { + "label": "Intro/interlude font", + "description": "Installed font family used only for intro and interlude characters in custom-font mode." + }, "scroll_mode": { "label": "Scroll mode", "description": "How lyrics scroll in the bar.", From 3a5c4be1dbd074ec89bf5ed54d71d58dac081e90 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 17 Jul 2026 23:55:40 +0000 Subject: [PATCH 23/34] chore: update plugin catalog [skip ci] --- catalog.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog.toml b/catalog.toml index 6212781..783f5ae 100644 --- a/catalog.toml +++ b/catalog.toml @@ -199,7 +199,7 @@ tags = ["bar", "launcher", "panel", "utility", "productivity"] [[plugin]] id = "h465855hgg/lyrics" name = "Lyrics" -version = "1.1.0" +version = "1.3.0" author = "h465855hgg" license = "MIT" icon = "music" From e720bcbaccd04b7392d0c0fdcdd62e978a638c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Gonz=C3=A1lez=20Gir=C3=B3n?= Date: Fri, 17 Jul 2026 18:11:11 -0600 Subject: [PATCH 24/34] Update gambled23/mangowm-keymode to 1.0.2 --- Hide on default keymode setting (#40) * feat(keymode): Setting to hide on default keymode * docs(keymode): Updated thumbnail with new tags * docs(readme): added new setting --- mangowm-keymode/README.md | 1 + mangowm-keymode/keymode.luau | 14 ++++++++++---- mangowm-keymode/plugin.toml | 8 +++++++- mangowm-keymode/thumbnail.webp | Bin 48220 -> 47890 bytes mangowm-keymode/translations/en.json | 3 ++- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/mangowm-keymode/README.md b/mangowm-keymode/README.md index 43c08f4..2373ee5 100644 --- a/mangowm-keymode/README.md +++ b/mangowm-keymode/README.md @@ -26,3 +26,4 @@ MangoWC changes keymode; click it to show the current keymode in a notification. | --- | --- | --- | --- | | `show_text` | `bool` | `true` | Shows the current keymode beside the widget glyph. | | `notify_change` | `bool` | `true` | Sends a notification when the keymode changes. | +| `hide_on_default` | `bool` | `false` | Hides the widget when default keymode is active. | diff --git a/mangowm-keymode/keymode.luau b/mangowm-keymode/keymode.luau index 8924061..dbac79c 100644 --- a/mangowm-keymode/keymode.luau +++ b/mangowm-keymode/keymode.luau @@ -1,5 +1,6 @@ local showText = noctalia.getConfig("show_text") local notifyChange = noctalia.getConfig("notify_change") +local hideOnDefault = noctalia.getConfig("hide_on_default") local currentKeymode = "default" @@ -17,11 +18,16 @@ end) function update() noctalia.setUpdateInterval(1000) - barWidget.setGlyph("keyboard") - if showText then - barWidget.setText(currentKeymode) + if hideOnDefault and currentKeymode == "default" then + barWidget.setVisible(false) else - barWidget.setText("") + barWidget.setVisible(true) + barWidget.setGlyph("keyboard") + if showText then + barWidget.setText(currentKeymode) + else + barWidget.setText("") + end end end diff --git a/mangowm-keymode/plugin.toml b/mangowm-keymode/plugin.toml index 499db6e..9ce3aa1 100644 --- a/mangowm-keymode/plugin.toml +++ b/mangowm-keymode/plugin.toml @@ -1,6 +1,6 @@ id = "gambled23/mangowm-keymode" name = "Mangowm Keymode" -version = "1.0.1" +version = "1.0.2" plugin_api = 3 author = "gambled23" license = "MIT" @@ -14,6 +14,12 @@ tags = ["bar", "mangowc"] id = "mangowm-keymode" entry = "keymode.luau" + [[widget.setting]] + key = "hide_on_default" + type = "bool" + label_key = "settings.hide_on_default.label" + default = false + [[widget.setting]] key = "show_text" type = "bool" diff --git a/mangowm-keymode/thumbnail.webp b/mangowm-keymode/thumbnail.webp index 890db853f3c0ce4e1d2e224c6a30e74326651d5e..ed0b9785562029266f7f49cfc16dd0c0cc000a9a 100644 GIT binary patch literal 47890 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 Date: Sat, 18 Jul 2026 00:11:20 +0000 Subject: [PATCH 25/34] chore: update plugin catalog [skip ci] --- catalog.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog.toml b/catalog.toml index 783f5ae..4c7751d 100644 --- a/catalog.toml +++ b/catalog.toml @@ -65,7 +65,7 @@ tags = ["launcher"] [[plugin]] id = "gambled23/mangowm-keymode" name = "Mangowm Keymode" -version = "1.0.1" +version = "1.0.2" author = "gambled23" license = "MIT" icon = "keyboard" From dd5d67b1e387c6ef275de16e10e02494f4edd15e Mon Sep 17 00:00:00 2001 From: Cleboost Date: Sat, 18 Jul 2026 02:31:04 +0200 Subject: [PATCH 26/34] Add Zed Provider launcher plugin (#17) * Add Zed Provider launcher plugin. Expose recent Zed workspaces in the launcher so users can reopen projects quickly. * Update Zed Provider thumbnail with launcher screenshot. Use the official Noctalia thumbnail generator export for the plugin card. * Address PR review feedback for Zed Provider. Fix thumbnail category label, refresh project cache when the query is cleared, and use noctalia.fuzzyScore for launcher filtering. * fix(zed-provider): update thumbnail with launcher category label * chore(zed-provider): reset manifest version to 1.0.0 * docs(zed-provider): align README with plugin documentation requirements * fix(zed-provider): replace min_noctalia with plugin_api * Add 'nohup' to plugin dependencies --------- Co-authored-by: Lemmy --- zed-provider/README.md | 38 +++++++++ zed-provider/plugin.toml | 34 ++++++++ zed-provider/thumbnail.webp | Bin 0 -> 33728 bytes zed-provider/translations/en.json | 11 +++ zed-provider/translations/fr.json | 11 +++ zed-provider/zed_provider.luau | 124 ++++++++++++++++++++++++++++++ 6 files changed, 218 insertions(+) create mode 100644 zed-provider/README.md create mode 100644 zed-provider/plugin.toml create mode 100644 zed-provider/thumbnail.webp create mode 100644 zed-provider/translations/en.json create mode 100644 zed-provider/translations/fr.json create mode 100644 zed-provider/zed_provider.luau diff --git a/zed-provider/README.md b/zed-provider/README.md new file mode 100644 index 0000000..eee0ef5 --- /dev/null +++ b/zed-provider/README.md @@ -0,0 +1,38 @@ +# Zed Provider + +![Zed Provider thumbnail](thumbnail.webp) + +Zed Provider integrates recent Zed workspaces with the Noctalia launcher so you +can reopen a project quickly without leaving the shell. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `cleboost/zed-provider` | +| Entry | Launcher provider: `provider` | +| Launcher Prefix | `/zed` | + +## Requirements + +Install [Zed](https://zed.dev) and ensure `zed` is available on `PATH` as +`zeditor`. The `sqlite3` command must also be available to read Zed's workspace +database. + +## Usage + +Open the Noctalia launcher and type `/zed` to list recent local Zed workspaces. +Continue typing to filter projects by name, then select one to open it with +`zeditor`. + +## Settings + +- `db_path` — path to Zed's `db.sqlite` workspace database. +- `max_results` — maximum number of projects shown in the launcher. + +## Notes + +Projects are read from Zed's workspace database, typically at +`~/.local/share/zed/db/0-stable/db.sqlite`. Remote workspaces are excluded. +The list is cached for the launcher session and refreshed when you clear the +query. diff --git a/zed-provider/plugin.toml b/zed-provider/plugin.toml new file mode 100644 index 0000000..a9743f0 --- /dev/null +++ b/zed-provider/plugin.toml @@ -0,0 +1,34 @@ +id = "cleboost/zed-provider" +name = "Zed Provider" +version = "1.0.0" +plugin_api = 3 +author = "cleboost" +license = "MIT" +icon = "folder-open" +description = "Open a recent Zed project from the launcher. Type /zed to list your projects." +tags = ["launcher", "development", "productivity"] +dependencies = ["sqlite3", "zed", "nohup"] + +[[setting]] +key = "db_path" +type = "file" +label_key = "settings.db_path.label" +description_key = "settings.db_path.description" +default = "~/.local/share/zed/db/0-stable/db.sqlite" + +[[setting]] +key = "max_results" +type = "int" +label_key = "settings.max_results.label" +description_key = "settings.max_results.description" +default = 20 +min = 1 +max = 100 + +[[launcher_provider]] +id = "provider" +entry = "zed_provider.luau" +prefix = "zed" +glyph = "bolt" +include_in_global_search = false +debounce_ms = 0 diff --git a/zed-provider/thumbnail.webp b/zed-provider/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..5ccde31d35f35ab6375882c34c768560e9128822 GIT binary patch literal 33728 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 0) and math.floor(n) or 20 +end + +local function trim(s) + return s:match("^%s*(.-)%s*$") +end + +local function projectName(path) + return path:match("([^/]+)$") or path +end + +local function shellQuote(s) + return "'" .. s:gsub("'", "'\"'\"'") .. "'" +end + +local function loadProjects(onDone) + local db = getDbPath() + local limit = getMaxResults() + local sql = string.format( + "SELECT DISTINCT paths FROM workspaces WHERE paths IS NOT NULL AND paths != '' AND remote_connection_id IS NULL ORDER BY timestamp DESC LIMIT %d;", + limit + ) + local cmd = string.format("sqlite3 -separator '\\n' %s %s 2>/dev/null", shellQuote(db), shellQuote(sql)) + + noctalia.runAsync(cmd, function(result) + local projects = {} + if result.exitCode == 0 and type(result.stdout) == "string" then + for line in result.stdout:gmatch("[^\n]+") do + local path = trim(line) + if path ~= "" then + table.insert(projects, path) + end + end + end + cachedProjects = projects + onDone(projects) + end) +end + +local function makeRows(projects, filter) + local home = noctalia.getenv("HOME") or "" + local rows = {} + for _, path in projects do + local name = projectName(path) + local score = filter == "" and 0 or noctalia.fuzzyScore(filter, name) + if score == nil then + score = noctalia.fuzzyScore(filter, path) + end + if filter == "" or score ~= nil then + local display = (home ~= "" and path:sub(1, #home) == home) and "~" .. path:sub(#home + 1) or path + table.insert(rows, { + id = path, + title = name, + subtitle = display, + icon = "zed", + score = filter == "" and nil or score, + }) + end + end + return rows +end + +local function showResults(query, projects, filter) + local rows = makeRows(projects, filter) + if #rows == 0 then + launcher.setResults(query, { + { + id = "", + title = noctalia.tr("no-projects-found"), + subtitle = filter ~= "" and noctalia.tr("filter-empty", { filter = filter }) or noctalia.tr("database-empty"), + glyph = "folder-x", + }, + }) + else + launcher.setResults(query, rows) + end +end + +function onQuery(query) + local filter = trim(query) + + if filter == "" then + cachedProjects = nil + end + + if cachedProjects then + showResults(query, cachedProjects, filter) + return + end + + launcher.setResults(query, { + { + id = "", + title = noctalia.tr("loading"), + subtitle = noctalia.tr("loading-subtitle"), + glyph = "loader", + }, + }) + + loadProjects(function(projects) + showResults(query, projects, filter) + end) +end + +function onActivate(id) + if id == "" then + return + end + noctalia.runAsync(string.format("nohup zeditor %s &>/dev/null &", shellQuote(id))) +end From 1ee9459483c70f505e9bd8ec0e4fd86373c7565b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 18 Jul 2026 00:31:13 +0000 Subject: [PATCH 27/34] chore: update plugin catalog [skip ci] --- catalog.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/catalog.toml b/catalog.toml index 4c7751d..cda2f2f 100644 --- a/catalog.toml +++ b/catalog.toml @@ -217,3 +217,14 @@ icon = "image" description = "Drag and drop an image onto the desktop to set it as wallpaper using Noctalia's wallpaper settings." plugin_api = 3 tags = ["desktop", "wallpaper"] + +[[plugin]] +id = "cleboost/zed-provider" +name = "Zed Provider" +version = "1.0.0" +author = "cleboost" +license = "MIT" +icon = "folder-open" +description = "Open a recent Zed project from the launcher. Type /zed to list your projects." +plugin_api = 3 +tags = ["launcher", "development", "productivity"] From 0133680993181017c176bf902ee982a26d15c8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Atoch?= Date: Sat, 18 Jul 2026 00:00:15 -0400 Subject: [PATCH 28/34] zed: fix validation warning --- zed-provider/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zed-provider/README.md b/zed-provider/README.md index eee0ef5..fd10db2 100644 --- a/zed-provider/README.md +++ b/zed-provider/README.md @@ -17,7 +17,7 @@ can reopen a project quickly without leaving the shell. Install [Zed](https://zed.dev) and ensure `zed` is available on `PATH` as `zeditor`. The `sqlite3` command must also be available to read Zed's workspace -database. +database. `nohup` command is required to launch Zed. ## Usage From 8296ca0f7e7f68be862cb4d7d09507469a5fe1f0 Mon Sep 17 00:00:00 2001 From: Artur Date: Sat, 18 Jul 2026 02:06:27 -0300 Subject: [PATCH 29/34] feat(hassio): Implemented the Home Assistant plugin for Noctalia v5. (#31) * feat(hassio): Implemented the Home Assistant plugin for Noctalia v5. * Update plugin.toml * Update plugin.toml * fix(*): Changed curl HTTP calls to native noctalia HTTP calls. * fix(*): Fixed headers on HTTP requests. * fix(service_sse): Fixed HA tokens visible on argv during streams. * fix(service_sse): Added an explicit exit signal for the stream and refresh/reload_entities no longer force `sseActive = false`. * fix(*): Fixed xdg-open missing from README.md and plugin.toml * refact(widget): Changed runInTerminal to runAsync on xdg-open calls to prevent the termial from popping up. * fix(*): Changed plugin data location to be stored where pluginDataDir() points. * fix(README): Added all IPC calls to README. * Updated README to reflect recent changes. * refact(*): Removed some dead code. * fix(*): Changed toggle timeout logic to use real time, fixing toggles being stuck in a loding animation. * refact(*): Added a token cleaner function. * refact(service_sse): Changed curl stream calls for the new native HTTP streaming API. * feat(*): Fixed some translations. --- hassio/README.md | 77 ++++ hassio/panel.luau | 634 +++++++++++++++++++++++++++++++++ hassio/plugin.toml | 95 +++++ hassio/service_sse.luau | 428 ++++++++++++++++++++++ hassio/shortcut.luau | 144 ++++++++ hassio/shortcut_2.luau | 144 ++++++++ hassio/shortcut_3.luau | 144 ++++++++ hassio/shortcut_4.luau | 144 ++++++++ hassio/shortcut_panel.luau | 10 + hassio/thumbnail.webp | Bin 0 -> 48548 bytes hassio/translations/en.json | 63 ++++ hassio/translations/pt-BR.json | 63 ++++ hassio/widget.luau | 96 +++++ 13 files changed, 2042 insertions(+) create mode 100644 hassio/README.md create mode 100644 hassio/panel.luau create mode 100644 hassio/plugin.toml create mode 100644 hassio/service_sse.luau create mode 100644 hassio/shortcut.luau create mode 100644 hassio/shortcut_2.luau create mode 100644 hassio/shortcut_3.luau create mode 100644 hassio/shortcut_4.luau create mode 100644 hassio/shortcut_panel.luau create mode 100644 hassio/thumbnail.webp create mode 100644 hassio/translations/en.json create mode 100644 hassio/translations/pt-BR.json create mode 100644 hassio/widget.luau diff --git a/hassio/README.md b/hassio/README.md new file mode 100644 index 0000000..58e8714 --- /dev/null +++ b/hassio/README.md @@ -0,0 +1,77 @@ +# Home Assistant + +Monitor and control your Home Assistant entities from the Noctalia bar and control center. Useful for quickly toggling lights, checking sensor states, and opening a full entity manager panel for richer controls. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `pozzoo/hassio` | +| Entries | Widget: `status`; Service: `connection`; Shortcuts: `ha_toggle_1`, `ha_toggle_2`, `ha_toggle_3`, `ha_toggle_4`, `ha_panel`; Panel: `entity_manager` | +| Launcher Prefix | — | + +## Requirements + +- A running Home Assistant instance with API access enabled +- A Long-lived Access Token (Profile → Security → Long-lived access tokens) +- `xdg-open` available on `PATH` (used to open the Home Assistant URL in your browser) + +## Usage + +1. Configure the plugin: open **Settings → Plugins → Home Assistant** and set: + + | Setting | Description | + | --- | --- | + | Home Assistant URL | The URL to your HA instance, for example `http://homeassistant.local:8123` | + | Long-Lived Access Token | Token created in HA under Profile → Security | + | Quick Toggle 1–4 — Entity ID | (Optional) Entity IDs to assign to each quick-toggle tile (e.g. `light.living_room`) | + +2. Add the bar widget: add the **status** widget from the widget picker to show connection state and (optionally) the number of monitored entities. Right-click the widget to open your Home Assistant URL in the default browser. + +3. Add control-center tiles: go to **Settings → Control Center** and add any combination of: + - **Home Assistant** (×4) — Quick-toggle tiles. Each corresponds to one of the four entity slots configured in plugin settings. + - **Home Assistant** (panel opener) — Opens the entity manager panel. + +4. Open the entity manager panel: use the panel opener tile or the panel IPC command to open the full browser and pin entities for monitoring. + +```sh +noctalia msg panel-toggle pozzoo/hassio:entity_manager +``` + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `ha_url` | `string` | `""` | Home Assistant base URL used for API requests (include protocol and port if needed). | +| `ha_token` | `string` | `""` | Long-lived access token for Home Assistant. Keep this secret. | +| `shortcut_entity_1` | `string` | `""` | Entity ID used by Quick Toggle 1 (e.g. `light.kitchen`). | +| `shortcut_entity_2` | `string` | `""` | Entity ID used by Quick Toggle 2. | +| `shortcut_entity_3` | `string` | `""` | Entity ID used by Quick Toggle 3. | +| `shortcut_entity_4` | `string` | `""` | Entity ID used by Quick Toggle 4. | +| `show_entity_count` | `bool` | `false` | Show the number of monitored entities next to the connection status in the `status` bar widget. | + +## IPC + +- Open the panel: + +```sh +noctalia msg panel-toggle pozzoo/hassio:entity_manager +``` + +- Force a refresh of the connection and entity states: + +```sh +noctalia msg plugin pozzoo/hassio:status focused refresh +``` + +Use `all` in place of `focused` to target every bar instance. This triggers the same refresh as sending the `refresh` command internally, and shows a notification when it starts. + +Notes: the plugin forwards Home Assistant state updates internally and uses Noctalia's state routing to update widgets and shortcuts. + +## Notes + +- The plugin maintains a live SSE connection to Home Assistant to receive real-time state changes. Noctalia's native HTTP streaming API is used for this connection; all other requests (fetching states, toggling entities, browsing) go through Noctalia's native HTTP API. +- The pinned entity list is saved to `managed_entities.json` in the plugin's persistent data directory (`noctalia.pluginDataDir()`), so it survives plugin updates. +- To authenticate the SSE connection without exposing the access token on the command line, the plugin uses Noctalia's native streaming request headers. +- The plugin issues HTTP requests to your HA instance; do not install untrusted plugins if you do not want them to access your network or tokens. +- If authentication fails, generate a new long-lived access token in Home Assistant and paste it into plugin settings. diff --git a/hassio/panel.luau b/hassio/panel.luau new file mode 100644 index 0000000..ff52d45 --- /dev/null +++ b/hassio/panel.luau @@ -0,0 +1,634 @@ +--!nonstrict + +local haUrl = noctalia.getConfig("ha_url") +local haToken = noctalia.getConfig("ha_token") + +local entityStates = {} +local status = "unconfigured" +local expandedEntityId = nil +local entitySlots = {} +local sliderDraft = {} +local sliderDirty = {} + +local pendingToggle = {} +local pendingSince = {} -- entity_id -> os.clock() when toggle was requested + +local PENDING_TIMEOUT_SECONDS = 8 + +local view = "list" -- "list" | "browser" +local allEntities = {} +local browserSlots = {} +local browserLoading = false +local searchText = "" +local monitoredEntities = {} -- current monitored list (owned here, saved to file) +local panelOpenCount = 0 + +local function tr(key, subst) + return noctalia.tr("panel." .. key, subst) +end + +local function getStatusText() + if status == "connected" then + return noctalia.tr("widget.status_connected") + elseif status == "connecting" then + return noctalia.tr("widget.status_connecting") + elseif status == "disconnected" then + return noctalia.tr("widget.status_disconnected") + elseif status == "auth_failed" then + return noctalia.tr("widget.status_auth_failed") + else + return noctalia.tr("widget.status_unconfigured") + end +end + +local function getCleanToken() + if type(haToken) ~= "string" then return "" end + return haToken:gsub("^%s+", ""):gsub("%s+$", "") +end + +local function haPost(path, body) + if not haUrl or haUrl == "" then return end + local cleanToken = getCleanToken() + if cleanToken == "" then return end + local encodedBody = noctalia.json.encode(body) + + noctalia.http({ + url = haUrl .. path, + method = "POST", + headers = { + "Authorization: Bearer " .. cleanToken, + "Content-Type: application/json", + }, + body = encodedBody, + }, function(response: HttpResponse)end) +end + +local function callService(domain, service, entityId) + haPost("/api/services/" .. domain .. "/" .. service, { entity_id = entityId }) +end + +local MANAGED_ENTITIES_FILE = "managed_entities.json" + +local function managedEntitiesPath() + local dataDir, dirErr = noctalia.pluginDataDir() + if not dataDir then + noctalia.log("Cannot resolve plugin data dir: " .. (dirErr or "unknown")) + return nil + end + return dataDir .. "/" .. MANAGED_ENTITIES_FILE +end + +local function loadMonitoredEntities() + local path = managedEntitiesPath() + local data = path and noctalia.readFile(path) + if data and data ~= "" then + local parsed = noctalia.json.decode(data) + if type(parsed) == "table" then + monitoredEntities = parsed + return + end + end + monitoredEntities = {} +end + +local function saveMonitoredEntities() + local path = managedEntitiesPath() + if not path then + noctalia.notifyError(noctalia.tr("shortcut.title"), tr("save_failed_no_data_dir")) + return + end + + local encodedEntities = noctalia.json.encode(monitoredEntities) + local ok, writeErr = noctalia.writeFile(path, encodedEntities) + if not ok then + noctalia.log("Failed to save managed entities: " .. (writeErr or "unknown")) + noctalia.notifyError(noctalia.tr("shortcut.title"), tr("save_failed")) + return + end + noctalia.state.set("entities_override", monitoredEntities) + noctalia.state.set("command", "reload_entities") +end + +local function isPinned(entityId) + for _, eid in ipairs(monitoredEntities) do + if eid == entityId then return true end + end + return false +end + +local function toggleBrowserPin(entityId) + if not entityId then return end + local newList, found = {}, false + for _, eid in ipairs(monitoredEntities) do + if eid == entityId then found = true + else table.insert(newList, eid) end + end + if not found then table.insert(newList, entityId) end + monitoredEntities = newList + saveMonitoredEntities() + render() +end + +local function fetchAllEntities() + if browserLoading then return end + local cleanToken = getCleanToken() + if not haUrl or haUrl == "" or cleanToken == "" then + allEntities = {} + browserLoading = false + render() + return + end + + browserLoading = true + render() + + noctalia.http({ + url = haUrl .. "/api/states", + headers = { + "Authorization: Bearer " .. cleanToken, + } + }, function(response: HttpResponse) + browserLoading = false + if response and response.body and response.body ~= "" then + local states = noctalia.json.decode(response.body) + if type(states) == "table" then + allEntities = {} + for _, s in ipairs(states) do + local attrs = s.attributes or {} + table.insert(allEntities, { + entity_id = s.entity_id, + friendly_name = attrs.friendly_name or s.entity_id, + domain = s.entity_id:match("^([^.]+)"), + }) + end + table.sort(allEntities, function(a, b) return a.entity_id < b.entity_id end) + end + end + render() + end) +end + +local function initDraft(entityId) + if sliderDraft[entityId] then return end + local e = entityStates[entityId] + local ct = e and e.color_temp or -1 + local ctKelvin + if ct > 500 then ctKelvin = math.floor(ct + 0.5) + elseif ct > 0 then ctKelvin = math.floor(1000000 / ct + 0.5) + else ctKelvin = 4000 end + sliderDraft[entityId] = { + brightness = e and (e.brightness > 0 and e.brightness or 255) or 255, + color_temp = ctKelvin, + hue = e and (e.hue or 0) or 0, + } +end + +local function markDirty(key) + if not expandedEntityId then return end + if not sliderDirty[expandedEntityId] then sliderDirty[expandedEntityId] = {} end + sliderDirty[expandedEntityId][key] = true +end + +local function clearPending(entityId) + pendingToggle[entityId] = nil + pendingSince[entityId] = nil +end + +local function isPendingTimedOut(entityId, now) + local startedAt = pendingSince[entityId] + if not startedAt then return false end + return (now or os.clock()) - startedAt >= PENDING_TIMEOUT_SECONDS +end + +local function reconcilePending(now) + local changed = false + for entityId, expected in pairs(pendingToggle) do + local real = entityStates[entityId] + if not real or real.state == expected or isPendingTimedOut(entityId, now) then + clearPending(entityId) + changed = true + end + end + return changed +end + +-- _actN/_expN are per-slot callback targets referenced by index from the rendered rows below. +-- In list view they act on the entity in that row's slot; in browser view _actN toggles its pin. +local function actSlot(i) + if view == "browser" then + toggleBrowserPin(browserSlots[i]) + return + end + local eid = entitySlots[i] + if not eid then return end + local entity = entityStates[eid] + if not entity then return end + local d = entity.domain + if d == "script" then callService("script", "turn_on", eid) + elseif d == "automation" then callService("automation", "trigger", eid) + else + local newState = entity.state == "on" and "off" or "on" + pendingToggle[eid] = newState + pendingSince[eid] = os.clock() + callService(d, "toggle", eid) + render() + end +end + +local function expSlot(i) + local eid = entitySlots[i] + if not eid then return end + if expandedEntityId == eid then + expandedEntityId = nil + else + sliderDraft[eid] = nil + sliderDirty[eid] = nil + expandedEntityId = eid + end + render() +end + +function _act1() actSlot(1) end; function _exp1() expSlot(1) end +function _act2() actSlot(2) end; function _exp2() expSlot(2) end +function _act3() actSlot(3) end; function _exp3() expSlot(3) end +function _act4() actSlot(4) end; function _exp4() expSlot(4) end +function _act5() actSlot(5) end; function _exp5() expSlot(5) end +function _act6() actSlot(6) end; function _exp6() expSlot(6) end +function _act7() actSlot(7) end; function _exp7() expSlot(7) end +function _act8() actSlot(8) end; function _exp8() expSlot(8) end +function _act9() actSlot(9) end; function _exp9() expSlot(9) end +function _act10() actSlot(10) end; function _exp10() expSlot(10) end +function _act11() actSlot(11) end; function _exp11() expSlot(11) end +function _act12() actSlot(12) end; function _exp12() expSlot(12) end +function _act13() actSlot(13) end; function _exp13() expSlot(13) end +function _act14() actSlot(14) end; function _exp14() expSlot(14) end +function _act15() actSlot(15) end; function _exp15() expSlot(15) end +function _act16() actSlot(16) end; function _exp16() expSlot(16) end +function _act17() actSlot(17) end; function _exp17() expSlot(17) end +function _act18() actSlot(18) end; function _exp18() expSlot(18) end +function _act19() actSlot(19) end; function _exp19() expSlot(19) end +function _act20() actSlot(20) end; function _exp20() expSlot(20) end +function _act21() actSlot(21) end; function _exp21() expSlot(21) end +function _act22() actSlot(22) end; function _exp22() expSlot(22) end +function _act23() actSlot(23) end; function _exp23() expSlot(23) end +function _act24() actSlot(24) end; function _exp24() expSlot(24) end +function _act25() actSlot(25) end; function _exp25() expSlot(25) end +function _act26() actSlot(26) end; function _exp26() expSlot(26) end +function _act27() actSlot(27) end; function _exp27() expSlot(27) end +function _act28() actSlot(28) end; function _exp28() expSlot(28) end +function _act29() actSlot(29) end; function _exp29() expSlot(29) end +function _act30() actSlot(30) end; function _exp30() expSlot(30) end + +function onBrightness(value) + if not expandedEntityId then return end + initDraft(expandedEntityId) + sliderDraft[expandedEntityId].brightness = math.floor((tonumber(value) or 255) + 0.5) + markDirty("brightness") + render() +end + +function onColorTemp(value) + if not expandedEntityId then return end + initDraft(expandedEntityId) + sliderDraft[expandedEntityId].color_temp = math.floor((tonumber(value) or 4000) + 0.5) + markDirty("color_temp") + render() +end + +function onHue(value) + if not expandedEntityId then return end + initDraft(expandedEntityId) + sliderDraft[expandedEntityId].hue = math.floor((tonumber(value) or 0) + 0.5) + markDirty("hue") + render() +end + +function onApplyLight() + if not expandedEntityId then return end + local draft = sliderDraft[expandedEntityId] + local dirty = sliderDirty[expandedEntityId] or {} + local entity = entityStates[expandedEntityId] + if not draft or not entity then return end + + local data = { entity_id = expandedEntityId } + if dirty.hue and entity.supports_rgb then + data.hs_color = { draft.hue, 100 } + if dirty.brightness and entity.supports_brightness then + data.brightness = draft.brightness + end + else + if dirty.brightness and entity.supports_brightness then + data.brightness = draft.brightness + end + if dirty.color_temp and entity.supports_color_temp then + data.color_temp_kelvin = draft.color_temp + end + end + + if dirty.brightness or dirty.color_temp or dirty.hue then + haPost("/api/services/light/turn_on", data) + sliderDirty[expandedEntityId] = {} + end +end + +function onNoop() end + +function onOpenBrowser() + view = "browser" + searchText = "" + fetchAllEntities() +end + +function onBackToList() + view = "list" + allEntities = {} + searchText = "" + render() +end + +function onSearchChange(value) + searchText = value or "" + render() +end + +local function isControllable(domain) + return domain == "light" or domain == "switch" or domain == "input_boolean" + or domain == "fan" or domain == "cover" or domain == "lock" +end + +local function isSensor(domain) + return domain == "sensor" or domain == "binary_sensor" or domain == "weather" or domain == "number" +end + +local function isAutomation(domain) + return domain == "automation" or domain == "script" +end + +local function domainGlyph(domain) + local g = { + light = "bulb", switch = "toggle-right", input_boolean = "toggle-right", + sensor = "chart-line", binary_sensor = "activity", climate = "temperature", + cover = "door", fan = "wind", lock = "lock", media_player = "device-speaker", + weather = "cloud", automation = "robot", script = "player-play", + } + return g[domain] or "smart-home" +end + +local function stateGlyph(domain, isOn) + if domain == "light" then return isOn and "bulb" or "bulb-off" + elseif domain == "switch" or domain == "input_boolean" then return isOn and "toggle-right" or "toggle-left" + elseif domain == "fan" then return isOn and "wind" or "wind-off" + elseif domain == "lock" then return isOn and "lock" or "lock-open" + elseif domain == "cover" then return isOn and "door-open" or "door" + end + return domainGlyph(domain) +end + +local function entityStateLabel(entity) + if isSensor(entity.domain) then + return entity.state .. (entity.unit ~= "" and " " .. entity.unit or "") + end + if entity.domain == "light" and entity.state == "on" and entity.brightness >= 0 then + local pct = math.floor(entity.brightness / 255 * 100 + 0.5) + return tr("state_on_brightness", { percent = pct }) + end + return entity.state +end + +local function buildExpandedSection(entity) + local eid = entity.entity_id + initDraft(eid) + local draft = sliderDraft[eid] + local rows = {} + + if entity.supports_brightness then + local bv = draft.brightness + table.insert(rows, ui.row({ align = "center", gap = 8 }, { + ui.label({ text = tr("brightness"), color = "on_surface_variant" }), + ui.slider({ min = 1, max = 255, step = 1, value = bv, onChange = "onBrightness", flexGrow = 1 }), + ui.label({ text = math.floor(bv / 255 * 100 + 0.5) .. "%" }), + })) + end + + if entity.supports_color_temp then + local ctk = draft.color_temp + table.insert(rows, ui.row({ align = "center", gap = 8 }, { + ui.label({ text = tr("color_temp"), color = "on_surface_variant" }), + ui.slider({ min = 2000, max = 6500, step = 50, value = ctk, onChange = "onColorTemp", flexGrow = 1 }), + ui.label({ text = math.floor(ctk) .. "K" }), + })) + end + + if entity.supports_rgb then + local hv = draft.hue + table.insert(rows, ui.row({ align = "center", gap = 8 }, { + ui.label({ text = tr("hue"), color = "on_surface_variant" }), + ui.slider({ min = 0, max = 360, step = 1, value = hv, onChange = "onHue", flexGrow = 1 }), + ui.label({ text = math.floor(hv) .. "°" }), + })) + end + + if #rows == 0 then return nil end + + table.insert(rows, ui.row({ justify = "end" }, { + ui.button({ glyph = "check", onClick = "onApplyLight" }), + })) + + return ui.column({ gap = 8 }, rows) +end + +local function buildEntityCard(entity, i) + local pending = pendingToggle[entity.entity_id] + local isOn = (pending or entity.state) == "on" + local domain = entity.domain + local canExpand = domain == "light" + and (entity.supports_brightness or entity.supports_color_temp or entity.supports_rgb) + local isExpanded = expandedEntityId == entity.entity_id + + local expandBtn + if canExpand then + expandBtn = ui.button({ + glyph = isExpanded and "chevron-up" or "chevron-down", + onClick = "_exp" .. i, + }) + end + + local isPending = pending ~= nil + local iconClick = isPending and "onNoop" + or (isControllable(domain) or isAutomation(domain)) and "_act" .. i or "onNoop" + local iconGlyph = isPending and "loader" + or isAutomation(domain) and "player-play" or stateGlyph(domain, isOn) + + local rowChildren = { + ui.button({ glyph = iconGlyph, onClick = iconClick }), + ui.column({ flexGrow = 1, gap = 2 }, { + ui.label({ text = entity.friendly_name or entity.entity_id, fontWeight = "medium" }), + ui.label({ text = entityStateLabel(entity), color = "on_surface_variant", fontSize = 12 }), + }), + } + if expandBtn then table.insert(rowChildren, expandBtn) end + + local cardChildren = { ui.row({ align = "center", gap = 8 }, rowChildren) } + + if isExpanded then + local expanded = buildExpandedSection(entity) + if expanded then table.insert(cardChildren, expanded) end + end + + return ui.column({ gap = 8 }, cardChildren) +end + +-- Capped to 30: matches the number of _actN/_expN slot callbacks defined above. +local MAX_SLOTS = 30 + +local function getOrderedIds() + local ids, seen = {}, {} + for _, eid in ipairs(monitoredEntities) do + if entityStates[eid] then + table.insert(ids, eid) + seen[eid] = true + if #ids >= MAX_SLOTS then return ids end + end + end + for eid in pairs(entityStates) do + if not seen[eid] then + table.insert(ids, eid) + if #ids >= MAX_SLOTS then return ids end + end + end + return ids +end + +local function buildListBody(ids) + if not haUrl or haUrl == "" or getCleanToken() == "" then + return ui.label({ text = tr("not_configured"), color = "on_surface_variant" }) + end + if status == "auth_failed" then + return ui.label({ text = tr("auth_failed"), color = "error" }) + end + if status == "connecting" then + return ui.label({ text = tr("connecting"), color = "on_surface_variant" }) + end + if status == "disconnected" then + return ui.label({ text = tr("disconnected_reconnecting"), color = "error" }) + end + if #ids == 0 then + return ui.label({ + text = status == "connected" + and tr("no_entities_monitored") + or tr("status_fallback", { status = status }), + color = "on_surface_variant", + }) + end + local cards = {} + for i, eid in ipairs(ids) do + table.insert(cards, buildEntityCard(entityStates[eid], i)) + end + return ui.scroll({ flexGrow = 1, gap = 8 }, cards) +end + +local function buildBrowserBody() + if browserLoading then + return ui.label({ text = tr("loading_entities"), color = "on_surface_variant" }) + end + if #allEntities == 0 then + return ui.label({ text = tr("no_entities_found"), color = "on_surface_variant" }) + end + + local q = searchText:lower() + local filtered = {} + for _, e in ipairs(allEntities) do + if q == "" + or e.entity_id:lower():find(q, 1, true) + or e.friendly_name:lower():find(q, 1, true) + then + table.insert(filtered, e) + if #filtered >= 30 then break end + end + end + + if #filtered == 0 then + return ui.label({ text = tr("no_entities_match"), color = "on_surface_variant" }) + end + + browserSlots = {} + local rows = {} + for i, e in ipairs(filtered) do + browserSlots[i] = e.entity_id + local pinned = isPinned(e.entity_id) + table.insert(rows, ui.row({ align = "center", gap = 8 }, { + ui.column({ flexGrow = 1, gap = 2 }, { + ui.label({ text = e.friendly_name, fontWeight = "medium" }), + ui.label({ text = e.entity_id, color = "on_surface_variant", fontSize = 12 }), + }), + ui.button({ glyph = pinned and "pin-filled" or "pin", onClick = "_act" .. i }), + })) + end + + return ui.scroll({ flexGrow = 1, gap = 4 }, rows) +end + +function render() + reconcilePending(os.clock()) + + if view == "browser" then + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.row({ align = "center", gap = 8 }, { + ui.button({ glyph = "arrow-left", onClick = "onBackToList" }), + ui.label({ text = tr("manage_entities_title"), fontSize = 16, fontWeight = "bold", color = "primary", flexGrow = 1 }), + ui.button({ glyph = "close", onClick = "onCloseClicked" }), + }), + ui.input({ key = "entity_search", placeholder = tr("search_placeholder"), onChange = "onSearchChange" }), + buildBrowserBody(), + })) + else + local ids = getOrderedIds() + entitySlots = {} + for i, eid in ipairs(ids) do entitySlots[i] = eid end + + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.row({ align = "center", gap = 8 }, { + ui.label({ text = noctalia.tr("shortcut.title"), fontSize = 16, fontWeight = "bold", color = "primary", flexGrow = 1 }), + ui.label({ text = getStatusText(), color = status == "connected" and "primary" or "on_surface_variant" }), + ui.button({ glyph = "list-search", onClick = "onOpenBrowser" }), + ui.button({ glyph = "close", onClick = "onCloseClicked" }), + }), + buildListBody(ids), + })) + end +end + +function onOpen(_context) + status = noctalia.state.get("connection_status") or "unconfigured" + entityStates = noctalia.state.get("entities") or {} + loadMonitoredEntities() + panelOpenCount = panelOpenCount + 1 + panel.setWantsSecondTicks(true) + noctalia.state.set("panel_open_signal", panelOpenCount) + render() +end + +function onClose() + panel.setWantsSecondTicks(false) +end + +function update() + if reconcilePending(os.clock()) then + render() + end +end + +function onCloseClicked() + panel.close() +end + +noctalia.state.watch("entities", function(value) + entityStates = value or {} + reconcilePending(os.clock()) + render() +end) + +noctalia.state.watch("connection_status", function(value) + status = value or "unconfigured" + render() +end) diff --git a/hassio/plugin.toml b/hassio/plugin.toml new file mode 100644 index 0000000..afef4a2 --- /dev/null +++ b/hassio/plugin.toml @@ -0,0 +1,95 @@ +id = "pozzoo/hassio" +name = "Home Assistant" +version = "2.0.0" +plugin_api = 4 +author = "Pozzoo" +license = "MIT" +tags = ["bar", "panel", "service", "shortcut", "network", "indicator"] +icon = "smart-home" +dependencies = ["xdg-open"] +description = "Monitor and control Home Assistant entities from the bar. Displays entity states and provides quick toggles." + +[[setting]] +key = "ha_url" +type = "string" +label_key = "settings.url.label" +description_key = "settings.url.description" +default = "" + +[[setting]] +key = "ha_token" +type = "string" +label_key = "settings.token.label" +description_key = "settings.token.description" +default = "" + +[[setting]] +key = "shortcut_entity_1" +type = "string" +label_key = "settings.shortcut_entity_1.label" +description_key = "settings.shortcut_entity.description" +default = "" + +[[setting]] +key = "shortcut_entity_2" +type = "string" +label_key = "settings.shortcut_entity_2.label" +description_key = "settings.shortcut_entity.description" +default = "" + +[[setting]] +key = "shortcut_entity_3" +type = "string" +label_key = "settings.shortcut_entity_3.label" +description_key = "settings.shortcut_entity.description" +default = "" + +[[setting]] +key = "shortcut_entity_4" +type = "string" +label_key = "settings.shortcut_entity_4.label" +description_key = "settings.shortcut_entity.description" +default = "" + +[[widget]] +id = "status" +entry = "widget.luau" + + [[widget.setting]] + key = "show_entity_count" + type = "bool" + label_key = "settings.show_entity_count.label" + default = false + +# Native streaming background service maintaining a live connection to HA +[[service]] +id = "connection" +entry = "service_sse.luau" + +[[shortcut]] +id = "ha_toggle_1" +entry = "shortcut.luau" + +[[shortcut]] +id = "ha_toggle_2" +entry = "shortcut_2.luau" + +[[shortcut]] +id = "ha_toggle_3" +entry = "shortcut_3.luau" + +[[shortcut]] +id = "ha_toggle_4" +entry = "shortcut_4.luau" + +[[shortcut]] +id = "ha_panel" +entry = "shortcut_panel.luau" + +[[panel]] +id = "entity_manager" +entry = "panel.luau" +width = 450 +height = 560 +placement = "floating" +position = "center" diff --git a/hassio/service_sse.luau b/hassio/service_sse.luau new file mode 100644 index 0000000..ead3d84 --- /dev/null +++ b/hassio/service_sse.luau @@ -0,0 +1,428 @@ +--!nonstrict + +local haUrl = noctalia.getConfig("ha_url") +local haToken = noctalia.getConfig("ha_token") + +local MANAGED_ENTITIES_FILE = "managed_entities.json" + +local function loadManagedEntities() + local dataDir, dirErr = noctalia.pluginDataDir() + if not dataDir then + noctalia.log("Cannot resolve plugin data dir: " .. (dirErr or "unknown")) + return {} + end + + local data = noctalia.readFile(dataDir .. "/" .. MANAGED_ENTITIES_FILE) + if data and data ~= "" then + local parsed = noctalia.json.decode(data) + if type(parsed) == "table" then return parsed end + end + return {} +end + +local entities = loadManagedEntities() + +local status = "unconfigured" +local entityStates = {} +local sseActive = false +local streamHandle = nil + +local MAX_RECONNECT_RETRIES = 10 +local CONNECTED_POLL_INTERVAL_MS = 30000 +local RECONNECT_POLL_INTERVAL_MS = 1000 +local retryCount = 0 +local maxRetriesNotified = false +local suspended = false +local connectionRequestInFlight = false + +local function getCleanToken() + if type(haToken) ~= "string" then return "" end + return noctalia.string.trim(haToken) +end + +local function syncUpdateInterval() + if status == "connected" and sseActive then + noctalia.setUpdateInterval(CONNECTED_POLL_INTERVAL_MS) + else + noctalia.setUpdateInterval(RECONNECT_POLL_INTERVAL_MS) + end +end + +local function isConfigured() + return haUrl and haUrl ~= "" and getCleanToken() ~= "" +end + +local function haRequest(endpoint, method, body, callback) + if not isConfigured() then return false end + + local url = haUrl .. endpoint + local cleanToken = getCleanToken() + + local jsonBody + if body then + jsonBody = noctalia.json.encode(body) + end + + local launched = noctalia.http({ + url = url, + method = method, + body = jsonBody, + headers = { + "Authorization: Bearer " .. cleanToken, + "Content-Type: application/json", + } + }, function(response: HttpResponse) + if not response then + callback({ ok = false, status = 0, body = "No response" }) + return + end + + callback({ + ok = response.status >= 200 and response.status < 300, + status = response.status, + body = response.body + }) + end) + + return launched + +end + +local function supportsColorMode(modes, targets) + if type(modes) ~= "table" then return false end + for _, mode in ipairs(modes) do + for _, target in ipairs(targets) do + if mode == target then return true end + end + end + return false +end + +local function processEntity(state) + if not state then return nil end + + local attrs = state.attributes or {} + local modes = attrs.supported_color_modes or {} + + -- stored as mireds for the panel slider + local colorTemp = -1 + if attrs.color_temp_kelvin and attrs.color_temp_kelvin > 0 then + colorTemp = math.floor(1000000 / attrs.color_temp_kelvin + 0.5) + elseif attrs.color_temp and attrs.color_temp > 0 then + colorTemp = attrs.color_temp + end + + local currentColor = "" + if type(attrs.rgb_color) == "table" and #attrs.rgb_color == 3 then + currentColor = attrs.rgb_color[1] .. "," .. attrs.rgb_color[2] .. "," .. attrs.rgb_color[3] + end + + return { + entity_id = state.entity_id, + state = state.state, + friendly_name = attrs.friendly_name or state.entity_id, + domain = state.entity_id:match("^([^.]+)"), + unit = attrs.unit_of_measurement or "", + brightness = attrs.brightness or -1, + color_temp = colorTemp, + hue = (type(attrs.hs_color) == "table") and (attrs.hs_color[1] or 0) or 0, + current_color = currentColor, + supports_brightness = supportsColorMode(modes, {"brightness","color_temp","hs","xy","rgb","rgbw","rgbww"}), + supports_color_temp = supportsColorMode(modes, {"color_temp"}), + supports_rgb = supportsColorMode(modes, {"hs","xy","rgb","rgbw","rgbww"}), + } +end + +local function updateEntity(entityId, newState) + if #entities > 0 then + local found = false + for _, id in ipairs(entities) do + if id == entityId then + found = true + break + end + end + if not found then return end + end + + local processed = processEntity(newState) + if processed then + entityStates[entityId] = processed + noctalia.state.set("entities", entityStates) + + local count = 0 + for _ in pairs(entityStates) do + count = count + 1 + end + noctalia.state.set("entity_count", count) + end +end + +-- HA embeds event_type inside the data JSON rather than a separate SSE "event:" field +local currentEvent = { + data = "", + event = "", +} + +local function tryDispatch() + if not currentEvent.data then return end + local parsed = noctalia.json.decode(currentEvent.data) + if not parsed then return end + local evType = currentEvent.event or parsed.event_type + if evType ~= "state_changed" then return end + local inner = parsed.data or {} + if inner.entity_id and inner.new_state then + updateEntity(inner.entity_id, inner.new_state) + end +end + +local function processSSELine(line) + if line == "" then + tryDispatch() + currentEvent = {} + elseif line:match("^event:") then + if currentEvent.data then tryDispatch() end + currentEvent = { event = line:match("^event:%s*(.+)") or "" } + elseif line:match("^data:") then + local data = line:match("^data:%s*(.+)") or "" + local parsed = noctalia.json.decode(data) + if parsed then + local evType = currentEvent.event or parsed.event_type + if evType == "state_changed" then + local inner = parsed.data or {} + if inner.entity_id and inner.new_state then + updateEntity(inner.entity_id, inner.new_state) + currentEvent = {} + return + end + end + end + if currentEvent.data and currentEvent.data ~= "" then + currentEvent.data = currentEvent.data .. "\n" .. data + else + currentEvent.data = data + end + end +end + +local function fetchInitialStates() + if not isConfigured() or suspended or connectionRequestInFlight then return end + connectionRequestInFlight = true + local launched = haRequest("/api/states", "GET", nil, function(res) + connectionRequestInFlight = false + + if not res.body or res.body == "" then + noctalia.log("Empty response body from /api/states") + status = "disconnected" + noctalia.state.set("connection_status", status) + syncUpdateInterval() + return + end + + if not res.ok or res.status == 401 or res.body:match("^401") or res.body:match("Unauthorized") then + status = "auth_failed" + noctalia.log("Authentication failed - check your token") + noctalia.notifyError(noctalia.tr("notifications.auth_failed")) + noctalia.state.set("connection_status", status) + syncUpdateInterval() + return + end + + if not res.ok or (res.status and res.status >= 400) then + status = "disconnected" + noctalia.log("HTTP request failed: status " .. (res.status or "unknown")) + noctalia.state.set("connection_status", status) + syncUpdateInterval() + return + end + + local allStates, err = noctalia.json.decode(res.body) + if not allStates then + noctalia.log("Failed to parse states: " .. (err or "unknown error")) + status = "disconnected" + noctalia.state.set("connection_status", status) + syncUpdateInterval() + return + end + + status = "connected" + noctalia.state.set("connection_status", status) + retryCount = 0 + maxRetriesNotified = false + suspended = false + + entityStates = {} + local count = 0 + + for _, state in ipairs(allStates) do + if #entities == 0 then break end + for _, entityId in ipairs(entities) do + if state.entity_id == entityId then + entityStates[entityId] = processEntity(state) + count = count + 1 + break + end + end + end + + noctalia.state.set("entities", entityStates) + noctalia.state.set("entity_count", count) + + if status == "connected" then + if not startSSEStream() then + status = "disconnected" + noctalia.state.set("connection_status", status) + syncUpdateInterval() + else + syncUpdateInterval() + end + end + end) + + if not launched then + connectionRequestInFlight = false + status = "disconnected" + noctalia.state.set("connection_status", status) + syncUpdateInterval() + end +end + +function startSSEStream() + if suspended then return false end + if sseActive then return true end + + local cleanToken = getCleanToken() + if cleanToken == "" then + return false + end + + local url = haUrl .. "/api/stream?restrict=state_changed" + + noctalia.log("Starting SSE stream") + currentEvent = { data = "", event = "" } + + local handle + handle = noctalia.httpStream({ + url = url, + headers = { + "Accept: text/event-stream", + "Authorization: Bearer " .. cleanToken, + }, + }, function(line) + processSSELine(line) + end, function(result) + if streamHandle ~= handle then return end + + streamHandle = nil + sseActive = false + currentEvent = {} + + if suspended then return end + + if result and result.ok and result.status == 401 then + status = "auth_failed" + noctalia.log("Authentication failed - check your token") + noctalia.notifyError(noctalia.tr("notifications.auth_failed")) + noctalia.state.set("connection_status", status) + syncUpdateInterval() + return + end + + status = "disconnected" + noctalia.log("SSE stream closed") + noctalia.state.set("connection_status", status) + syncUpdateInterval() + end) + + if not handle then + noctalia.log("Failed to start SSE stream") + return false + end + + streamHandle = handle + sseActive = true + syncUpdateInterval() + return true +end + +noctalia.state.watch("command", function(cmd) + if cmd == "refresh" then + -- Just refetch a fresh snapshot over HTTP. Do NOT touch sseActive here: + -- the running stream (if any) is untouched by this, and forcing the + -- flag false would bypass startSSEStream()'s duplicate guard and spawn + -- a second stream on top of one that's still alive. + fetchInitialStates() + elseif cmd == "reload_entities" then + local override = noctalia.state.get("entities_override") + if type(override) == "table" then + entities = override + else + entities = loadManagedEntities() + end + -- Entity filtering happens client-side in updateEntity(), so the + -- existing stream keeps working for the new entity list as-is. + -- The initial snapshot needs refetching, though, to account for any + -- entities that were removed from the filter. See the note above for why + -- sseActive must not be forced here. + fetchInitialStates() + end +end) + +noctalia.state.watch("panel_open_signal", function(value) + if value then + retryCount = 0 + maxRetriesNotified = false + suspended = false + end +end) + +function update() + syncUpdateInterval() + + if not isConfigured() then + status = "unconfigured" + noctalia.state.set("connection_status", status) + sseActive = false + return + end + + if suspended then + return + end + + if status == "disconnected" then + retryCount = retryCount + 1 + if retryCount >= MAX_RECONNECT_RETRIES then + if not maxRetriesNotified then + maxRetriesNotified = true + noctalia.notifyError(noctalia.tr("notifications.reconnect_failed", { count = MAX_RECONNECT_RETRIES })) + end + suspended = true + status = "disconnected" + noctalia.state.set("connection_status", status) + return + end + + status = "connecting" + noctalia.state.set("connection_status", status) + fetchInitialStates() + end +end + +function onExit() + if streamHandle then + streamHandle.stop() + streamHandle = nil + end + sseActive = false +end + +noctalia.state.set("connection_status", status) +noctalia.state.set("entity_count", 0) +noctalia.state.set("entities", {}) + +if isConfigured() then + status = "connecting" + noctalia.state.set("connection_status", status) + fetchInitialStates() +end diff --git a/hassio/shortcut.luau b/hassio/shortcut.luau new file mode 100644 index 0000000..664bb48 --- /dev/null +++ b/hassio/shortcut.luau @@ -0,0 +1,144 @@ +--!nonstrict + +local haUrl = noctalia.getConfig("ha_url") +local haToken = noctalia.getConfig("ha_token") +local configuredEntityId = noctalia.getConfig("shortcut_entity_1") or "" +local SLOT_LABEL = noctalia.tr("shortcut.label_1") + +local entityStates = {} +local pendingToggle = {} +local pendingSince = {} +local pendingTimerToken = {} +local pendingTimerSeq = 0 + +local PENDING_TIMEOUT_SECONDS = 8 +local render + +local function getCleanToken() + if type(haToken) ~= "string" then return "" end + return haToken:gsub("^%s+", ""):gsub("%s+$", "") +end + +local function stateGlyph(domain, isOn) + if domain == "light" then return isOn and "bulb" or "bulb-off" + elseif domain == "switch" or domain == "input_boolean" then return isOn and "toggle-right" or "toggle-left" + elseif domain == "fan" then return isOn and "wind" or "wind-off" + elseif domain == "lock" then return isOn and "lock" or "lock-open" + elseif domain == "cover" then return isOn and "door-open" or "door" + end + return "smart-home" +end + +local function getEntity() + if configuredEntityId == "" then return nil end + return entityStates[configuredEntityId] +end + +local function clearPending(entityId) + pendingToggle[entityId] = nil + pendingSince[entityId] = nil + pendingTimerToken[entityId] = nil +end + +local function isPendingTimedOut(entityId, now) + local startedAt = pendingSince[entityId] + if not startedAt then return false end + return (now or os.clock()) - startedAt >= PENDING_TIMEOUT_SECONDS +end + +local function reconcilePending(now) + for entityId, expected in pairs(pendingToggle) do + local real = entityStates[entityId] + if not real or real.state == expected or isPendingTimedOut(entityId, now) then + clearPending(entityId) + end + end +end + +local function schedulePendingTimeout(entityId) + pendingTimerSeq = pendingTimerSeq + 1 + local token = pendingTimerSeq + pendingSince[entityId] = os.clock() + pendingTimerToken[entityId] = token + + noctalia.runAsync("sleep " .. tostring(PENDING_TIMEOUT_SECONDS), function(_result) + if pendingTimerToken[entityId] ~= token then return end + if pendingToggle[entityId] and isPendingTimedOut(entityId) then + clearPending(entityId) + render() + end + end) +end + +render = function() + reconcilePending(os.clock()) + + local entity = getEntity() + + if not entity then + shortcut.setLabel(configuredEntityId ~= "" and configuredEntityId or SLOT_LABEL) + shortcut.setIcon("smart-home") + shortcut.setActive(false) + shortcut.setEnabled(false) + return + end + + local eid = entity.entity_id + local pending = pendingToggle[eid] + + if pending then + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon("loader") + shortcut.setActive(pending == "on") + shortcut.setEnabled(false) + return + end + + local isOn = entity.state == "on" + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon(stateGlyph(entity.domain, true), stateGlyph(entity.domain, false)) + shortcut.setActive(isOn) + shortcut.setEnabled(true) +end + +noctalia.state.watch("entities", function(value) + entityStates = value or {} + reconcilePending(os.clock()) + render() +end) + +noctalia.state.watch("connection_status", function(_value) + render() +end) + +function onClick() + reconcilePending(os.clock()) + + local entity = getEntity() + local cleanToken = getCleanToken() + if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + + local eid = entity.entity_id + if pendingToggle[eid] then return end + + local newState = entity.state == "on" and "off" or "on" + pendingToggle[eid] = newState + schedulePendingTimeout(eid) + + local encoded = noctalia.json.encode({ entity_id = eid }) + + noctalia.http({ + url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + method = "POST", + headers = { + "Authorization: Bearer " .. cleanToken, + "Content-Type: application/json", + }, + body = encoded, + }, function(response)end) + + render() +end + +entityStates = noctalia.state.get("entities") or {} +render() diff --git a/hassio/shortcut_2.luau b/hassio/shortcut_2.luau new file mode 100644 index 0000000..3e27b2f --- /dev/null +++ b/hassio/shortcut_2.luau @@ -0,0 +1,144 @@ +--!nonstrict + +local haUrl = noctalia.getConfig("ha_url") +local haToken = noctalia.getConfig("ha_token") +local configuredEntityId = noctalia.getConfig("shortcut_entity_2") or "" +local SLOT_LABEL = noctalia.tr("shortcut.label_2") + +local entityStates = {} +local pendingToggle = {} +local pendingSince = {} +local pendingTimerToken = {} +local pendingTimerSeq = 0 + +local PENDING_TIMEOUT_SECONDS = 8 +local render + +local function getCleanToken() + if type(haToken) ~= "string" then return "" end + return haToken:gsub("^%s+", ""):gsub("%s+$", "") +end + +local function stateGlyph(domain, isOn) + if domain == "light" then return isOn and "bulb" or "bulb-off" + elseif domain == "switch" or domain == "input_boolean" then return isOn and "toggle-right" or "toggle-left" + elseif domain == "fan" then return isOn and "wind" or "wind-off" + elseif domain == "lock" then return isOn and "lock" or "lock-open" + elseif domain == "cover" then return isOn and "door-open" or "door" + end + return "smart-home" +end + +local function getEntity() + if configuredEntityId == "" then return nil end + return entityStates[configuredEntityId] +end + +local function clearPending(entityId) + pendingToggle[entityId] = nil + pendingSince[entityId] = nil + pendingTimerToken[entityId] = nil +end + +local function isPendingTimedOut(entityId, now) + local startedAt = pendingSince[entityId] + if not startedAt then return false end + return (now or os.clock()) - startedAt >= PENDING_TIMEOUT_SECONDS +end + +local function reconcilePending(now) + for entityId, expected in pairs(pendingToggle) do + local real = entityStates[entityId] + if not real or real.state == expected or isPendingTimedOut(entityId, now) then + clearPending(entityId) + end + end +end + +local function schedulePendingTimeout(entityId) + pendingTimerSeq = pendingTimerSeq + 1 + local token = pendingTimerSeq + pendingSince[entityId] = os.clock() + pendingTimerToken[entityId] = token + + noctalia.runAsync("sleep " .. tostring(PENDING_TIMEOUT_SECONDS), function(_result) + if pendingTimerToken[entityId] ~= token then return end + if pendingToggle[entityId] and isPendingTimedOut(entityId) then + clearPending(entityId) + render() + end + end) +end + +render = function() + reconcilePending(os.clock()) + + local entity = getEntity() + + if not entity then + shortcut.setLabel(configuredEntityId ~= "" and configuredEntityId or SLOT_LABEL) + shortcut.setIcon("smart-home") + shortcut.setActive(false) + shortcut.setEnabled(false) + return + end + + local eid = entity.entity_id + local pending = pendingToggle[eid] + + if pending then + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon("loader") + shortcut.setActive(pending == "on") + shortcut.setEnabled(false) + return + end + + local isOn = entity.state == "on" + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon(stateGlyph(entity.domain, true), stateGlyph(entity.domain, false)) + shortcut.setActive(isOn) + shortcut.setEnabled(true) +end + +noctalia.state.watch("entities", function(value) + entityStates = value or {} + reconcilePending(os.clock()) + render() +end) + +noctalia.state.watch("connection_status", function(_value) + render() +end) + +function onClick() + reconcilePending(os.clock()) + + local entity = getEntity() + local cleanToken = getCleanToken() + if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + + local eid = entity.entity_id + if pendingToggle[eid] then return end + + local newState = entity.state == "on" and "off" or "on" + pendingToggle[eid] = newState + schedulePendingTimeout(eid) + + local encoded = noctalia.json.encode({ entity_id = eid }) + + noctalia.http({ + url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + method = "POST", + headers = { + "Authorization: Bearer " .. cleanToken, + "Content-Type: application/json", + }, + body = encoded, + }, function(response)end) + + render() +end + +entityStates = noctalia.state.get("entities") or {} +render() diff --git a/hassio/shortcut_3.luau b/hassio/shortcut_3.luau new file mode 100644 index 0000000..cf25cfe --- /dev/null +++ b/hassio/shortcut_3.luau @@ -0,0 +1,144 @@ +--!nonstrict + +local haUrl = noctalia.getConfig("ha_url") +local haToken = noctalia.getConfig("ha_token") +local configuredEntityId = noctalia.getConfig("shortcut_entity_3") or "" +local SLOT_LABEL = noctalia.tr("shortcut.label_3") + +local entityStates = {} +local pendingToggle = {} +local pendingSince = {} +local pendingTimerToken = {} +local pendingTimerSeq = 0 + +local PENDING_TIMEOUT_SECONDS = 8 +local render + +local function getCleanToken() + if type(haToken) ~= "string" then return "" end + return haToken:gsub("^%s+", ""):gsub("%s+$", "") +end + +local function stateGlyph(domain, isOn) + if domain == "light" then return isOn and "bulb" or "bulb-off" + elseif domain == "switch" or domain == "input_boolean" then return isOn and "toggle-right" or "toggle-left" + elseif domain == "fan" then return isOn and "wind" or "wind-off" + elseif domain == "lock" then return isOn and "lock" or "lock-open" + elseif domain == "cover" then return isOn and "door-open" or "door" + end + return "smart-home" +end + +local function getEntity() + if configuredEntityId == "" then return nil end + return entityStates[configuredEntityId] +end + +local function clearPending(entityId) + pendingToggle[entityId] = nil + pendingSince[entityId] = nil + pendingTimerToken[entityId] = nil +end + +local function isPendingTimedOut(entityId, now) + local startedAt = pendingSince[entityId] + if not startedAt then return false end + return (now or os.clock()) - startedAt >= PENDING_TIMEOUT_SECONDS +end + +local function reconcilePending(now) + for entityId, expected in pairs(pendingToggle) do + local real = entityStates[entityId] + if not real or real.state == expected or isPendingTimedOut(entityId, now) then + clearPending(entityId) + end + end +end + +local function schedulePendingTimeout(entityId) + pendingTimerSeq = pendingTimerSeq + 1 + local token = pendingTimerSeq + pendingSince[entityId] = os.clock() + pendingTimerToken[entityId] = token + + noctalia.runAsync("sleep " .. tostring(PENDING_TIMEOUT_SECONDS), function(_result) + if pendingTimerToken[entityId] ~= token then return end + if pendingToggle[entityId] and isPendingTimedOut(entityId) then + clearPending(entityId) + render() + end + end) +end + +render = function() + reconcilePending(os.clock()) + + local entity = getEntity() + + if not entity then + shortcut.setLabel(configuredEntityId ~= "" and configuredEntityId or SLOT_LABEL) + shortcut.setIcon("smart-home") + shortcut.setActive(false) + shortcut.setEnabled(false) + return + end + + local eid = entity.entity_id + local pending = pendingToggle[eid] + + if pending then + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon("loader") + shortcut.setActive(pending == "on") + shortcut.setEnabled(false) + return + end + + local isOn = entity.state == "on" + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon(stateGlyph(entity.domain, true), stateGlyph(entity.domain, false)) + shortcut.setActive(isOn) + shortcut.setEnabled(true) +end + +noctalia.state.watch("entities", function(value) + entityStates = value or {} + reconcilePending(os.clock()) + render() +end) + +noctalia.state.watch("connection_status", function(_value) + render() +end) + +function onClick() + reconcilePending(os.clock()) + + local entity = getEntity() + local cleanToken = getCleanToken() + if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + + local eid = entity.entity_id + if pendingToggle[eid] then return end + + local newState = entity.state == "on" and "off" or "on" + pendingToggle[eid] = newState + schedulePendingTimeout(eid) + + local encoded = noctalia.json.encode({ entity_id = eid }) + + noctalia.http({ + url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + method = "POST", + headers = { + "Authorization: Bearer " .. cleanToken, + "Content-Type: application/json", + }, + body = encoded, + }, function(response)end) + + render() +end + +entityStates = noctalia.state.get("entities") or {} +render() diff --git a/hassio/shortcut_4.luau b/hassio/shortcut_4.luau new file mode 100644 index 0000000..369bed1 --- /dev/null +++ b/hassio/shortcut_4.luau @@ -0,0 +1,144 @@ +--!nonstrict + +local haUrl = noctalia.getConfig("ha_url") +local haToken = noctalia.getConfig("ha_token") +local configuredEntityId = noctalia.getConfig("shortcut_entity_4") or "" +local SLOT_LABEL = noctalia.tr("shortcut.label_4") + +local entityStates = {} +local pendingToggle = {} +local pendingSince = {} +local pendingTimerToken = {} +local pendingTimerSeq = 0 + +local PENDING_TIMEOUT_SECONDS = 8 +local render + +local function getCleanToken() + if type(haToken) ~= "string" then return "" end + return haToken:gsub("^%s+", ""):gsub("%s+$", "") +end + +local function stateGlyph(domain, isOn) + if domain == "light" then return isOn and "bulb" or "bulb-off" + elseif domain == "switch" or domain == "input_boolean" then return isOn and "toggle-right" or "toggle-left" + elseif domain == "fan" then return isOn and "wind" or "wind-off" + elseif domain == "lock" then return isOn and "lock" or "lock-open" + elseif domain == "cover" then return isOn and "door-open" or "door" + end + return "smart-home" +end + +local function getEntity() + if configuredEntityId == "" then return nil end + return entityStates[configuredEntityId] +end + +local function clearPending(entityId) + pendingToggle[entityId] = nil + pendingSince[entityId] = nil + pendingTimerToken[entityId] = nil +end + +local function isPendingTimedOut(entityId, now) + local startedAt = pendingSince[entityId] + if not startedAt then return false end + return (now or os.clock()) - startedAt >= PENDING_TIMEOUT_SECONDS +end + +local function reconcilePending(now) + for entityId, expected in pairs(pendingToggle) do + local real = entityStates[entityId] + if not real or real.state == expected or isPendingTimedOut(entityId, now) then + clearPending(entityId) + end + end +end + +local function schedulePendingTimeout(entityId) + pendingTimerSeq = pendingTimerSeq + 1 + local token = pendingTimerSeq + pendingSince[entityId] = os.clock() + pendingTimerToken[entityId] = token + + noctalia.runAsync("sleep " .. tostring(PENDING_TIMEOUT_SECONDS), function(_result) + if pendingTimerToken[entityId] ~= token then return end + if pendingToggle[entityId] and isPendingTimedOut(entityId) then + clearPending(entityId) + render() + end + end) +end + +render = function() + reconcilePending(os.clock()) + + local entity = getEntity() + + if not entity then + shortcut.setLabel(configuredEntityId ~= "" and configuredEntityId or SLOT_LABEL) + shortcut.setIcon("smart-home") + shortcut.setActive(false) + shortcut.setEnabled(false) + return + end + + local eid = entity.entity_id + local pending = pendingToggle[eid] + + if pending then + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon("loader") + shortcut.setActive(pending == "on") + shortcut.setEnabled(false) + return + end + + local isOn = entity.state == "on" + shortcut.setLabel(entity.friendly_name or eid) + shortcut.setIcon(stateGlyph(entity.domain, true), stateGlyph(entity.domain, false)) + shortcut.setActive(isOn) + shortcut.setEnabled(true) +end + +noctalia.state.watch("entities", function(value) + entityStates = value or {} + reconcilePending(os.clock()) + render() +end) + +noctalia.state.watch("connection_status", function(_value) + render() +end) + +function onClick() + reconcilePending(os.clock()) + + local entity = getEntity() + local cleanToken = getCleanToken() + if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + + local eid = entity.entity_id + if pendingToggle[eid] then return end + + local newState = entity.state == "on" and "off" or "on" + pendingToggle[eid] = newState + schedulePendingTimeout(eid) + + local encoded = noctalia.json.encode({ entity_id = eid }) + + noctalia.http({ + url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + method = "POST", + headers = { + "Authorization: Bearer " .. cleanToken, + "Content-Type: application/json", + }, + body = encoded, + }, function(response)end) + + render() +end + +entityStates = noctalia.state.get("entities") or {} +render() diff --git a/hassio/shortcut_panel.luau b/hassio/shortcut_panel.luau new file mode 100644 index 0000000..3b0e832 --- /dev/null +++ b/hassio/shortcut_panel.luau @@ -0,0 +1,10 @@ +--!nonstrict + +shortcut.setLabel(noctalia.tr("shortcut.panel_label")) +shortcut.setIcon("layout-list") +shortcut.setActive(false) +shortcut.setEnabled(true) + +function onClick() + noctalia.togglePanel("pozzoo/hassio:entity_manager") +end diff --git a/hassio/thumbnail.webp b/hassio/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..af01f61374330db347408d6605c99918f8fde22e GIT binary patch literal 48548 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 MU3)pVsyQ$K0J{R*Q2+n{ literal 0 HcmV?d00001 diff --git a/hassio/translations/en.json b/hassio/translations/en.json new file mode 100644 index 0000000..9715269 --- /dev/null +++ b/hassio/translations/en.json @@ -0,0 +1,63 @@ +{ + "widget": { + "status_connected": "Connected", + "status_disconnected": "Disconnected", + "status_connecting": "Connecting", + "status_auth_failed": "Auth Failed", + "status_unconfigured": "Not Configured", + "tooltip": "Home Assistant: {status}", + "tooltip_entities": "Home Assistant: {status} ({count} entities)", + "refreshing_connection": "Refreshing connection…" + }, + "shortcut": { + "title": "Home Assistant", + "panel_label": "Entity Manager", + "label_1": "Quick Toggle 1", + "label_2": "Quick Toggle 2", + "label_3": "Quick Toggle 3", + "label_4": "Quick Toggle 4" + }, + "panel": { + "manage_entities_title": "Manage Entities", + "search_placeholder": "Search entities…", + "not_configured": "Not configured. Set your Home Assistant URL and token in settings.", + "auth_failed": "Authentication failed. Check your access token.", + "connecting": "Connecting…", + "disconnected_reconnecting": "Disconnected. Reconnecting…", + "no_entities_monitored": "No entities monitored yet. Use the browser to add some.", + "status_fallback": "Status: {status}", + "loading_entities": "Loading entities…", + "no_entities_found": "No entities found", + "no_entities_match": "No entities match your search", + "state_on_brightness": "On · {percent}%", + "brightness": "Brightness", + "color_temp": "Color Temperature", + "hue": "Hue", + "save_failed": "Failed to save monitored entities", + "save_failed_no_data_dir": "Could not save: plugin data directory unavailable" + }, + "settings": { + "url": { + "label": "Home Assistant URL", + "description": "The URL to your Home Assistant instance (e.g., http://homeassistant.local:8123)" + }, + "token": { + "label": "Long-Lived Access Token", + "description": "Create a token in Home Assistant under Profile → Security → Long-lived access tokens" + }, + "shortcut_entity": { + "description": "Home Assistant entity ID to show and toggle on this tile (e.g. light.living_room)." + }, + "shortcut_entity_1": { "label": "Quick Toggle 1 - Entity ID" }, + "shortcut_entity_2": { "label": "Quick Toggle 2 - Entity ID" }, + "shortcut_entity_3": { "label": "Quick Toggle 3 - Entity ID" }, + "shortcut_entity_4": { "label": "Quick Toggle 4 - Entity ID" }, + "show_entity_count": { + "label": "Show entity count in widget" + } + }, + "notifications": { + "auth_failed": "Authentication failed. Check your access token.", + "reconnect_failed": "Unable to reconnect to Home Assistant after {count} attempts." + } +} diff --git a/hassio/translations/pt-BR.json b/hassio/translations/pt-BR.json new file mode 100644 index 0000000..311592e --- /dev/null +++ b/hassio/translations/pt-BR.json @@ -0,0 +1,63 @@ +{ + "widget": { + "status_connected": "Conectado", + "status_disconnected": "Desconectado", + "status_connecting": "Conectando", + "status_auth_failed": "Falha de Autenticação", + "status_unconfigured": "Não Configurado", + "tooltip": "Home Assistant: {status}", + "tooltip_entities": "Home Assistant: {status} ({count} entidades)", + "refreshing_connection": "Atualizando conexão…" + }, + "shortcut": { + "title": "Home Assistant", + "panel_label": "Gerenciador de Entidades", + "label_1": "Botão Rápido 1", + "label_2": "Botão Rápido 2", + "label_3": "Botão Rápido 3", + "label_4": "Botão Rápido 4" + }, + "panel": { + "manage_entities_title": "Gerenciar Entidades", + "search_placeholder": "Buscar entidades…", + "not_configured": "Não configurado. Defina a URL e o token do Home Assistant nas configurações.", + "auth_failed": "Falha na autenticação. Verifique seu token de acesso.", + "connecting": "Conectando…", + "disconnected_reconnecting": "Desconectado. Reconectando…", + "no_entities_monitored": "Nenhuma entidade monitorada ainda. Use o navegador para adicionar.", + "status_fallback": "Status: {status}", + "loading_entities": "Carregando entidades…", + "no_entities_found": "Nenhuma entidade encontrada", + "no_entities_match": "Nenhuma entidade corresponde à sua busca", + "state_on_brightness": "Ligado · {percent}%", + "brightness": "Brilho", + "color_temp": "Temperatura de Cor", + "hue": "Matiz", + "save_failed": "Falha ao salvar as entidades monitoradas", + "save_failed_no_data_dir": "Não foi possível salvar: diretório de dados do plugin indisponível" + }, + "settings": { + "url": { + "label": "URL do Home Assistant", + "description": "A URL para sua instância do Home Assistant (e.g., http://homeassistant.local:8123)" + }, + "token": { + "label": "Token de Acesso Longo", + "description": "Crie um token no Home Assistant em Profile → Security → Long-lived access tokens" + }, + "shortcut_entity": { + "description": "ID da entidade do Home Assistant para mostrar e alternar neste espaço (e.g. light.living_room)." + }, + "shortcut_entity_1": { "label": "Botão Rápido 1 - ID da Entidade" }, + "shortcut_entity_2": { "label": "Botão Rápido 2 - ID da Entidade" }, + "shortcut_entity_3": { "label": "Botão Rápido 3 - ID da Entidade" }, + "shortcut_entity_4": { "label": "Botão Rápido 4 - ID da Entidade" }, + "show_entity_count": { + "label": "Mostrar o Número de Entidades" + } + }, + "notifications": { + "auth_failed": "Falha na autenticação. Verifique seu token de acesso.", + "reconnect_failed": "Não foi possível reconectar ao Home Assistant após {count} tentativas." + } +} diff --git a/hassio/widget.luau b/hassio/widget.luau new file mode 100644 index 0000000..07e6d60 --- /dev/null +++ b/hassio/widget.luau @@ -0,0 +1,96 @@ +--!nonstrict + +local haUrl = noctalia.getConfig("ha_url") +local showEntityCount = noctalia.getConfig("show_entity_count") + +local status = "unconfigured" +local entityCount = 0 + +local render + +local function tr(key, subst) + return noctalia.tr("widget." .. key, subst) +end + +noctalia.state.watch("connection_status", function(value) + status = value or "unconfigured" + if render then render() end +end) + +noctalia.state.watch("entity_count", function(value) + entityCount = value or 0 + if render then render() end +end) + +local function getStatusText() + if status == "connected" then + return tr("status_connected") + elseif status == "connecting" then + return tr("status_connecting") + elseif status == "disconnected" then + return tr("status_disconnected") + elseif status == "auth_failed" then + return tr("status_auth_failed") + else + return tr("status_unconfigured") + end +end + +local function getStatusColor() + if status == "connected" then + return "primary" + elseif status == "connecting" then + return "on_error" + elseif status == "disconnected" or status == "auth_failed" then + return "error" + else + return "on_surface_variant" + end +end + +render = function() + barWidget.setGlyph("smart-home") + barWidget.setGlyphColor(getStatusColor()) + + if showEntityCount and entityCount > 0 then + barWidget.setText(tostring(entityCount)) + barWidget.setTooltip(tr("tooltip_entities", { + status = getStatusText(), + count = entityCount + })) + else + barWidget.setTooltip(tr("tooltip", { + status = getStatusText() + })) + end +end + +function update() + noctalia.setUpdateInterval(5000) + + if status == "unconfigured" then + local serviceStatus = noctalia.state.get("connection_status") + if serviceStatus then + status = serviceStatus + end + end + + render() +end + +function onClick() + noctalia.togglePanel("pozzoo/hassio:entity_manager") +end + +function onRightClick() + if haUrl and haUrl ~= "" then + noctalia.runAsync("xdg-open " .. ("'" .. haUrl:gsub("'", "'\\''") .. "'")) + end +end + +function onIpc(event, payload) + if event == "refresh" then + noctalia.state.set("command", "refresh") + noctalia.notify(noctalia.tr("shortcut.title"), tr("refreshing_connection")) + end +end From 8c1d5ff2f67c42f04c8066a0ce16bf74ba2b5df8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 18 Jul 2026 05:06:37 +0000 Subject: [PATCH 30/34] chore: update plugin catalog [skip ci] --- catalog.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/catalog.toml b/catalog.toml index cda2f2f..688ed17 100644 --- a/catalog.toml +++ b/catalog.toml @@ -228,3 +228,14 @@ icon = "folder-open" description = "Open a recent Zed project from the launcher. Type /zed to list your projects." plugin_api = 3 tags = ["launcher", "development", "productivity"] + +[[plugin]] +id = "pozzoo/hassio" +name = "Home Assistant" +version = "2.0.0" +author = "Pozzoo" +license = "MIT" +icon = "smart-home" +description = "Monitor and control Home Assistant entities from the bar. Displays entity states and provides quick toggles." +plugin_api = 4 +tags = ["bar", "panel", "service", "shortcut", "network", "indicator"] From a3287ecc1f2e1f14501aaa2f75bae0fe944d96b3 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Sat, 18 Jul 2026 01:22:35 -0400 Subject: [PATCH 31/34] fix(portctl): normalize category translation keys --- portctl/panel.luau | 2 +- portctl/plugin.toml | 2 +- portctl/translations/en.json | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/portctl/panel.luau b/portctl/panel.luau index 3aad2ab..2087f77 100644 --- a/portctl/panel.luau +++ b/portctl/panel.luau @@ -277,7 +277,7 @@ local function catSection(catName, ports) fill = "surface_container/0.4", }, { ui.glyph({ name = meta.icon, size = 12, color = meta.color }), - ui.label({ text = noctalia.tr("categories." .. catName), fontSize = 11, fontWeight = "bold", color = meta.color }), + ui.label({ text = noctalia.tr("categories." .. catName:lower()), fontSize = 11, fontWeight = "bold", color = meta.color }), ui.label({ text = tostring(#ports), fontSize = 10, color = meta.color .. "/0.6" }), })) diff --git a/portctl/plugin.toml b/portctl/plugin.toml index abaa635..a89e4bf 100644 --- a/portctl/plugin.toml +++ b/portctl/plugin.toml @@ -2,7 +2,7 @@ id = "rxtsel/portctl" name = "Portctl" -version = "0.2.0" +version = "0.2.1" plugin_api = 3 author = "Cristhian Melo" license = "MIT" diff --git a/portctl/translations/en.json b/portctl/translations/en.json index 9c3084f..516ac41 100644 --- a/portctl/translations/en.json +++ b/portctl/translations/en.json @@ -13,12 +13,12 @@ "pid_copied": "Copied PID {pid}" }, "categories": { - "Development": "Development", - "Databases": "Databases", - "Containers": "Containers", - "Servers": "Servers", - "Cloud": "Cloud", - "Other": "Other" + "development": "Development", + "databases": "Databases", + "containers": "Containers", + "servers": "Servers", + "cloud": "Cloud", + "other": "Other" }, "service": { "terminated": "Process {pid} terminated", From 3e87f3a086b4696ee52ef0ddaf484875968e62be Mon Sep 17 00:00:00 2001 From: Lemmy Date: Sat, 18 Jul 2026 01:27:43 -0400 Subject: [PATCH 32/34] ci(chore): pull/push scripts --- .tools/i18n-pull.sh | 111 ++++++++++++++++++++++++++++++ .tools/i18n-push.sh | 164 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 9 +++ 3 files changed, 284 insertions(+) create mode 100755 .tools/i18n-pull.sh create mode 100755 .tools/i18n-push.sh diff --git a/.tools/i18n-pull.sh b/.tools/i18n-pull.sh new file mode 100755 index 0000000..b3d129d --- /dev/null +++ b/.tools/i18n-pull.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env -S bash + +set -euo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)" +API_BASE="${I18N_API_BASE:-https://i18n.noctalia.dev}" +PROJECT_SLUG="community-plugins" + +if [[ $# -ne 0 ]]; then + echo "Usage: $0" >&2 + exit 1 +fi + +for command in curl jq; do + if ! command -v "$command" >/dev/null 2>&1; then + echo "Error: $command is required" >&2 + exit 1 + fi +done + +echo "Project: $PROJECT_SLUG" +echo "Output repository: $REPO_ROOT" +read -r -p "Pull translations and overwrite returned local files? [y/N] " reply +if [[ ! "$reply" =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 0 +fi + +RESPONSE_FILE="$(mktemp)" +STAGING_DIR="$(mktemp -d)" +trap 'rm -f "$RESPONSE_FILE"; rm -rf "$STAGING_DIR"' EXIT + +HTTP_CODE="$(curl --silent --show-error \ + --output "$RESPONSE_FILE" \ + --write-out '%{http_code}' \ + "$API_BASE/api/projects/$PROJECT_SLUG/pull")" +if [[ "$HTTP_CODE" != "200" ]]; then + echo "Error: HTTP $HTTP_CODE" >&2 + jq . "$RESPONSE_FILE" 2>/dev/null || cat "$RESPONSE_FILE" + exit 1 +fi + +if ! jq -e 'type == "object" and length > 0' "$RESPONSE_FILE" >/dev/null; then + echo "Error: API response must be a non-empty locale object" >&2 + exit 1 +fi + +mapfile -t LOCALES < <(jq -r 'keys[]' "$RESPONSE_FILE") +FILE_COUNT=0 +for locale in "${LOCALES[@]}"; do + if [[ ! "$locale" =~ ^[A-Za-z0-9][A-Za-z0-9_-]*$ ]]; then + echo "Error: API returned an invalid locale: $locale" >&2 + exit 1 + fi + if ! jq -e --arg locale "$locale" '.[$locale] | type == "object" and length > 0' "$RESPONSE_FILE" >/dev/null; then + echo "Error: Locale payload must be a non-empty object: $locale" >&2 + exit 1 + fi + + mapfile -t PLUGINS < <(jq -r --arg locale "$locale" '.[$locale] | keys[]' "$RESPONSE_FILE") + for plugin in "${PLUGINS[@]}"; do + if [[ ! "$plugin" =~ ^[a-z0-9][a-z0-9._-]*$ ]]; then + echo "Error: API returned an invalid plugin name: $plugin" >&2 + exit 1 + fi + if [[ ! -f "$REPO_ROOT/$plugin/plugin.toml" ]]; then + echo "Error: API returned unknown plugin: $plugin" >&2 + exit 1 + fi + if ! jq -e --arg locale "$locale" --arg plugin "$plugin" ' + def valid_translation: + if type == "object" then all(.[]; valid_translation) + else type == "string" + end; + .[$locale][$plugin] | type == "object" and valid_translation + ' "$RESPONSE_FILE" >/dev/null; then + echo "Error: Invalid translation payload for $plugin/$locale" >&2 + exit 1 + fi + + mkdir -p "$STAGING_DIR/$plugin/translations" + jq --arg locale "$locale" --arg plugin "$plugin" \ + '.[$locale][$plugin]' "$RESPONSE_FILE" \ + >"$STAGING_DIR/$plugin/translations/$locale.json" + FILE_COUNT=$((FILE_COUNT + 1)) + done +done + +shopt -s nullglob +MANIFESTS=("$REPO_ROOT"/*/plugin.toml) +for manifest in "${MANIFESTS[@]}"; do + plugin="$(basename -- "$(dirname -- "$manifest")")" + if ! jq -e --arg plugin "$plugin" '.en[$plugin] | type == "object"' "$RESPONSE_FILE" >/dev/null; then + echo "Error: English payload is missing plugin: $plugin" >&2 + exit 1 + fi +done + +while IFS= read -r -d '' staged_file; do + relative_path="${staged_file#"$STAGING_DIR/"}" + output_file="$REPO_ROOT/$relative_path" + output_dir="$(dirname -- "$output_file")" + mkdir -p "$output_dir" + temporary_file="$(mktemp "$output_dir/.i18n-pull.XXXXXX")" + cp -- "$staged_file" "$temporary_file" + mv -- "$temporary_file" "$output_file" + echo "Saved: $relative_path" +done < <(find "$STAGING_DIR" -type f -name '*.json' -print0 | sort -z) + +echo "Successfully pulled $FILE_COUNT translation file(s)." diff --git a/.tools/i18n-push.sh b/.tools/i18n-push.sh new file mode 100755 index 0000000..db8ff36 --- /dev/null +++ b/.tools/i18n-push.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env -S bash + +set -euo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)" +API_BASE="${I18N_API_BASE:-https://i18n.noctalia.dev}" +PROJECT_SLUG="community-plugins" +OVERWRITE=false +SINGLE_LANG="" + +usage() { + echo "Usage: COMMUNITY_PLUGINS_PUSH_SECRET=... $0 [--overwrite] [--lang ]" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --overwrite) + OVERWRITE=true + shift + ;; + --lang) + if [[ $# -lt 2 ]]; then + echo "Error: --lang requires a locale" >&2 + usage >&2 + exit 1 + fi + SINGLE_LANG="$2" + shift 2 + ;; + --help|-h) + usage + exit 0 + ;; + *) + echo "Error: Unknown argument: $1" >&2 + usage >&2 + exit 1 + ;; + esac +done + +for command in curl jq; do + if ! command -v "$command" >/dev/null 2>&1; then + echo "Error: $command is required" >&2 + exit 1 + fi +done + +if [[ -z "${COMMUNITY_PLUGINS_PUSH_SECRET:-}" ]]; then + echo "Error: COMMUNITY_PLUGINS_PUSH_SECRET is required" >&2 + exit 1 +fi + +if [[ -n "$SINGLE_LANG" && ! "$SINGLE_LANG" =~ ^[A-Za-z0-9][A-Za-z0-9_-]*$ ]]; then + echo "Error: Invalid locale: $SINGLE_LANG" >&2 + exit 1 +fi + +shopt -s nullglob +MANIFESTS=("$REPO_ROOT"/*/plugin.toml) +if [[ ${#MANIFESTS[@]} -eq 0 ]]; then + echo "Error: No plugin manifests found in $REPO_ROOT" >&2 + exit 1 +fi + +validate_translation_file() { + local file="$1" + if ! jq -e ' + def valid_translation: + if type == "object" then all(.[]; valid_translation) + else type == "string" + end; + type == "object" and valid_translation + ' "$file" >/dev/null; then + echo "Error: Translation must be a JSON object containing only objects and strings: $file" >&2 + exit 1 + fi +} + +COMBINED_JSON='{}' +FILE_COUNT=0 + +for manifest in "${MANIFESTS[@]}"; do + plugin_dir="$(dirname -- "$manifest")" + plugin="$(basename -- "$plugin_dir")" + if [[ ! "$plugin" =~ ^[a-z0-9][a-z0-9._-]*$ ]]; then + echo "Error: Invalid plugin directory name: $plugin" >&2 + exit 1 + fi + + if [[ -n "$SINGLE_LANG" ]]; then + translation_files=("$plugin_dir/translations/$SINGLE_LANG.json") + else + english_file="$plugin_dir/translations/en.json" + if [[ ! -f "$english_file" ]]; then + echo "Error: Missing English translation: $english_file" >&2 + exit 1 + fi + translation_files=("$plugin_dir"/translations/*.json) + fi + + for file in "${translation_files[@]}"; do + [[ -f "$file" ]] || continue + locale="$(basename -- "$file" .json)" + if [[ ! "$locale" =~ ^[A-Za-z0-9][A-Za-z0-9_-]*$ ]]; then + echo "Error: Invalid locale filename: $file" >&2 + exit 1 + fi + validate_translation_file "$file" + COMBINED_JSON="$(jq \ + --arg locale "$locale" \ + --arg plugin "$plugin" \ + --slurpfile content "$file" \ + '. + {($locale): ((.[$locale] // {}) + {($plugin): $content[0]})}' \ + <<<"$COMBINED_JSON")" + echo "Loaded: $plugin/translations/$locale.json" + FILE_COUNT=$((FILE_COUNT + 1)) + done +done + +if [[ $FILE_COUNT -eq 0 ]]; then + if [[ -n "$SINGLE_LANG" ]]; then + echo "Error: No plugin provides locale: $SINGLE_LANG" >&2 + else + echo "Error: No translation files found" >&2 + fi + exit 1 +fi + +LOCALE_COUNT="$(jq 'keys | length' <<<"$COMBINED_JSON")" +echo "Project: $PROJECT_SLUG" +echo "Found $FILE_COUNT file(s) across $LOCALE_COUNT locale(s)" +read -r -p "Push these translations to $API_BASE? [y/N] " reply +if [[ ! "$reply" =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 0 +fi + +PUSH_URL="$API_BASE/api/projects/$PROJECT_SLUG/push" +if [[ "$OVERWRITE" == true ]]; then + PUSH_URL="$PUSH_URL?overwrite=true" + echo "Overwrite mode enabled" +fi + +RESPONSE_FILE="$(mktemp)" +trap 'rm -f "$RESPONSE_FILE"' EXIT +HTTP_CODE="$(curl --silent --show-error \ + --output "$RESPONSE_FILE" \ + --write-out '%{http_code}' \ + --request POST \ + --header "Authorization: Bearer $COMMUNITY_PLUGINS_PUSH_SECRET" \ + --header "Content-Type: application/json" \ + --data-binary @- \ + "$PUSH_URL" <<<"$COMBINED_JSON")" + +if [[ "$HTTP_CODE" != "200" ]]; then + echo "Error: HTTP $HTTP_CODE" >&2 + jq . "$RESPONSE_FILE" 2>/dev/null || cat "$RESPONSE_FILE" + exit 1 +fi + +echo "Translations pushed successfully." +jq . "$RESPONSE_FILE" 2>/dev/null || cat "$RESPONSE_FILE" diff --git a/README.md b/README.md index 3080c21..a31f9c3 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,15 @@ error messages show the exact missing value, while maintainers review the useful Write `translations/en.json` only. Every `label_key` and `description_key` in your manifest must resolve to a key in it, and CI checks this. Do not add machine-translated locales; other languages are handled separately. +To test the latest translated locales from [Noctalia Translate](https://i18n.noctalia.dev) in a working checkout, run: + +```sh +./.tools/i18n-pull.sh +``` + +The command asks for confirmation and overwrites the locale files returned by the translation service. It does not +delete local locale files that are absent from the export. Review the resulting diff before committing anything. + ### Tags The `tags` in `plugin.toml` are used for catalog search. Tags must be lowercase and selected from this list: From cd74418265da7e8854e2bc539b3877f4ace391be Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 18 Jul 2026 05:27:53 +0000 Subject: [PATCH 33/34] chore: update plugin catalog [skip ci] --- catalog.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog.toml b/catalog.toml index 688ed17..4ad8e14 100644 --- a/catalog.toml +++ b/catalog.toml @@ -155,7 +155,7 @@ tags = ["hardware"] [[plugin]] id = "rxtsel/portctl" name = "Portctl" -version = "0.2.0" +version = "0.2.1" author = "Cristhian Melo" license = "MIT" icon = "plug" From 1e23c02e0b05f34ce3f7130c07b14989c64ffecb Mon Sep 17 00:00:00 2001 From: Lemmy Date: Sat, 18 Jul 2026 01:36:29 -0400 Subject: [PATCH 34/34] ci(i18n): first pull, only automatic a-z re-ordering --- color_picker/translations/en.json | 65 ++++-- color_picker/translations/pt-BR.json | 65 ++++-- daily-wallpaper/translations/en.json | 24 +- dropwall/translations/en.json | 64 +++-- file-search/translations/en.json | 58 +++-- hassio/translations/en.json | 122 +++++----- hassio/translations/pt-BR.json | 122 +++++----- .../translations/en.json | 24 +- iio_lock/translations/en.json | 70 +++--- lyrics/translations/en.json | 152 ++++++------ mangowm-keymode/translations/en.json | 14 +- mini-docker/translations/en.json | 204 ++++++++-------- nix-monitor/translations/en.json | 220 ++++++++++++------ noctwhspr/translations/en.json | 10 +- portctl/translations/en.json | 76 +++--- prismlauncher-instances/translations/en.json | 24 +- proton-pass/translations/en.json | 10 +- sharednd/translations/en.json | 22 +- shelly/translations/en.json | 74 +++--- todo/translations/en.json | 42 ++-- um5606_fan_state/translations/en.json | 14 +- upbeat/translations/en.json | 28 +-- zed-provider/translations/en.json | 24 +- zed-provider/translations/fr.json | 24 +- 24 files changed, 881 insertions(+), 671 deletions(-) diff --git a/color_picker/translations/en.json b/color_picker/translations/en.json index fd0eebe..96f7287 100644 --- a/color_picker/translations/en.json +++ b/color_picker/translations/en.json @@ -1,31 +1,48 @@ { - "color_picker": "Color Picker", - "no_color_picked": "No color picked yet.", - "recent_colors": "Recent Colors", - "opacity": "Opacity", - "no_history": "No colors in history yet.", "color_copied": "Color {color} copied.", "color_picked": "Color {color} picked.", - "hyprpicker_not_installed": "hyprpicker is not installed.", + "color_picker": "Color Picker", "could_not_parse": "could not parse hyprpicker output.", "glyph": "Glyph", "hex": "HEX", + "hyprpicker_not_installed": "hyprpicker is not installed.", + "no_color_picked": "No color picked yet.", + "no_history": "No colors in history yet.", + "opacity": "Opacity", + "recent_colors": "Recent Colors", "rgb": "RGB", - - "settings.hyprpicker_format.label": "Default Format", - "settings.hyprpicker_format.description": "Default color format to copy to clipboard (Hex or RGB).", - "settings.swatch_radius.label": "Swatches Corner Roundness", - "settings.swatch_radius.description": "Corner radius of the history swatches and current-color preview.", - "settings.hyprpicker_lowercase.label": "Lowercase Hex", - "settings.hyprpicker_lowercase.description": "Outputs the hexcode in lowercase.", - "settings.hyprpicker_scale.label": "Zoom Scale", - "settings.hyprpicker_scale.description": "Zoom lens magnification, from 1 to 10.", - "settings.hyprpicker_radius.label": "Zoom Radius", - "settings.hyprpicker_radius.description": "Zoom lens circle radius in pixels, from 1 to 1000.", - "settings.hyprpicker_no_zoom.label": "Disable Zoom Lens", - "settings.hyprpicker_no_zoom.description": "Turns off the magnifying zoom lens while picking.", - "settings.hyprpicker_disable_preview.label": "Disable Live Preview", - "settings.hyprpicker_disable_preview.description": "Turns off the live color preview while picking.", - "settings.hyprpicker_cursor.label": "Show cursor", - "settings.hyprpicker_cursor.description": "Includes the cursor in the frozen screen preview." -} \ No newline at end of file + "settings": { + "hyprpicker_cursor": { + "description": "Includes the cursor in the frozen screen preview.", + "label": "Show cursor" + }, + "hyprpicker_disable_preview": { + "description": "Turns off the live color preview while picking.", + "label": "Disable Live Preview" + }, + "hyprpicker_format": { + "description": "Default color format to copy to clipboard (Hex or RGB).", + "label": "Default Format" + }, + "hyprpicker_lowercase": { + "description": "Outputs the hexcode in lowercase.", + "label": "Lowercase Hex" + }, + "hyprpicker_no_zoom": { + "description": "Turns off the magnifying zoom lens while picking.", + "label": "Disable Zoom Lens" + }, + "hyprpicker_radius": { + "description": "Zoom lens circle radius in pixels, from 1 to 1000.", + "label": "Zoom Radius" + }, + "hyprpicker_scale": { + "description": "Zoom lens magnification, from 1 to 10.", + "label": "Zoom Scale" + }, + "swatch_radius": { + "description": "Corner radius of the history swatches and current-color preview.", + "label": "Swatches Corner Roundness" + } + } +} diff --git a/color_picker/translations/pt-BR.json b/color_picker/translations/pt-BR.json index dc85550..3b34248 100644 --- a/color_picker/translations/pt-BR.json +++ b/color_picker/translations/pt-BR.json @@ -1,31 +1,48 @@ { - "color_picker": "Seletor de Cores", - "no_color_picked": "Nenhuma cor escolhida ainda.", - "recent_colors": "Cores Recentes", - "opacity": "Opacidade", - "no_history": "Ainda não há cores no histórico.", "color_copied": "Cor {color} copiada.", "color_picked": "Cor {color} selecionada.", - "hyprpicker_not_installed": "hyprpicker não está instalado.", + "color_picker": "Seletor de Cores", "could_not_parse": "não foi possível extrair a saída do hyprpicker.", "glyph": "Símbolo", "hex": "HEX", + "hyprpicker_not_installed": "hyprpicker não está instalado.", + "no_color_picked": "Nenhuma cor escolhida ainda.", + "no_history": "Ainda não há cores no histórico.", + "opacity": "Opacidade", + "recent_colors": "Cores Recentes", "rgb": "RGB", - - "settings.hyprpicker_format.label": "Formato Padrão", - "settings.hyprpicker_format.description": "Formato de cor padrão para copiar para a área de transferência (Hex ou RGB).", - "settings.swatch_radius.label": "Arredondamento de Cantos das Amostras", - "settings.swatch_radius.description": "Raio dos cantos das amostras do histórico e da prévia da cor atual.", - "settings.hyprpicker_lowercase.label": "Hexadecimal em Minúsculas", - "settings.hyprpicker_lowercase.description": "Exibe o código hexadecimal em letras minúsculas.", - "settings.hyprpicker_scale.label": "Escala do Zoom", - "settings.hyprpicker_scale.description": "Ampliação da lupa, de 1 a 10.", - "settings.hyprpicker_radius.label": "Raio do Zoom", - "settings.hyprpicker_radius.description": "Raio do círculo da lupa em pixels, de 1 a 1000.", - "settings.hyprpicker_no_zoom.label": "Desabilitar Lupa", - "settings.hyprpicker_no_zoom.description": "Dpesativa a lupa ao selecionar a cor.", - "settings.hyprpicker_disable_preview.label": "Desabilitar Prévia em Tempo Real", - "settings.hyprpicker_disable_preview.description": "Desativa a prévia da cor em tempo real ao selecionar.", - "settings.hyprpicker_cursor.label": "Mostrar cursor", - "settings.hyprpicker_cursor.description": "Inclui o cursor na prévia congelada da tela." -} \ No newline at end of file + "settings": { + "hyprpicker_cursor": { + "description": "Inclui o cursor na prévia congelada da tela.", + "label": "Mostrar cursor" + }, + "hyprpicker_disable_preview": { + "description": "Desativa a prévia da cor em tempo real ao selecionar.", + "label": "Desabilitar Prévia em Tempo Real" + }, + "hyprpicker_format": { + "description": "Formato de cor padrão para copiar para a área de transferência (Hex ou RGB).", + "label": "Formato Padrão" + }, + "hyprpicker_lowercase": { + "description": "Exibe o código hexadecimal em letras minúsculas.", + "label": "Hexadecimal em Minúsculas" + }, + "hyprpicker_no_zoom": { + "description": "Dpesativa a lupa ao selecionar a cor.", + "label": "Desabilitar Lupa" + }, + "hyprpicker_radius": { + "description": "Raio do círculo da lupa em pixels, de 1 a 1000.", + "label": "Raio do Zoom" + }, + "hyprpicker_scale": { + "description": "Ampliação da lupa, de 1 a 10.", + "label": "Escala do Zoom" + }, + "swatch_radius": { + "description": "Raio dos cantos das amostras do histórico e da prévia da cor atual.", + "label": "Arredondamento de Cantos das Amostras" + } + } +} diff --git a/daily-wallpaper/translations/en.json b/daily-wallpaper/translations/en.json index 8d1260b..b6e215f 100644 --- a/daily-wallpaper/translations/en.json +++ b/daily-wallpaper/translations/en.json @@ -1,9 +1,19 @@ { - "notify.applied": "Wallpaper applied", - "notify.failed": "Daily wallpaper failed", - "settings.locale.description": "Bing market locale such as en-US, de-DE, or fr-FR. Empty uses en-US.", - "settings.locale.label": "Locale", - "settings.source.label": "Source", - "settings.source.options.bing": "Bing", - "settings.source.options.nasa": "NASA" + "notify": { + "applied": "Wallpaper applied", + "failed": "Daily wallpaper failed" + }, + "settings": { + "locale": { + "description": "Bing market locale such as en-US, de-DE, or fr-FR. Empty uses en-US.", + "label": "Locale" + }, + "source": { + "label": "Source", + "options": { + "bing": "Bing", + "nasa": "NASA" + } + } + } } diff --git a/dropwall/translations/en.json b/dropwall/translations/en.json index 18025db..4deb0c0 100644 --- a/dropwall/translations/en.json +++ b/dropwall/translations/en.json @@ -1,27 +1,41 @@ { - "title": "DropWall", - "settings.per_monitor.label": "Per-monitor drop", - "settings.per_monitor.description": "Set the wallpaper only on the monitor the image was dropped on. When off, apply it to every output.", - "settings.copy_to_wallpaper_dir.label": "Copy into wallpaper directory", - "settings.copy_to_wallpaper_dir.description": "Copy the dropped image into the system wallpaper directory before applying. Existing files are never replaced; a numeric suffix is added when needed.", - "settings.notify_on_set.label": "Notify on set", - "settings.notify_on_set.description": "Show a notification when a dropped image is applied.", - "settings.layer.label": "Drop surface layer", - "settings.layer.description": "Layer-shell layer for the invisible drop surface. \"Background\" is the least intrusive; use \"Bottom\" if drops don't register.", - "settings.layer.options.background": "Background", - "settings.layer.options.bottom": "Bottom", - "notify.set_title": "Wallpaper set", - "notify.invalid_title": "Not an image (jpg, png, webp, bmp, gif)", - "notify.missing_title": "Dropped file not found", - "notify.output_error_title": "Could not identify the target monitor", - "notify.helper_error_title": "DropWall helper error", - "notify.python_missing": "python3 is not available on PATH.", - "notify.plugin_dir_missing": "Noctalia did not provide the plugin directory.", - "notify.helper_file_missing": "The DropWall supervisor file is missing.", - "notify.helper_start_failed": "Noctalia could not open the helper stream.", - "notify.helper_busy": "Another DropWall helper is still running. The plugin will keep retrying.", - "notify.no_outputs": "The helper could not create a drop target for any output.", - "notify.copy_dir_title": "Wallpaper was not copied", - "notify.copy_dir_missing": "No wallpaper directory is configured; the original file will be used.", - "notify.copy_failed": "The safe copy failed; the original file will be used." + "notify": { + "copy_dir_missing": "No wallpaper directory is configured; the original file will be used.", + "copy_dir_title": "Wallpaper was not copied", + "copy_failed": "The safe copy failed; the original file will be used.", + "helper_busy": "Another DropWall helper is still running. The plugin will keep retrying.", + "helper_error_title": "DropWall helper error", + "helper_file_missing": "The DropWall supervisor file is missing.", + "helper_start_failed": "Noctalia could not open the helper stream.", + "invalid_title": "Not an image (jpg, png, webp, bmp, gif)", + "missing_title": "Dropped file not found", + "no_outputs": "The helper could not create a drop target for any output.", + "output_error_title": "Could not identify the target monitor", + "plugin_dir_missing": "Noctalia did not provide the plugin directory.", + "python_missing": "python3 is not available on PATH.", + "set_title": "Wallpaper set" + }, + "settings": { + "copy_to_wallpaper_dir": { + "description": "Copy the dropped image into the system wallpaper directory before applying. Existing files are never replaced; a numeric suffix is added when needed.", + "label": "Copy into wallpaper directory" + }, + "layer": { + "description": "Layer-shell layer for the invisible drop surface. \"Background\" is the least intrusive; use \"Bottom\" if drops don't register.", + "label": "Drop surface layer", + "options": { + "background": "Background", + "bottom": "Bottom" + } + }, + "notify_on_set": { + "description": "Show a notification when a dropped image is applied.", + "label": "Notify on set" + }, + "per_monitor": { + "description": "Set the wallpaper only on the monitor the image was dropped on. When off, apply it to every output.", + "label": "Per-monitor drop" + } + }, + "title": "DropWall" } diff --git a/file-search/translations/en.json b/file-search/translations/en.json index 99d3f5b..82f2aa8 100644 --- a/file-search/translations/en.json +++ b/file-search/translations/en.json @@ -1,30 +1,44 @@ { - "title": "File Search", - "tooltip_open": "File search open — {path}\nClick to close", - "tooltip_closed": "File search — {path}\nClick to search · right-click: folder · middle-click: copy path", "copied_path": "Search folder path copied to clipboard", - "search_placeholder": "Type to search files and folders…", - "status_indexing": "Indexing {path}…", - "no_results": "No matches for \"{query}\"", "counts": "{shown} shown · {total} indexed", + "err_bad_record": "Ignored an invalid index record — rebuild the index", "err_index": "Failed to index the search folder", "err_no_fzf": "fzf not found — install fzf to use this plugin", "err_spawn": "Could not run the search command", - "err_bad_record": "Ignored an invalid index record — rebuild the index", - "tip_refresh": "Rebuild the file index", + "launcher": { + "indexing": "Indexing files…", + "no_results": "No matches", + "reindex_done": "Search index dropped — it rebuilds on the next search", + "reindex_title": "Rebuild search index" + }, + "no_results": "No matches for \"{query}\"", + "search_placeholder": "Type to search files and folders…", + "settings": { + "exclude_dirs": { + "description": "Folder names skipped while indexing, separated by ',' or ';' (matched anywhere in the tree), e.g. '.git, node_modules, .cache'.", + "label": "Excluded folders" + }, + "glyph": { + "description": "Icon shown on the bar.", + "label": "Glyph" + }, + "max_results": { + "description": "How many matches the panel lists at most.", + "label": "Max results" + }, + "search_folder": { + "description": "Root folder the search indexes. Defaults to your home folder when empty.", + "label": "Search folder" + }, + "show_hidden": { + "description": "Index files and folders whose name starts with a dot.", + "label": "Include hidden entries" + } + }, + "status_indexing": "Indexing {path}…", "tip_close": "Close", - "launcher.indexing": "Indexing files…", - "launcher.no_results": "No matches", - "launcher.reindex_title": "Rebuild search index", - "launcher.reindex_done": "Search index dropped — it rebuilds on the next search", - "settings.search_folder.label": "Search folder", - "settings.search_folder.description": "Root folder the search indexes. Defaults to your home folder when empty.", - "settings.exclude_dirs.label": "Excluded folders", - "settings.exclude_dirs.description": "Folder names skipped while indexing, separated by ',' or ';' (matched anywhere in the tree), e.g. '.git, node_modules, .cache'.", - "settings.show_hidden.label": "Include hidden entries", - "settings.show_hidden.description": "Index files and folders whose name starts with a dot.", - "settings.max_results.label": "Max results", - "settings.max_results.description": "How many matches the panel lists at most.", - "settings.glyph.label": "Glyph", - "settings.glyph.description": "Icon shown on the bar." + "tip_refresh": "Rebuild the file index", + "title": "File Search", + "tooltip_closed": "File search — {path}\nClick to search · right-click: folder · middle-click: copy path", + "tooltip_open": "File search open — {path}\nClick to close" } diff --git a/hassio/translations/en.json b/hassio/translations/en.json index 9715269..e7b6e7d 100644 --- a/hassio/translations/en.json +++ b/hassio/translations/en.json @@ -1,63 +1,71 @@ { - "widget": { - "status_connected": "Connected", - "status_disconnected": "Disconnected", - "status_connecting": "Connecting", - "status_auth_failed": "Auth Failed", - "status_unconfigured": "Not Configured", - "tooltip": "Home Assistant: {status}", - "tooltip_entities": "Home Assistant: {status} ({count} entities)", - "refreshing_connection": "Refreshing connection…" - }, - "shortcut": { - "title": "Home Assistant", - "panel_label": "Entity Manager", - "label_1": "Quick Toggle 1", - "label_2": "Quick Toggle 2", - "label_3": "Quick Toggle 3", - "label_4": "Quick Toggle 4" - }, - "panel": { - "manage_entities_title": "Manage Entities", - "search_placeholder": "Search entities…", - "not_configured": "Not configured. Set your Home Assistant URL and token in settings.", - "auth_failed": "Authentication failed. Check your access token.", - "connecting": "Connecting…", - "disconnected_reconnecting": "Disconnected. Reconnecting…", - "no_entities_monitored": "No entities monitored yet. Use the browser to add some.", - "status_fallback": "Status: {status}", - "loading_entities": "Loading entities…", - "no_entities_found": "No entities found", - "no_entities_match": "No entities match your search", - "state_on_brightness": "On · {percent}%", - "brightness": "Brightness", - "color_temp": "Color Temperature", - "hue": "Hue", - "save_failed": "Failed to save monitored entities", - "save_failed_no_data_dir": "Could not save: plugin data directory unavailable" - }, - "settings": { - "url": { - "label": "Home Assistant URL", - "description": "The URL to your Home Assistant instance (e.g., http://homeassistant.local:8123)" - }, - "token": { - "label": "Long-Lived Access Token", - "description": "Create a token in Home Assistant under Profile → Security → Long-lived access tokens" - }, - "shortcut_entity": { - "description": "Home Assistant entity ID to show and toggle on this tile (e.g. light.living_room)." - }, - "shortcut_entity_1": { "label": "Quick Toggle 1 - Entity ID" }, - "shortcut_entity_2": { "label": "Quick Toggle 2 - Entity ID" }, - "shortcut_entity_3": { "label": "Quick Toggle 3 - Entity ID" }, - "shortcut_entity_4": { "label": "Quick Toggle 4 - Entity ID" }, - "show_entity_count": { - "label": "Show entity count in widget" - } - }, "notifications": { "auth_failed": "Authentication failed. Check your access token.", "reconnect_failed": "Unable to reconnect to Home Assistant after {count} attempts." + }, + "panel": { + "auth_failed": "Authentication failed. Check your access token.", + "brightness": "Brightness", + "color_temp": "Color Temperature", + "connecting": "Connecting…", + "disconnected_reconnecting": "Disconnected. Reconnecting…", + "hue": "Hue", + "loading_entities": "Loading entities…", + "manage_entities_title": "Manage Entities", + "no_entities_found": "No entities found", + "no_entities_match": "No entities match your search", + "no_entities_monitored": "No entities monitored yet. Use the browser to add some.", + "not_configured": "Not configured. Set your Home Assistant URL and token in settings.", + "save_failed": "Failed to save monitored entities", + "save_failed_no_data_dir": "Could not save: plugin data directory unavailable", + "search_placeholder": "Search entities…", + "state_on_brightness": "On · {percent}%", + "status_fallback": "Status: {status}" + }, + "settings": { + "shortcut_entity": { + "description": "Home Assistant entity ID to show and toggle on this tile (e.g. light.living_room)." + }, + "shortcut_entity_1": { + "label": "Quick Toggle 1 - Entity ID" + }, + "shortcut_entity_2": { + "label": "Quick Toggle 2 - Entity ID" + }, + "shortcut_entity_3": { + "label": "Quick Toggle 3 - Entity ID" + }, + "shortcut_entity_4": { + "label": "Quick Toggle 4 - Entity ID" + }, + "show_entity_count": { + "label": "Show entity count in widget" + }, + "token": { + "description": "Create a token in Home Assistant under Profile → Security → Long-lived access tokens", + "label": "Long-Lived Access Token" + }, + "url": { + "description": "The URL to your Home Assistant instance (e.g., http://homeassistant.local:8123)", + "label": "Home Assistant URL" + } + }, + "shortcut": { + "label_1": "Quick Toggle 1", + "label_2": "Quick Toggle 2", + "label_3": "Quick Toggle 3", + "label_4": "Quick Toggle 4", + "panel_label": "Entity Manager", + "title": "Home Assistant" + }, + "widget": { + "refreshing_connection": "Refreshing connection…", + "status_auth_failed": "Auth Failed", + "status_connected": "Connected", + "status_connecting": "Connecting", + "status_disconnected": "Disconnected", + "status_unconfigured": "Not Configured", + "tooltip": "Home Assistant: {status}", + "tooltip_entities": "Home Assistant: {status} ({count} entities)" } } diff --git a/hassio/translations/pt-BR.json b/hassio/translations/pt-BR.json index 311592e..d5ef560 100644 --- a/hassio/translations/pt-BR.json +++ b/hassio/translations/pt-BR.json @@ -1,63 +1,71 @@ { - "widget": { - "status_connected": "Conectado", - "status_disconnected": "Desconectado", - "status_connecting": "Conectando", - "status_auth_failed": "Falha de Autenticação", - "status_unconfigured": "Não Configurado", - "tooltip": "Home Assistant: {status}", - "tooltip_entities": "Home Assistant: {status} ({count} entidades)", - "refreshing_connection": "Atualizando conexão…" - }, - "shortcut": { - "title": "Home Assistant", - "panel_label": "Gerenciador de Entidades", - "label_1": "Botão Rápido 1", - "label_2": "Botão Rápido 2", - "label_3": "Botão Rápido 3", - "label_4": "Botão Rápido 4" - }, - "panel": { - "manage_entities_title": "Gerenciar Entidades", - "search_placeholder": "Buscar entidades…", - "not_configured": "Não configurado. Defina a URL e o token do Home Assistant nas configurações.", - "auth_failed": "Falha na autenticação. Verifique seu token de acesso.", - "connecting": "Conectando…", - "disconnected_reconnecting": "Desconectado. Reconectando…", - "no_entities_monitored": "Nenhuma entidade monitorada ainda. Use o navegador para adicionar.", - "status_fallback": "Status: {status}", - "loading_entities": "Carregando entidades…", - "no_entities_found": "Nenhuma entidade encontrada", - "no_entities_match": "Nenhuma entidade corresponde à sua busca", - "state_on_brightness": "Ligado · {percent}%", - "brightness": "Brilho", - "color_temp": "Temperatura de Cor", - "hue": "Matiz", - "save_failed": "Falha ao salvar as entidades monitoradas", - "save_failed_no_data_dir": "Não foi possível salvar: diretório de dados do plugin indisponível" - }, - "settings": { - "url": { - "label": "URL do Home Assistant", - "description": "A URL para sua instância do Home Assistant (e.g., http://homeassistant.local:8123)" - }, - "token": { - "label": "Token de Acesso Longo", - "description": "Crie um token no Home Assistant em Profile → Security → Long-lived access tokens" - }, - "shortcut_entity": { - "description": "ID da entidade do Home Assistant para mostrar e alternar neste espaço (e.g. light.living_room)." - }, - "shortcut_entity_1": { "label": "Botão Rápido 1 - ID da Entidade" }, - "shortcut_entity_2": { "label": "Botão Rápido 2 - ID da Entidade" }, - "shortcut_entity_3": { "label": "Botão Rápido 3 - ID da Entidade" }, - "shortcut_entity_4": { "label": "Botão Rápido 4 - ID da Entidade" }, - "show_entity_count": { - "label": "Mostrar o Número de Entidades" - } - }, "notifications": { "auth_failed": "Falha na autenticação. Verifique seu token de acesso.", "reconnect_failed": "Não foi possível reconectar ao Home Assistant após {count} tentativas." + }, + "panel": { + "auth_failed": "Falha na autenticação. Verifique seu token de acesso.", + "brightness": "Brilho", + "color_temp": "Temperatura de Cor", + "connecting": "Conectando…", + "disconnected_reconnecting": "Desconectado. Reconectando…", + "hue": "Matiz", + "loading_entities": "Carregando entidades…", + "manage_entities_title": "Gerenciar Entidades", + "no_entities_found": "Nenhuma entidade encontrada", + "no_entities_match": "Nenhuma entidade corresponde à sua busca", + "no_entities_monitored": "Nenhuma entidade monitorada ainda. Use o navegador para adicionar.", + "not_configured": "Não configurado. Defina a URL e o token do Home Assistant nas configurações.", + "save_failed": "Falha ao salvar as entidades monitoradas", + "save_failed_no_data_dir": "Não foi possível salvar: diretório de dados do plugin indisponível", + "search_placeholder": "Buscar entidades…", + "state_on_brightness": "Ligado · {percent}%", + "status_fallback": "Status: {status}" + }, + "settings": { + "shortcut_entity": { + "description": "ID da entidade do Home Assistant para mostrar e alternar neste espaço (e.g. light.living_room)." + }, + "shortcut_entity_1": { + "label": "Botão Rápido 1 - ID da Entidade" + }, + "shortcut_entity_2": { + "label": "Botão Rápido 2 - ID da Entidade" + }, + "shortcut_entity_3": { + "label": "Botão Rápido 3 - ID da Entidade" + }, + "shortcut_entity_4": { + "label": "Botão Rápido 4 - ID da Entidade" + }, + "show_entity_count": { + "label": "Mostrar o Número de Entidades" + }, + "token": { + "description": "Crie um token no Home Assistant em Profile → Security → Long-lived access tokens", + "label": "Token de Acesso Longo" + }, + "url": { + "description": "A URL para sua instância do Home Assistant (e.g., http://homeassistant.local:8123)", + "label": "URL do Home Assistant" + } + }, + "shortcut": { + "label_1": "Botão Rápido 1", + "label_2": "Botão Rápido 2", + "label_3": "Botão Rápido 3", + "label_4": "Botão Rápido 4", + "panel_label": "Gerenciador de Entidades", + "title": "Home Assistant" + }, + "widget": { + "refreshing_connection": "Atualizando conexão…", + "status_auth_failed": "Falha de Autenticação", + "status_connected": "Conectado", + "status_connecting": "Conectando", + "status_disconnected": "Desconectado", + "status_unconfigured": "Não Configurado", + "tooltip": "Home Assistant: {status}", + "tooltip_entities": "Home Assistant: {status} ({count} entidades)" } } diff --git a/ideapad-conservation-mode/translations/en.json b/ideapad-conservation-mode/translations/en.json index 1dd0538..b881c93 100644 --- a/ideapad-conservation-mode/translations/en.json +++ b/ideapad-conservation-mode/translations/en.json @@ -1,19 +1,19 @@ { - "title": "Conservation Mode", - "shortcut": { - "on": "Conservation On", - "off": "Conservation Off", - "na": "Conservation N/A" - }, - "notify": { - "enabled": "Enabled - charging capped for battery health.", - "disabled": "Disabled - charging to 100%.", - "setup_needed": "One-time setup needed - check the terminal window that just opened." - }, "error": { "device_not_found": "Could not find the ideapad_acpi conservation_mode sysfs file on this machine.", "read_failed": "Could not read the current conservation_mode state.", "write_failed": "Failed to write conservation_mode ({error}) and could not locate the plugin directory to run setup.", "write_failed_manual": "Failed to write conservation_mode ({error}). Run scripts/setup-permissions.sh with sudo manually, then log out and back in." - } + }, + "notify": { + "disabled": "Disabled - charging to 100%.", + "enabled": "Enabled - charging capped for battery health.", + "setup_needed": "One-time setup needed - check the terminal window that just opened." + }, + "shortcut": { + "na": "Conservation N/A", + "off": "Conservation Off", + "on": "Conservation On" + }, + "title": "Conservation Mode" } diff --git a/iio_lock/translations/en.json b/iio_lock/translations/en.json index 6d4f88c..b3762e1 100644 --- a/iio_lock/translations/en.json +++ b/iio_lock/translations/en.json @@ -1,29 +1,45 @@ { - "settings.iio.label": "IIO Tool", - "settings.iio.description": "Executable used to control orientation", - "settings.iio.options.sway":"iio-sway", - "settings.iio.options.hyprland":"iio-hyprland", - - "settings.transform.label": "Transform Order", - "settings.transform.description":"Rotation values for Up, Left, Down, Right.", - - "settings.wm.label": "Window Manager", - "settings.wm.description": "Choose the window manager backend.", - "settings.wm.options.sway":"Sway", - "settings.wm.options.hyprland":"Hyprland", - - - "settings.glyph.locked.label": "Locked Glyph", - "settings.glyph.locked.description": "Icon displayed when the device is locked.", - - "settings.glyph.unlocked.label": "Unlocked Glyph", - "settings.glyph.unlocked.description": "Icon displayed when the device is unlocked.", - - - "panel.title": "iio-lock", - "panel.lock": "Toggle Lock", - - "widget.locked": "Locked", - "widget.unlocked": "Unlocked", - "toggle.description": "Toggle orientation lock" + "panel": { + "lock": "Toggle Lock", + "title": "iio-lock" + }, + "settings": { + "glyph": { + "locked": { + "description": "Icon displayed when the device is locked.", + "label": "Locked Glyph" + }, + "unlocked": { + "description": "Icon displayed when the device is unlocked.", + "label": "Unlocked Glyph" + } + }, + "iio": { + "description": "Executable used to control orientation", + "label": "IIO Tool", + "options": { + "hyprland": "iio-hyprland", + "sway": "iio-sway" + } + }, + "transform": { + "description": "Rotation values for Up, Left, Down, Right.", + "label": "Transform Order" + }, + "wm": { + "description": "Choose the window manager backend.", + "label": "Window Manager", + "options": { + "hyprland": "Hyprland", + "sway": "Sway" + } + } + }, + "toggle": { + "description": "Toggle orientation lock" + }, + "widget": { + "locked": "Locked", + "unlocked": "Unlocked" + } } diff --git a/lyrics/translations/en.json b/lyrics/translations/en.json index ed3f66c..e62e25b 100644 --- a/lyrics/translations/en.json +++ b/lyrics/translations/en.json @@ -1,113 +1,113 @@ { - "title": "Lyrics", - "no_lyrics": "♪ No lyrics available", - "intro": "Intro", "instrumental": "Instrumental", + "intro": "Intro", + "no_lyrics": "♪ No lyrics available", "settings": { - "player_allowlist": { - "label": "Allowed players", - "description": "Only use matching MPRIS player names or instances. Supports * wildcards; leave empty to allow all players." + "active_color": { + "description": "Color used for the current and already-sung lyric characters. Defaults to the interface text color.", + "label": "Active lyric color" }, - "player_blocklist": { - "label": "Blocked players", - "description": "Ignore matching MPRIS player names or instances. Supports * wildcards and takes priority over the allowlist." + "animation": { + "description": "How lyrics animate on line change.", + "label": "Animation", + "options": { + "cascade": "Character cascade", + "fade": "Fade only", + "karaoke": "Karaoke gradient + fade", + "none": "No animation", + "wave": "Character wave reveal" + } + }, + "char_width": { + "description": "Approximate pixel width per character, used to fix the widget width and clip scrolling.", + "label": "Character width (px)" + }, + "cue_font_family": { + "description": "Installed font family used only for intro and interlude characters in custom-font mode.", + "label": "Intro/interlude font" + }, + "cue_font_mode": { + "description": "Choose whether intro and interlude characters follow Noctalia's interface font or use another installed font.", + "label": "Intro/interlude font mode", + "options": { + "custom": "Custom font", + "follow": "Follow interface font" + } + }, + "cue_text": { + "description": "Text or characters highlighted during intros and interludes.", + "label": "Intro/interlude characters" + }, + "custom_json_field": { + "description": "Lyrics field in a JSON response, with dotted paths such as data.lyric. Leave empty for plain LRC.", + "label": "JSON lyrics field" + }, + "custom_url": { + "description": "Supports {title}, {artist}, {album}, and {duration} placeholders. Text responses may contain LRC directly.", + "label": "Custom endpoint URL" }, "glyph": { "label": "Glyph" }, - "show_artist": { - "label": "Show artist" + "gradient": { + "description": "Light up each character as the song progresses (karaoke style).", + "label": "Per-character gradient" }, "hide_when_paused": { "label": "Hide when paused" }, - "show_cover": { - "label": "Show album cover", - "description": "Display the song's album art next to the lyrics." - }, - "active_color": { - "label": "Active lyric color", - "description": "Color used for the current and already-sung lyric characters. Defaults to the interface text color." - }, "inactive_color": { - "label": "Inactive lyric color", - "description": "Color used for upcoming lyrics, paused playback, and secondary lines." + "description": "Color used for upcoming lyrics, paused playback, and secondary lines.", + "label": "Inactive lyric color" }, "lyrics_source": { - "label": "Lyrics source", "description": "Choose a preset source, local-player lyrics, a custom endpoint, or external push protocol.", + "label": "Lyrics source", "options": { "auto": "Automatic fallback", - "lrclib": "LRCLIB", - "netease": "NetEase Music (public API)", - "mpris": "Local player (MPRIS)", "custom": "Custom HTTP endpoint", - "external": "External IPC push" + "external": "External IPC push", + "lrclib": "LRCLIB", + "mpris": "Local player (MPRIS)", + "netease": "NetEase Music (public API)" } }, - "custom_url": { - "label": "Custom endpoint URL", - "description": "Supports {title}, {artist}, {album}, and {duration} placeholders. Text responses may contain LRC directly." + "marquee_speed": { + "description": "Pixels per second for long-line scrolling.", + "label": "Marquee speed" }, - "custom_json_field": { - "label": "JSON lyrics field", - "description": "Lyrics field in a JSON response, with dotted paths such as data.lyric. Leave empty for plain LRC." + "max_chars": { + "description": "Visible width before a long lyric line scrolls (marquee).", + "label": "Max characters" }, - "cue_text": { - "label": "Intro/interlude characters", - "description": "Text or characters highlighted during intros and interludes." + "max_lines": { + "description": "Maximum lyric lines to show at once.", + "label": "Max lines" }, - "cue_font_mode": { - "label": "Intro/interlude font mode", - "description": "Choose whether intro and interlude characters follow Noctalia's interface font or use another installed font.", - "options": { - "follow": "Follow interface font", - "custom": "Custom font" - } + "player_allowlist": { + "description": "Only use matching MPRIS player names or instances. Supports * wildcards; leave empty to allow all players.", + "label": "Allowed players" }, - "cue_font_family": { - "label": "Intro/interlude font", - "description": "Installed font family used only for intro and interlude characters in custom-font mode." + "player_blocklist": { + "description": "Ignore matching MPRIS player names or instances. Supports * wildcards and takes priority over the allowlist.", + "label": "Blocked players" }, "scroll_mode": { - "label": "Scroll mode", "description": "How lyrics scroll in the bar.", + "label": "Scroll mode", "options": { "auto": "Auto (synced)", "marquee": "Marquee", "static": "Static" } }, - "marquee_speed": { - "label": "Marquee speed", - "description": "Pixels per second for long-line scrolling." + "show_artist": { + "label": "Show artist" }, - "max_lines": { - "label": "Max lines", - "description": "Maximum lyric lines to show at once." - }, - "gradient": { - "label": "Per-character gradient", - "description": "Light up each character as the song progresses (karaoke style)." - }, - "animation": { - "label": "Animation", - "description": "How lyrics animate on line change.", - "options": { - "karaoke": "Karaoke gradient + fade", - "cascade": "Character cascade", - "wave": "Character wave reveal", - "fade": "Fade only", - "none": "No animation" - } - }, - "max_chars": { - "label": "Max characters", - "description": "Visible width before a long lyric line scrolls (marquee)." - }, - "char_width": { - "label": "Character width (px)", - "description": "Approximate pixel width per character, used to fix the widget width and clip scrolling." + "show_cover": { + "description": "Display the song's album art next to the lyrics.", + "label": "Show album cover" } - } + }, + "title": "Lyrics" } diff --git a/mangowm-keymode/translations/en.json b/mangowm-keymode/translations/en.json index 79cd194..7af21f0 100644 --- a/mangowm-keymode/translations/en.json +++ b/mangowm-keymode/translations/en.json @@ -1,5 +1,13 @@ { - "settings.show_text.label": "Show text on bar", - "settings.notify_change.label": "Notify change", - "settings.hide_on_default.label": "Hide on default keymode" + "settings": { + "hide_on_default": { + "label": "Hide on default keymode" + }, + "notify_change": { + "label": "Notify change" + }, + "show_text": { + "label": "Show text on bar" + } + } } diff --git a/mini-docker/translations/en.json b/mini-docker/translations/en.json index 16ab6a2..6173b39 100644 --- a/mini-docker/translations/en.json +++ b/mini-docker/translations/en.json @@ -1,116 +1,116 @@ { - "title": "Mini Docker", - "widget": { - "running": "Running containers: {count}", - "unavailable": "Docker is not available", - "refresh_requested": "Docker refresh requested" - }, - "settings": { - "refresh_interval": { - "label": "Refresh interval", - "description": "How often Mini Docker refreshes Docker state, in seconds." - }, - "default_network": { - "label": "Default network", - "description": "Network selected when running an image." - }, - "show_count": { - "label": "Show running count", - "description": "Show the number of running containers beside the Docker icon." - }, - "glyph_color": { - "label": "Icon color", - "description": "Theme color used by the Docker icon." - }, - "status_mode": { - "label": "Status indicator", - "description": "Choose when the status dot is visible.", - "options": { - "always": "Always", - "running_only": "Only while containers are running", - "hidden": "Hidden" - } - }, - "active_color": { - "label": "Active indicator color", - "description": "Color used when at least one container is running." - }, - "inactive_color": { - "label": "Inactive indicator color", - "description": "Color used when no containers are running." - } + "actions": { + "cancel": "Cancel", + "close": "Close", + "refresh": "Refresh", + "remove": "Remove", + "restart": "Restart", + "run": "Run", + "select": "Select", + "start": "Start", + "stop": "Stop" }, "colors": { "default": "Default", + "error": "Error", + "muted": "Muted", "primary": "Primary", "secondary": "Secondary", - "tertiary": "Tertiary", "success": "Success", - "error": "Error", - "muted": "Muted" + "tertiary": "Tertiary" + }, + "details": { + "created": "Created: {value}", + "driver": "Driver: {value}", + "id": "ID: {value}", + "image": "Image: {value}", + "mountpoint": "Mountpoint: {value}", + "ports": "Ports: {value}", + "scope": "Scope: {value}", + "size": "Size: {value}", + "status": "Status: {value}" + }, + "panel": { + "busy": "Docker command in progress…", + "default_network": "Built-in network", + "image_in_use": "Used by a container", + "image_unused": "Not used by a container", + "loading": "Loading Docker state…", + "no_containers": "No containers found.", + "no_images": "No images found.", + "no_networks": "No networks found.", + "no_volumes": "No volumes found.", + "select_hint": "Select an item to see available actions.", + "showing_limit": "Showing the first {count} items.", + "updated": "Last updated: {time}" + }, + "result": { + "command_busy": "Another Docker command is still running.", + "docker_missing": "The Docker CLI is not installed.", + "docker_unreachable": "Could not reach the Docker daemon.", + "failed": "Docker command failed: {error}", + "success": "Docker command completed." + }, + "run_form": { + "container_name": "Container name (optional)", + "container_name_placeholder": "my-container", + "environment": "Environment variables", + "environment_help": "Enter one KEY=value pair per line.", + "environment_placeholder": "KEY=value\nANOTHER_KEY=value", + "invalid_environment": "Invalid environment-variable line: {line}", + "invalid_name": "Container names may contain letters, numbers, dots, underscores, and hyphens.", + "invalid_port": "Port must be a number from 1 to 65535.", + "network": "Network", + "port": "Host and container port", + "port_placeholder": "8080", + "publish_port": "Publish a port", + "title": "Run {image}" + }, + "settings": { + "active_color": { + "description": "Color used when at least one container is running.", + "label": "Active indicator color" + }, + "default_network": { + "description": "Network selected when running an image.", + "label": "Default network" + }, + "glyph_color": { + "description": "Theme color used by the Docker icon.", + "label": "Icon color" + }, + "inactive_color": { + "description": "Color used when no containers are running.", + "label": "Inactive indicator color" + }, + "refresh_interval": { + "description": "How often Mini Docker refreshes Docker state, in seconds.", + "label": "Refresh interval" + }, + "show_count": { + "description": "Show the number of running containers beside the Docker icon.", + "label": "Show running count" + }, + "status_mode": { + "description": "Choose when the status dot is visible.", + "label": "Status indicator", + "options": { + "always": "Always", + "hidden": "Hidden", + "running_only": "Only while containers are running" + } + } }, "tabs": { "containers": "Containers", "images": "Images", - "volumes": "Volumes", - "networks": "Networks" + "networks": "Networks", + "volumes": "Volumes" }, - "actions": { - "refresh": "Refresh", - "select": "Select", - "start": "Start", - "stop": "Stop", - "restart": "Restart", - "remove": "Remove", - "run": "Run", - "cancel": "Cancel", - "close": "Close" - }, - "panel": { - "loading": "Loading Docker state…", - "busy": "Docker command in progress…", - "updated": "Last updated: {time}", - "select_hint": "Select an item to see available actions.", - "no_containers": "No containers found.", - "no_images": "No images found.", - "no_volumes": "No volumes found.", - "no_networks": "No networks found.", - "showing_limit": "Showing the first {count} items.", - "default_network": "Built-in network", - "image_in_use": "Used by a container", - "image_unused": "Not used by a container" - }, - "details": { - "image": "Image: {value}", - "status": "Status: {value}", - "ports": "Ports: {value}", - "id": "ID: {value}", - "created": "Created: {value}", - "size": "Size: {value}", - "driver": "Driver: {value}", - "mountpoint": "Mountpoint: {value}", - "scope": "Scope: {value}" - }, - "run_form": { - "title": "Run {image}", - "container_name": "Container name (optional)", - "container_name_placeholder": "my-container", - "network": "Network", - "publish_port": "Publish a port", - "port": "Host and container port", - "port_placeholder": "8080", - "environment": "Environment variables", - "environment_placeholder": "KEY=value\nANOTHER_KEY=value", - "environment_help": "Enter one KEY=value pair per line.", - "invalid_name": "Container names may contain letters, numbers, dots, underscores, and hyphens.", - "invalid_port": "Port must be a number from 1 to 65535.", - "invalid_environment": "Invalid environment-variable line: {line}" - }, - "result": { - "success": "Docker command completed.", - "failed": "Docker command failed: {error}", - "docker_missing": "The Docker CLI is not installed.", - "docker_unreachable": "Could not reach the Docker daemon.", - "command_busy": "Another Docker command is still running." + "title": "Mini Docker", + "widget": { + "refresh_requested": "Docker refresh requested", + "running": "Running containers: {count}", + "unavailable": "Docker is not available" } } diff --git a/nix-monitor/translations/en.json b/nix-monitor/translations/en.json index 65cb305..87cbe87 100644 --- a/nix-monitor/translations/en.json +++ b/nix-monitor/translations/en.json @@ -1,78 +1,146 @@ { - "bar.checking": "Checking...", - "bar.update_available": "Update available!", - "bar.up_to_date": "Up to date", - "bar.unknown": "Unknown", - "notification.checking_update": "Checking NixOS update...", - "notification.update_is_available": "NixOS update is available!", - "notification.update_check_completed": "NixOS update check completed!", - "notification.update_command_is_empty": "Update command is empty!", - "notification.clean_command_is_empty": "Clean command is empty!", - "panel.title": "Nix Monitor", - "panel.cancel": "Cancel", - "panel.update": "Update", - "panel.check": "Check", - "panel.clean": "Clean", - "panel.local": "Local", - "panel.remote": "Remote", - "panel.last_checked": "Last checked", - "panel.current": "Current", - "panel.store_size": "Store size", - "panel.closure_size": "Closure size", - "terminal.press_enter_to_exit": "Press enter to exit...", - "setting.widget.show_text.label": "Show text", - "setting.widget.colorize_text.label": "Colorize text", - "setting.widget.show_glyph.label": "Show glyph", - "setting.widget.colorize_glyph.label": "Colorize glyph", - "setting.widget.up_to_date_glyph.label": "Up to date glyph", - "setting.widget.up_to_date_color.label": "Up to date color", - "setting.widget.checking_glyph.label": "Checking glyph", - "setting.widget.checking_color.label": "Checking color", - "setting.widget.update_available_glyph.label": "Update available glyph", - "setting.widget.update_available_color.label": "Update available color", - "setting.widget.unknown_glyph.label": "Unknown status glyph", - "setting.widget.unknown_color.label": "Unknown status color", - "setting.widget.panel_card_background_color.label": "Panel card background color", - "setting.widget.panel_card_background_opacity.label": "Panel card background opacity", - "setting.update_check_interval.label": "Update check interval", - "setting.update_check_interval.description": "How often to check for updates (in minutes)", - "setting.update_check_duration_threshold.label": "Update check duration threshold", - "setting.update_check_duration_threshold.description": "Cancel update check if it took too long (in minutes)", - "setting.system_stats_check_interval.label": "System stats check interval", - "setting.system_stats_check_interval.description": "How often to check for system stats (in minutes)", - "setting.system_stats_check_duration_threshold.label": "System stats check duration threshold", - "setting.system_stats_check_duration_threshold.description": "Cancel system stats check if it took too long (in minutes)", - "setting.show_update_check_notification.label": "Show update check notification", - "setting.show_update_check_notification.description": "Whether to show a notification whenever update check is in progress and completed", - "setting.show_update_available_notification.label": "Show update available notification", - "setting.show_update_available_notification.description": "Whether to show a notification whenever an update is available", - "setting.branch.label": "Branch", - "setting.branch.description": "Which nixpkgs branch to use", - "setting.update_command.label": "Update command", - "setting.update_command.description": "Command to run when clicking Update button", - "setting.clean_command.label": "Clean command", - "setting.clean_command.description": "Command to run when clicking Clean button", - "setting.hide_update_button.label": "Hide update button", - "setting.hide_update_button.description": "Whether to hide the update button on the panel", - "setting.hide_clean_button.label": "Hide clean button", - "setting.hide_clean_button.description": "Whether to hide the clean button on the panel", - "setting.close_on_enter.label": "Close on press Enter", - "setting.close_on_enter.description": "Add 'Press enter to exit' on the terminal window", - "setting.option.branch.master": "Master", - "setting.option.branch.nixos_unstable": "NixOS Unstable", - "setting.option.branch.nixos_unstable_small": "NixOS Unstable Small", - "setting.option.branch.nixos_26_05": "NixOS 26.05", - "setting.option.branch.nixos_25_11": "NixOS 25.11", - "setting.option.branch.nixos_25_05": "NixOS 25.05", - "setting.option.branch.nixos_24_11": "NixOS 24.11", - "setting.option.branch.nixos_24_05": "NixOS 24.05", - "setting.option.branch.nixos_23_11": "NixOS 23.11", - "setting.option.branch.nixos_23_05": "NixOS 23.05", - "setting.option.branch.nixos_26_05_small": "NixOS 26.05 Small", - "setting.option.branch.nixos_25_11_small": "NixOS 25.11 Small", - "setting.option.branch.nixos_25_05_small": "NixOS 25.05 Small", - "setting.option.branch.nixos_24_11_small": "NixOS 24.11 Small", - "setting.option.branch.nixos_24_05_small": "NixOS 24.05 Small", - "setting.option.branch.nixos_23_11_small": "NixOS 23.11 Small", - "setting.option.branch.nixos_23_05_small": "NixOS 23.05 Small" + "bar": { + "checking": "Checking...", + "unknown": "Unknown", + "up_to_date": "Up to date", + "update_available": "Update available!" + }, + "notification": { + "checking_update": "Checking NixOS update...", + "clean_command_is_empty": "Clean command is empty!", + "update_check_completed": "NixOS update check completed!", + "update_command_is_empty": "Update command is empty!", + "update_is_available": "NixOS update is available!" + }, + "panel": { + "cancel": "Cancel", + "check": "Check", + "clean": "Clean", + "closure_size": "Closure size", + "current": "Current", + "last_checked": "Last checked", + "local": "Local", + "remote": "Remote", + "store_size": "Store size", + "title": "Nix Monitor", + "update": "Update" + }, + "setting": { + "branch": { + "description": "Which nixpkgs branch to use", + "label": "Branch" + }, + "clean_command": { + "description": "Command to run when clicking Clean button", + "label": "Clean command" + }, + "close_on_enter": { + "description": "Add 'Press enter to exit' on the terminal window", + "label": "Close on press Enter" + }, + "hide_clean_button": { + "description": "Whether to hide the clean button on the panel", + "label": "Hide clean button" + }, + "hide_update_button": { + "description": "Whether to hide the update button on the panel", + "label": "Hide update button" + }, + "option": { + "branch": { + "master": "Master", + "nixos_23_05": "NixOS 23.05", + "nixos_23_05_small": "NixOS 23.05 Small", + "nixos_23_11": "NixOS 23.11", + "nixos_23_11_small": "NixOS 23.11 Small", + "nixos_24_05": "NixOS 24.05", + "nixos_24_05_small": "NixOS 24.05 Small", + "nixos_24_11": "NixOS 24.11", + "nixos_24_11_small": "NixOS 24.11 Small", + "nixos_25_05": "NixOS 25.05", + "nixos_25_05_small": "NixOS 25.05 Small", + "nixos_25_11": "NixOS 25.11", + "nixos_25_11_small": "NixOS 25.11 Small", + "nixos_26_05": "NixOS 26.05", + "nixos_26_05_small": "NixOS 26.05 Small", + "nixos_unstable": "NixOS Unstable", + "nixos_unstable_small": "NixOS Unstable Small" + } + }, + "show_update_available_notification": { + "description": "Whether to show a notification whenever an update is available", + "label": "Show update available notification" + }, + "show_update_check_notification": { + "description": "Whether to show a notification whenever update check is in progress and completed", + "label": "Show update check notification" + }, + "system_stats_check_duration_threshold": { + "description": "Cancel system stats check if it took too long (in minutes)", + "label": "System stats check duration threshold" + }, + "system_stats_check_interval": { + "description": "How often to check for system stats (in minutes)", + "label": "System stats check interval" + }, + "update_check_duration_threshold": { + "description": "Cancel update check if it took too long (in minutes)", + "label": "Update check duration threshold" + }, + "update_check_interval": { + "description": "How often to check for updates (in minutes)", + "label": "Update check interval" + }, + "update_command": { + "description": "Command to run when clicking Update button", + "label": "Update command" + }, + "widget": { + "checking_color": { + "label": "Checking color" + }, + "checking_glyph": { + "label": "Checking glyph" + }, + "colorize_glyph": { + "label": "Colorize glyph" + }, + "colorize_text": { + "label": "Colorize text" + }, + "panel_card_background_color": { + "label": "Panel card background color" + }, + "panel_card_background_opacity": { + "label": "Panel card background opacity" + }, + "show_glyph": { + "label": "Show glyph" + }, + "show_text": { + "label": "Show text" + }, + "unknown_color": { + "label": "Unknown status color" + }, + "unknown_glyph": { + "label": "Unknown status glyph" + }, + "up_to_date_color": { + "label": "Up to date color" + }, + "up_to_date_glyph": { + "label": "Up to date glyph" + }, + "update_available_color": { + "label": "Update available color" + }, + "update_available_glyph": { + "label": "Update available glyph" + } + } + }, + "terminal": { + "press_enter_to_exit": "Press enter to exit..." + } } diff --git a/noctwhspr/translations/en.json b/noctwhspr/translations/en.json index a141050..591cefc 100644 --- a/noctwhspr/translations/en.json +++ b/noctwhspr/translations/en.json @@ -1,5 +1,9 @@ { - "title": "noctwhspr", - "settings.root.label": "hyprwhspr install root", - "settings.root.description": "Directory hyprwhspr is installed under. Leave at the default unless hyprwhspr lives at a non-standard prefix." + "settings": { + "root": { + "description": "Directory hyprwhspr is installed under. Leave at the default unless hyprwhspr lives at a non-standard prefix.", + "label": "hyprwhspr install root" + } + }, + "title": "noctwhspr" } diff --git a/portctl/translations/en.json b/portctl/translations/en.json index 516ac41..d7644f8 100644 --- a/portctl/translations/en.json +++ b/portctl/translations/en.json @@ -1,54 +1,54 @@ { - "title": "Portctl", + "categories": { + "cloud": "Cloud", + "containers": "Containers", + "databases": "Databases", + "development": "Development", + "other": "Other", + "servers": "Servers" + }, "panel": { - "search_placeholder": "Search port, process, PID…", - "tcp": "TCP", - "udp": "UDP", - "no_ports": "No listening ports", - "no_results": "No results for \"{query}\"", - "killing": "Killing {name}…", - "kill_confirm": "Kill {name}?", "cancel": "Cancel", "kill": "Kill", - "pid_copied": "Copied PID {pid}" - }, - "categories": { - "development": "Development", - "databases": "Databases", - "containers": "Containers", - "servers": "Servers", - "cloud": "Cloud", - "other": "Other" + "kill_confirm": "Kill {name}?", + "killing": "Killing {name}…", + "no_ports": "No listening ports", + "no_results": "No results for \"{query}\"", + "pid_copied": "Copied PID {pid}", + "search_placeholder": "Search port, process, PID…", + "tcp": "TCP", + "udp": "UDP" }, "service": { - "terminated": "Process {pid} terminated", "kill_failed": "Failed to kill PID {pid}", - "ss_not_found": "ss (iproute2) not found — install the iproute2 package" + "ss_not_found": "ss (iproute2) not found — install the iproute2 package", + "terminated": "Process {pid} terminated" }, "settings": { - "refresh_interval": { - "label": "Refresh interval", - "description": "Seconds between port scans" - }, - "ignore_list": { - "label": "Ignore processes", - "description": "Comma-separated process name substrings to hide (e.g. discord,chrome,steam)" - }, - "ignore_ports": { - "label": "Ignore ports", - "description": "Comma-separated port numbers to hide (e.g. 37700,6463)" + "glyph": { + "description": "Icon shown in the bar.", + "label": "Glyph" }, "hide_system_ports": { - "label": "Hide system ports", - "description": "Hide ports below 1024 (privileged/root ports)" + "description": "Hide ports below 1024 (privileged/root ports)", + "label": "Hide system ports" }, "hide_unknown_ports": { - "label": "Hide unknown ports", - "description": "Hide ports whose process info is not accessible (e.g. rootlessport, root-owned processes without sudo)" + "description": "Hide ports whose process info is not accessible (e.g. rootlessport, root-owned processes without sudo)", + "label": "Hide unknown ports" }, - "glyph": { - "label": "Glyph", - "description": "Icon shown in the bar." + "ignore_list": { + "description": "Comma-separated process name substrings to hide (e.g. discord,chrome,steam)", + "label": "Ignore processes" + }, + "ignore_ports": { + "description": "Comma-separated port numbers to hide (e.g. 37700,6463)", + "label": "Ignore ports" + }, + "refresh_interval": { + "description": "Seconds between port scans", + "label": "Refresh interval" } - } + }, + "title": "Portctl" } diff --git a/prismlauncher-instances/translations/en.json b/prismlauncher-instances/translations/en.json index 087c092..cda2d65 100644 --- a/prismlauncher-instances/translations/en.json +++ b/prismlauncher-instances/translations/en.json @@ -1,16 +1,16 @@ { - "settings": { - "prismlauncher_path": { - "label": "PrismLauncher path", - "description": "Path to PrismLauncher" - }, - "launcher_exec_command": { - "label": "Prism Executable", - "description": "Start Prismlauncher or fork of choice" - } - }, "no_instances": { - "title": "No instances found", - "subtitle": "Filter: " + "subtitle": "Filter: ", + "title": "No instances found" + }, + "settings": { + "launcher_exec_command": { + "description": "Start Prismlauncher or fork of choice", + "label": "Prism Executable" + }, + "prismlauncher_path": { + "description": "Path to PrismLauncher", + "label": "PrismLauncher path" + } } } diff --git a/proton-pass/translations/en.json b/proton-pass/translations/en.json index ed49843..2d47d44 100644 --- a/proton-pass/translations/en.json +++ b/proton-pass/translations/en.json @@ -1,7 +1,7 @@ { - "copied-password": "Copied password to clipboard", - "failed-list-vaults": "Failed to list vaults. Are you logged into pass-cli?", - "item-not-found": "Item not found", - "loading-items": "Loading Items…", - "loading-vaults": "Loading Vaults…" + "copied-password": "Copied password to clipboard", + "failed-list-vaults": "Failed to list vaults. Are you logged into pass-cli?", + "item-not-found": "Item not found", + "loading-items": "Loading Items…", + "loading-vaults": "Loading Vaults…" } diff --git a/sharednd/translations/en.json b/sharednd/translations/en.json index 02e33af..cfcd0dd 100644 --- a/sharednd/translations/en.json +++ b/sharednd/translations/en.json @@ -1,9 +1,17 @@ { - "title": "ShareDND", - "settings.only_active.label": "Only active streams", - "settings.only_active.description": "Count only screencasts that are actively streaming. When off, any open screencast session (even one paused or showing nothing) keeps Do Not Disturb enabled.", - "settings.always_off_after.label": "Always disable DND after sharing", - "settings.always_off_after.description": "Turn Do Not Disturb off when sharing ends even if it was already enabled before sharing started. When off, DND is only disabled if this plugin enabled it.", - "notify.no_niri_title": "ShareDND: niri not found", - "notify.no_niri_body": "This looks like a niri session (NIRI_SOCKET is set), but the niri binary is not in PATH, so screen sharing cannot be detected." + "notify": { + "no_niri_body": "This looks like a niri session (NIRI_SOCKET is set), but the niri binary is not in PATH, so screen sharing cannot be detected.", + "no_niri_title": "ShareDND: niri not found" + }, + "settings": { + "always_off_after": { + "description": "Turn Do Not Disturb off when sharing ends even if it was already enabled before sharing started. When off, DND is only disabled if this plugin enabled it.", + "label": "Always disable DND after sharing" + }, + "only_active": { + "description": "Count only screencasts that are actively streaming. When off, any open screencast session (even one paused or showing nothing) keeps Do Not Disturb enabled.", + "label": "Only active streams" + } + }, + "title": "ShareDND" } diff --git a/shelly/translations/en.json b/shelly/translations/en.json index 25430a7..ac9f5a6 100644 --- a/shelly/translations/en.json +++ b/shelly/translations/en.json @@ -1,12 +1,11 @@ { - "title": "Shelly", - "notify": { - "new_updates": { - "title": "New Updates Available", - "description": "There are {count} new updates available for your system." - } - }, "bar": { + "click_handler": { + "error": { + "missing_cli": "Shelly CLI is not installed. Please install it to use this feature.", + "missing_gui": "Shelly GUI is not installed. Please install it to use this feature." + } + }, "text": { "error": "?", "updates": { @@ -16,53 +15,54 @@ }, "tooltip": { "aur_title": "AUR", - "flatpak_title": "Flatpak", - "packages_title": "Packages", - "no_updates": "System is up to date", "error": { "decode_json": "Failed to decode output from `shelly check-updates --json`" - } - }, - "click_handler": { - "error": { - "missing_gui": "Shelly GUI is not installed. Please install it to use this feature.", - "missing_cli": "Shelly CLI is not installed. Please install it to use this feature." - } + }, + "flatpak_title": "Flatpak", + "no_updates": "System is up to date", + "packages_title": "Packages" + } + }, + "notify": { + "new_updates": { + "description": "There are {count} new updates available for your system.", + "title": "New Updates Available" } }, "settings": { - "interval": { - "label": "Refresh Seconds", - "description": "How often the service checks for updates in the background." - }, - "notify": { - "label": "Notify", - "description": "Whether to show a notification when new updates are available." - }, "click_action": { - "label": "Click Action", "description": "What happens when you click on the bar.", + "label": "Click Action", "options": { "none": "Nothing", "open_gui": "Open Shelly GUI", "open_updater": "Start Update in Terminal" } }, - "hide_when_up_to_date": { - "label": "Hide When Up-to-Date", - "description": "Whether to hide the bar when there are no updates available." - }, "color": { - "label": "Color", - "description": "The color of the bar text." + "description": "The color of the bar text.", + "label": "Color" }, "glyph": { - "label": "Glyph", - "description": "The glyph shown before the label." + "description": "The glyph shown before the label.", + "label": "Glyph" }, "glyph_color": { - "label": "Glyph Color", - "description": "The color of the glyph." + "description": "The color of the glyph.", + "label": "Glyph Color" + }, + "hide_when_up_to_date": { + "description": "Whether to hide the bar when there are no updates available.", + "label": "Hide When Up-to-Date" + }, + "interval": { + "description": "How often the service checks for updates in the background.", + "label": "Refresh Seconds" + }, + "notify": { + "description": "Whether to show a notification when new updates are available.", + "label": "Notify" } - } + }, + "title": "Shelly" } diff --git a/todo/translations/en.json b/todo/translations/en.json index 2af0fdd..8e15a46 100644 --- a/todo/translations/en.json +++ b/todo/translations/en.json @@ -1,30 +1,36 @@ { - "title": "To Do", + "clear_done_confirm": "Delete all done entries?", + "clear_done_no": "Cancel", + "clear_done_yes": "Delete", "empty": "No tasks yet — add one with +", "placeholder": "New task…", - "tooltip": "To Do — {count} to do", - "save_failed": "Failed to save the task list", + "prio_important": "Important", "prio_low": "Low", "prio_medium": "Medium", - "prio_important": "Important", - "sort_priority": "Priority", + "save_failed": "Failed to save the task list", + "settings": { + "glyph": { + "description": "The glyph shown for the To Do widget on the bar.", + "label": "Bar glyph" + }, + "todo_folder": { + "description": "Folder holding the task list (todo.json). Defaults to ~/Documents/Todo.", + "label": "To Do folder" + } + }, "sort_manual": "Manual", - "clear_done_confirm": "Delete all done entries?", - "clear_done_yes": "Delete", - "clear_done_no": "Cancel", - "tip_sort": "Switch ordering mode", - "tip_clear_done": "Delete all done tasks", + "sort_priority": "Priority", "tip_add": "Add a task", + "tip_clear_done": "Delete all done tasks", "tip_close": "Close", + "tip_commit": "Save (Enter)", + "tip_delete": "Delete task", + "tip_done": "Mark as done", + "tip_edit": "Edit", "tip_grip": "Reorder — click to pick this row up", "tip_grip_drop": "Click another grip to drop here, or this one to cancel", - "tip_commit": "Save (Enter)", - "tip_done": "Mark as done", + "tip_sort": "Switch ordering mode", "tip_undone": "Mark as to do", - "tip_edit": "Edit", - "tip_delete": "Delete task", - "settings.todo_folder.label": "To Do folder", - "settings.todo_folder.description": "Folder holding the task list (todo.json). Defaults to ~/Documents/Todo.", - "settings.glyph.label": "Bar glyph", - "settings.glyph.description": "The glyph shown for the To Do widget on the bar." + "title": "To Do", + "tooltip": "To Do — {count} to do" } diff --git a/um5606_fan_state/translations/en.json b/um5606_fan_state/translations/en.json index 815535d..c5f1f9e 100644 --- a/um5606_fan_state/translations/en.json +++ b/um5606_fan_state/translations/en.json @@ -1,12 +1,12 @@ { - "title": "ASUS UM5606 Fan State", "settings": { + "poll_interval": { + "description": "Poll interval in ms", + "label": "Poll interval" + }, "show_label": { "label": "Show label" - }, - "poll_interval": { - "label": "Poll interval", - "description": "Poll interval in ms" } - } -} \ No newline at end of file + }, + "title": "ASUS UM5606 Fan State" +} diff --git a/upbeat/translations/en.json b/upbeat/translations/en.json index 357c74a..3a514bb 100644 --- a/upbeat/translations/en.json +++ b/upbeat/translations/en.json @@ -1,16 +1,16 @@ { - "settings": { - "show_centibeats": { - "label": "Display subbeats", - "description": "Toggle subbeat display (.xx)" - }, - "beat_display": { - "label": "Display .beats", - "description": "Toggle internet time notation (.beats)" - }, - "time_format_toggle": { - "label": "Toggle 24HR time", - "description": "Display 24 hour time" - } + "settings": { + "beat_display": { + "description": "Toggle internet time notation (.beats)", + "label": "Display .beats" + }, + "show_centibeats": { + "description": "Toggle subbeat display (.xx)", + "label": "Display subbeats" + }, + "time_format_toggle": { + "description": "Display 24 hour time", + "label": "Toggle 24HR time" } - } \ No newline at end of file + } +} diff --git a/zed-provider/translations/en.json b/zed-provider/translations/en.json index c2814a8..3ba3b23 100644 --- a/zed-provider/translations/en.json +++ b/zed-provider/translations/en.json @@ -1,11 +1,17 @@ { - "loading": "Loading…", - "loading-subtitle": "Reading Zed projects", - "no-projects-found": "No projects found", - "filter-empty": "Filter: \"{filter}\"", - "database-empty": "Zed database is empty or not found", - "settings.db_path.label": "Zed database path", - "settings.db_path.description": "Path to Zed's db.sqlite file.", - "settings.max_results.label": "Maximum results", - "settings.max_results.description": "Maximum number of projects to display." + "database-empty": "Zed database is empty or not found", + "filter-empty": "Filter: \"{filter}\"", + "loading": "Loading…", + "loading-subtitle": "Reading Zed projects", + "no-projects-found": "No projects found", + "settings": { + "db_path": { + "description": "Path to Zed's db.sqlite file.", + "label": "Zed database path" + }, + "max_results": { + "description": "Maximum number of projects to display.", + "label": "Maximum results" + } + } } diff --git a/zed-provider/translations/fr.json b/zed-provider/translations/fr.json index 795ff90..8c9a1d7 100644 --- a/zed-provider/translations/fr.json +++ b/zed-provider/translations/fr.json @@ -1,11 +1,17 @@ { - "loading": "Chargement…", - "loading-subtitle": "Lecture des projets Zed", - "no-projects-found": "Aucun projet trouvé", - "filter-empty": "Filtre : « {filter} »", - "database-empty": "La base Zed est vide ou introuvable", - "settings.db_path.label": "Chemin de la base Zed", - "settings.db_path.description": "Chemin vers le fichier db.sqlite de Zed.", - "settings.max_results.label": "Nombre maximum de résultats", - "settings.max_results.description": "Nombre maximum de projets à afficher." + "database-empty": "La base Zed est vide ou introuvable", + "filter-empty": "Filtre : « {filter} »", + "loading": "Chargement…", + "loading-subtitle": "Lecture des projets Zed", + "no-projects-found": "Aucun projet trouvé", + "settings": { + "db_path": { + "description": "Chemin vers le fichier db.sqlite de Zed.", + "label": "Chemin de la base Zed" + }, + "max_results": { + "description": "Nombre maximum de projets à afficher.", + "label": "Nombre maximum de résultats" + } + } }