native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
6.8 kB · 207 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208import SwiftUI
struct PullRequestChecksPopoverView: View { let pullRequest: GithubPullRequest let checks: [GithubPullRequestStatusCheck] private let breakdown: PullRequestCheckBreakdown private let sortedChecks: [GithubPullRequestStatusCheck] @Environment(\.analyticsClient) private var analyticsClient @Environment(\.openURL) private var openURL @Environment(\.resolvedKeybindings) private var resolvedKeybindings
init( pullRequest: GithubPullRequest, checks: [GithubPullRequestStatusCheck] ) { self.pullRequest = pullRequest self.checks = checks self.breakdown = PullRequestCheckBreakdown(checks: checks) self.sortedChecks = checks.sorted { let left = Self.sortRank(for: $0.checkState) let right = Self.sortRank(for: $1.checkState) if left == right { return $0.displayName.localizedStandardCompare($1.displayName) == .orderedAscending } return left < right } }
var body: some View { let pullRequestURL = URL(string: pullRequest.url) let stateLabel = pullRequest.state.uppercased() let draftLabel = pullRequest.isDraft ? "\(stateLabel)/DRAFT" : stateLabel let titlePrefix = Text("\(draftLabel) - ").foregroundStyle(.secondary) let titleSuffix = Text(verbatim: " #\(pullRequest.number)") .foregroundStyle(.secondary) let titleLine = Text("\(titlePrefix)\(pullRequest.title)\(titleSuffix)") let authorLogin = pullRequest.authorLogin ?? String(localized: "Someone") let commitsCount = pullRequest.commitsCount ?? 0 let commitsLabel = commitsCount == 1 ? String(localized: "commit") : String(localized: "commits") let baseRefName = pullRequest.baseRefName ?? "base" let headRefName = pullRequest.headRefName ?? "branch" let baseRef = Text("`\(baseRefName)`").monospaced() let headRef = Text("`\(headRefName)`").monospaced() let summaryLine = Text( "\(authorLogin) wants to merge \(commitsCount, format: .number) \(commitsLabel) into \(baseRef) from \(headRef)" ).foregroundStyle(.secondary) let additionsText = Text("+\(pullRequest.additions, format: .number)") let deletionsText = Text("-\(pullRequest.deletions, format: .number)") let hasConflicts = PullRequestMergeReadiness(pullRequest: pullRequest).isConflicting ScrollView { VStack(alignment: .leading) { if let pullRequestURL { Button { analyticsClient.capture("github_pr_opened", nil) openURL(pullRequestURL) } label: { titleLine .lineLimit(1) } .buttonStyle(.plain) .focusable(false) .onHover { _ in } .pointerStyle(.link) .help(openPullRequestHelpText) .modifier(KeyboardShortcutModifier(shortcut: openPullRequestShortcut?.keyboardShortcut)) .font(.headline) } else { titleLine .lineLimit(1) .font(.headline) } summaryLine .font(.subheadline) .lineLimit(1) HStack { additionsText .foregroundStyle(.green) deletionsText .foregroundStyle(.red) if hasConflicts { Text("•") .foregroundStyle(.secondary) Text("Merge Conflicts") .foregroundStyle(.red) } } .font(.subheadline)
if let mergeQueueStatus = PullRequestMergeQueueStatus(pullRequest: pullRequest) { PullRequestMergeQueueRow(status: mergeQueueStatus) }
if breakdown.total > 0 { HStack { PullRequestChecksRingView(breakdown: breakdown) Text(breakdown.summaryText) .foregroundStyle(.secondary) } .font(.caption) }
if !sortedChecks.isEmpty { Divider() VStack(alignment: .leading) { ForEach(sortedChecks, id: \.self) { check in let style = PullRequestCheckStatusStyle(state: check.checkState) HStack { Image(systemName: style.symbol) .foregroundStyle(style.color) .accessibilityHidden(true) if let url = check.detailsUrl.flatMap(URL.init(string:)) { Button { analyticsClient.capture("github_ci_check_opened", nil) openURL(url) } label: { LinkLabel(text: check.displayName) .lineLimit(1) } .buttonStyle(.plain) .focusable(false) .help("Open check details on GitHub") } else { Text(check.displayName) .lineLimit(1) } Spacer() Text(style.label) .foregroundStyle(.secondary) } .font(.caption) } } } } .padding() } .frame(minWidth: 260, maxWidth: 840, maxHeight: 720) }
private struct PullRequestMergeQueueRow: View { let status: PullRequestMergeQueueStatus
var body: some View { VStack(alignment: .leading, spacing: 2) { HStack(spacing: 6) { Image(systemName: "arrow.triangle.merge") .foregroundStyle(.brown) .accessibilityHidden(true) Text(status.summary) .foregroundStyle(.brown) } .font(.subheadline) if let detail = status.detail { Text(detail) .font(.caption) .foregroundStyle(.secondary) } } .accessibilityElement(children: .combine) } }
private static func sortRank(for state: GithubPullRequestCheckState) -> Int { switch state { case .failure: return 0 case .inProgress: return 1 case .expected: return 2 case .skipped: return 3 case .success: return 4 } }
private var openPullRequestShortcut: AppShortcut? { AppShortcuts.resolvedShortcut( for: AppShortcuts.CommandID.openPullRequest, in: resolvedKeybindings ) }
private var openPullRequestHelpText: String { if let display = openPullRequestShortcut?.display { return String(localized: "Open pull request on GitHub (\(display))") } return String(localized: "Open pull request on GitHub") }}
private struct LinkLabel: View { let text: String @State private var isHovering = false
var body: some View { Text(text) .underline() .foregroundStyle(isHovering ? .blue : .secondary) .onHover { hovering in isHovering = hovering } .pointerStyle(.link) .accessibilityHint("Open on GitHub") }}