summaryrefslogtreecommitdiff
path: root/Hutch/Views/Repositories/ReferencesListView.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-17 23:19:43 -0500
committerChristian Cleberg <[email protected]>2026-03-17 23:19:43 -0500
commit32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5 (patch)
treeee36d421d704e508d5617d803b4c8cbdb4804fe1 /Hutch/Views/Repositories/ReferencesListView.swift
parent8f2057c53e9009c2529c9c4849c914666c0e4b40 (diff)
downloadhutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.gz
hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.bz2
hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.zip
v1.0
Diffstat (limited to 'Hutch/Views/Repositories/ReferencesListView.swift')
-rw-r--r--Hutch/Views/Repositories/ReferencesListView.swift90
1 files changed, 90 insertions, 0 deletions
diff --git a/Hutch/Views/Repositories/ReferencesListView.swift b/Hutch/Views/Repositories/ReferencesListView.swift
new file mode 100644
index 0000000..615ba25
--- /dev/null
+++ b/Hutch/Views/Repositories/ReferencesListView.swift
@@ -0,0 +1,90 @@
+import SwiftUI
+
+struct ReferencesListView: View {
+ let viewModel: RepositoryDetailViewModel
+
+ var body: some View {
+ List {
+ if !viewModel.branches.isEmpty {
+ Section("Branches") {
+ ForEach(viewModel.branches, id: \.name) { ref in
+ ReferenceRow(reference: ref, prefix: "refs/heads/")
+ }
+ }
+ }
+
+ if !viewModel.tags.isEmpty {
+ Section("Tags") {
+ ForEach(viewModel.tags, id: \.name) { ref in
+ ReferenceRow(reference: ref, prefix: "refs/tags/")
+ }
+ }
+ }
+ }
+ .listStyle(.insetGrouped)
+ .overlay {
+ if viewModel.isLoadingRefs, viewModel.branches.isEmpty, viewModel.tags.isEmpty {
+ SRHTLoadingStateView(message: "Loading references…")
+ } else if let error = viewModel.error, viewModel.branches.isEmpty, viewModel.tags.isEmpty {
+ SRHTErrorStateView(
+ title: "Couldn't Load References",
+ message: error,
+ retryAction: { await viewModel.loadReferences() }
+ )
+ } else if viewModel.branches.isEmpty, viewModel.tags.isEmpty {
+ ContentUnavailableView(
+ "No References",
+ systemImage: "arrow.triangle.branch",
+ description: Text("This repository has no branches or tags.")
+ )
+ }
+ }
+ .task {
+ if viewModel.branches.isEmpty, viewModel.tags.isEmpty {
+ await viewModel.loadReferences()
+ }
+ }
+ .refreshable {
+ await viewModel.loadReferences()
+ }
+ }
+}
+
+private struct ReferenceRow: View {
+ let reference: Reference
+ let prefix: String
+
+ var body: some View {
+ HStack {
+ Label {
+ Text(shortName)
+ .font(.body.monospaced())
+ } icon: {
+ Image(systemName: icon)
+ .foregroundStyle(iconColor)
+ }
+
+ Spacer()
+
+ Text(String((reference.target ?? "").prefix(8)))
+ .font(.caption.monospaced())
+ .foregroundStyle(.secondary)
+ }
+ }
+
+ private var shortName: String {
+ if reference.name.hasPrefix(prefix) {
+ String(reference.name.dropFirst(prefix.count))
+ } else {
+ reference.name
+ }
+ }
+
+ private var icon: String {
+ prefix.contains("tags") ? "tag" : "arrow.triangle.branch"
+ }
+
+ private var iconColor: Color {
+ prefix.contains("tags") ? .orange : .blue
+ }
+}