[client/ui-wails] Show GUI and daemon versions in the About submenu

Restore the legacy Fyne UI's two disabled "GUI: x.y.z" / "Daemon: a.b.c"
entries under About so users (and support) can read the running
versions from the tray. The GUI line is baked in at build time via
version.NetbirdVersion() — the same -ldflags chain the rest of the
repo uses. The daemon line starts as "—" and is rewritten in
applyStatus on every Status snapshot whose DaemonVersion differs from
the last one we recorded, so a daemon restart with a new build
(e.g. after an enforced update) updates the menu automatically.

Drive-by: rename the local variable that shadowed the version package
in handleUpdate so the import resolves cleanly.
This commit is contained in:
Zoltán Papp
2026-05-06 16:55:52 +02:00
parent 2b272e74c8
commit 8b8f38de1b

View File

@@ -16,6 +16,7 @@ import (
"github.com/wailsapp/wails/v3/pkg/services/notifications"
"github.com/netbirdio/netbird/client/ui-wails/services"
"github.com/netbirdio/netbird/version"
)
// User-facing strings exposed in the tray, OS notifications and the
@@ -48,6 +49,12 @@ const (
// menuInstallVersionPrefix is rewritten with the target version when
// the management server enforces the update.
menuInstallVersionPrefix = "Install version "
// menuGUIVersionFmt and menuDaemonVersionFmt drive the disabled
// version-info entries under About. The daemon line is "—" until the
// first Status snapshot reports the daemon's version.
menuGUIVersionFmt = "GUI: %s"
menuDaemonVersionFmt = "Daemon: %s"
menuVersionUnknown = "—"
// OS notifications.
notifyUpdateTitle = "NetBird update available"
@@ -96,12 +103,13 @@ type Tray struct {
window *application.WebviewWindow
svc TrayServices
statusItem *application.MenuItem
upItem *application.MenuItem
downItem *application.MenuItem
exitNodeItem *application.MenuItem
networksItem *application.MenuItem
updateItem *application.MenuItem
statusItem *application.MenuItem
upItem *application.MenuItem
downItem *application.MenuItem
exitNodeItem *application.MenuItem
networksItem *application.MenuItem
updateItem *application.MenuItem
daemonVersionItem *application.MenuItem
mu sync.Mutex
connected bool
@@ -110,6 +118,7 @@ type Tray struct {
updateEnforced bool
exitNodes []string
lastStatus string
lastDaemonVersion string
notificationsEnabled bool
activeProfile string
activeUsername string
@@ -208,6 +217,11 @@ func (t *Tray) buildMenu() *application.Menu {
_ = t.app.Browser.OpenURL(urlGitHubRepo)
})
about.Add(menuDocumentation).SetEnabled(false)
// Disabled informational entries: the GUI version is baked in at
// build time via -ldflags, the daemon version comes from the first
// Status snapshot and is updated in applyStatus.
about.Add(fmt.Sprintf(menuGUIVersionFmt, version.NetbirdVersion())).SetEnabled(false)
t.daemonVersionItem = about.Add(fmt.Sprintf(menuDaemonVersionFmt, menuVersionUnknown)).SetEnabled(false)
// Hidden until the daemon emits EventUpdateAvailable. The label is
// rewritten in onUpdateAvailable to match the legacy Fyne UI:
// menuDownloadLatestVersion for opt-in, menuInstallVersionPrefix+version
@@ -353,7 +367,7 @@ func (t *Tray) onUpdateAvailable(ev *application.CustomEvent) {
func (t *Tray) handleUpdate() {
t.mu.Lock()
enforced := t.updateEnforced
version := t.updateVersion
updateVersion := t.updateVersion
t.mu.Unlock()
if !enforced {
@@ -366,8 +380,8 @@ func (t *Tray) handleUpdate() {
// RPC the /update page is polling.
if t.window != nil {
url := "/#/update"
if version != "" {
url += "?version=" + version
if updateVersion != "" {
url += "?version=" + updateVersion
}
t.window.SetURL(url)
t.window.Show()
@@ -419,8 +433,12 @@ func (t *Tray) applyStatus(st services.Status) {
// flag in onSessionExpire.
sessionExpiredEnter := strings.EqualFold(st.Status, statusSessionExpired) &&
!strings.EqualFold(t.lastStatus, statusSessionExpired)
daemonVersionChanged := st.DaemonVersion != "" && st.DaemonVersion != t.lastDaemonVersion
t.connected = connected
t.lastStatus = st.Status
if daemonVersionChanged {
t.lastDaemonVersion = st.DaemonVersion
}
exitNodes := exitNodesFromStatus(st)
exitNodesChanged := !equalStrings(exitNodes, t.exitNodes)
@@ -442,6 +460,9 @@ func (t *Tray) applyStatus(st services.Status) {
if exitNodesChanged {
t.rebuildExitNodes(exitNodes)
}
if daemonVersionChanged && t.daemonVersionItem != nil {
t.daemonVersionItem.SetLabel(fmt.Sprintf(menuDaemonVersionFmt, st.DaemonVersion))
}
if sessionExpiredEnter {
t.handleSessionExpired()
}