Files
ios-client/NetBirdWidgetExtension/Controls/ToggleVPNControlIntent.swift
evgeniyChepelev ca8cf59d55 Feature/widget toggle switch UI (#138)
* feat(widget): replace action button with toggle switch control

All connection states now render as a unified toggle-style control:
green (connected), red (disconnected), orange with spinner (transitioning).

* fix(widget+auth): toggle UI, VPN state sync, and login flow fixes

* fix(widget+sdk): update Go SDK to fix/ios-debug-bundle, fix Control Center transitioning state and app disconnect flash

* fix(widget): remove transitioning states, update toggle colors and UI

* Change color indicator

* fix(widget+auth): toggle UI, VPN state sync, and login flow fixes

* fix framework version
2026-06-15 13:32:57 +02:00

57 lines
1.7 KiB
Swift

import AppIntents
import NetworkExtension
import WidgetKit
@available(iOS 18.0, *)
struct VPNControlIntent: AppIntent {
static var title: LocalizedStringResource = "Toggle NetBird VPN"
static var openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult {
let defaults = VPNIntentHelpers.defaults
let loginRequired = defaults?.bool(forKey: WidgetConstants.keyLoginRequired) ?? false
guard !loginRequired else {
await reload()
return .result()
}
guard let first = await loadManager() else {
await reload()
return .result()
}
let status = first.connection.status
switch status {
case .disconnected, .invalid:
guard let session = first.connection as? NETunnelProviderSession else { break }
try VPNIntentHelpers.startTunnel(session: session)
case .connected, .connecting:
first.connection.stopVPNTunnel()
default:
break
}
await VPNIntentHelpers.waitForStableState(manager: first)
await reload()
return .result()
}
private func loadManager() async -> NETunnelProviderManager? {
await withCheckedContinuation { continuation in
NETunnelProviderManager.loadAllFromPreferences { managers, error in
guard error == nil else {
continuation.resume(returning: nil)
return
}
continuation.resume(returning: managers?.first)
}
}
}
private func reload() async {
await ControlCenter.shared.reloadControls(ofKind: NetBirdVPNControl.kind)
}
}