169 lines
6.3 KiB
Swift
169 lines
6.3 KiB
Swift
import SwiftUI
|
|
|
|
struct SettingsView: View {
|
|
|
|
@Binding
|
|
var keyManager: KeyManagement
|
|
|
|
@Binding
|
|
var serverAddress: String
|
|
|
|
@Binding
|
|
var localAddress: String
|
|
|
|
@Binding
|
|
var deviceID: Int
|
|
|
|
@Binding
|
|
var nextMessageCounter: Int
|
|
|
|
@Binding
|
|
var isCompensatingDaylightTime: Bool
|
|
|
|
@Binding
|
|
var useLocalConnection: Bool
|
|
|
|
@State
|
|
private var showDeviceIdInput = false
|
|
|
|
@State
|
|
private var deviceIdText = ""
|
|
|
|
@State
|
|
private var showCounterInput = false
|
|
|
|
@State
|
|
private var counterText = ""
|
|
|
|
|
|
var body: some View {
|
|
NavigationView {
|
|
ScrollView {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
VStack(alignment: .leading) {
|
|
Text("Server address")
|
|
.bold()
|
|
TextField("Server address", text: $serverAddress)
|
|
.foregroundColor(.secondary)
|
|
.padding(.leading, 8)
|
|
}.padding(.vertical, 8)
|
|
VStack(alignment: .leading) {
|
|
Text("Local address")
|
|
.bold()
|
|
TextField("Local address", text: $localAddress)
|
|
.foregroundColor(.secondary)
|
|
.padding(.leading, 8)
|
|
}.padding(.vertical, 8)
|
|
Toggle(isOn: $useLocalConnection) {
|
|
Text("Use direct connection to device")
|
|
}
|
|
Text("Attempt to communicate directly with the device. This is useful if the server is unavailable. Requires a WiFi connection on the same network as the device.")
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
VStack(alignment: .leading) {
|
|
Text("Device id")
|
|
.bold()
|
|
HStack(alignment: .bottom) {
|
|
Text("\(deviceID)")
|
|
.font(.system(.body, design: .monospaced))
|
|
.foregroundColor(.secondary)
|
|
.padding([.trailing, .bottom])
|
|
Button("Edit", action: showAlertToChangeDeviceID)
|
|
.padding([.horizontal, .bottom])
|
|
.padding(.top, 4)
|
|
}
|
|
}.padding(.vertical, 8)
|
|
VStack(alignment: .leading) {
|
|
Text("Message counter")
|
|
.bold()
|
|
HStack(alignment: .bottom) {
|
|
Text("\(nextMessageCounter)")
|
|
.font(.system(.body, design: .monospaced))
|
|
.foregroundColor(.secondary)
|
|
.padding([.trailing, .bottom])
|
|
Button("Edit", action: showAlertToChangeCounter)
|
|
.padding([.horizontal, .bottom])
|
|
.padding(.top, 4)
|
|
}
|
|
}.padding(.vertical, 8)
|
|
ForEach(KeyManagement.KeyType.allCases) { keyType in
|
|
SingleKeyView(
|
|
keyManager: $keyManager,
|
|
type: keyType)
|
|
}
|
|
Toggle(isOn: $isCompensatingDaylightTime) {
|
|
Text("Compensate daylight savings time")
|
|
}
|
|
Text("If the remote has daylight savings time wrongly set, then the time validation will fail. Use this option to send messages with adjusted timestamps. Warning: Incorrect use of this option will allow replay attacks.")
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
}.padding()
|
|
}.onDisappear {
|
|
if !localAddress.hasSuffix("/") {
|
|
localAddress += "/"
|
|
}
|
|
}
|
|
.navigationTitle("Settings")
|
|
.alert("Update device ID", isPresented: $showDeviceIdInput, actions: {
|
|
TextField("Device ID", text: $deviceIdText)
|
|
.keyboardType(.decimalPad)
|
|
.font(.system(.body, design: .monospaced))
|
|
.foregroundColor(.black)
|
|
Button("Save", action: saveDeviceID)
|
|
Button("Cancel", role: .cancel, action: {})
|
|
}, message: {
|
|
Text("Enter the device ID")
|
|
})
|
|
.alert("Update message counter", isPresented: $showCounterInput, actions: {
|
|
TextField("Message counter", text: $counterText)
|
|
.keyboardType(.decimalPad)
|
|
.font(.system(.body, design: .monospaced))
|
|
.foregroundColor(.black)
|
|
Button("Save", action: saveCounter)
|
|
Button("Cancel", role: .cancel, action: {})
|
|
}, message: {
|
|
Text("Enter the message counter")
|
|
})
|
|
}
|
|
}
|
|
|
|
private func showAlertToChangeDeviceID() {
|
|
deviceIdText = "\(deviceID)"
|
|
showDeviceIdInput = true
|
|
}
|
|
|
|
private func saveDeviceID() {
|
|
guard let id = UInt8(deviceIdText) else {
|
|
print("Invalid device id '\(deviceIdText)'")
|
|
return
|
|
}
|
|
self.deviceID = Int(id)
|
|
}
|
|
|
|
private func showAlertToChangeCounter() {
|
|
counterText = "\(nextMessageCounter)"
|
|
showCounterInput = true
|
|
}
|
|
|
|
private func saveCounter() {
|
|
guard let id = UInt32(counterText) else {
|
|
print("Invalid message counter '\(counterText)'")
|
|
return
|
|
}
|
|
self.nextMessageCounter = Int(id)
|
|
}
|
|
}
|
|
|
|
struct SettingsView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
SettingsView(
|
|
keyManager: .constant(KeyManagement()),
|
|
serverAddress: .constant("https://example.com"),
|
|
localAddress: .constant("192.168.178.42"),
|
|
deviceID: .constant(0),
|
|
nextMessageCounter: .constant(12345678),
|
|
isCompensatingDaylightTime: .constant(true),
|
|
useLocalConnection: .constant(false))
|
|
}
|
|
}
|