diff options
| author | Christian Cleberg <[email protected]> | 2026-03-17 23:19:43 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-03-17 23:19:43 -0500 |
| commit | 32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5 (patch) | |
| tree | ee36d421d704e508d5617d803b4c8cbdb4804fe1 /Hutch/Views/Repositories/ReferencesListView.swift | |
| parent | 8f2057c53e9009c2529c9c4849c914666c0e4b40 (diff) | |
| download | hutch-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.swift | 90 |
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 + } +} |
