import SwiftUI /// One commit: what it says, who signed it, whether it passed, and what /// it changed. struct CommitView: View { @State private var model: CommitDetailViewModel init(client: GitbayClient, repo: String, sha: String) { _model = State(initialValue: CommitDetailViewModel( client: client, repoPath: repo, sha: sha )) } var body: some View { List { if let commit = model.state.value { Section { VStack(alignment: .leading, spacing: 6) { Text(commit.subject) .font(.gbSans(.headline)) if let message = commit.message, !message.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { Text(message.trimmingCharacters(in: .whitespacesAndNewlines)) .font(.gbSans(.subheadline)) .foregroundStyle(.secondary) } HStack(spacing: 6) { Text(commit.shortSHA) .font(.gbMono(.caption)) .foregroundStyle(.secondary) SignatureBadge(signature: commit.signature) } HStack(spacing: 6) { Text(commit.authorName) Text(commit.date, format: .dateTime.year().month().day()) .foregroundStyle(.tertiary) } .font(.gbSans(.caption)) .foregroundStyle(.secondary) } .padding(.vertical, 2) } if let checks = commit.checks, !checks.isEmpty { Section("Checks") { ForEach(checks) { check in HStack { Image(systemName: check.state == "success" ? "checkmark.circle.fill" : check.state == "pending" ? "circle.dotted" : "xmark.circle.fill") .foregroundStyle(check.state == "success" ? Color.gbOK : check.state == "pending" ? Color.gbWarn : Color.gbBad) Text(check.context) .font(.gbSans(.subheadline)) Spacer() Text(check.state) .font(.gbSans(.caption)) .foregroundStyle(.secondary) } } } } if let diff = model.diff, !diff.files.isEmpty { // The patch, in place. The web's commit page is the // diff — a file header expands its hunks rather than // linking away to the whole file. ForEach(diff.files) { file in DiffFileSection(file: file) } } } } .overlay { LoadStateOverlay(state: model.state) } .navigationTitle(String(model.sha.prefix(10))) .navigationBarTitleDisplayMode(.inline) .task { await model.load() } .refreshable { await model.load() } } }