Add a relay ping and backend status to the iOS app
The relay now answers a stateless ping with pong. The Relay card auto-checks on appear and address changes, showing latency or the connection error; this verifies the endpoint speaks the share protocol, not just that a TCP port is open.
This commit is contained in:
@@ -267,6 +267,8 @@ struct SetupView: View {
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
relayStatusRow
|
||||
|
||||
if model.showAdvanced {
|
||||
VStack(alignment: .leading, spacing: 9) {
|
||||
TextField("host:port", text: $model.relay)
|
||||
@@ -303,6 +305,70 @@ struct SetupView: View {
|
||||
.transition(.opacity.combined(with: .move(edge: .top)))
|
||||
}
|
||||
}
|
||||
.task { model.scheduleRelayCheck() }
|
||||
.onChange(of: model.relay) { _ in model.scheduleRelayCheck() }
|
||||
}
|
||||
|
||||
private var relayStatusRow: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(spacing: 7) {
|
||||
if model.isCheckingRelay {
|
||||
ProgressView()
|
||||
.controlSize(.mini)
|
||||
.tint(Theme.blue)
|
||||
} else {
|
||||
Circle()
|
||||
.fill(relayStatusColor)
|
||||
.frame(width: 7, height: 7)
|
||||
}
|
||||
|
||||
Text(relayStatusText)
|
||||
.font(.system(size: 11.5, weight: .medium, design: .rounded))
|
||||
.foregroundStyle(relayStatusColor)
|
||||
.lineLimit(1)
|
||||
|
||||
Spacer(minLength: 8)
|
||||
|
||||
Button {
|
||||
model.checkRelay()
|
||||
} label: {
|
||||
Image(systemName: "arrow.clockwise")
|
||||
.font(.system(size: 11, weight: .bold))
|
||||
.foregroundStyle(Theme.secondaryText)
|
||||
.frame(width: 28, height: 28)
|
||||
.background(Color.white.opacity(0.05), in: Circle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.disabled(model.isCheckingRelay)
|
||||
.accessibilityLabel("Check backend connectivity")
|
||||
}
|
||||
|
||||
if let error = model.relayCheck?.error,
|
||||
!error.isEmpty,
|
||||
model.relayCheck?.ok == false {
|
||||
Text(error)
|
||||
.font(.system(size: 10, design: .rounded))
|
||||
.foregroundStyle(Theme.danger.opacity(0.85))
|
||||
.lineLimit(2)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
}
|
||||
.padding(.top, 10)
|
||||
}
|
||||
|
||||
private var relayStatusColor: Color {
|
||||
if model.isCheckingRelay { return Theme.blue }
|
||||
guard let check = model.relayCheck else { return Theme.tertiaryText }
|
||||
return check.ok ? Theme.mint : Theme.danger
|
||||
}
|
||||
|
||||
private var relayStatusText: String {
|
||||
if model.isCheckingRelay { return "Checking backend…" }
|
||||
guard let check = model.relayCheck else { return "Backend status unknown" }
|
||||
if check.ok {
|
||||
return "Backend reachable · \(check.latencyMs) ms"
|
||||
}
|
||||
return "Backend unreachable"
|
||||
}
|
||||
|
||||
// MARK: - Start
|
||||
|
||||
Reference in New Issue
Block a user