Commit Graph

10 Commits

Author SHA1 Message Date
Zoltán Papp
bb2bf673a0 [client/ui-wails] Wire up the SSO login flow end-to-end
Mirror the Fyne client's login path: the daemon Login RPC now defaults
ProfileName/Username from GetActiveProfile + the OS user and sets
IsUnixDesktopClient on Linux/FreeBSD so the daemon picks the SSO
browser flow. A new OpenURL service launches the user's default
browser via xdg-open / open / rundll32 (Fyne's openURL helper) — the
embedded WebKit's window.open silently fails for external URLs.

The frontend gains a Login page that drives the full Login →
window.open via OpenURL → WaitSSOLogin → Up sequence with progress
states. Status surfaces a Login button while the daemon reports
NeedsLogin/SessionExpired, and the tray's status row stops being a
purely-decorative label: it becomes a clickable Login entry whenever
re-authentication is required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:48:47 +02:00
Zoltán Papp
8b8f38de1b [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.
2026-05-06 16:55:52 +02:00
Zoltán Papp
e6cbf30415 [client/ui-wails] Surface daemon SessionExpired in the tray
Port the Fyne UI's onSessionExpire 1:1 to the Wails tray so an SSO token
expiry no longer leaves the user staring at a stale peer list. When
applyStatus sees the transition into the daemon's StatusSessionExpired,
fire a single OS notification (the lastStatus guard rate-limits it to
the transition itself, mirroring the Fyne sendNotification flag) and
bring the main window forward on the /login route so the frontend can
drive the renewed SSO flow. The Fyne client achieved the same end with
a runSelfCommand "login-url" helper; here the window is already
in-process so we route to it directly.
2026-05-06 15:57:34 +02:00
Zoltán Papp
6f93cf6ac3 [client/ui-wails] Group Tray's services into a TrayServices struct
NewTray's eight-parameter signature crossed Sonar's seven-parameter
threshold once Update joined the dependency list. Bundle the six service
pointers (Connection, Settings, Profiles, Peers, Notifier, Update) into
a TrayServices struct, leaving NewTray with three arguments — the two
Wails platform handles plus the service bag. Tray.svc replaces the
individual fields; call sites use t.svc.Connection etc.

Adding another service later is now a one-line struct change instead
of a NewTray signature break.
2026-05-05 15:37:25 +02:00
Zoltán Papp
2e61b42e92 [client/ui-wails] Slim the tray menu, move toggles to Settings page
The Fyne 1:1 tray pulled the entire daemon-config knobset (Allow SSH,
Connect on Startup, Quantum-Resistance, Lazy Connections, Block Inbound,
Notifications) into a Settings submenu — useful in a tray-only UI but
redundant now that the Wails app has a real Settings page. Drop the
submenu and route a single top-level "Settings" entry to /settings;
"Create Debug Bundle" stays at the top level for support workflows.

Side effects:
  - flipFlag and ptrBool go away with the checkbox callbacks.
  - loadConfig keeps seeding notificationsEnabled (the tray still gates
    OS toasts in onSystemEvent on it) but no longer mirrors any other
    config field.
  - Unused menu/notify constants (Allow SSH, Connect on Startup, ...,
    notifyErrorSettingsFmt) are removed from the central const block.
2026-05-05 12:19:41 +02:00
Zoltán Papp
bc609c3ae7 [client/ui-wails] Wire up enforced-update tray menu item
Surface the Fyne UI's "Download latest version" / "Install version X.Y.Z"
About-submenu entry in the Wails tray. The item starts hidden and is
revealed by onUpdateAvailable when the daemon emits EventUpdateAvailable;
opt-in updates open github.com/netbirdio/netbird/releases/latest in the
browser, enforced updates surface the in-window /update progress page
and call TriggerUpdate on the daemon.

Also lift every user-facing string and external URL in tray.go into
named const declarations at the top of the file, so future copy edits
and (eventual) localisation have a single source of truth.

The /update React route is the frontend counterpart and is owned by the
React side of the refactor.
2026-05-05 11:56:57 +02:00
Zoltán Papp
a69037630b [client/ui-wails] Skip tray click-to-toggle on Linux
GNOME Shell + AppIndicator extension opens the attached menu on
left-click in addition to firing SNI Activate, so binding the window
toggle to the click handler made both the window and the menu pop on a
single click. The default Wails3 SystemTray.applySmartDefaults made it
worse: AttachWindow alone is enough to install ToggleWindow as the
implicit click handler, so dropping OnClick wasn't sufficient.

Mirror the legacy Fyne client: skip both AttachWindow and OnClick on
Linux and expose the main window through an explicit "Open NetBird"
menu item. Windows and macOS keep the click-to-toggle behaviour where
the OS cleanly separates left and right click.
2026-05-04 16:08:10 +02:00
Zoltán Papp
88a2bf582d [client] Push-based status stream for the Wails UI
Adds a SubscribeStatus gRPC RPC that pushes a fresh FullStatus snapshot
on every peer-recorder state change, replacing the Wails UI's 2-second
Status poll. The daemon's notifier already triggers on Connected /
Disconnected / Connecting / management or signal flip / address
change / peers-list change; we now coalesce those into ticks on a
buffered chan and stream the resulting snapshots over gRPC.

- Status recorder gains SubscribeToStateChanges /
  UnsubscribeFromStateChanges + a non-blocking notifyStateChange that
  drops ticks when a subscriber's 1-slot buffer is full (next snapshot
  the consumer pulls already reflects everything).
- Server.Status handler split: the snapshot composition is shared
  with the new SubscribeStatus stream handler so unary and stream
  paths return identical bytes.
- UI peers service: pollLoop replaced by statusStreamLoop. The local
  name of the existing SubscribeEvents loop is now toastStreamLoop so
  the two streams are easy to tell apart — the underlying RPC name is
  unchanged.
- Tray applyStatus skips the icon refresh when connected/lastStatus
  hasn't changed; rapid SubscribeStatus bursts during health probes
  no longer churn Shell_NotifyIcon or the log.
2026-04-30 11:45:43 +02:00
Zoltán Papp
0148d926d5 [client/ui-wails] Use original Fyne tray PNGs and drop the .ico split
The SVG-derived tray icons + multi-resolution .ico path looked correct on
disk but Wails3's Shell_NotifyIcon update never landed on the running
Windows tray — the icon stayed frozen on the .exe resource regardless of
how many times we called SetIcon. Single-PNG fed through the same path
updates correctly, so revert to the source-of-truth PNGs that ship with
the legacy Fyne UI and remove the icons_windows.go / tray_icon_*.go
split. The 6 colored tray PNGs and 6 macOS-template PNGs come from
client/ui/assets verbatim. Generation pipeline (assets/svg/) is gone.
2026-04-29 18:54:51 +02:00
Zoltán Papp
504dceedf3 [client] Add Wails3 + React desktop UI scaffold
Stage 1 of the client/ui (Fyne) replacement. Adds a new client/ui-wails
module that runs on Linux/macOS/Windows from a single React + Vite +
Tailwind frontend driven by a thin gRPC services layer in Go.

- Single-module integration (no submodule): merge Wails3 into root go.mod
  with build tags !android !ios !freebsd !js so cross-compiles on those
  targets exclude the package automatically.
- Seven gRPC-bound services: Connection, Settings, Networks, Profiles,
  Debug, Update, Peers. Peers bridges Status polling and SubscribeEvents
  to the Wails event bus (netbird:status, netbird:event).
- Tray + window shell mirrors the Fyne menu 1:1 with hide-on-close,
  SIGUSR1 / Windows named-event for external "show window" triggers.
- React pages cover functional parity for Status, Settings (3 tabs),
  Networks (3 tabs), Profiles, Debug, Update, QuickActions, LoginUrl.
- SVG-sourced tray icons (12 source SVGs incl. macOS template variants)
  rasterized to PNG via task common:generate:tray:icons.
- Linux launcher sets WEBKIT_DISABLE_DMABUF_RENDERER=1 in the .desktop
  Exec= line and in task linux:run so the app renders correctly under
  RDP, VirtualBox, KVM, and bare WMs (Fluxbox/dwm) without DRM access.
2026-04-29 11:10:23 +02:00