krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

v2.4.0: Hutch/Views/Repositories/ReferencesListView.swift · raw

 1import SwiftUI
 2
 3struct ReferencesListView: View {
 4    let viewModel: RepositoryDetailViewModel
 5
 6    var body: some View {
 7        List {
 8            if !viewModel.branches.isEmpty {
 9                Section("Branches") {
10                    ForEach(viewModel.branches, id: \.name) { ref in
11                        ReferenceRow(reference: ref, prefix: "refs/heads/")
12                    }
13                }
14            }
15
16            if !viewModel.tags.isEmpty {
17                Section("Tags") {
18                    ForEach(viewModel.tags, id: \.name) { ref in
19                        ReferenceRow(reference: ref, prefix: "refs/tags/")
20                    }
21                }
22            }
23        }
24        .listStyle(.insetGrouped)
25        .overlay {
26            if viewModel.isLoadingRefs, viewModel.branches.isEmpty, viewModel.tags.isEmpty {
27                SRHTLoadingStateView(message: "Loading references…")
28            } else if let error = viewModel.error, viewModel.branches.isEmpty, viewModel.tags.isEmpty {
29                SRHTErrorStateView(
30                    title: "Couldn't Load References",
31                    message: error,
32                    retryAction: { await viewModel.loadReferences() }
33                )
34            } else if viewModel.branches.isEmpty, viewModel.tags.isEmpty {
35                ContentUnavailableView(
36                    "No References",
37                    systemImage: "arrow.triangle.branch",
38                    description: Text("This repository has no branches or tags.")
39                )
40            }
41        }
42        .task {
43            if viewModel.branches.isEmpty, viewModel.tags.isEmpty {
44                await viewModel.loadReferences()
45            }
46        }
47        .refreshable {
48            await viewModel.loadReferences()
49        }
50    }
51}
52
53private struct ReferenceRow: View {
54    let reference: Reference
55    let prefix: String
56
57    var body: some View {
58        HStack {
59            Label {
60                Text(shortName)
61                    .font(.body.monospaced())
62            } icon: {
63                Image(systemName: icon)
64                    .foregroundStyle(iconColor)
65            }
66
67            Spacer()
68
69            Text(String((reference.target ?? "").prefix(8)))
70                .font(.caption.monospaced())
71                .foregroundStyle(.secondary)
72        }
73    }
74
75    private var shortName: String {
76        if reference.name.hasPrefix(prefix) {
77            String(reference.name.dropFirst(prefix.count))
78        } else {
79            reference.name
80        }
81    }
82
83    private var icon: String {
84        prefix.contains("tags") ? "tag" : "arrow.triangle.branch"
85    }
86
87    private var iconColor: Color {
88        prefix.contains("tags") ? .orange : .blue
89    }
90}