diff --git a/apps/.i18n/native-source.json b/apps/.i18n/native-source.json index de6c5e6f7b10..d1b6dc683c72 100644 --- a/apps/.i18n/native-source.json +++ b/apps/.i18n/native-source.json @@ -9035,7 +9035,7 @@ }, { "kind": "conditional-branch", - "line": 867, + "line": 858, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Configured", "surface": "apple", @@ -9043,7 +9043,7 @@ }, { "kind": "conditional-branch", - "line": 867, + "line": 858, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Not configured", "surface": "apple", @@ -9051,7 +9051,7 @@ }, { "kind": "conditional-branch", - "line": 932, + "line": 923, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Connect to the gateway.", "surface": "apple", @@ -9059,7 +9059,7 @@ }, { "kind": "conditional-branch", - "line": 932, + "line": 923, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Gateway requests will appear here.", "surface": "apple", @@ -9067,7 +9067,7 @@ }, { "kind": "conditional-branch", - "line": 979, + "line": 970, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "High", "surface": "apple", @@ -9075,7 +9075,7 @@ }, { "kind": "conditional-branch", - "line": 979, + "line": 970, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Resolving", "surface": "apple", @@ -9083,7 +9083,7 @@ }, { "kind": "conditional-branch", - "line": 984, + "line": 975, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "One-time approval", "surface": "apple", @@ -9091,7 +9091,7 @@ }, { "kind": "conditional-branch", - "line": 984, + "line": 975, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Permission can be saved", "surface": "apple", @@ -9099,7 +9099,7 @@ }, { "kind": "conditional-branch", - "line": 986, + "line": 977, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Medium", "surface": "apple", @@ -9107,7 +9107,7 @@ }, { "kind": "conditional-branch", - "line": 986, + "line": 977, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Review", "surface": "apple", @@ -9115,7 +9115,7 @@ }, { "kind": "conditional-branch", - "line": 1007, + "line": 998, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "\\(diagnosticsIssueCount)", "surface": "apple", @@ -9123,7 +9123,7 @@ }, { "kind": "conditional-branch", - "line": 1018, + "line": 1009, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Location off", "surface": "apple", @@ -9131,7 +9131,7 @@ }, { "kind": "conditional-branch", - "line": 1020, + "line": 1011, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Location While Using", "surface": "apple", @@ -9139,7 +9139,7 @@ }, { "kind": "conditional-branch", - "line": 1022, + "line": 1013, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Location While Using, effective Off", "surface": "apple", @@ -9147,7 +9147,7 @@ }, { "kind": "conditional-branch", - "line": 1024, + "line": 1015, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Location While Using, effective Always", "surface": "apple", @@ -9155,7 +9155,7 @@ }, { "kind": "conditional-branch", - "line": 1026, + "line": 1017, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Location Always", "surface": "apple", @@ -9163,7 +9163,7 @@ }, { "kind": "conditional-branch", - "line": 1028, + "line": 1019, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Location Always, effective While Using", "surface": "apple", @@ -9171,7 +9171,7 @@ }, { "kind": "conditional-branch", - "line": 1030, + "line": 1021, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Location Always, effective Off", "surface": "apple", @@ -9179,7 +9179,7 @@ }, { "kind": "conditional-branch", - "line": 1058, + "line": 1049, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Checking iOS notification permission.", "surface": "apple", @@ -9187,7 +9187,7 @@ }, { "kind": "conditional-branch", - "line": 1060, + "line": 1051, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "OpenClaw can show approval prompts and event alerts when the app is not active.", "surface": "apple", @@ -9195,7 +9195,7 @@ }, { "kind": "conditional-branch", - "line": 1062, + "line": 1053, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Notifications have been denied. Enable them in iOS Settings.", "surface": "apple", @@ -9203,7 +9203,7 @@ }, { "kind": "conditional-branch", - "line": 1064, + "line": 1055, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "Enable notifications to receive approval prompts and event alerts outside the app.", "surface": "apple", @@ -9211,7 +9211,7 @@ }, { "kind": "conditional-branch", - "line": 1066, + "line": 1057, "path": "apps/ios/Sources/Design/SettingsProTabActions.swift", "source": "OpenClaw cannot determine the current notification permission state.", "surface": "apple", @@ -9874,12 +9874,12 @@ "id": "native.apple.518cef9408771a92" }, { - "kind": "ui-named-argument", - "line": 946, + "kind": "ui-call", + "line": 945, "path": "apps/ios/Sources/Design/SettingsProTabSections.swift", "source": "Wake Words", "surface": "apple", - "id": "native.apple.e1383011b9ccc3a3" + "id": "native.apple.1604352fea16d495" }, { "kind": "ui-call", @@ -9994,12 +9994,12 @@ "id": "native.apple.c695f785d4f3331a" }, { - "kind": "ui-named-argument", + "kind": "ui-call", "line": 1030, "path": "apps/ios/Sources/Design/SettingsProTabSections.swift", "source": "Discovery Logs", "surface": "apple", - "id": "native.apple.2bb13c2d7465f99e" + "id": "native.apple.8584babe715b1133" }, { "kind": "ui-call", @@ -10027,7 +10027,7 @@ }, { "kind": "conditional-branch", - "line": 93, + "line": 118, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Enabled", "surface": "apple", @@ -10035,7 +10035,7 @@ }, { "kind": "conditional-branch", - "line": 94, + "line": 119, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Denied", "surface": "apple", @@ -10043,7 +10043,7 @@ }, { "kind": "conditional-branch", - "line": 95, + "line": 120, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Not Enabled", "surface": "apple", @@ -10051,7 +10051,7 @@ }, { "kind": "conditional-branch", - "line": 96, + "line": 121, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Unknown", "surface": "apple", @@ -10059,7 +10059,7 @@ }, { "kind": "conditional-branch", - "line": 102, + "line": 127, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Enable Notifications", "surface": "apple", @@ -10067,7 +10067,7 @@ }, { "kind": "conditional-branch", - "line": 104, + "line": 129, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Checking", "surface": "apple", @@ -10075,7 +10075,7 @@ }, { "kind": "conditional-branch", - "line": 106, + "line": 131, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Manage in iOS Settings", "surface": "apple", @@ -10083,7 +10083,7 @@ }, { "kind": "conditional-branch", - "line": 108, + "line": 133, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Open iOS Settings", "surface": "apple", @@ -10091,7 +10091,7 @@ }, { "kind": "ui-call", - "line": 250, + "line": 275, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Connected", "surface": "apple", @@ -10099,7 +10099,7 @@ }, { "kind": "ui-named-argument", - "line": 252, + "line": 277, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Gateway online", "surface": "apple", @@ -10107,7 +10107,7 @@ }, { "kind": "ui-named-argument", - "line": 253, + "line": 278, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Connected to openclaw-gateway.tailnet.ts.net.", "surface": "apple", @@ -10115,7 +10115,7 @@ }, { "kind": "ui-call", - "line": 263, + "line": 288, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Loading", "surface": "apple", @@ -10123,7 +10123,7 @@ }, { "kind": "ui-named-argument", - "line": 265, + "line": 290, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Checking gateway", "surface": "apple", @@ -10131,7 +10131,7 @@ }, { "kind": "ui-named-argument", - "line": 266, + "line": 291, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Refreshing connection, discovery, and device trust state.", "surface": "apple", @@ -10139,7 +10139,7 @@ }, { "kind": "ui-call", - "line": 272, + "line": 297, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Empty", "surface": "apple", @@ -10147,7 +10147,7 @@ }, { "kind": "ui-named-argument", - "line": 274, + "line": 299, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "No gateway configured", "surface": "apple", @@ -10155,7 +10155,7 @@ }, { "kind": "ui-named-argument", - "line": 275, + "line": 300, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Scan a setup QR code, paste a setup code, or choose a discovered gateway.", "surface": "apple", @@ -10163,7 +10163,7 @@ }, { "kind": "ui-call", - "line": 281, + "line": 306, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Error", "surface": "apple", @@ -10171,7 +10171,7 @@ }, { "kind": "ui-named-argument", - "line": 283, + "line": 308, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Tailscale warning", "surface": "apple", @@ -10179,7 +10179,7 @@ }, { "kind": "ui-named-argument", - "line": 284, + "line": 309, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Tailscale is off on this device. Turn it on, then try again.", "surface": "apple", @@ -10187,7 +10187,7 @@ }, { "kind": "ui-call", - "line": 333, + "line": 358, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Address", "surface": "apple", @@ -10195,7 +10195,7 @@ }, { "kind": "ui-call", - "line": 335, + "line": 360, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Server", "surface": "apple", @@ -10203,7 +10203,7 @@ }, { "kind": "ui-call", - "line": 337, + "line": 362, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Discovered", "surface": "apple", @@ -10211,7 +10211,7 @@ }, { "kind": "ui-call", - "line": 339, + "line": 364, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Default Agent", "surface": "apple", @@ -10219,7 +10219,7 @@ }, { "kind": "ui-call", - "line": 361, + "line": 386, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Reconnect", "surface": "apple", @@ -10227,7 +10227,7 @@ }, { "kind": "ui-call", - "line": 362, + "line": 387, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Diagnose", "surface": "apple", @@ -10235,7 +10235,7 @@ }, { "kind": "ui-call", - "line": 371, + "line": 396, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Scan QR", "surface": "apple", @@ -10243,7 +10243,7 @@ }, { "kind": "ui-call", - "line": 372, + "line": 397, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Connect", "surface": "apple", @@ -10251,7 +10251,7 @@ }, { "kind": "ui-call", - "line": 374, + "line": 399, "path": "apps/ios/Sources/Design/SettingsProTabSupport.swift", "source": "Discovered gateways and manual setup live here when the gateway has not connected yet.", "surface": "apple", diff --git a/apps/ios/Sources/Design/SettingsProTabActions.swift b/apps/ios/Sources/Design/SettingsProTabActions.swift index 5ae406b70a0d..66de49cd0c0c 100644 --- a/apps/ios/Sources/Design/SettingsProTabActions.swift +++ b/apps/ios/Sources/Design/SettingsProTabActions.swift @@ -108,15 +108,6 @@ extension SettingsProTab { } } - func detailRow(_ label: String, value: String) -> some View { - LabeledContent(label) { - Text(value) - .font(OpenClawType.subhead) - .lineLimit(1) - .truncationMode(.middle) - } - } - func reconnectGateway() async { guard !self.appModel.isAppleReviewDemoModeEnabled else { return } guard !self.isReconnectingGateway else { return } diff --git a/apps/ios/Sources/Design/SettingsProTabSections.swift b/apps/ios/Sources/Design/SettingsProTabSections.swift index 3dcea85dec89..ef4540009c3c 100644 --- a/apps/ios/Sources/Design/SettingsProTabSections.swift +++ b/apps/ios/Sources/Design/SettingsProTabSections.swift @@ -113,9 +113,9 @@ extension SettingsProTab { NavigationLink(value: SettingsRoute.gateway) { self.gatewayConnectionRow } - LabeledContent("Address", value: self.gatewayAddress) - LabeledContent("Server", value: self.gatewayServer) - LabeledContent("Agents", value: "\(self.appModel.gatewayAgents.count)") + SettingsDetailRow("Address", value: self.gatewayAddress) + SettingsDetailRow("Server", value: self.gatewayServer) + SettingsDetailRow("Agents", value: "\(self.appModel.gatewayAgents.count)") self.gatewayActions } } @@ -272,11 +272,11 @@ extension SettingsProTab { color: self.gatewayStatusColor) self.detailListCard { - self.detailRow("Address", value: self.gatewayAddress) - self.detailRow("Server", value: self.gatewayServer) - self.detailRow("Discovered", value: "\(self.gatewayController.gateways.count)") - self.detailRow("Default Agent", value: self.appModel.activeAgentName) - self.detailRow("Agents", value: "\(self.appModel.gatewayAgents.count)") + SettingsDetailRow("Address", value: self.gatewayAddress) + SettingsDetailRow("Server", value: self.gatewayServer) + SettingsDetailRow("Discovered", value: "\(self.gatewayController.gateways.count)") + SettingsDetailRow("Default Agent", value: self.appModel.activeAgentName) + SettingsDetailRow("Agents", value: "\(self.appModel.gatewayAgents.count)") } Section { @@ -457,10 +457,10 @@ extension SettingsProTab { self.diagnosticChecksCard self.detailListCard { - self.detailRow("Device", value: DeviceInfoHelper.deviceFamily()) - self.detailRow("Platform", value: DeviceInfoHelper.platformStringForDisplay()) - self.detailRow("App", value: DeviceInfoHelper.openClawVersionString()) - self.detailRow("Model", value: DeviceInfoHelper.modelIdentifier()) + SettingsDetailRow("Device", value: DeviceInfoHelper.deviceFamily()) + SettingsDetailRow("Platform", value: DeviceInfoHelper.platformStringForDisplay()) + SettingsDetailRow("App", value: DeviceInfoHelper.openClawVersionString()) + SettingsDetailRow("Model", value: DeviceInfoHelper.modelIdentifier()) } self.diagnosticsAdvancedCard @@ -638,9 +638,9 @@ extension SettingsProTab { // Concise public details only; deep hardware identifiers live in Diagnostics. detailListCard { - self.detailRow("OpenClaw app version", value: DeviceInfoHelper.openClawVersionString()) - self.detailRow("Device", value: DeviceInfoHelper.deviceFamily()) - self.detailRow("iOS", value: DeviceInfoHelper.iOSVersionStringForDisplay()) + SettingsDetailRow("OpenClaw app version", value: DeviceInfoHelper.openClawVersionString()) + SettingsDetailRow("Device", value: DeviceInfoHelper.deviceFamily()) + SettingsDetailRow("iOS", value: DeviceInfoHelper.iOSVersionStringForDisplay()) } Section { @@ -942,8 +942,8 @@ extension SettingsProTab { NavigationLink { VoiceWakeWordsSettingsView() } label: { - self.simpleSettingsRow( - title: "Wake Words", + SettingsDetailRow( + "Wake Words", value: VoiceWakePreferences.displayString(for: self.voiceWake.triggerWords)) } } @@ -979,13 +979,13 @@ extension SettingsProTab { } .font(OpenClawType.body) } - self.detailRow("Voice Mode", value: self.appModel.talkMode.gatewayTalkVoiceModeTitle) - self.detailRow("Active Voice", value: self.gatewayTalkActiveVoiceDetail) + SettingsDetailRow("Voice Mode", value: self.appModel.talkMode.gatewayTalkVoiceModeTitle) + SettingsDetailRow("Active Voice", value: self.gatewayTalkActiveVoiceDetail) if let issue = self.gatewayTalkLastIssueDetail { - self.detailRow("Last Voice Issue", value: issue) + SettingsDetailRow("Last Voice Issue", value: issue) } - self.detailRow("Transport", value: self.appModel.talkMode.gatewayTalkTransportLabel) - self.detailRow("API Key", value: self.talkApiKeyStatus) + SettingsDetailRow("Transport", value: self.appModel.talkMode.gatewayTalkTransportLabel) + SettingsDetailRow("API Key", value: self.talkApiKeyStatus) } } } @@ -1027,7 +1027,7 @@ extension SettingsProTab { NavigationLink { GatewayDiscoveryDebugLogView() } label: { - self.simpleSettingsRow(title: "Discovery Logs", value: self.gatewayController.discoveryStatusText) + SettingsDetailRow("Discovery Logs", value: self.gatewayController.discoveryStatusText) } } } @@ -1036,7 +1036,7 @@ extension SettingsProTab { Section("Device") { TextField("Device Name", text: self.$displayName) .font(OpenClawType.body) - self.detailRow("Instance ID", value: self.instanceId) + SettingsDetailRow("Instance ID", value: self.instanceId) } } @@ -1047,19 +1047,10 @@ extension SettingsProTab { { Toggle(isOn: isOn) { Text(title) - .font(OpenClawType.subhead) + .font(OpenClawType.body) } .onChange(of: isOn.wrappedValue) { _, enabled in onChange?(enabled) } } - - func simpleSettingsRow(title: String, value: String) -> some View { - LabeledContent(title) { - Text(value) - .font(OpenClawType.subhead) - .lineLimit(1) - .truncationMode(.middle) - } - } } diff --git a/apps/ios/Sources/Design/SettingsProTabSupport.swift b/apps/ios/Sources/Design/SettingsProTabSupport.swift index baa5a4648373..6754118599c6 100644 --- a/apps/ios/Sources/Design/SettingsProTabSupport.swift +++ b/apps/ios/Sources/Design/SettingsProTabSupport.swift @@ -21,6 +21,31 @@ enum SettingsLayout { static let rowHeight: CGFloat = 58 } +/// Canonical label/value list row for Settings and Talk surfaces. Keep every +/// detail row on this view so row typography cannot drift between sections; +/// plain `LabeledContent(String, value:)` renders unbranded system fonts. +struct SettingsDetailRow: View { + let label: String + let value: String + + init(_ label: String, value: String) { + self.label = label + self.value = value + } + + var body: some View { + LabeledContent { + Text(self.value) + .font(OpenClawType.subhead) + .lineLimit(1) + .truncationMode(.middle) + } label: { + Text(self.label) + .font(OpenClawType.body) + } + } +} + struct SettingsApprovalItem: Identifiable { let id: String let icon: String diff --git a/apps/ios/Sources/Design/TalkProTab.swift b/apps/ios/Sources/Design/TalkProTab.swift index 240e29c75fb5..65dff0d5bbe7 100644 --- a/apps/ios/Sources/Design/TalkProTab.swift +++ b/apps/ios/Sources/Design/TalkProTab.swift @@ -150,22 +150,22 @@ struct TalkProTab: View { private var conversationSection: some View { Section("Conversation") { - LabeledContent("Agent", value: self.appModel.chatAgentName) - LabeledContent("Session", value: self.appModel.chatSessionKey) - LabeledContent("Runtime", value: self.appModel.talkMode.statusText) + SettingsDetailRow("Agent", value: self.appModel.chatAgentName) + SettingsDetailRow("Session", value: self.appModel.chatSessionKey) + SettingsDetailRow("Runtime", value: self.appModel.talkMode.statusText) } } private var voiceModeSection: some View { Section("Voice Mode") { - LabeledContent("Configured", value: self.appModel.talkMode.gatewayTalkVoiceModeTitle) - LabeledContent("Active", value: self.activeModeText) - LabeledContent("Transport", value: self.transportText) + SettingsDetailRow("Configured", value: self.appModel.talkMode.gatewayTalkVoiceModeTitle) + SettingsDetailRow("Active", value: self.activeModeText) + SettingsDetailRow("Transport", value: self.transportText) if let issueText = self.talkIssueText { - LabeledContent("Last issue", value: issueText) + SettingsDetailRow("Last issue", value: issueText) } - LabeledContent("Permission", value: self.permissionText) - LabeledContent("Speech language", value: self.speechLocaleText) + SettingsDetailRow("Permission", value: self.permissionText) + SettingsDetailRow("Speech language", value: self.speechLocaleText) } } diff --git a/apps/ios/Tests/OpenClawTypographyTests.swift b/apps/ios/Tests/OpenClawTypographyTests.swift index 44391cbcf42e..28fc41f2cf41 100644 --- a/apps/ios/Tests/OpenClawTypographyTests.swift +++ b/apps/ios/Tests/OpenClawTypographyTests.swift @@ -216,7 +216,7 @@ struct OpenClawTypographyTests { #expect(settingsSections.contains(".font(OpenClawType.subhead)")) #expect(settingsSections.contains("private struct AppearanceSettingsScreen")) #expect(settingsSections.contains("Section(\"Gateway\")")) - #expect(settingsSections.contains("LabeledContent(\"Address\", value: self.gatewayAddress)")) + #expect(settingsSections.contains("SettingsDetailRow(\"Address\", value: self.gatewayAddress)")) #expect(settingsSections.contains("func gatewayActionButton")) #expect(settingsSections.contains("func settingsToggle")) #expect(settingsSections.contains(".font(OpenClawType.subheadSemiBold)")) @@ -387,7 +387,7 @@ struct OpenClawTypographyTests { private static func isShorthandControlCall(_ line: String) -> Bool { line.range( - of: #"\b(Button|Link|Picker|Toggle|TextField|SecureField|Menu|DisclosureGroup)\s*\(""#, + of: #"\b(Button|Link|Picker|Toggle|TextField|SecureField|Menu|DisclosureGroup|LabeledContent)\s*\(""#, options: .regularExpression) != nil } diff --git a/apps/ios/Tests/RootTabsSourceGuardTests.swift b/apps/ios/Tests/RootTabsSourceGuardTests.swift index d2dbfead5b9d..78d6bc8dc46a 100644 --- a/apps/ios/Tests/RootTabsSourceGuardTests.swift +++ b/apps/ios/Tests/RootTabsSourceGuardTests.swift @@ -291,17 +291,17 @@ struct RootTabsSourceGuardTests { #expect(!aboutDestination.contains("detailStatusCard(")) #expect(aboutDestination.contains("detailListCard")) - #expect(aboutDestination.contains("self.detailRow(\"OpenClaw app version\"")) - #expect(aboutDestination.contains("self.detailRow(\"Device\", value: DeviceInfoHelper.deviceFamily())")) + #expect(aboutDestination.contains("SettingsDetailRow(\"OpenClaw app version\"")) + #expect(aboutDestination.contains("SettingsDetailRow(\"Device\", value: DeviceInfoHelper.deviceFamily())")) #expect(aboutDestination - .contains("self.detailRow(\"iOS\", value: DeviceInfoHelper.iOSVersionStringForDisplay())")) - #expect(!aboutDestination.contains("self.detailRow(\"Version\"")) - #expect(!aboutDestination.contains("self.detailRow(\"Platform\"")) - #expect(!aboutDestination.contains("self.detailRow(\"Model\"")) - #expect(diagnosticsDestination.contains("self.detailRow(\"Device\", value: DeviceInfoHelper.deviceFamily())")) + .contains("SettingsDetailRow(\"iOS\", value: DeviceInfoHelper.iOSVersionStringForDisplay())")) + #expect(!aboutDestination.contains("SettingsDetailRow(\"Version\"")) + #expect(!aboutDestination.contains("SettingsDetailRow(\"Platform\"")) + #expect(!aboutDestination.contains("SettingsDetailRow(\"Model\"")) + #expect(diagnosticsDestination.contains("SettingsDetailRow(\"Device\", value: DeviceInfoHelper.deviceFamily())")) #expect(diagnosticsDestination - .contains("self.detailRow(\"Platform\", value: DeviceInfoHelper.platformStringForDisplay())")) - #expect(diagnosticsDestination.contains("self.detailRow(\"Model\", value: DeviceInfoHelper.modelIdentifier())")) + .contains("SettingsDetailRow(\"Platform\", value: DeviceInfoHelper.platformStringForDisplay())")) + #expect(diagnosticsDestination.contains("SettingsDetailRow(\"Model\", value: DeviceInfoHelper.modelIdentifier())")) } @Test func `routed headers use shared adaptive layout`() throws {