a native ios client for gitbay

client ios swift

https://gitbay.org

gitbay/Views/Repos/TreeView.swift

82 lines · 2691 bytes

 1import SwiftUI
 2
 3struct TreeView: View {
 4
 5    @State private var model: TreeViewModel
 6
 7    init(client: GitbayClient, repo: String, directory: String, ref: String?) {
 8        _model = State(initialValue: TreeViewModel(
 9            client: client, repoPath: repo, directory: directory, ref: ref
10        ))
11    }
12
13    var body: some View {
14        List {
15            ForEach(model.entries) { entry in
16                if entry.isDirectory {
17                    NavigationLink(value: RepoRoute.tree(
18                        repo: model.repoPath,
19                        directory: model.childDirectory(entry),
20                        ref: model.ref
21                    )) {
22                        EntryRow(entry: entry)
23                    }
24                } else {
25                    NavigationLink(value: RepoRoute.file(
26                        repo: model.repoPath,
27                        path: model.childDirectory(entry),
28                        ref: model.ref
29                    )) {
30                        EntryRow(entry: entry)
31                    }
32                }
33            }
34        }
35        .overlay { LoadStateOverlay(state: model.state) }
36        .navigationTitle(model.directory.isEmpty
37            ? String(model.repoPath.split(separator: "/").last ?? "")
38            : String(model.directory.split(separator: "/").last ?? ""))
39        .navigationBarTitleDisplayMode(.inline)
40        .toolbar {
41            ToolbarItem(placement: .topBarTrailing) {
42                NavigationLink(value: RepoRoute.log(
43                    repo: model.repoPath, ref: model.ref, path: nil
44                )) {
45                    Image(systemName: "clock")
46                }
47                .accessibilityIdentifier("tree-history-button")
48            }
49        }
50        .task { await model.load() }
51        .refreshable { await model.load() }
52    }
53}
54
55private struct EntryRow: View {
56    let entry: TreeEntry
57
58    var body: some View {
59        HStack {
60            Label {
61                Text(entry.name)
62                    .lineLimit(1)
63            } icon: {
64                Image(systemName: icon)
65                    .foregroundStyle(entry.isDirectory ? Color.accentColor : .secondary)
66            }
67            Spacer()
68            if let size = entry.size, !entry.isDirectory {
69                Text(size.formatted(.byteCount(style: .file)))
70                    .font(.gbSans(.caption))
71                    .foregroundStyle(.tertiary)
72                    .monospacedDigit()
73            }
74        }
75    }
76
77    private var icon: String {
78        if entry.isDirectory { return "folder.fill" }
79        if entry.isSymlink { return "arrow.turn.down.right" }
80        return "doc"
81    }
82}