From d1bcb17b0d7b222a34bf4a4a41bbc32f1d0ca629 Mon Sep 17 00:00:00 2001 From: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:04:58 -0800 Subject: [PATCH] Add explicit save for HTTP host allowlist setting --- Sources/cmuxApp.swift | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Sources/cmuxApp.swift b/Sources/cmuxApp.swift index 80ee0437..c29c3a0a 100644 --- a/Sources/cmuxApp.swift +++ b/Sources/cmuxApp.swift @@ -2284,6 +2284,7 @@ struct SettingsView: View { @State private var settingsTitleLeadingInset: CGFloat = 92 @State private var showClearBrowserHistoryConfirmation = false @State private var browserHistoryEntryCount: Int = 0 + @State private var browserInsecureHTTPAllowlistDraft = BrowserInsecureHTTPSettings.defaultAllowlistText private var selectedWorkspacePlacement: NewWorkspacePlacement { NewWorkspacePlacement(rawValue: newWorkspacePlacement) ?? WorkspacePlacementSettings.defaultPlacement @@ -2304,6 +2305,10 @@ struct SettingsView: View { } } + private var browserInsecureHTTPAllowlistHasUnsavedChanges: Bool { + browserInsecureHTTPAllowlistDraft != browserInsecureHTTPAllowlist + } + private func blurOpacity(forContentOffset offset: CGFloat) -> Double { guard let baseline = topBlurBaselineOffset else { return 0 } let reveal = (baseline - offset) / 24 @@ -2460,7 +2465,7 @@ struct SettingsView: View { .font(.caption) .foregroundStyle(.secondary) - TextEditor(text: $browserInsecureHTTPAllowlist) + TextEditor(text: $browserInsecureHTTPAllowlistDraft) .font(.system(size: 12, weight: .regular, design: .monospaced)) .frame(minHeight: 86) .padding(6) @@ -2474,6 +2479,17 @@ struct SettingsView: View { ) .accessibilityIdentifier("SettingsBrowserHTTPAllowlistField") + HStack { + Spacer(minLength: 0) + Button("Save") { + saveBrowserInsecureHTTPAllowlist() + } + .buttonStyle(.bordered) + .controlSize(.small) + .disabled(!browserInsecureHTTPAllowlistHasUnsavedChanges) + .accessibilityIdentifier("SettingsBrowserHTTPAllowlistSaveButton") + } + Text("One host or wildcard per line (for example: localhost, 127.0.0.1, *.localtest.me).") .font(.caption) .foregroundStyle(.secondary) @@ -2606,6 +2622,13 @@ struct SettingsView: View { .onAppear { BrowserHistoryStore.shared.loadIfNeeded() browserHistoryEntryCount = BrowserHistoryStore.shared.entries.count + browserInsecureHTTPAllowlistDraft = browserInsecureHTTPAllowlist + } + .onChange(of: browserInsecureHTTPAllowlist) { oldValue, newValue in + // Keep draft in sync with external changes unless the user has local unsaved edits. + if browserInsecureHTTPAllowlistDraft == oldValue { + browserInsecureHTTPAllowlistDraft = newValue + } } .onReceive(BrowserHistoryStore.shared.$entries) { entries in browserHistoryEntryCount = entries.count @@ -2632,11 +2655,16 @@ struct SettingsView: View { browserSearchSuggestionsEnabled = BrowserSearchSettings.defaultSearchSuggestionsEnabled openTerminalLinksInCmuxBrowser = BrowserLinkOpenSettings.defaultOpenTerminalLinksInCmuxBrowser browserInsecureHTTPAllowlist = BrowserInsecureHTTPSettings.defaultAllowlistText + browserInsecureHTTPAllowlistDraft = BrowserInsecureHTTPSettings.defaultAllowlistText notificationDockBadgeEnabled = NotificationBadgeSettings.defaultDockBadgeEnabled newWorkspacePlacement = WorkspacePlacementSettings.defaultPlacement.rawValue KeyboardShortcutSettings.resetAll() shortcutResetToken = UUID() } + + private func saveBrowserInsecureHTTPAllowlist() { + browserInsecureHTTPAllowlist = browserInsecureHTTPAllowlistDraft + } } private struct SettingsTopOffsetPreferenceKey: PreferenceKey {