Sesame-iOS/Sesame/SettingsView.swift
2023-08-07 15:47:40 +02:00

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))
}
}