refactor: extract ExitNodeManager, DiagnosticsBuilder, QrCodeHelper from TailscaleController #2

Open
hermes wants to merge 1 commit from refactor/split-controller-pr2 into main
Member

Summary

Breaks up the TailscaleController god class (1346 lines) by extracting three focused helper classes. All Q_PROPERTY and Q_INVOKABLE signatures remain identical — zero QML changes needed.

New files

ExitNodeManager (277 + 59 lines):

  • Exit-node group building from status JSON (Mullvad country/city parsing, direct nodes)
  • Country favorites with JSON persistence
  • Quick-connect logic (random favorite country → probe 3 nodes → connect to fastest)
  • All m_exitNodeCandidates, m_exitNodeCountries, m_directExitNodes, m_countryNodes, m_favoriteCountries, m_quickProbe* members moved here
  • Emits setBusyRequested / probeNextQuickCandidate signals back to the controller

DiagnosticsBuilder (105 + 51 lines):

  • Owns m_logLines, appendLogLine, m_tailscaleLogs, m_netcheckText
  • Builds the diagnostics text dump from a DiagnosticsSnapshot struct the controller fills in
  • Separator string "---- log ----" now lives in one place (fixes the magic-string coupling)

QrCodeHelper (41 + 19 lines):

  • Wraps the vendored Nayuki qrcodegen library
  • generateQrCode() method moved here verbatim
  • qrcodegen.{c,h} stay in place (vendored, untouched)

Modified files

  • tailscalecontroller.{h,cpp} — 1346 → 1091 lines; keeps DBus layer, parseStatusJson, status/login/ping polling, and all QML-facing properties/methods; delegates to the three helpers
  • app/app.pro — added 3 SOURCES + 3 HEADERS

Verification

  • ✅ All Q_PROPERTY/Q_INVOKABLE signatures unchanged — QML needs no edits
  • ✅ No duplicate or missing method definitions (cross-checked header ↔ cpp)
  • ✅ Brace balance verified
  • ✅ No dangling references to moved members in the controller
  • ✅ Translation context: .ts file is essentially empty, so tr() context change is safe
  • ⚠️ Could not compile-verify (no podman/docker daemon or Qt toolchain in this environment) — the changes are a mechanical extraction; a real mb2 build on the release host is recommended before tagging

Stats

  • 9 files changed, 643 insertions(+), 350 deletions(-)
  • Controller: 1346 → 1091 lines (19% reduction)
## Summary Breaks up the `TailscaleController` god class (1346 lines) by extracting three focused helper classes. All Q_PROPERTY and Q_INVOKABLE signatures remain identical — **zero QML changes needed**. ### New files **`ExitNodeManager`** (277 + 59 lines): - Exit-node group building from status JSON (Mullvad country/city parsing, direct nodes) - Country favorites with JSON persistence - Quick-connect logic (random favorite country → probe 3 nodes → connect to fastest) - All `m_exitNodeCandidates`, `m_exitNodeCountries`, `m_directExitNodes`, `m_countryNodes`, `m_favoriteCountries`, `m_quickProbe*` members moved here - Emits `setBusyRequested` / `probeNextQuickCandidate` signals back to the controller **`DiagnosticsBuilder`** (105 + 51 lines): - Owns `m_logLines`, `appendLogLine`, `m_tailscaleLogs`, `m_netcheckText` - Builds the diagnostics text dump from a `DiagnosticsSnapshot` struct the controller fills in - Separator string `"---- log ----"` now lives in one place (fixes the magic-string coupling) **`QrCodeHelper`** (41 + 19 lines): - Wraps the vendored Nayuki `qrcodegen` library - `generateQrCode()` method moved here verbatim - `qrcodegen.{c,h}` stay in place (vendored, untouched) ### Modified files - `tailscalecontroller.{h,cpp}` — 1346 → 1091 lines; keeps DBus layer, `parseStatusJson`, status/login/ping polling, and all QML-facing properties/methods; delegates to the three helpers - `app/app.pro` — added 3 SOURCES + 3 HEADERS ### Verification - ✅ All Q_PROPERTY/Q_INVOKABLE signatures unchanged — QML needs no edits - ✅ No duplicate or missing method definitions (cross-checked header ↔ cpp) - ✅ Brace balance verified - ✅ No dangling references to moved members in the controller - ✅ Translation context: `.ts` file is essentially empty, so `tr()` context change is safe - ⚠️ Could not compile-verify (no podman/docker daemon or Qt toolchain in this environment) — the changes are a mechanical extraction; a real `mb2 build` on the release host is recommended before tagging ### Stats - 9 files changed, 643 insertions(+), 350 deletions(-) - Controller: 1346 → 1091 lines (19% reduction)
Some checks failed
Build aarch64 rpm / build (pull_request) Failing after 1m11s
This pull request has changes conflicting with the target branch.
  • app/src/tailscalecontroller.cpp
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin 'refactor/split-controller-pr2:refactor/split-controller-pr2'
git switch 'refactor/split-controller-pr2'

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch 'main'
git merge --no-ff 'refactor/split-controller-pr2'
git switch 'refactor/split-controller-pr2'
git rebase 'main'
git switch 'main'
git merge --ff-only 'refactor/split-controller-pr2'
git switch 'refactor/split-controller-pr2'
git rebase 'main'
git switch 'main'
git merge --no-ff 'refactor/split-controller-pr2'
git switch 'main'
git merge --squash 'refactor/split-controller-pr2'
git switch 'main'
git merge --ff-only 'refactor/split-controller-pr2'
git switch 'main'
git merge 'refactor/split-controller-pr2'
git push origin 'main'
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ews-network/finnscale!2
No description provided.