diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Configuration.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Configuration.swift index 5eee42c6c..ddea5741d 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Configuration.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Configuration.swift @@ -72,6 +72,11 @@ public class Configuration: ObservableObject { set { defaults.set(newValue, forKey: Keys.disableUpdateCheck) } } + var supportURL: String { + get { defaults.string(forKey: Keys.supportURL) ?? Self.defaultSupportURL } + set { defaults.set(newValue, forKey: Keys.supportURL) } + } + #if DEBUG static let defaultAuthURL = "https://app.firez.one" static let defaultApiURL = "wss://api.firez.one" @@ -86,6 +91,7 @@ public class Configuration: ObservableObject { static let defaultConnectOnStart = true static let defaultStartOnLogin = false static let defaultDisableUpdateCheck = false + static let defaultSupportURL = "https://firezone.dev/support" private struct Keys { static let authURL = "authURL" @@ -97,6 +103,7 @@ public class Configuration: ObservableObject { static let connectOnStart = "connectOnStart" static let startOnLogin = "startOnLogin" static let disableUpdateCheck = "disableUpdateCheck" + static let supportURL = "supportURL" } private var defaults: UserDefaults diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/ViewModels/SettingsViewModel.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/ViewModels/SettingsViewModel.swift index 171a36f82..981286473 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/ViewModels/SettingsViewModel.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/ViewModels/SettingsViewModel.swift @@ -44,6 +44,14 @@ class SettingsViewModel: ObservableObject { }) .store(in: &cancellables) + self.configuration.objectWillChange + .receive(on: RunLoop.main) + .debounce(for: .seconds(0.3), scheduler: RunLoop.main) + .sink(receiveValue: { [weak self] _ in + self?.updateDerivedState() + }) + .store(in: &cancellables) + Publishers.MergeMany( $connectOnStart, $startOnLogin @@ -58,12 +66,12 @@ class SettingsViewModel: ObservableObject { } func reset() { - authURL = Configuration.defaultAuthURL - apiURL = Configuration.defaultApiURL - logFilter = Configuration.defaultLogFilter - accountSlug = Configuration.defaultAccountSlug - connectOnStart = Configuration.defaultConnectOnStart - startOnLogin = Configuration.defaultStartOnLogin + if !configuration.isAuthURLForced { authURL = Configuration.defaultAuthURL } + if !configuration.isApiURLForced { apiURL = Configuration.defaultApiURL } + if !configuration.isLogFilterForced { logFilter = Configuration.defaultLogFilter } + if !configuration.isAccountSlugForced { accountSlug = Configuration.defaultAccountSlug } + if !configuration.isConnectOnStartForced { connectOnStart = Configuration.defaultConnectOnStart } + if !configuration.isStartOnLoginForced { startOnLogin = Configuration.defaultStartOnLogin } updateDerivedState() } @@ -121,12 +129,12 @@ class SettingsViewModel: ObservableObject { func isDefault() -> Bool { return ( - authURL == Configuration.defaultAuthURL && - apiURL == Configuration.defaultApiURL && - logFilter == Configuration.defaultLogFilter && - accountSlug == Configuration.defaultAccountSlug && - connectOnStart == Configuration.defaultConnectOnStart && - startOnLogin == Configuration.defaultStartOnLogin + (configuration.isAuthURLForced || authURL == Configuration.defaultAuthURL) && + (configuration.isApiURLForced || apiURL == Configuration.defaultApiURL) && + (configuration.isLogFilterForced || logFilter == Configuration.defaultLogFilter) && + (configuration.isAccountSlugForced || accountSlug == Configuration.defaultAccountSlug) && + (configuration.isConnectOnStartForced || connectOnStart == Configuration.defaultConnectOnStart) && + (configuration.isStartOnLoginForced || startOnLogin == Configuration.defaultStartOnLogin) ) } diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift index 3dd7b4799..3e241c076 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift @@ -802,7 +802,7 @@ public final class MenuBar: NSObject, ObservableObject { } @objc func supportButtonTapped() { - let url = URL(string: "https://www.firezone.dev/support?utm_source=macos-client")! + let url = URL(string: configuration.supportURL) ?? URL(string: Configuration.defaultSupportURL)! Task { await NSWorkspace.shared.openAsync(url) } } diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/iOSNavigationView.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/iOSNavigationView.swift index 285cd6e25..9845e420b 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/iOSNavigationView.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/iOSNavigationView.swift @@ -17,6 +17,8 @@ struct iOSNavigationView: View { // swiftlint:disable:this type_n let content: Content + private let configuration = Configuration.shared + init(@ViewBuilder content: () -> Content) { self.content = content() } @@ -83,7 +85,7 @@ struct iOSNavigationView: View { // swiftlint:disable:this type_n Divider() Button( action: { - openURL(URL(string: "https://www.firezone.dev/support?utm_source=ios-client")!) + supportButtonTapped() }, label: { Label("Support...", systemImage: "safari") @@ -135,5 +137,10 @@ struct iOSNavigationView: View { // swiftlint:disable:this type_n } } } + + private func supportButtonTapped() { + let url = URL(string: configuration.supportURL) ?? URL(string: Configuration.defaultSupportURL)! + openURL(url) + } } #endif