From 21783d547870ac392f12aa7fa48d2005a31d05eb Mon Sep 17 00:00:00 2001 From: torlando-tech <239676438+torlando-tech@users.noreply.github.com> Date: Fri, 9 Oct 2026 19:59:26 +0000 Subject: [PATCH 1/2] ui: remove 'Disable Background Transport' button from explainer sheet The Start/Stop control in the Reticulum Network settings card is the authoritative way to stop the tunnel. The explainer sheet's disable button is now redundant - remove it. The enable button remains for the not-yet-enabled state. --- .../Settings/BackgroundTransportView.swift | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/Sources/ColumbaApp/Views/Settings/BackgroundTransportView.swift b/Sources/ColumbaApp/Views/Settings/BackgroundTransportView.swift index 104bf85c..69250cd7 100644 --- a/Sources/ColumbaApp/Views/Settings/BackgroundTransportView.swift +++ b/Sources/ColumbaApp/Views/Settings/BackgroundTransportView.swift @@ -196,24 +196,7 @@ struct BackgroundTransportView: View { @ViewBuilder private var actionButton: some View { - if isEnabledState { - // Disable: clear on-demand + stop (a bare stop() would auto-reconnect). - Button { - errorMessage = nil - Task { - do { try await tunnel.disable() } - catch { errorMessage = error.localizedDescription } - } - } label: { - Text("Disable Background Transport") - .font(.headline) - .foregroundStyle(.white) - .frame(maxWidth: .infinity) - .padding(.vertical, 16) - .background(Theme.error) - .clipShape(RoundedRectangle(cornerRadius: Theme.cornerRadiusLarge)) - } - } else { + if !isEnabledState { // Enable: install the profile (also arms on-demand) then start. Button { enable() From 0247d71666e795e3884b2c99e081fdeaebaf4122 Mon Sep 17 00:00:00 2001 From: torlando-tech <239676438+torlando-tech@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:05:42 +0000 Subject: [PATCH 2/2] fix: Reticulum card offers Stop during connecting/reasserting Greptile P1: removing the explainer sheet's disable button left no in-app stop while the tunnel is .connecting or .reasserting, because the card's Start/Stop used tunnel.isRunning (true only for .connected) and would show 'Start' in those states. Add reticulumIsOn() mirroring the explainer's isEnabledState (on for connected/connecting/reasserting/disconnecting) and use it for the card button's action, label, and color. User can now cancel a slow connect or in-progress stop. --- .../Views/Settings/SettingsView.swift | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Sources/ColumbaApp/Views/Settings/SettingsView.swift b/Sources/ColumbaApp/Views/Settings/SettingsView.swift index 2a241421..04051ef8 100644 --- a/Sources/ColumbaApp/Views/Settings/SettingsView.swift +++ b/Sources/ColumbaApp/Views/Settings/SettingsView.swift @@ -563,7 +563,7 @@ struct SettingsView: View { // profile (re-arms on-demand) and reconnects in this session. Button { guard !isReticulumActionWorking else { return } - let stopping = tunnel.isRunning + let stopping = reticulumIsOn(tunnel) isReticulumActionWorking = true Task { defer { isReticulumActionWorking = false } @@ -583,14 +583,14 @@ struct SettingsView: View { if isReticulumActionWorking { ProgressView().tint(.white) } else { - Text(tunnel.isRunning ? String(localized: "Stop") : String(localized: "Start")) + Text(reticulumIsOn(tunnel) ? String(localized: "Stop") : String(localized: "Start")) } } .font(.subheadline.weight(.semibold)) .foregroundStyle(.white) .frame(maxWidth: .infinity) .padding(.vertical, 14) - .background(tunnel.isRunning + .background(reticulumIsOn(tunnel) ? LinearGradient(colors: [Theme.error], startPoint: .top, endPoint: .bottom) : Theme.accentGradient) .clipShape(RoundedRectangle(cornerRadius: Theme.cornerRadiusMedium)) @@ -643,6 +643,24 @@ struct SettingsView: View { @unknown default: return Theme.textSecondary } } + + /// Whether the card's action button should present the "Stop" (disable) + /// affordance. Mirrors the explainer sheet's `isEnabledState`: the tunnel + /// counts as "on" whenever it is connected, mid-connect, reasserting, or + /// tearing down - so a user can cancel a slow connect / in-progress stop + /// instead of being stuck on "Start". (A bare `isRunning` is only true for + /// `.connected`, which hides the stop action during `.connecting` / + /// `.reasserting` - the gap PR #217's removed explainer button used to cover.) + private func reticulumIsOn(_ tunnel: TunnelManager) -> Bool { + switch tunnel.status { + case .connected, .connecting, .reasserting, .disconnecting: + return true + case .disconnected, .invalid: + return false + @unknown default: + return tunnel.isEnabled + } + } #endif // MARK: - Identity Card