gitbay/ContentView.swift

1c5622210d0f72efd86582ce195a6741401e7939
gitbay-ios/gitbay/ContentView.swift history · blame · raw

168 lines · 5895 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                Tab("Explore", systemImage: "safari") {
 29                    NavigationStack {
 30                        ExploreView(client: client)
 31                            .navigationDestinations(client: client)
 32                    }
 33                }
 34            }
 35            .id(account.id) // fresh screens on account switch
 36        } else {
 37            NavigationStack {
 38                SignInView()
 39            }
 40        }
 41    }
 42
 43}
 44
 45/// Every value-routed screen, attachable to any stack root.
 46private struct RouteDestinations: ViewModifier {
 47
 48    let client: GitbayClient
 49
 50    func body(content: Content) -> some View {
 51        content
 52            .navigationDestination(for: RepoRoute.self) { route in
 53                destination(route, client: client)
 54            }
 55            .navigationDestination(for: MRRoute.self) { route in
 56                destination(route, client: client)
 57            }
 58            .navigationDestination(for: IssueRoute.self) { route in
 59                destination(route, client: client)
 60            }
 61            .navigationDestination(for: BuildRoute.self) { route in
 62                destination(route, client: client)
 63            }
 64            .navigationDestination(for: ReleaseRoute.self) { route in
 65                destination(route, client: client)
 66            }
 67            .navigationDestination(for: OrgRoute.self) { route in
 68                destination(route, client: client)
 69            }
 70    }
 71
 72    @ViewBuilder
 73    private func destination(_ route: RepoRoute, client: GitbayClient) -> some View {
 74        switch route {
 75        case .repo(let path):
 76            RepoView(client: client, path: path)
 77        case .tree(let repo, let directory, let ref):
 78            TreeView(client: client, repo: repo, directory: directory, ref: ref)
 79        case .file(let repo, let path, let ref):
 80            FileView(client: client, repo: repo, path: path, ref: ref)
 81        case .log(let repo, let ref, let path):
 82            LogView(client: client, repo: repo, ref: ref, path: path)
 83        case .settings(let repo):
 84            RepoSettingsView(client: client, repo: repo)
 85        case .grep(let repo):
 86            GrepView(client: client, repo: repo)
 87        case .blame(let repo, let path, let ref):
 88            BlameView(client: client, repo: repo, path: path, ref: ref)
 89        case .refs(let repo):
 90            RefsView(client: client, repo: repo)
 91        case .milestones(let repo):
 92            MilestoneListView(client: client, repo: repo)
 93        case .commit(let repo, let sha):
 94            CommitView(client: client, repo: repo, sha: sha)
 95        case .commitDiff(let repo, let sha):
 96            CommitDiffView(client: client, repo: repo, sha: sha)
 97        case .profile(let name):
 98            ProfileView(client: client, name: name)
 99        case .account:
100            AccountView(client: client)
101        case .addAccount:
102            SignInView()
103        }
104    }
105
106    @ViewBuilder
107    private func destination(_ route: MRRoute, client: GitbayClient) -> some View {
108        switch route {
109        case .list(let repo):
110            MRListView(client: client, repo: repo)
111        case .mr(let repo, let number):
112            MRView(client: client, repo: repo, number: number)
113        case .diff(let repo, let number):
114            DiffView(client: client, repo: repo, number: number)
115        }
116    }
117
118    @ViewBuilder
119    private func destination(_ route: IssueRoute, client: GitbayClient) -> some View {
120        switch route {
121        case .list(let repo):
122            IssueListView(client: client, repo: repo)
123        case .issue(let repo, let number):
124            IssueView(client: client, repo: repo, number: number)
125        }
126    }
127
128    @ViewBuilder
129    private func destination(_ route: OrgRoute, client: GitbayClient) -> some View {
130        switch route {
131        case .org(let name):
132            OrgView(client: client, org: name)
133        case .team(let org, let team):
134            TeamView(client: client, org: org, team: team)
135        }
136    }
137
138    @ViewBuilder
139    private func destination(_ route: ReleaseRoute, client: GitbayClient) -> some View {
140        switch route {
141        case .list(let repo):
142            ReleaseListView(client: client, repo: repo)
143        case .release(let repo, let tag):
144            ReleaseView(client: client, repo: repo, tag: tag)
145        }
146    }
147
148    @ViewBuilder
149    private func destination(_ route: BuildRoute, client: GitbayClient) -> some View {
150        switch route {
151        case .list(let repo):
152            BuildListView(client: client, repo: repo)
153        case .log(let repo, let number):
154            BuildLogView(client: client, repo: repo, number: number)
155        }
156    }
157}
158
159extension View {
160    func navigationDestinations(client: GitbayClient) -> some View {
161        modifier(RouteDestinations(client: client))
162    }
163}
164
165#Preview {
166    ContentView()
167        .environment(SessionStore())
168}