import SwiftUI /// A repository's wiki pages, landing page first. struct WikiView: View { @State private var model: WikiViewModel init(client: GitbayClient, repo: String) { _model = State(initialValue: WikiViewModel(client: client, repoPath: repo)) } /// The landing page leads, then the rest in the order the server /// gave them — the same order the web's sidebar shows. private var ordered: [String] { guard let listing = model.state.value else { return [] } guard let home = listing.home else { return listing.pages } return [home] + listing.pages.filter { $0 != home } } var body: some View { List { ForEach(ordered, id: \.self) { page in NavigationLink(value: RepoRoute.wikiPage( repo: model.repoPath, page: page )) { HStack(spacing: 8) { Label(page, systemImage: "doc.text") .font(.gbSans(.subheadline)) if page == model.state.value?.home { GBChip("home", .gbAccent) } } } } } .overlay { LoadStateOverlay(state: model.state) } .navigationTitle("Wiki") .navigationBarTitleDisplayMode(.inline) .task { await model.load() } .refreshable { await model.load() } } } /// One wiki page, rendered by its format — the pages here are .org as /// often as .md, so ReadmeView picks the renderer. struct WikiPageView: View { @State private var model: WikiPageViewModel init(client: GitbayClient, repo: String, page: String) { _model = State(initialValue: WikiPageViewModel( client: client, repoPath: repo, page: page )) } var body: some View { ScrollView { if let page = model.state.value { if page.isBinary { ContentUnavailableView { Label("Not a page", systemImage: "doc.zipper") } description: { Text(page.file) } } else if let content = page.content { ReadmeView(name: page.file, content: content) .padding(.horizontal, 16) .padding(.vertical, 12) .frame(maxWidth: .infinity, alignment: .leading) } } } .overlay { LoadStateOverlay(state: model.state) } .navigationTitle(model.page) .navigationBarTitleDisplayMode(.inline) .task { await model.load() } .refreshable { await model.load() } } }