summaryrefslogtreecommitdiff
path: root/Hutch/Views/Builds/BuildDetailView.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Hutch/Views/Builds/BuildDetailView.swift')
-rw-r--r--Hutch/Views/Builds/BuildDetailView.swift38
1 files changed, 38 insertions, 0 deletions
diff --git a/Hutch/Views/Builds/BuildDetailView.swift b/Hutch/Views/Builds/BuildDetailView.swift
index 1c2e2bb..33590e2 100644
--- a/Hutch/Views/Builds/BuildDetailView.swift
+++ b/Hutch/Views/Builds/BuildDetailView.swift
@@ -9,6 +9,7 @@ struct BuildDetailView: View {
@State private var selectedTaskName: String?
@State private var showEditResubmitSheet = false
@State private var showCancelConfirmation = false
+ @State private var isOpeningRepository = false
private var isPresentingLogSheet: Bool {
selectedTaskName != nil
@@ -158,6 +159,28 @@ struct BuildDetailView: View {
LabeledContent("Updated", value: job.updated.relativeDescription)
}
+ if let repositoryReference = HomeViewModel.primaryRepositoryReference(in: job.manifest) {
+ Section("Source") {
+ Button {
+ openRepository(ownerCanonicalName: repositoryReference.ownerCanonicalName, repositoryName: repositoryReference.name)
+ } label: {
+ HStack {
+ Label("\(repositoryReference.ownerCanonicalName)/\(repositoryReference.name)", systemImage: "book.closed")
+ Spacer()
+ if isOpeningRepository {
+ ProgressView()
+ .controlSize(.small)
+ } else {
+ Image(systemName: "arrow.up.right")
+ .font(.caption)
+ .foregroundStyle(.tertiary)
+ }
+ }
+ }
+ .disabled(isOpeningRepository)
+ }
+ }
+
// Per-task logs
if !job.tasks.isEmpty {
ForEach(job.tasks) { task in
@@ -241,6 +264,21 @@ struct BuildDetailView: View {
))
}
}
+
+ private func openRepository(ownerCanonicalName: String, repositoryName: String) {
+ guard !isOpeningRepository else { return }
+ isOpeningRepository = true
+ Task {
+ defer { isOpeningRepository = false }
+ do {
+ let ownerUsername = ownerCanonicalName.hasPrefix("~") ? String(ownerCanonicalName.dropFirst()) : ownerCanonicalName
+ let repository = try await appState.resolveRepository(owner: ownerUsername, name: repositoryName)
+ appState.navigateToRepository(repository)
+ } catch {
+ appState.presentRepositoryDeepLinkError()
+ }
+ }
+ }
}
private struct EditResubmitBuildSheet: View {