- Add API methods for fetching online devices and redeeming pairing codes - Add OnlineDevice model and corresponding ViewModel state management - Add UI sections for online device list and pairing code input in SetupPanel - Ensure access token is verified before connecting to signaling server
125 lines
5.2 KiB
Swift
125 lines
5.2 KiB
Swift
import SwiftUI
|
||
|
||
/// 设置面板:未连接时显示,用于查看本机设备 ID、配置信令服务器与连接目标。
|
||
struct SetupPanelView: View {
|
||
@ObservedObject var viewModel: ControllerViewModel
|
||
|
||
var body: some View {
|
||
NavigationView {
|
||
Form {
|
||
Section("本机信息") {
|
||
HStack {
|
||
Text("本机设备 ID")
|
||
Spacer()
|
||
Text(viewModel.myDeviceId)
|
||
.font(.system(.body, design: .monospaced))
|
||
.foregroundColor(.secondary)
|
||
.textSelection(.enabled)
|
||
}
|
||
}
|
||
|
||
Section("连接设置") {
|
||
TextField("信令服务器地址 (wss://...)", text: $viewModel.serverUrl)
|
||
.keyboardType(.URL)
|
||
.autocapitalization(.none)
|
||
.disableAutocorrection(true)
|
||
TextField("目标设备 ID", text: $viewModel.targetDeviceId)
|
||
.autocapitalization(.allCharacters)
|
||
.disableAutocorrection(true)
|
||
|
||
Button {
|
||
viewModel.loadOnlineDevices()
|
||
} label: {
|
||
HStack {
|
||
Text("刷新在线设备")
|
||
Spacer()
|
||
if viewModel.isLoadingOnlineDevices {
|
||
ProgressView()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if !viewModel.onlineDevices.isEmpty {
|
||
Section("在线设备(点击填入目标 ID)") {
|
||
ForEach(viewModel.onlineDevices) { device in
|
||
Button {
|
||
viewModel.targetDeviceId = device.deviceId
|
||
} label: {
|
||
HStack {
|
||
VStack(alignment: .leading, spacing: 2) {
|
||
Text(device.nickname)
|
||
Text(device.deviceId)
|
||
.font(.system(.caption, design: .monospaced))
|
||
.foregroundColor(.secondary)
|
||
}
|
||
Spacer()
|
||
if viewModel.targetDeviceId == device.deviceId {
|
||
Image(systemName: "checkmark")
|
||
.foregroundColor(.accentColor)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Section("配对码兑换(建立新绑定)") {
|
||
HStack {
|
||
TextField("输入被控端显示的配对码", text: $viewModel.pairingCode)
|
||
.textInputAutocapitalization(.never)
|
||
.autocorrectionDisabled()
|
||
Button {
|
||
viewModel.redeemPairingCode()
|
||
} label: {
|
||
if viewModel.isRedeemingPairing {
|
||
ProgressView()
|
||
} else {
|
||
Text("兑换")
|
||
}
|
||
}
|
||
.disabled(viewModel.isRedeemingPairing || viewModel.pairingCode.trimmingCharacters(in: .whitespaces).isEmpty)
|
||
}
|
||
Text("在被控端生成配对码后填入此处即可建立绑定,绑定成功后会出现在上方在线设备列表中。")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
Section {
|
||
Button {
|
||
viewModel.requestConnect()
|
||
} label: {
|
||
HStack {
|
||
Spacer()
|
||
if viewModel.isConnecting {
|
||
ProgressView()
|
||
.padding(.trailing, 8)
|
||
}
|
||
Text(viewModel.isConnecting ? "连接中..." : "连接")
|
||
.font(.system(size: 15, weight: .semibold))
|
||
Spacer()
|
||
}
|
||
}
|
||
.disabled(viewModel.isConnecting)
|
||
|
||
if viewModel.isConnecting {
|
||
Button(role: .destructive) {
|
||
viewModel.disconnect()
|
||
} label: {
|
||
HStack {
|
||
Spacer()
|
||
Text("取消")
|
||
Spacer()
|
||
}
|
||
}
|
||
}
|
||
} footer: {
|
||
Text(viewModel.statusText)
|
||
}
|
||
}
|
||
.navigationTitle("WebRTC 控制端")
|
||
}
|
||
.navigationViewStyle(.stack)
|
||
}
|
||
}
|