gitbay/ContentView.swift

5411753023a5e2958f17b523903abce380941107
gitbay-ios/gitbay/ContentView.swift history · blame · raw

152 lines · 5093 bytes

  1import SwiftUI
  2
  3struct ContentView: View {
  4
  5    @Environment(SessionStore.self) private var session
  6
  7    var body: some View {
  8        if let client = session.client, let account = session.current {
  9            TabView {
 10                Tab("Dashboard", systemImage: "square.grid.2x2") {
 11                    NavigationStack {
 12                        DashboardView(client: client)
 13                            .navigationDestinations(client: client)
 14                    }
 15                }
 16                Tab("Feed", systemImage: "bolt") {
 17                    NavigationStack {
 18                        FeedView(client: client)
 19                            .navigationDestinations(client: client)
 20                    }
 21                }
 22                Tab("Repositories", systemImage: "books.vertical") {
 23                    NavigationStack {
 24                        RepoListView(client: client)
 25                            .navigationDestinations(client: client)
 26                    }
 27                }
 28            }
 29            .id(account.id) // fresh screens on account switch
 30        } else {
 31            NavigationStack {
 32                SignInView()
 33            }
 34        }
 35    }
 36
 37}
 38
 39/// Every value-routed screen, attachable to any stack root.
 40private struct RouteDestinations: ViewModifier {
 41
 42    let client: GitbayClient
 43
 44    func body(content: Content) -> some View {
 45        content
 46            .navigationDestination(for: RepoRoute.self) { route in
 47                destination(route, client: client)
 48            }
 49            .navigationDestination(for: MRRoute.self) { route in
 50                destination(route, client: client)
 51            }
 52            .navigationDestination(for: IssueRoute.self) { route in
 53                destination(route, client: client)
 54            }
 55            .navigationDestination(for: BuildRoute.self) { route in
 56                destination(route, client: client)
 57            }
 58            .navigationDestination(for: ReleaseRoute.self) { route in
 59                destination(route, client: client)
 60            }
 61            .navigationDestination(for: OrgRoute.self) { route in
 62                destination(route, client: client)
 63            }
 64    }
 65
 66    @ViewBuilder
 67    private func destination(_ route: RepoRoute, client: GitbayClient) -> some View {
 68        switch route {
 69        case .repo(let path):
 70            RepoView(client: client, path: path)
 71        case .tree(let repo, let directory, let ref):
 72            TreeView(client: client, repo: repo, directory: directory, ref: ref)
 73        case .file(let repo, let path, let ref):
 74            FileView(client: client, repo: repo, path: path, ref: ref)
 75        case .log(let repo):
 76            LogView(client: client, repo: repo)
 77        case .settings(let repo):
 78            RepoSettingsView(client: client, repo: repo)
 79        case .grep(let repo):
 80            GrepView(client: client, repo: repo)
 81        case .profile(let name):
 82            ProfileView(client: client, name: name)
 83        case .account:
 84            AccountView(client: client)
 85        case .addAccount:
 86            SignInView()
 87        }
 88    }
 89
 90    @ViewBuilder
 91    private func destination(_ route: MRRoute, client: GitbayClient) -> some View {
 92        switch route {
 93        case .list(let repo):
 94            MRListView(client: client, repo: repo)
 95        case .mr(let repo, let number):
 96            MRView(client: client, repo: repo, number: number)
 97        case .diff(let repo, let number):
 98            DiffView(client: client, repo: repo, number: number)
 99        }
100    }
101
102    @ViewBuilder
103    private func destination(_ route: IssueRoute, client: GitbayClient) -> some View {
104        switch route {
105        case .list(let repo):
106            IssueListView(client: client, repo: repo)
107        case .issue(let repo, let number):
108            IssueView(client: client, repo: repo, number: number)
109        }
110    }
111
112    @ViewBuilder
113    private func destination(_ route: OrgRoute, client: GitbayClient) -> some View {
114        switch route {
115        case .org(let name):
116            OrgView(client: client, org: name)
117        case .team(let org, let team):
118            TeamView(client: client, org: org, team: team)
119        }
120    }
121
122    @ViewBuilder
123    private func destination(_ route: ReleaseRoute, client: GitbayClient) -> some View {
124        switch route {
125        case .list(let repo):
126            ReleaseListView(client: client, repo: repo)
127        case .release(let repo, let tag):
128            ReleaseView(client: client, repo: repo, tag: tag)
129        }
130    }
131
132    @ViewBuilder
133    private func destination(_ route: BuildRoute, client: GitbayClient) -> some View {
134        switch route {
135        case .list(let repo):
136            BuildListView(client: client, repo: repo)
137        case .log(let repo, let number):
138            BuildLogView(client: client, repo: repo, number: number)
139        }
140    }
141}
142
143extension View {
144    func navigationDestinations(client: GitbayClient) -> some View {
145        modifier(RouteDestinations(client: client))
146    }
147}
148
149#Preview {
150    ContentView()
151        .environment(SessionStore())
152}