| Code | What It Does | How It Does It |
| ▶ IMPORTS | | |
| import SwiftUI | Framework imports | Imports SwiftUI. |
| ▶ LINE COLOURS (MTA PALETTE) — CANONICAL DEFINITION FOR WATCH TARGET | | |
| func watchLineColor(for line: String) -> Color {
switch line {
case "1", "2", "3": return Color(red: 238/255, green: 53/255, blue: 46/255)
case "4", "5", "6": return Color(red: 0/255, green: 147/255, blue: 60/255)
case "7": return Color(red: 185/255, green: 51/255, blue: 173/255)
case "A", "C", "E": return Color(red: 0/255, green: 57/255, blue: 166/255)
case "B", "D", "F", "M": return Color(red: 255/255, green: 99/255, blue: 25/255)
case "G": return Color(red: 108/255, green: 190/255, blue: 69/255)
case "J", "Z": return Color(red: 153/255, green: 102/255, blue: 51/255)
case "L": return Color(red: 167/255, green: 169/255, blue: 172/255)
case "N", "Q", "R", "W": return Color(red: 252/255, green: 204/255, blue: 10/255)
default: return .gray
}
} | `watchLineColor()` function | Implements `watchLineColor`. Returns `Color`. |
| func watchLineTextColor(for line: String) -> Color {
["N", "Q", "R", "W"].contains(line) ? .black : .white
} | `watchLineTextColor()` function | Implements `watchLineTextColor`. Returns `Color`. |
| ▶ INLINE BADGE IMAGE (WATCHOS VERSION USING IMAGERENDERER) | | |
| /// Renders a subway line badge as a UIImage so it can be embedded inline in a SwiftUI Text.
/// Uses SwiftUI's ImageRenderer — the watchOS equivalent of UIGraphicsImageRenderer.
@MainActor
private func watchLineBadgeImage(for line: String, size: CGFloat = 14) -> Image? {
let badge = ZStack {
Circle()
.fill(watchLineColor(for: line))
.frame(width: size, height: size)
Text(line)
.font(.system(size: size * 0.62, weight: .bold))
.foregroundColor(watchLineTextColor(for: line))
}
.frame(width: size, height: size)
let renderer = ImageRenderer(content: badge)
renderer.scale = 2.0
if let cgImage = renderer.cgImage {
return Image(cgImage, scale: 2.0, label: Text(line))
}
return nil
} | Documentation comment | Describes the following declaration. |
| ▶ INLINE ALERT-HEADER TEXT (SAME TECHNIQUE AS NEARBYMAPVIEW'S ALERTHEADERTEXT) | | |
| /// Parses `[X]` tokens in an alert header and returns a concatenated SwiftUI Text
/// where each token is replaced by a coloured circle badge — identical to the
/// approach used in NearbyMapView's black station-callout bubbles.
@MainActor
func watchAlertHeaderText(_ header: String,
fontSize: CGFloat = 13,
textColor: Color = .primary) -> Text {
let plain = Text(header)
.font(.system(size: fontSize))
.foregroundColor(textColor) | Documentation comment | Describes the following declaration. |
| guard let regex = try? NSRegularExpression(pattern: #"\[([A-Z0-9]{1,2})\]"#) else {
return plain
} | `regex` let | Property `regex`. Type: `#"\[([A-Z0-9]{1,2})\]"#)`. |
| let ns = header as NSString
let matches = regex.matches(in: header,
range: NSRange(location: 0, length: ns.length))
guard !matches.isEmpty else { return plain } | `ns` let | Property `ns`. |
| let style = Font.system(size: fontSize)
var result = Text("")
var lastEnd = 0 | `style` let | Property `style`. Type: `fontSize)`. |
| for match in matches {
let matchRange = match.range
if matchRange.location > lastEnd {
let seg = ns.substring(with: NSRange(location: lastEnd,
length: matchRange.location - lastEnd))
result = Text("\(result)\(Text(seg).font(style).foregroundColor(textColor))")
}
if let lineRange = Range(match.range(at: 1), in: header) {
let line = String(header[lineRange])
if let img = watchLineBadgeImage(for: line, size: fontSize + 2) {
result = Text("\(result)\(Text(img).baselineOffset(-1))")
} else {
// Fallback: plain text label
result = Text("\(result)\(Text("[\(line)]").font(style).foregroundColor(textColor))")
}
}
lastEnd = matchRange.location + matchRange.length
} | Code block | See source code for full implementation. |
| if lastEnd < ns.length {
result = Text("\(result)\(Text(ns.substring(from: lastEnd)).font(style).foregroundColor(textColor))")
} | Code block | See source code for full implementation. |
| return result
} | Code block | See source code for full implementation. |
| ▶ [X] TOKEN PARSER (USED TO EXTRACT AFFECTED ROUTES WHEN HEADER HAS NO TOKENS) | | |
| /// Splits an MTA alert header into clean text + extracted line tokens like [A], [C], [1].
func parseAlertHeader(_ text: String) -> (text: String, lines: [String]) {
guard let re = try? NSRegularExpression(pattern: "\\[([A-Z0-9]+)\\]") else {
return (text, [])
}
let ns = text as NSString
let range = NSRange(location: 0, length: ns.length)
var extracted: [String] = []
for m in re.matches(in: text, range: range) {
if m.numberOfRanges > 1 {
extracted.append(ns.substring(with: m.range(at: 1)))
}
}
var cleaned = re.stringByReplacingMatches(in: text, range: range, withTemplate: "")
while cleaned.contains(" ") { cleaned = cleaned.replacingOccurrences(of: " ", with: " ") }
cleaned = cleaned.trimmingCharacters(in: .whitespaces)
return (cleaned, extracted)
} | Documentation comment | Describes the following declaration. |
| ▶ LINE BADGE (SMALL COLOURED CIRCLE, USED IN WATCHSCHEDULEVIEW) | | |
| struct AlertLineBadge: View {
let line: String
var size: CGFloat = 20
var body: some View {
ZStack {
Circle()
.fill(watchLineColor(for: line))
.frame(width: size, height: size)
Text(line)
.font(.system(size: size * 0.5, weight: .bold))
.foregroundColor(watchLineTextColor(for: line))
}
}
} | `AlertLineBadge` struct | Defines the `AlertLineBadge` struct. Conforms to View. |
| ▶ ALERT ROW | | |
| struct WatchAlertRow: View {
let alert: WatchSubwayAlert
var body: some View {
let headerHasTokens = alert.header.contains("[")
VStack(alignment: .leading, spacing: 5) {
// If the header has no [X] tokens, show affectedRoutes as coloured badges
if !headerHasTokens && !alert.affectedRoutes.isEmpty {
HStack(spacing: 4) {
ForEach(Array(alert.affectedRoutes.prefix(8).enumerated()), id: \.offset) { _, line in
AlertLineBadge(line: line, size: 18)
}
Spacer(minLength: 0)
}
}
// Alert type
if !alert.alertType.isEmpty {
Text(alert.alertType)
.font(.system(size: 11, weight: .semibold))
.foregroundColor(.orange)
}
// Header — [X] tokens replaced inline with coloured circle badges,
// exactly as NearbyMapView does in its station callout bubbles.
watchAlertHeaderText(alert.header, fontSize: 13, textColor: .primary)
.fixedSize(horizontal: false, vertical: true)
}
.padding(.vertical, 5)
}
} | `WatchAlertRow` struct | Defines the `WatchAlertRow` struct. Conforms to View. |