Files
VibeCoding/webrtc_controller_ios/web_rtc_controller_ios/Views/SetupPanelView.swift
TongTongStudio 1bd0318d35 feat(ios): add online device list and pairing code redemption
- 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
2026-08-03 21:42:31 +08:00

125 lines
5.2 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}
}