mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-28 21:26:40 +00:00
5.4 KiB
5.4 KiB
Flutter UI Migration
Current Boundary
Keep the daemon as-is and replace only the desktop UI process. The Flutter app
should continue to talk to DaemonService from client/proto/daemon.proto.
The current UI is not a simple settings window. It owns:
- tray/menu-bar state and nested menu actions
- gRPC connection management and event subscription
- connect, disconnect, login, and session-expired flows
- profile switching, deregistration, and profile windows
- network route and exit-node selection
- advanced settings
- debug bundle creation and upload status dialogs
- enforced update notifications and progress windows
- OS sleep/wake notification to the daemon
- single-instance signaling and quick-actions windows
Phases
-
Scaffold and generated gRPC client
- Done: generated Dart stubs from
client/proto/daemon.proto. - Done: app defaults to a gRPC-backed implementation and keeps
--fake-daemonfor UI-only work. - Remaining: replace the development user agent suffix with the release version at build time.
- Done: generated Dart stubs from
-
Core connection parity
- Done: status polling and
SubscribeEventsrefresh hooks. - Done:
connect()runsLogin→ optional SSO browser handoff viaopenExternalUrl→WaitSSOLogin→Up, with anawaitingLoginsnapshot state and a banner that exposes the verification URI and user code. - Done:
disconnect()callsDown. - Match current daemon address defaults:
- Windows:
tcp://127.0.0.1:41731 - Unix-like desktop:
unix:///var/run/netbird.sock
- Windows:
- Done: status polling and
-
Settings, profiles, and networks
- Done:
GetConfig/SetConfigfor the toggleable settings (auto-connect, allow SSH, quantum resistance, lazy connections, block inbound, notifications). Read-only fields (management URL, interface, port, MTU) still need editable forms. - Done: profile add/switch/remove/logout via
AddProfile,SwitchProfile,RemoveProfile,Logout. - Done: network list with overlap filtering, per-route
SelectNetworks/DeselectNetworks, and exit-node single-selection.
- Done:
-
Desktop integration
- Done: tray icon and menu via
tray_manager(status header, profile, Connect/Disconnect, Show window, Quit) with status-aware icons that fall back to template variants on macOS. - Done: window lifecycle via
window_manager— close hides instead of exiting; tray "Quit" actually destroys the window. - Done: native notifications via
local_notifier, fed by the daemon'sSubscribeEventsstream and gated by thenotificationssetting (with CRITICAL severity always firing). - Done: browser launch and clipboard via
Process.runandflutter/servicesClipboard. - Remaining: file/folder reveal for debug bundles, single-instance
signaling, quick-actions invocation, and sleep/wake forwarding through
NotifyOSLifecycle. Settings/Networks submenus on the tray are deferred until the window-side flows are stable. - Note:
local_notifieruses macOS's deprecatedNSUserNotificationCenter(warns at build time). Plan to swap toflutter_local_notificationsbefore release.
- Done: tray icon and menu via
-
Debug and update flows
- Done: rich debug bundle screen with anonymize, system-info, upload (URL),
and run-with-trace + duration. State machine drives
GetLogLevel→SetLogLevel(TRACE)→Down→SetSyncResponsePersistence→Up→ progress over duration →StopCPUProfile→DebugBundle, with restore of original log level and persistence in a finally. Result dialog covers uploaded, upload-failed, and local-only outcomes with copy/open actions. - Done: enforced-update modal triggered by daemon
progress_window=showmetadata. PollsGetInstallerResultwith a 15-min timeout, blocks close for 10 s, then surfaces success (auto-close) or failure (error message). - Remaining: hook a "Check for updates" / "Install now" button into the
About surface that calls
TriggerUpdatedirectly.
- Done: rich debug bundle screen with anonymize, system-info, upload (URL),
and run-with-trace + duration. State machine drives
-
Release pipeline
- Update
.github/workflows/release.ymlUI build steps. - Update
client/netbird.wxs,release_files/install.sh, andrelease_files/ui-post-install.shwhere they assume the Go UI artifact. - Update updater restart behavior in
client/internal/updater/installer. - Preserve public artifact names until installers and updater logic are intentionally migrated.
- Update
RPCs Used By The Current UI
The first production implementation should cover:
Status,Up,DownLogin,WaitSSOLogin,LogoutGetConfig,SetConfig,GetFeaturesSubscribeEventsListNetworks,SelectNetworks,DeselectNetworksListProfiles,AddProfile,SwitchProfile,RemoveProfile,GetActiveProfileDebugBundle,GetLogLevel,SetLogLevel,SetSyncResponsePersistence,StartCPUProfile,StopCPUProfileTriggerUpdate,GetInstallerResultNotifyOSLifecycle
Risk Register
- Desktop tray support differs sharply across Windows, macOS, and Linux.
- Linux app indicators and desktop-session startup need distro-level testing.
- The updater currently restarts
netbird-uiby process/app name on Windows and macOS, so artifact naming changes must be coordinated. - Dart gRPC over Unix domain sockets must be validated against the daemon's
existing
unix://address behavior. - Flutter desktop packaging is separate from Go builds, so release CI needs a new toolchain and cache strategy.