Refactored MenuView into MenuItemToggleView
This change fixes some subtle state bugs in the switch handling by making isOn a direct function of the Tunnel.
This commit is contained in:
parent
5438542284
commit
32e4e9d1d7
4 changed files with 108 additions and 93 deletions
|
|
@ -7,63 +7,55 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
struct MenuView: View {
|
||||
@State private var isToggled = false
|
||||
struct MenuItemToggleView: View {
|
||||
@ObservedObject var tunnel: Tunnel
|
||||
|
||||
private func start() {
|
||||
|
||||
do {
|
||||
try tunnel.start()
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
private func stop() {
|
||||
tunnel.stop()
|
||||
}
|
||||
|
||||
private func configure() {
|
||||
Task { try await tunnel.configure() }
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
Text("Burrow")
|
||||
.fontWeight(.bold)
|
||||
|
||||
Spacer()
|
||||
Toggle("", isOn: $isToggled)
|
||||
.toggleStyle(SwitchToggleStyle(tint: .blue))
|
||||
.onChange(of: isToggled) { value in
|
||||
if value {
|
||||
start()
|
||||
} else {
|
||||
stop()
|
||||
}
|
||||
print("Toggle value: \(value)")
|
||||
}
|
||||
}
|
||||
Divider()
|
||||
switch tunnel.status {
|
||||
case .permissionRequired:
|
||||
VStack(alignment: .leading) {
|
||||
Text("Burrow requires additional permissions to function optimally on your machine. Please grant the necessary permissions to ensure smooth operation.")
|
||||
.font(.caption)
|
||||
.truncationMode(.tail)
|
||||
|
||||
Button("Grant Permissions", action: configure)
|
||||
}
|
||||
default:
|
||||
|
||||
Text("Burrow is equipped with the necessary permissions to operate seamlessly on your device.")
|
||||
.font(.caption)
|
||||
}
|
||||
HStack {
|
||||
Text("Burrow")
|
||||
.font(.headline)
|
||||
Spacer()
|
||||
Toggle("Burrow", isOn: tunnel.isOn)
|
||||
.labelsHidden()
|
||||
.disabled(tunnel.isDisabled)
|
||||
.toggleStyle(.switch)
|
||||
}
|
||||
.frame(width: 250)
|
||||
.padding(16)
|
||||
.padding(.horizontal, 4)
|
||||
.padding(10)
|
||||
.frame(minWidth: 300, minHeight: 32, maxHeight: 32)
|
||||
.task { await tunnel.update() }
|
||||
}
|
||||
}
|
||||
|
||||
extension Tunnel {
|
||||
var isDisabled: Bool {
|
||||
switch self.status {
|
||||
case .disconnected, .permissionRequired, .connected:
|
||||
return false
|
||||
case .unknown, .disabled, .connecting, .reasserting, .disconnecting, .invalid, .configurationReadWriteFailed:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
var isOn: Binding<Bool> {
|
||||
Binding {
|
||||
switch self.status {
|
||||
case .unknown, .disabled, .disconnecting, .disconnected, .invalid, .permissionRequired, .configurationReadWriteFailed:
|
||||
return false
|
||||
case .connecting, .reasserting, .connected:
|
||||
return true
|
||||
}
|
||||
} set: { newValue in
|
||||
switch (self.status, newValue) {
|
||||
case (.permissionRequired, true):
|
||||
Task { try await self.configure() }
|
||||
case (.disconnected, true):
|
||||
try? self.start()
|
||||
case (.connected, false):
|
||||
self.stop()
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue