ServerConfig parses https base URL and derives wss livekit URL; TokenClient POSTs /token with clean 503/offline error states; TLSPinning holds optional cert SHA-384 pins (empty = system trust); Settings gains a Connection test screen proving the endpoint works.
87 lines
2.9 KiB
Swift
87 lines
2.9 KiB
Swift
import SwiftUI
|
|
|
|
struct ConnectionTestView: View {
|
|
@ObservedObject var settings: SettingsStore
|
|
@State private var isBusy = false
|
|
@State private var result: Result<TokenResponse, Error>?
|
|
@State private var urlError: String?
|
|
|
|
var body: some View {
|
|
Form {
|
|
Section("Server") {
|
|
LabeledContent("URL") {
|
|
Text(settings.trimmedServerURL)
|
|
.font(.footnote.monospaced())
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
if let urlError {
|
|
Label(urlError, systemImage: "xmark.octagon")
|
|
.foregroundStyle(.red)
|
|
}
|
|
}
|
|
Section {
|
|
Button(action: runTest) {
|
|
HStack {
|
|
Spacer()
|
|
if isBusy {
|
|
ProgressView()
|
|
} else {
|
|
Text("Get token")
|
|
}
|
|
Spacer()
|
|
}
|
|
}
|
|
.disabled(isBusy || settings.trimmedServerURL.isEmpty)
|
|
}
|
|
if let result {
|
|
switch result {
|
|
case .success(let response):
|
|
Section("Success") {
|
|
LabeledContent("Room") {
|
|
Text(response.room)
|
|
.font(.footnote.monospaced())
|
|
}
|
|
LabeledContent("User") {
|
|
Text(response.user.displayName ?? response.user.id)
|
|
}
|
|
Label("Token endpoint and TLS are working.", systemImage: "checkmark.circle")
|
|
.foregroundStyle(.green)
|
|
}
|
|
case .failure(let error):
|
|
Section("Error") {
|
|
Label(error.localizedDescription, systemImage: "xmark.octagon")
|
|
.foregroundStyle(.red)
|
|
.font(.footnote)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle("Connection test")
|
|
}
|
|
|
|
private func runTest() {
|
|
result = nil
|
|
urlError = nil
|
|
switch ServerConfig.parse(settings.trimmedServerURL) {
|
|
case .success(let config):
|
|
isBusy = true
|
|
Task {
|
|
let client = TokenClient(config: config)
|
|
do {
|
|
let response = try await client.fetchToken()
|
|
result = .success(response)
|
|
} catch {
|
|
result = .failure(error)
|
|
}
|
|
isBusy = false
|
|
}
|
|
case .failure(let error):
|
|
urlError = error.localizedDescription
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
ConnectionTestView(settings: SettingsStore())
|
|
}
|