diff --git a/topgrade-wrapper/panel.luau b/topgrade-wrapper/panel.luau index 4955e9c..2fd6722 100644 --- a/topgrade-wrapper/panel.luau +++ b/topgrade-wrapper/panel.luau @@ -12,6 +12,18 @@ local STATE_KEY = "topgrade_state" local REQUEST_KEY = "topgrade_request" +-- Read out of the plugin's own manifest (readFile resolves a relative path +-- against the plugin directory), so the header cannot drift from the version +-- the store shows. Empty when unreadable — a missing version is not worth an +-- error line in the panel. +local pluginVersion = (function() + local text = noctalia.readFile("plugin.toml") + if type(text) ~= "string" then + return "" + end + return ("\n" .. text):match('\nversion%s*=%s*"([^"]+)"') or "" +end)() + local snapshot = nil local expanded = {} -- manager key -> the package list is open local hoverKey = nil -- package row currently under the pointer @@ -331,14 +343,21 @@ render = function() local hasUpdates = totalOf() > 0 and (phase == "ready" or phase == "running") local children = { - ui.row({ gap = 8, align = "center" }, { + -- Every child of the header carries a stable key, so the reconciler + -- matches roles instead of guessing by position and type. + ui.row({ key = "header", gap = 8, align = "center" }, { ui.label({ + key = "title", text = tr("title"), fontSize = 16, fontWeight = "bold", color = "on_surface", - flexGrow = 1, }), + -- Version off the manifest, small and dimmed: it answers "which + -- build am I running" without competing with the title. The spacer + -- rather than a flexGrow title keeps the two together on the left. + ui.label({ key = "version", text = pluginVersion, fontSize = 10, color = "on_surface_variant" }), + ui.spacer({ key = "gap", flexGrow = 1 }), ui.button({ key = "header-check" .. (busy() and "-off" or ""), glyph = "refresh", @@ -353,6 +372,7 @@ render = function() -- supplies the plugin id, so a plugin can only ever open its own). -- The panel closes on the way; the engine keeps running. ui.button({ + key = "settings", glyph = "settings", variant = "ghost", tooltip = tr("tip_settings"), @@ -361,6 +381,7 @@ render = function() end, }), ui.button({ + key = "close", glyph = "close", variant = "ghost", tooltip = tr("tip_close"), diff --git a/topgrade-wrapper/plugin.toml b/topgrade-wrapper/plugin.toml index 8593081..4ceef57 100644 --- a/topgrade-wrapper/plugin.toml +++ b/topgrade-wrapper/plugin.toml @@ -11,7 +11,7 @@ id = "nightwatch75/topgrade-wrapper" name = "Topgrade Wrapper" -version = "0.0.4" +version = "0.0.6" plugin_api = 15 author = "nightwatch75" license = "MIT" diff --git a/topgrade-wrapper/service.luau b/topgrade-wrapper/service.luau index 45017cf..658a351 100644 --- a/topgrade-wrapper/service.luau +++ b/topgrade-wrapper/service.luau @@ -48,6 +48,12 @@ local MAX_LISTED = 200 -- `nameinstalledavailable`. Either version may be empty -- when the tool does not report it. -- +-- Every query — and the dry run itself — is spawned with `export LC_ALL=C;` in +-- front of it: these parsers key off English words and fixed column layouts +-- (`^Inst `, the zypper table, the pip header), which a translated system turns +-- into gibberish. Reported upstream from a French desktop (community-plugins +-- #204). The interactive run is deliberately left in the user's own locale. +-- -- The count is simply how many lines came back, so the number on the bar and the -- list the panel expands are the same answer to the same question, asked once: -- no second round trip to a mirror, and no way for the two to disagree.