[PR #6976] [client] Add a Reconnect entry to the tray menu #29347

Open
opened 2026-08-05 08:07:54 -04:00 by saavagebueno · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/6976
Author: @atj393
Created: 7/30/2026
Status: 🔄 Open

Base: mainHead: feature/tray-reconnect


📝 Commits (8)

  • 3b6d884 [client] Add a Reconnect entry to the tray menu
  • 7fa188a Merge branch 'main' into feature/tray-reconnect
  • ca447fe Merge branch 'main' into feature/tray-reconnect
  • 1a52a91 Merge branch 'main' into feature/tray-reconnect
  • cf72c78 [client] Trim the Reconnect comments to the surrounding density
  • 544dc97 [client] Align the Reconnect comments with AGENTS.md
  • 4d489bd [client] Address CodeRabbit review on the Reconnect entry
  • c057ab7 [client] Wait for a cancelled reconnect to unwind before Down

📊 Changes

14 files changed (+311 additions, -0 deletions)

View changed files

📝 client/ui/i18n/locales/de/common.json (+6 -0)
📝 client/ui/i18n/locales/en/common.json (+8 -0)
📝 client/ui/i18n/locales/es/common.json (+6 -0)
📝 client/ui/i18n/locales/fr/common.json (+6 -0)
📝 client/ui/i18n/locales/hu/common.json (+6 -0)
📝 client/ui/i18n/locales/it/common.json (+6 -0)
📝 client/ui/i18n/locales/ja/common.json (+6 -0)
📝 client/ui/i18n/locales/pt/common.json (+6 -0)
📝 client/ui/i18n/locales/ru/common.json (+6 -0)
📝 client/ui/i18n/locales/zh-CN/common.json (+6 -0)
📝 client/ui/services/connection.go (+17 -0)
client/ui/services/connection_test.go (+82 -0)
📝 client/ui/tray.go (+146 -0)
📝 client/ui/tray_profiles.go (+4 -0)

📄 Description

Describe your changes

When the client goes stale after a sleep/wake, a network roam, or peers reading connected while no traffic flows, the remedy is always Disconnect, wait, Connect. The tray exposes only the two halves, so that is four interactions plus a judgement call about when the state has settled, and it is awkward to talk a non-technical colleague through over the phone.

This adds a Reconnect entry that does the round trip in one click. It shares Disconnect's visibility rules, since a reconnect with no session to tear down is just Connect.

Connection.Reconnect owns the ordering. Down is synchronous, so Up follows only once the daemon reports the teardown finished, and a failed Down aborts rather than stacking an Up on a session that is still up. It takes a context so Disconnect and quit can cancel a round trip mid-flight; without that the queued Up lands after the user has explicitly asked to go down, and brings the session back.

The transitional feedback reuses DaemonFeed.BeginProfileSwitch instead of adding a "Reconnecting..." state. A profile switch is already a Down then Up, so the machinery exists: an optimistic Connecting, suppression of the stale blink during teardown, and a login-watch that opens browser-login when the Up lands in NeedsLogin. A parallel state would have to fight the daemon's own status pushes. The name is the part that does not fit two callers; BeginTransition/CancelTransition would read better and I will rename here if you want it.

Two decisions that the diff cannot explain for itself. A click during an in-flight profile switch is ignored rather than cancelling the switch, because cancelling one midway can leave the daemon and the CLI's on-disk profile state disagreeing. And the in-flight guard is a cancel func rather than the menu item's enabled state, because buildMenu recreates every item on relayout, and the status pushes a reconnect produces are what trigger those relayouts.

Discussion: https://github.com/netbirdio/netbird/discussions/6943

No agreed issue exists. The discussion has had no reply since 28 July, so this PR does not meet the ticket-first bar and I am not asking for it to be merged as it stands. It is here as a concrete proposal to react to: validate the discussion and I will follow whatever approach you settle on, or close this and I will take no offence.

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)
  • I ran and tested this change locally — I did not rely on CI to find out whether it works
  • This PR has a single purpose (not a fix + refactor + feature in one)
  • This change is a trivial fix, OR it links an issue the NetBird team agreed on beforehand. Changes to the public API, gRPC protocols, functionality behavior, CLI / service flags, or new features always need that agreement first. See CONTRIBUTING.md.

