native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #193 from supabitapp/branch-icons

authored by

khoi and committed by
GitHub
1385bbc6 dd7b2d6d

+79 -12
+79 -12
supacode/Features/Repositories/Views/WorktreeRow.swift
··· 6 6 let worktreeColor: WorktreeColor 7 7 let isBusy: Bool 8 8 let gitIconName: String 9 - let gitIconColor: Color 9 + let gitIconColor: AnyShapeStyle 10 10 let isArchiving: Bool 11 11 let isDeleting: Bool 12 12 let info: WorktreeInfoEntry? ··· 16 16 let showsNotificationIndicator: Bool 17 17 let notifications: [WorktreeTerminalNotification] 18 18 let shortcutHint: String? 19 + let checkBadgeState: CheckBadgeState? 19 20 20 21 enum WorktreeColor { 21 22 case `default` ··· 23 24 case pinned 24 25 } 25 26 27 + enum CheckBadgeState { 28 + case passing 29 + case failing 30 + case inProgress 31 + 32 + var symbolName: String { 33 + switch self { 34 + case .passing: "checkmark" 35 + case .failing: "xmark" 36 + case .inProgress: "ellipsis" 37 + } 38 + } 39 + 40 + var color: Color { 41 + switch self { 42 + case .passing: .green 43 + case .failing: .red 44 + case .inProgress: .yellow 45 + } 46 + } 47 + 48 + var accessibilityLabel: String { 49 + switch self { 50 + case .passing: "Checks passed" 51 + case .failing: "Checks failed" 52 + case .inProgress: "Checks in progress" 53 + } 54 + } 55 + } 56 + 26 57 init( 27 58 row: WorktreeRowModel, 28 59 displayMode: WorktreeRowDisplayMode, ··· 79 110 switch pullRequest.state.uppercased() { 80 111 case "MERGED": 81 112 self.gitIconName = "git-merge" 82 - self.gitIconColor = .purple 113 + self.gitIconColor = AnyShapeStyle(.purple) 83 114 case "CLOSED": 84 115 self.gitIconName = "git-pull-request-closed" 85 - self.gitIconColor = .red 116 + self.gitIconColor = AnyShapeStyle(.red) 86 117 case "OPEN" where pullRequest.isDraft: 87 118 self.gitIconName = "git-pull-request-draft" 88 - self.gitIconColor = .secondary 119 + self.gitIconColor = AnyShapeStyle(.tertiary) 89 120 case "OPEN": 90 121 self.gitIconName = "git-pull-request" 91 - let readiness = PullRequestMergeReadiness(pullRequest: pullRequest) 92 - self.gitIconColor = readiness.isBlocking ? .red : .green 122 + self.gitIconColor = AnyShapeStyle(.green) 93 123 default: 94 124 self.gitIconName = "git-branch" 95 - self.gitIconColor = .secondary 125 + self.gitIconColor = AnyShapeStyle(.secondary) 96 126 } 97 127 } else { 98 128 self.gitIconName = "git-branch" 99 - self.gitIconColor = .secondary 129 + self.gitIconColor = AnyShapeStyle(.secondary) 130 + } 131 + 132 + // Check badge for PRs with status checks. 133 + if let checks = prDisplay.pullRequest?.statusCheckRollup?.checks, 134 + !checks.isEmpty 135 + { 136 + let breakdown = PullRequestCheckBreakdown(checks: checks) 137 + if breakdown.failed > 0 { 138 + self.checkBadgeState = .failing 139 + } else if breakdown.inProgress > 0 || breakdown.expected > 0 { 140 + self.checkBadgeState = .inProgress 141 + } else { 142 + self.checkBadgeState = .passing 143 + } 144 + } else { 145 + self.checkBadgeState = nil 100 146 } 101 147 } 102 148 ··· 116 162 117 163 var body: some View { 118 164 Label { 119 - HStack(spacing: 6) { 165 + HStack(spacing: 8) { 120 166 TitleView( 121 167 name: name, 122 168 subtitle: subtitle, ··· 140 186 isArchiving: isArchiving, 141 187 isDeleting: isDeleting, 142 188 gitIconName: gitIconName, 143 - gitIconColor: gitIconColor 189 + gitIconColor: gitIconColor, 190 + checkBadgeState: checkBadgeState 144 191 ) 145 192 } 146 193 .labelStyle(.verticallyCentered) ··· 189 236 let isArchiving: Bool 190 237 let isDeleting: Bool 191 238 let gitIconName: String 192 - let gitIconColor: Color 239 + let gitIconColor: AnyShapeStyle 240 + let checkBadgeState: WorktreeRow.CheckBadgeState? 193 241 @Environment(\.backgroundProminence) private var backgroundProminence 194 242 195 243 private var isEmphasized: Bool { ··· 206 254 guard !isEmphasized else { return AnyShapeStyle(.secondary) } 207 255 if isArchiving { return AnyShapeStyle(.orange) } 208 256 if isDeleting { return AnyShapeStyle(.red) } 209 - return AnyShapeStyle(gitIconColor) 257 + return gitIconColor 210 258 } 211 259 212 260 private var isSystemImage: Bool { ··· 229 277 } 230 278 } 231 279 .foregroundStyle(resolvedColor) 280 + .overlay(alignment: .bottomTrailing) { 281 + if let checkBadgeState, !isSystemImage { 282 + let badgeColor = AnyShapeStyle(checkBadgeState.color) 283 + let background = AnyShapeStyle(.windowBackground) 284 + Image(systemName: checkBadgeState.symbolName) 285 + .resizable() 286 + .symbolVariant(.circle.fill) 287 + .symbolRenderingMode(.palette) 288 + .fontWeight(.black) 289 + .frame(width: 10, height: 10) 290 + .foregroundStyle( 291 + isEmphasized ? badgeColor : background, 292 + isEmphasized ? background : badgeColor, 293 + ) 294 + .background(in: Circle()) 295 + .accessibilityLabel(checkBadgeState.accessibilityLabel) 296 + .offset(x: 2, y: 2) 297 + } 298 + } 232 299 .accessibilityLabel(accessibilityLabel ?? "") 233 300 .accessibilityHidden(accessibilityLabel == nil) 234 301 }