fix(interfaces): remove redundant Apply button on the Swift build (changes apply live)#100
Conversation
…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 SummaryThis 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
Confidence Score: 5/5Safe 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
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]
%%{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]
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>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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
toggle/add/update/delete) callsInterfaceRepository.saveInterfaces(), which writes the sharedinterfacesKeyand postsconfigChangedimmediately.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.requiresExplicitApply→ hidden on the Swift build, kept on Python.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