Two boxes left unticked deliberately. The local-testing box: gofmt, go build, go vet, go test and golangci-lint run all pass over ./client/ui/... on Windows, but the entry itself has never been clicked, since I have no Wails toolchain or running daemon on this machine, so I will not claim to have tested the feature. The agreement box: covered above.

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

A tray entry with no new setting, flag, or API. If the docs enumerate the tray menu somewhere I missed, point me at it and I will open the matching netbirdio/docs PR.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

n/a

Summary by CodeRabbit

  • New Features

    • Added a Reconnect option to the system tray menu.
    • Reconnects the app by safely disconnecting and reconnecting the service.
    • Prevents duplicate reconnect attempts and coordinates reconnection with disconnecting, quitting, and profile switching.
    • Added localized reconnect and reconnection-failure messages across supported languages.
  • Bug Fixes

    • Improved recovery when reconnection fails, including clearer status updates and error handling.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbirdio/netbird/pull/6976 **Author:** [@atj393](https://github.com/atj393) **Created:** 7/30/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feature/tray-reconnect` --- ### 📝 Commits (8) - [`3b6d884`](https://github.com/netbirdio/netbird/commit/3b6d8845fb029d1b8787a874a7e9f294024c543d) [client] Add a Reconnect entry to the tray menu - [`7fa188a`](https://github.com/netbirdio/netbird/commit/7fa188a30e74f9ebc4175d3384d73da4cc564ce6) Merge branch 'main' into feature/tray-reconnect - [`ca447fe`](https://github.com/netbirdio/netbird/commit/ca447fe7e93e973735365657c9fd6891aa05ef25) Merge branch 'main' into feature/tray-reconnect - [`1a52a91`](https://github.com/netbirdio/netbird/commit/1a52a915b32c879bdbc1a2c8922a417f9fab8665) Merge branch 'main' into feature/tray-reconnect - [`cf72c78`](https://github.com/netbirdio/netbird/commit/cf72c781a83c83e53b3827e3af638f905a3c3024) [client] Trim the Reconnect comments to the surrounding density - [`544dc97`](https://github.com/netbirdio/netbird/commit/544dc9708ff499168631b239e6f495358b936734) [client] Align the Reconnect comments with AGENTS.md - [`4d489bd`](https://github.com/netbirdio/netbird/commit/4d489bd26811679398997e4c49c74d6b90d982e2) [client] Address CodeRabbit review on the Reconnect entry - [`c057ab7`](https://github.com/netbirdio/netbird/commit/c057ab7c2885240a5b38303adf66a6e927543a1e) [client] Wait for a cancelled reconnect to unwind before Down ### 📊 Changes **14 files changed** (+311 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `client/ui/i18n/locales/de/common.json` (+6 -0) 📝 `client/ui/i18n/locales/en/common.json` (+8 -0) 📝 `client/ui/i18n/locales/es/common.json` (+6 -0) 📝 `client/ui/i18n/locales/fr/common.json` (+6 -0) 📝 `client/ui/i18n/locales/hu/common.json` (+6 -0) 📝 `client/ui/i18n/locales/it/common.json` (+6 -0) 📝 `client/ui/i18n/locales/ja/common.json` (+6 -0) 📝 `client/ui/i18n/locales/pt/common.json` (+6 -0) 📝 `client/ui/i18n/locales/ru/common.json` (+6 -0) 📝 `client/ui/i18n/locales/zh-CN/common.json` (+6 -0) 📝 `client/ui/services/connection.go` (+17 -0) ➕ `client/ui/services/connection_test.go` (+82 -0) 📝 `client/ui/tray.go` (+146 -0) 📝 `client/ui/tray_profiles.go` (+4 -0) </details> ### 📄 Description ## Describe your changes When the client goes stale after a sleep/wake, a network roam, or peers reading connected while no traffic flows, the remedy is always Disconnect, wait, Connect. The tray exposes only the two halves, so that is four interactions plus a judgement call about when the state has settled, and it is awkward to talk a non-technical colleague through over the phone. This adds a Reconnect entry that does the round trip in one click. It shares Disconnect's visibility rules, since a reconnect with no session to tear down is just Connect. `Connection.Reconnect` owns the ordering. Down is synchronous, so Up follows only once the daemon reports the teardown finished, and a failed Down aborts rather than stacking an Up on a session that is still up. It takes a context so Disconnect and quit can cancel a round trip mid-flight; without that the queued Up lands after the user has explicitly asked to go down, and brings the session back. The transitional feedback reuses `DaemonFeed.BeginProfileSwitch` instead of adding a "Reconnecting..." state. A profile switch is already a Down then Up, so the machinery exists: an optimistic Connecting, suppression of the stale blink during teardown, and a login-watch that opens browser-login when the Up lands in NeedsLogin. A parallel state would have to fight the daemon's own status pushes. The name is the part that does not fit two callers; `BeginTransition`/`CancelTransition` would read better and I will rename here if you want it. Two decisions that the diff cannot explain for itself. A click during an in-flight profile switch is ignored rather than cancelling the switch, because cancelling one midway can leave the daemon and the CLI's on-disk profile state disagreeing. And the in-flight guard is a cancel func rather than the menu item's enabled state, because `buildMenu` recreates every item on relayout, and the status pushes a reconnect produces are what trigger those relayouts. ## Issue ticket number and link Discussion: https://github.com/netbirdio/netbird/discussions/6943 No agreed issue exists. The discussion has had no reply since 28 July, so this PR does not meet the ticket-first bar and I am not asking for it to be merged as it stands. It is here as a concrete proposal to react to: validate the discussion and I will follow whatever approach you settle on, or close this and I will take no offence. ## Stack <!-- branch-stack --> ### Checklist - [ ] Is it a bug fix - [ ] Is a typo/documentation fix - [x] Is a feature enhancement - [ ] It is a refactor - [x] Created tests that fail without the change (if possible) - [ ] I ran and tested this change locally — I did not rely on CI to find out whether it works - [x] This PR has a single purpose (not a fix + refactor + feature in one) - [ ] This change is a trivial fix, **OR** it links an issue the NetBird team agreed on beforehand. Changes to the public API, gRPC protocols, functionality behavior, CLI / service flags, or new features always need that agreement first. See [CONTRIBUTING.md](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTING.md#ticket-first-pr-second). Two boxes left unticked deliberately. The local-testing box: `gofmt`, `go build`, `go vet`, `go test` and `golangci-lint run` all pass over `./client/ui/...` on Windows, but the entry itself has never been clicked, since I have no Wails toolchain or running daemon on this machine, so I will not claim to have tested the feature. The agreement box: covered above. > By submitting this pull request, you confirm that you have read and agree to the terms of the [Contributor License Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md). ## Documentation Select exactly one: - [ ] I added/updated documentation for this change - [x] Documentation is **not needed** for this change (explain why) A tray entry with no new setting, flag, or API. If the docs enumerate the tray menu somewhere I missed, point me at it and I will open the matching netbirdio/docs PR. ### Docs PR URL (required if "docs added" is checked) Paste the PR link from https://github.com/netbirdio/docs here: n/a <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a **Reconnect** option to the system tray menu. - Reconnects the app by safely disconnecting and reconnecting the service. - Prevents duplicate reconnect attempts and coordinates reconnection with disconnecting, quitting, and profile switching. - Added localized reconnect and reconnection-failure messages across supported languages. - **Bug Fixes** - Improved recovery when reconnection fails, including clearer status updates and error handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
saavagebueno added the pull-request label 2026-08-05 08:07:54 -04:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#29347