[client/ui] Introduce localisation (i18n + preferences) feature packages

Adds a tray + React translation pipeline driven by a single JSON locale
tree (frontend/src/i18n/locales) embedded into the Go binary. The tray
re-renders on language switch via a Localizer that subscribes to the
preferences store.

Layout:
- client/ui/i18n: Bundle, LanguageCode, Language, errors, embedded-FS
  loader. Pure domain, no Wails/daemon deps.
- client/ui/preferences: Store + UIPreferences for user-scope UI state,
  persisted under os.UserConfigDir()/netbird/ui-preferences.json with
  atomic writes and a subscribe/broadcast channel.
- client/ui/services: thin Wails-binding facades (services.I18n,
  services.Preferences) so React sees ctx-first signatures.
- client/ui/localizer.go: tray bridge that owns the active language,
  exposes T()/StatusLabel() and re-paints the menu on prefs change.
- tray.go: every user-facing const replaced by translation keys via
  t.loc.T(...); menu rebuild + state replay on language switch.
- main.go: //go:embed all:frontend/src/i18n/locales, wires Bundle ->
  Store -> Localizer -> Wails facades in order.

Frontend API exposed via Wails bindings: I18n.Languages, I18n.Bundle,
Preferences.Get, Preferences.SetLanguage, plus the
netbird:preferences:changed event.

Includes regenerated Wails TS bindings (peers/profileswitcher/etc.
re-emitted as part of the build) and en/hu seed bundles.
This commit is contained in:
Zoltan Papp
2026-05-15 11:19:00 +02:00
parent c0b0eeb6ab
commit 17cae1a75c
18 changed files with 1449 additions and 108 deletions
@@ -0,0 +1,6 @@
{
"languages": [
{"code": "en", "displayName": "English", "englishName": "English"},
{"code": "hu", "displayName": "Magyar", "englishName": "Hungarian"}
]
}
@@ -0,0 +1,34 @@
{
"tray.tooltip": "NetBird",
"tray.status.disconnected": "Disconnected",
"tray.status.daemonUnavailable": "Not running",
"tray.status.error": "Error",
"tray.menu.open": "Open NetBird",
"tray.menu.connect": "Connect",
"tray.menu.disconnect": "Disconnect",
"tray.menu.exitNode": "Exit Node",
"tray.menu.networks": "Resources",
"tray.menu.profiles": "Profiles",
"tray.menu.settings": "Settings",
"tray.menu.debugBundle": "Create Debug Bundle",
"tray.menu.about": "About",
"tray.menu.github": "GitHub",
"tray.menu.documentation": "Documentation",
"tray.menu.downloadLatest": "Download latest version",
"tray.menu.installVersion": "Install version {version}",
"tray.menu.guiVersion": "GUI: {version}",
"tray.menu.daemonVersion": "Daemon: {version}",
"tray.menu.versionUnknown": "—",
"tray.menu.quit": "Quit",
"notify.update.title": "NetBird update available",
"notify.update.body": "NetBird {version} is available.",
"notify.update.enforcedSuffix": " Your administrator requires this update.",
"notify.error.title": "Error",
"notify.error.connect": "Failed to connect",
"notify.error.disconnect": "Failed to disconnect",
"notify.error.switchProfile": "Failed to switch to {profile}",
"notify.sessionExpired.title": "NetBird session expired",
"notify.sessionExpired.body": "Your NetBird session has expired. Please log in again."
}
@@ -0,0 +1,34 @@
{
"tray.tooltip": "NetBird",
"tray.status.disconnected": "Lekapcsolva",
"tray.status.daemonUnavailable": "Nem fut",
"tray.status.error": "Hiba",
"tray.menu.open": "NetBird megnyitása",
"tray.menu.connect": "Csatlakozás",
"tray.menu.disconnect": "Bontás",
"tray.menu.exitNode": "Kilépő csomópont",
"tray.menu.networks": "Erőforrások",
"tray.menu.profiles": "Profilok",
"tray.menu.settings": "Beállítások",
"tray.menu.debugBundle": "Hibakeresési csomag készítése",
"tray.menu.about": "Névjegy",
"tray.menu.github": "GitHub",
"tray.menu.documentation": "Dokumentáció",
"tray.menu.downloadLatest": "Legfrissebb verzió letöltése",
"tray.menu.installVersion": "{version} verzió telepítése",
"tray.menu.guiVersion": "Felület: {version}",
"tray.menu.daemonVersion": "Daemon: {version}",
"tray.menu.versionUnknown": "—",
"tray.menu.quit": "Kilépés",
"notify.update.title": "NetBird frissítés elérhető",
"notify.update.body": "Elérhető a NetBird {version}.",
"notify.update.enforcedSuffix": " A rendszergazda kötelezővé tette ezt a frissítést.",
"notify.error.title": "Hiba",
"notify.error.connect": "Csatlakozás sikertelen",
"notify.error.disconnect": "Bontás sikertelen",
"notify.error.switchProfile": "Átváltás sikertelen erre: {profile}",
"notify.sessionExpired.title": "NetBird munkamenet lejárt",
"notify.sessionExpired.body": "A NetBird munkamenet lejárt. Kérjük, jelentkezzen be újra."
}