138 lines
4.0 KiB
Swift
138 lines
4.0 KiB
Swift
|
import Foundation
|
||
|
import SwiftUI
|
||
|
|
||
|
enum ClientState {
|
||
|
|
||
|
/// The initial state after app launch
|
||
|
case initial
|
||
|
|
||
|
/// There are no keys stored locally on the client. New keys must be generated before use.
|
||
|
case noKeysAvailable
|
||
|
|
||
|
/// New keys have been generated and can now be transmitted to the device.
|
||
|
case newKeysGenerated
|
||
|
|
||
|
/// The device status could not be determined
|
||
|
case statusRequestFailed
|
||
|
|
||
|
/// The status received from the server could not be decoded
|
||
|
case unknownDeviceStatus
|
||
|
|
||
|
/// The remote device is not connected (no socket opened)
|
||
|
case deviceDisconnected
|
||
|
|
||
|
/// The device is connected and ready to receive a key
|
||
|
case deviceConnected
|
||
|
|
||
|
/// The key is being transmitted and a response is awaited
|
||
|
case waitingForResponse
|
||
|
|
||
|
/// The transmitted key was rejected (multiple possible reasons)
|
||
|
case keyRejected
|
||
|
|
||
|
/// Internal errors with the implementation
|
||
|
case internalError
|
||
|
|
||
|
/// The configuration of the devices doesn't match
|
||
|
case configurationError
|
||
|
|
||
|
/// The device responded that the opening action was started
|
||
|
case openSesame
|
||
|
|
||
|
/// All keys have been used
|
||
|
case allKeysUsed
|
||
|
|
||
|
var canSendKey: Bool {
|
||
|
switch self {
|
||
|
case .deviceConnected, .openSesame, .keyRejected:
|
||
|
return true
|
||
|
default:
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
init(keyResult: KeyResult) {
|
||
|
switch keyResult {
|
||
|
case .textReceived, .unexpectedSocketEvent, .unknownDeviceError:
|
||
|
self = .unknownDeviceStatus
|
||
|
case .invalidPayloadSize, .invalidKeyIndex, .invalidKey:
|
||
|
self = .configurationError
|
||
|
case .keyAlreadyUsed, .keyWasSkipped:
|
||
|
self = .keyRejected
|
||
|
case .keyAccepted:
|
||
|
self = .openSesame
|
||
|
case .noBodyData, .corruptkeyData:
|
||
|
self = .internalError
|
||
|
case .deviceNotConnected, .deviceTimedOut:
|
||
|
self = .deviceDisconnected
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var description: String {
|
||
|
switch self {
|
||
|
case .initial:
|
||
|
return "Checking state..."
|
||
|
case .noKeysAvailable:
|
||
|
return "No keys found"
|
||
|
case .newKeysGenerated:
|
||
|
return "New keys generated"
|
||
|
case .deviceDisconnected:
|
||
|
return "Device not connected"
|
||
|
case .statusRequestFailed:
|
||
|
return "Unable to get device status"
|
||
|
case .unknownDeviceStatus:
|
||
|
return "Unknown device status"
|
||
|
case .deviceConnected:
|
||
|
return "Device connected"
|
||
|
case .waitingForResponse:
|
||
|
return "Waiting for response"
|
||
|
case .internalError:
|
||
|
return "An internal error occured"
|
||
|
case .configurationError:
|
||
|
return "Configuration error"
|
||
|
|
||
|
case .allKeysUsed:
|
||
|
return "No fresh keys available"
|
||
|
case .keyRejected:
|
||
|
return "The key was rejected"
|
||
|
case .openSesame:
|
||
|
return "Unlocked"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var openButtonText: String {
|
||
|
switch self {
|
||
|
case .initial, .statusRequestFailed, .unknownDeviceStatus, .deviceDisconnected, .newKeysGenerated, .configurationError, .internalError:
|
||
|
return "Connect"
|
||
|
case .allKeysUsed, .noKeysAvailable:
|
||
|
return "Disabled"
|
||
|
case .deviceConnected, .keyRejected, .openSesame:
|
||
|
return "Unlock"
|
||
|
case .waitingForResponse:
|
||
|
return "Unlocking..."
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var openButtonColor: Color {
|
||
|
switch self {
|
||
|
case .initial, .newKeysGenerated, .statusRequestFailed, .waitingForResponse:
|
||
|
return .yellow
|
||
|
case .noKeysAvailable, .allKeysUsed, .deviceDisconnected, .unknownDeviceStatus, .keyRejected, .configurationError, .internalError:
|
||
|
return .red
|
||
|
case .deviceConnected, .openSesame:
|
||
|
return .green
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var openActionIsEnabled: Bool {
|
||
|
switch self {
|
||
|
case .allKeysUsed, .noKeysAvailable, .waitingForResponse:
|
||
|
return false
|
||
|
default:
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|