fix(ios): improve fleet overview and app identity
- Show stable group health in a fixed 2x2 metric grid - Add link-chain state to fleet cards and parse hardware/control/SIM/cellular - Replace the wrapped icon with a full-bleed app icon - Bump the IPA build number
This commit is contained in:
@@ -26,10 +26,16 @@ public enum ConnectionStatus: String, Equatable, Sendable {
|
||||
|
||||
public struct ConnectionResult: Equatable, Sendable {
|
||||
public let status: ConnectionStatus
|
||||
public let requestLatencyMilliseconds: Int?
|
||||
public let checkedAt: Date
|
||||
|
||||
public init(status: ConnectionStatus, checkedAt: Date) {
|
||||
public init(
|
||||
status: ConnectionStatus,
|
||||
requestLatencyMilliseconds: Int? = nil,
|
||||
checkedAt: Date
|
||||
) {
|
||||
self.status = status
|
||||
self.requestLatencyMilliseconds = requestLatencyMilliseconds
|
||||
self.checkedAt = checkedAt
|
||||
}
|
||||
}
|
||||
@@ -42,21 +48,50 @@ public struct ConnectionProbe: Sendable {
|
||||
}
|
||||
|
||||
public func test(_ instance: Instance) async throws -> ConnectionResult {
|
||||
let startedAt = DispatchTime.now()
|
||||
do {
|
||||
let response = try await client.send(.health, baseURL: instance.origin, cookie: nil)
|
||||
let latency = Self.elapsedMilliseconds(since: startedAt)
|
||||
if response.status == 401 || response.status == 403 {
|
||||
return ConnectionResult(status: .authRequired, checkedAt: Date())
|
||||
return ConnectionResult(
|
||||
status: .authRequired,
|
||||
requestLatencyMilliseconds: latency,
|
||||
checkedAt: Date()
|
||||
)
|
||||
}
|
||||
return ConnectionResult(status: .online, checkedAt: Date())
|
||||
return ConnectionResult(
|
||||
status: .online,
|
||||
requestLatencyMilliseconds: latency,
|
||||
checkedAt: Date()
|
||||
)
|
||||
} catch {
|
||||
let latency = Self.elapsedMilliseconds(since: startedAt)
|
||||
switch error {
|
||||
case UpstreamError.unauthorized:
|
||||
return ConnectionResult(status: .authRequired, checkedAt: Date())
|
||||
return ConnectionResult(
|
||||
status: .authRequired,
|
||||
requestLatencyMilliseconds: latency,
|
||||
checkedAt: Date()
|
||||
)
|
||||
case UpstreamError.timeout, is URLError:
|
||||
return ConnectionResult(status: .offline, checkedAt: Date())
|
||||
return ConnectionResult(
|
||||
status: .offline,
|
||||
requestLatencyMilliseconds: latency,
|
||||
checkedAt: Date()
|
||||
)
|
||||
default:
|
||||
return ConnectionResult(status: .degraded, checkedAt: Date())
|
||||
return ConnectionResult(
|
||||
status: .degraded,
|
||||
requestLatencyMilliseconds: latency,
|
||||
checkedAt: Date()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func elapsedMilliseconds(since startedAt: DispatchTime) -> Int? {
|
||||
let nanoseconds = DispatchTime.now().uptimeNanoseconds &- startedAt.uptimeNanoseconds
|
||||
let milliseconds = Double(nanoseconds) / 1_000_000
|
||||
return milliseconds.isFinite ? Int(milliseconds.rounded()) : nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user