gitbay/Views/Repos/RefsView.swift
69 lines · 2177 bytes
1import SwiftUI
2
3/// Branches and tags. Tapping one browses the repository at that ref.
4struct RefsView: View {
5
6 @State private var model: RefsViewModel
7
8 init(client: GitbayClient, repo: String) {
9 _model = State(initialValue: RefsViewModel(client: client, repoPath: repo))
10 }
11
12 var body: some View {
13 List {
14 if !model.branches.isEmpty {
15 Section("Branches") {
16 ForEach(model.branches) { ref in
17 NavigationLink(value: RepoRoute.tree(
18 repo: model.repoPath, directory: "", ref: ref.name
19 )) {
20 RefRow(ref: ref, isDefault: ref.name == model.defaultBranch)
21 }
22 }
23 }
24 }
25 if !model.tags.isEmpty {
26 Section("Tags") {
27 ForEach(model.tags) { ref in
28 NavigationLink(value: RepoRoute.tree(
29 repo: model.repoPath, directory: "", ref: ref.name
30 )) {
31 RefRow(ref: ref, isDefault: false)
32 }
33 }
34 }
35 }
36 }
37 .overlay {
38 LoadStateOverlay(
39 state: model.state,
40 isEmpty: model.branches.isEmpty && model.tags.isEmpty
41 )
42 }
43 .searchable(text: Bindable(model).searchText, prompt: "Filter refs")
44 .navigationTitle("Branches & Tags")
45 .navigationBarTitleDisplayMode(.inline)
46 .task { await model.load() }
47 .refreshable { await model.load() }
48 }
49}
50
51private struct RefRow: View {
52 let ref: RepoRef
53 let isDefault: Bool
54
55 var body: some View {
56 HStack(spacing: 8) {
57 Text(ref.name)
58 .font(.gbSans(.subheadline))
59 .lineLimit(1)
60 if isDefault {
61 GBChip("default", .gbAccent)
62 }
63 Spacer()
64 Text(String(ref.sha.prefix(10)))
65 .font(.gbMono(.caption2))
66 .foregroundStyle(.tertiary)
67 }
68 }
69}