fix(ios): address ClawSweeper review findings

- Remove location guidance from SettingsProTabSections (out of scope)
- Revert ChatProTab to connectionStatusButton/connectionStatusIcon
  to preserve source guard contract (plain style, Circle content shape)
- Change OpenClawType from static let to static var for Dynamic Type
  responsiveness (re-computes through UIFontMetrics each access)
- Add exact provenance: upstream revision URLs and SHA-256 checksums
  for all 14 bundled font binaries
- Re-sync native i18n inventory

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
joelnishanth
2026-07-02 16:17:22 -07:00
committed by Josh Avant
parent 9f73c9acdc
commit 97e582ec74
4 changed files with 143 additions and 42 deletions

View File

@@ -119,7 +119,7 @@ struct ChatProTab: View {
self.headerIdentityBadge
}
} accessory: {
self.connectionPillButton
self.connectionStatusButton
}
.padding(.horizontal, OpenClawProMetric.pagePadding)
.padding(.bottom, 4)
@@ -197,32 +197,40 @@ struct ChatProTab: View {
}
@ViewBuilder
private var connectionPillButton: some View {
private var connectionStatusButton: some View {
if let openSettings {
Button(action: openSettings) {
self.connectionPill
self.connectionStatusIcon
}
.buttonBorderShape(.capsule)
.openClawGlassButton()
.buttonStyle(.plain)
.contentShape(Circle())
.accessibilityLabel(self.gatewayAccessibilityLabel)
.accessibilityHint("Opens Settings / Gateway")
.accessibilityIdentifier("chat-gateway-status")
} else {
self.connectionPill
self.connectionStatusIcon
.accessibilityLabel(self.gatewayAccessibilityLabel)
}
}
private var connectionPill: some View {
HStack(spacing: 6) {
ProStatusDot(color: self.gatewayPillColor)
Text(Self.gatewayPillTitle(state: self.gatewayDisplayState, isGatewayUsable: self.gatewayConnected))
.font(OpenClawType.captionSemiBold)
.lineLimit(1)
private var connectionStatusIcon: some View {
Image(systemName: self.gatewayStatusSymbol)
.font(OpenClawType.subheadSemiBold)
.foregroundStyle(self.gatewayPillColor)
.frame(width: 44, height: 44)
}
private var gatewayStatusSymbol: String {
switch self.gatewayDisplayState {
case .connected:
self.gatewayConnected ? "checkmark.circle.fill" : "exclamationmark.circle"
case .connecting:
"arrow.trianglehead.2.clockwise.rotate.90"
case .error:
"exclamationmark.triangle.fill"
case .disconnected:
"wifi.slash"
}
.foregroundStyle(self.gatewayPillColor)
.padding(.horizontal, 4)
.frame(height: 30)
}
private var gatewayConnected: Bool {

View File

@@ -2,33 +2,103 @@ import SwiftUI
import UIKit
enum OpenClawType {
// Display Plus Jakarta Sans
static let title1 = scaledDisplay(name: Display.extraBold, size: 34, relativeTo: .largeTitle)
static let title2 = scaledDisplay(name: Display.bold, size: 28, relativeTo: .title1)
static let title3 = scaledDisplay(name: Display.bold, size: 22, relativeTo: .title2)
static let headline = scaledDisplay(name: Display.semiBold, size: 17, relativeTo: .headline)
// Body DM Sans
static let body = scaledBody(name: Body.regular, size: 17, relativeTo: .body)
static let callout = scaledBody(name: Body.regular, size: 16, relativeTo: .callout)
static let subhead = scaledBody(name: Body.medium, size: 15, relativeTo: .subheadline)
static let subheadSemiBold = scaledDisplay(name: Display.semiBold, size: 15, relativeTo: .subheadline)
static let footnote = scaledBody(name: Body.regular, size: 13, relativeTo: .footnote)
static let footnoteMedium = scaledBody(name: Body.medium, size: 13, relativeTo: .footnote)
static let footnoteSemiBold = scaledBody(name: Body.semiBold, size: 13, relativeTo: .footnote)
static let caption = scaledBody(name: Body.regular, size: 12, relativeTo: .caption1)
static let captionMedium = scaledBody(name: Body.medium, size: 12, relativeTo: .caption1)
static let captionSemiBold = scaledBody(name: Body.semiBold, size: 12, relativeTo: .caption1)
static let caption2 = scaledBody(name: Body.regular, size: 11, relativeTo: .caption2)
static let caption2Medium = scaledBody(name: Body.medium, size: 11, relativeTo: .caption2)
static let caption2SemiBold = scaledBody(name: Body.semiBold, size: 11, relativeTo: .caption2)
static let caption2Bold = scaledDisplay(name: Display.bold, size: 11, relativeTo: .caption2)
static let title2SemiBold = scaledDisplay(name: Display.semiBold, size: 28, relativeTo: .title1)
// MARK: - Display Plus Jakarta Sans
// Mono JetBrains Mono
static let mono = scaledMono(name: Mono.regular, size: 14, relativeTo: .body)
static let monoSmall = scaledMono(name: Mono.regular, size: 12, relativeTo: .caption1)
static let monoFootnote = scaledMono(name: Mono.regular, size: 13, relativeTo: .footnote)
static let monoHeadline = scaledMono(name: Mono.medium, size: 17, relativeTo: .headline)
static var title1: Font {
scaledDisplay(name: Display.extraBold, size: 34, relativeTo: .largeTitle)
}
static var title2: Font {
scaledDisplay(name: Display.bold, size: 28, relativeTo: .title1)
}
static var title3: Font {
scaledDisplay(name: Display.bold, size: 22, relativeTo: .title2)
}
static var headline: Font {
scaledDisplay(name: Display.semiBold, size: 17, relativeTo: .headline)
}
// MARK: - Body DM Sans
static var body: Font {
scaledBody(name: Body.regular, size: 17, relativeTo: .body)
}
static var callout: Font {
scaledBody(name: Body.regular, size: 16, relativeTo: .callout)
}
static var subhead: Font {
scaledBody(name: Body.medium, size: 15, relativeTo: .subheadline)
}
static var subheadSemiBold: Font {
scaledDisplay(name: Display.semiBold, size: 15, relativeTo: .subheadline)
}
static var footnote: Font {
scaledBody(name: Body.regular, size: 13, relativeTo: .footnote)
}
static var footnoteMedium: Font {
scaledBody(name: Body.medium, size: 13, relativeTo: .footnote)
}
static var footnoteSemiBold: Font {
scaledBody(name: Body.semiBold, size: 13, relativeTo: .footnote)
}
static var caption: Font {
scaledBody(name: Body.regular, size: 12, relativeTo: .caption1)
}
static var captionMedium: Font {
scaledBody(name: Body.medium, size: 12, relativeTo: .caption1)
}
static var captionSemiBold: Font {
scaledBody(name: Body.semiBold, size: 12, relativeTo: .caption1)
}
static var caption2: Font {
scaledBody(name: Body.regular, size: 11, relativeTo: .caption2)
}
static var caption2Medium: Font {
scaledBody(name: Body.medium, size: 11, relativeTo: .caption2)
}
static var caption2SemiBold: Font {
scaledBody(name: Body.semiBold, size: 11, relativeTo: .caption2)
}
static var caption2Bold: Font {
scaledDisplay(name: Display.bold, size: 11, relativeTo: .caption2)
}
static var title2SemiBold: Font {
scaledDisplay(name: Display.semiBold, size: 28, relativeTo: .title1)
}
// MARK: - Mono JetBrains Mono
static var mono: Font {
scaledMono(name: Mono.regular, size: 14, relativeTo: .body)
}
static var monoSmall: Font {
scaledMono(name: Mono.regular, size: 12, relativeTo: .caption1)
}
static var monoFootnote: Font {
scaledMono(name: Mono.regular, size: 13, relativeTo: .footnote)
}
static var monoHeadline: Font {
scaledMono(name: Mono.medium, size: 17, relativeTo: .headline)
}
/// PostScript names for bundled fonts. Keep aligned with `UIAppFonts` in `project.yml`.
static let registeredPostScriptNames: [String] = [

View File

@@ -1,4 +1,3 @@
import CoreLocation
import OpenClawKit
import SwiftUI

View File

@@ -12,6 +12,15 @@ Copyright 2020 The Plus Jakarta Sans Project Authors
License: SIL Open Font License 1.1
Source: https://github.com/tokotype/PlusJakartaSans
Version: 2.7.1
Download: https://github.com/tokotype/PlusJakartaSans/releases/tag/v2.7.1
SHA-256 checksums:
PlusJakartaSans-Light.ttf: 930b92c1dac0da70cdf90448558ac041cd97daeebc952965ae8b71b8473b7198
PlusJakartaSans-Regular.ttf: 6bcfbb10639b8a206b4f8a0a1a29459e7255b1481c95e20d587dd1f1a4b24646
PlusJakartaSans-Medium.ttf: 8e60a920af7fcc9d9e2768aaa51c8595a1c72a9ff3da87c216a319023158ebf2
PlusJakartaSans-SemiBold.ttf: de75ddb3917c5a3f2b7d0cd65fcf63795710f2e1fd944199a73a01731e66fd43
PlusJakartaSans-Bold.ttf: 14972f80fb151f32fb7129c6ad1893f6dd2a9d8bac30c40508c99e7f289b6682
PlusJakartaSans-ExtraBold.ttf: 37f9ae473fd96337e942de37ae34042016853ec2c6fdf2d87e1d93e737041d49
DM Sans
-------
@@ -20,6 +29,15 @@ Copyright 2014-2022 Jonny Pinhorn
(https://github.com/googlefonts/dm-fonts)
License: SIL Open Font License 1.1
Source: https://github.com/googlefonts/dm-fonts
Version: 2.100 (variable; static instances extracted)
Download: https://github.com/googlefonts/dm-fonts/tree/main/ofl/dmsans
SHA-256 checksums:
DMSans-Light.ttf: 5c5184ec4b159b71ec6cc8caf304cb0e1e5cfa6d15153738311098d55ee4f3fb
DMSans-Regular.ttf: a95a338942aa357145427be7c963ff691f9fe859c3512d9c0483e1914d57a208
DMSans-Italic.ttf: 42d8646461572da4dba94e08372b94c4e4b5fd934508ba567f43d29b905fa51f
DMSans-Medium.ttf: 26af1a05d62906ffc3316ee6b4cbaf7ae86a1e607c5b9d89c64ec37f85063fbf
DMSans-SemiBold.ttf: 52897fabe96fa9dfe59b52681b57493f6bdce268ca3add5b82d701460ecc100d
JetBrains Mono
--------------
@@ -28,6 +46,12 @@ Copyright 2020 The JetBrains Mono Project Authors
License: SIL Open Font License 1.1
Source: https://github.com/JetBrains/JetBrainsMono
Version: 2.304
Download: https://github.com/JetBrains/JetBrainsMono/releases/tag/v2.304
SHA-256 checksums:
JetBrainsMono-Regular.ttf: a0bf60ef0f83c5ed4d7a75d45838548b1f6873372dfac88f71804491898d138f
JetBrainsMono-Medium.ttf: 31c92d01a8a08528b718a43addf0ad3df0af2ca4b7b3290a452f70f358e14d3d
JetBrainsMono-SemiBold.ttf: 1b3bfa1ed5665a4ce3f9feb68d2d4e40e70bf8b4b7d9a3edd418f321b4e166a0
---