Some checks are pending
Build AppImage / Build AppImage (push) Waiting to run
Build Apple Apps / Build App (iOS) (push) Waiting to run
Build Apple Apps / Build App (iOS Simulator) (push) Waiting to run
Build Apple Apps / Build App (macOS) (push) Waiting to run
Build Docker / Build Docker Image (push) Waiting to run
Build Rust Crate / Build Crate (macOS (Intel)) (push) Waiting to run
Build Rust Crate / Build Crate (macOS) (push) Waiting to run
Build Rust Crate / Build Crate (Linux) (push) Waiting to run
Build Rust Crate / Build Crate (Windows) (push) Waiting to run
73 lines
1.5 KiB
Swift
73 lines
1.5 KiB
Swift
import SwiftUI
|
|
|
|
struct TunnelButton: View {
|
|
@Environment(\.tunnel)
|
|
var tunnel: any Tunnel
|
|
|
|
private var action: Action? { tunnel.action }
|
|
|
|
var body: some View {
|
|
Button {
|
|
if let action {
|
|
tunnel.perform(action)
|
|
}
|
|
} label: {
|
|
Text(action.description)
|
|
}
|
|
.disabled(action.isDisabled)
|
|
.padding(.horizontal)
|
|
.buttonStyle(.floating)
|
|
}
|
|
}
|
|
|
|
extension Tunnel {
|
|
@MainActor fileprivate var action: TunnelButton.Action? {
|
|
switch status {
|
|
case .permissionRequired, .invalid:
|
|
.enable
|
|
case .disabled, .disconnecting, .disconnected:
|
|
.start
|
|
case .connecting, .connected, .reasserting:
|
|
.stop
|
|
case .unknown, .configurationReadWriteFailed:
|
|
nil
|
|
}
|
|
}
|
|
}
|
|
|
|
extension TunnelButton {
|
|
fileprivate enum Action {
|
|
case enable
|
|
case start
|
|
case stop
|
|
}
|
|
}
|
|
|
|
extension TunnelButton.Action? {
|
|
var description: LocalizedStringKey {
|
|
switch self {
|
|
case .enable: "Enable"
|
|
case .start: "Start"
|
|
case .stop: "Stop"
|
|
case .none: "Start"
|
|
}
|
|
}
|
|
|
|
var isDisabled: Bool {
|
|
if case .none = self {
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Tunnel {
|
|
fileprivate func perform(_ action: TunnelButton.Action) {
|
|
switch action {
|
|
case .enable: enable()
|
|
case .start: start()
|
|
case .stop: stop()
|
|
}
|
|
}
|
|
}
|