fix(watch): preserve localized terminal status

This commit is contained in:
Vincent Koc
2026-07-12 15:02:36 +02:00
parent da0e6bdb18
commit 0e49f09112
4 changed files with 50 additions and 4 deletions
+14 -2
View File
@@ -6051,10 +6051,16 @@ extension NodeAppModel {
let statusText = self.gatewayStatusText == "Connected"
? self.operatorStatusText
: self.gatewayStatusText
if statusText != "Offline" {
switch statusText {
case "Connecting…":
return OpenClawWatchAppStatus(code: .gatewayConnecting)
case "Reconnecting…":
return OpenClawWatchAppStatus(code: .gatewayReconnecting)
case "Offline":
return OpenClawWatchAppStatus(code: .gatewayOffline)
default:
return OpenClawWatchAppStatus(code: .legacy, verbatim: statusText)
}
return OpenClawWatchAppStatus(code: .gatewayOffline)
}
private static func makeWatchGatewayProblemStatus(
@@ -6100,6 +6106,12 @@ extension NodeAppModel {
if self.talkMode.hasActivePushToTalkSession {
return self.makeWatchTalkPresentationStatus()
}
switch self.talkMode.watchPresentation {
case .localized, .verbatim:
return self.makeWatchTalkPresentationStatus()
case .phase:
break
}
if !self.talkMode.isEnabled {
return OpenClawWatchAppStatus(code: .talkOff)
}
+25 -2
View File
@@ -4730,8 +4730,8 @@ private func overrideNotificationServingPreference(_ enabled: Bool) -> () -> Voi
}
let status = try #require(watchService.lastSentAppSnapshot?.gatewayStatus)
#expect(status.code == .legacy)
#expect(status.verbatim == "Connecting…")
#expect(status.code == .gatewayConnecting)
#expect(status.verbatim == nil)
#expect(watchService.lastSentAppSnapshot?.gatewayStatusText == "Connecting…")
}
@@ -4780,6 +4780,29 @@ private func overrideNotificationServingPreference(_ enabled: Bool) -> () -> Voi
#expect(watchService.lastSentAppSnapshot?.talkStatus.code == .talkThinking)
}
@Test @MainActor func `watch app snapshot preserves terminal push to talk failure`() async {
let watchService = MockWatchMessagingService()
let appModel = NodeAppModel(watchMessagingService: watchService)
appModel.talkMode._test_handleRealtimeRelayStatus("Backend rejected realtime request")
watchService.emitAppSnapshotRequest(
WatchAppSnapshotRequestEvent(
requestId: "app-snapshot-push-to-talk-failure",
sentAtMs: 123,
transport: "sendMessage"))
for _ in 0..<20 {
if watchService.lastSentAppSnapshot != nil {
break
}
try? await Task.sleep(nanoseconds: 50_000_000)
}
#expect(watchService.lastSentAppSnapshot?.talkStatus.code == .talkFailure)
#expect(
watchService.lastSentAppSnapshot?.talkStatus.verbatim
== "Backend rejected realtime request")
}
@Test @MainActor func `watch app snapshot publishes online when operator reconnects`() async {
let watchService = MockWatchMessagingService()
let appModel = NodeAppModel(watchMessagingService: watchService)
@@ -72,6 +72,7 @@ typealias WatchAppCommand = OpenClawWatchAppCommand
enum WatchStatusLocalizationKey: String {
case connected
case reconnecting
case offline
case gatewayProblemRequestIDFormat
case ready
@@ -117,6 +118,8 @@ enum WatchStatusLocalizationKey: String {
switch self {
case .connected:
String(localized: "Connected")
case .reconnecting:
String(localized: "Reconnecting…")
case .offline:
String(localized: "Offline")
case .gatewayProblemRequestIDFormat:
@@ -878,6 +881,10 @@ extension OpenClawWatchAppStatus {
return switch self.code {
case .gatewayConnected:
localize(.connected)
case .gatewayConnecting:
localize(.connecting)
case .gatewayReconnecting:
localize(.reconnecting)
case .gatewayOffline:
localize(.offline)
case .gatewayProblem:
@@ -278,6 +278,8 @@ public struct OpenClawWatchChatCompletionMessage: Codable, Sendable, Equatable {
public enum OpenClawWatchAppStatusCode: String, Codable, Sendable, Equatable {
case gatewayConnected
case gatewayConnecting
case gatewayReconnecting
case gatewayOffline
case gatewayProblem
case gatewayProblemWithRequestID
@@ -611,6 +613,8 @@ public struct OpenClawWatchAppSnapshotMessage: Codable, Sendable, Equatable {
}
return switch status.code {
case .gatewayConnected: "Connected"
case .gatewayConnecting: "Connecting…"
case .gatewayReconnecting: "Reconnecting…"
case .gatewayOffline: "Offline"
case .gatewayProblem, .gatewayProblemWithRequestID: "Gateway unavailable"
case .talkOff: "Off"