Skip to content

fix(interfaces): remove redundant Apply button on the Swift build (changes apply live)#100

Merged
torlando-tech merged 2 commits into
mainfrom
fix/ios-interface-apply-wording
Jun 21, 2026
Merged

fix(interfaces): remove redundant Apply button on the Swift build (changes apply live)#100
torlando-tech merged 2 commits into
mainfrom
fix/ios-interface-apply-wording

Conversation

@torlando-tech

@torlando-tech torlando-tech commented Jun 21, 2026

Copy link
Copy Markdown
Owner

What

On the Swift / Model B build, interface changes apply live the moment you make them, so the "Apply" button (and the "tap Apply to restart" prompt) was redundant — it did nothing. Remove it on that build; keep it on Python where it's still needed.

Why the button was a no-op on Model B

  • Every repository edit (toggle/add/update/delete) calls InterfaceRepository.saveInterfaces(), which writes the shared interfacesKey and posts configChanged immediately.
  • On Model B the NE observes that and live-reconciles its ne-tcp-relay-* / BLE / RNode interfaces — "a relay add/edit/remove takes effect with NO VPN restart."
  • AppServices.applyInterfaceChanges() early-returns on Model B — so tapping "Apply" did literally nothing (and nothing ever restarted, despite the old wording).

Change

  • InterfaceManagementViewModel.requiresExplicitApply = !BackendPreference.modelB.
  • Screen: the Apply toolbar button is only shown when requiresExplicitApply → hidden on the Swift build, kept on Python.
  • Toasts: on Model B, edit confirmations drop the "tap Apply" hint (the change is already live: "Interface added", "Hub enabled", …); on Python they keep "— tap Apply to take effect".
  • Fixed the stale comments (no phantom "Apply & Restart" button, no "Reticulum has no hot-reload").

Python behavior unchanged — Apply still hot-applies via applyInterfaceChanges().

Builds clean (Columba-Swift); verified on-device that the button is gone and changes apply live.

🤖 Generated with Claude Code

…ply live)

Interface changes are applied live on every backend — no restart:
- Model B (Swift build): applyInterfaceChanges() hands the change to the NE
  via configChanged, which live-reconciles its ne-tcp-relay-* interfaces with
  NO VPN restart (AppServices.swift).
- Python: the same path hot add/removes interfaces on the running stack.

But the toolbar button is just "Apply", and the success toasts + doc comments
still said "tap Apply to restart" / referenced an "Apply & Restart" button and
"Reticulum (which has no hot-reload)" — all stale, and especially confusing on
the Swift build which never restarts. Reword the four toasts to "tap Apply to
take effect" and fix the comments to describe the live hot add/remove.

No behavior change — strings and comments only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes stale user-facing toast strings ("tap Apply to restart" → "tap Apply to take effect") and corrects doc comments that referenced a phantom "Apply & Restart" button and a non-existent Reticulum restart requirement. It also introduces requiresExplicitApply and applyHint computed properties to drive both toast text and the Apply toolbar button's visibility based on which backend is active.

  • Four success toasts are updated to use applyHint, which resolves to the new wording on Python and to an empty string on Model B (Swift), where changes are already live on save.
  • The Apply toolbar button in InterfaceManagementScreen now also gates on requiresExplicitApply, so it is hidden entirely on Model B — a functional change that the PR description describes as "strings and comments only."

Confidence Score: 5/5

Safe to merge — all changes are string corrections, comment updates, and a toolbar button guard that correctly reflects the live-reconcile behavior of the Model B backend.

The toast rewording and doc-comment corrections are accurate and harmless. The new requiresExplicitApply guard on the Apply toolbar button is the only functional code change; it aligns the UI with the documented no-op behavior of applyInterfaceChanges() on Model B, so it fixes a latent inconsistency rather than introducing one.

No files require special attention. The toolbar condition change in InterfaceManagementScreen.swift is the one logical change worth a quick read, but it is well-commented and consistent with the ViewModel's new requiresExplicitApply property.

Important Files Changed

Filename Overview
Sources/ColumbaApp/ViewModels/InterfaceManagementViewModel.swift Adds requiresExplicitApply / applyHint helpers and rewires four toast strings to use them; doc comments updated to accurately describe live vs. staged apply behavior.
Sources/ColumbaApp/Views/Settings/InterfaceManagementScreen.swift Adds requiresExplicitApply guard to the Apply toolbar button condition, hiding it on Model B; comment explains the live-reconcile rationale.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Interface action: toggle / delete / add / update] --> B{BackendPreference.modelB?}
    B -->|Yes - Model B| C[requiresExplicitApply = false]
    B -->|No - Python| D[requiresExplicitApply = true]
    C --> E[applyHint = empty string]
    D --> F[applyHint = tap Apply to take effect]
    E --> G[Toast shows action only\nApply button hidden]
    F --> H[Toast shows action plus hint\nApply button visible when pending]
    G --> I[NE reconciles change live on save]
    H --> J[User taps Apply to push to Python stack]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Interface action: toggle / delete / add / update] --> B{BackendPreference.modelB?}
    B -->|Yes - Model B| C[requiresExplicitApply = false]
    B -->|No - Python| D[requiresExplicitApply = true]
    C --> E[applyHint = empty string]
    D --> F[applyHint = tap Apply to take effect]
    E --> G[Toast shows action only\nApply button hidden]
    F --> H[Toast shows action plus hint\nApply button visible when pending]
    G --> I[NE reconciles change live on save]
    H --> J[User taps Apply to push to Python stack]
Loading

Reviews (2): Last reviewed commit: "fix(interfaces): remove redundant Apply ..." | Re-trigger Greptile

…uild

The "Apply" button did nothing on the Swift build: applyInterfaceChanges()
early-returns on Model B, and every repository edit already calls
saveInterfaces() → posts configChanged → the NE live-reconciles immediately.
So a change is live the moment it's made; Apply was a no-op (and the "tap
Apply…" toasts were misleading).

- ViewModel: add requiresExplicitApply (= !BackendPreference.modelB).
- Screen: hide the Apply toolbar button unless requiresExplicitApply (so it's
  gone on the Swift build, kept on Python).
- Toasts: drop the "tap Apply" hint on Model B (change already live); Python
  keeps "— tap Apply to take effect".

Python behavior unchanged — Apply still hot-applies via applyInterfaceChanges().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@torlando-tech torlando-tech changed the title fix(interfaces): correct stale "Apply to restart" wording (changes apply live) fix(interfaces): remove redundant Apply button on the Swift build (changes apply live) Jun 21, 2026
@codecov

codecov Bot commented Jun 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@torlando-tech torlando-tech merged commit 3cdd02e into main Jun 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant