a native ios client for gitbay

client ios swift

https://gitbay.org

gitbay/Repos/WikiViewModel.swift

ui-smoke
gitbay-ios/gitbay/Repos/WikiViewModel.swift history · blame · raw

78 lines · 1990 bytes

 1import Foundation
 2import Observation
 3
 4/// `wiki list`  the pages, and which one is the landing page.
 5nonisolated struct WikiListing: Decodable, Sendable, Hashable {
 6    let path: String
 7    let home: String?
 8    let pages: [String]
 9}
10
11/// `wiki show`  one page's source. Rendered by format, as a README is.
12nonisolated struct WikiPage: Decodable, Sendable, Hashable {
13    let path: String
14    let page: String
15    let file: String
16    let size: Int
17    let binary: Bool?
18    let content: String?
19
20    var isBinary: Bool { binary ?? false }
21}
22
23/// A repository's wiki. The pages live in a companion repo and are
24/// edited by pushing to it, so this is a reading surface only  the
25/// same write interface every surface has.
26@Observable
27@MainActor
28final class WikiViewModel {
29
30    private(set) var state: LoadState<WikiListing> = .loading
31
32    private let client: GitbayClient
33    let repoPath: String
34
35    init(client: GitbayClient, repoPath: String) {
36        self.client = client
37        self.repoPath = repoPath
38    }
39
40    func load() async {
41        do {
42            let listing = try await client.read(
43                ["wiki", "list", repoPath], as: WikiListing.self)
44            state = listing.pages.isEmpty
45                ? .empty("This wiki has no pages yet.")
46                : .loaded(listing)
47        } catch {
48            state = .from(error)
49        }
50    }
51}
52
53/// One wiki page.
54@Observable
55@MainActor
56final class WikiPageViewModel {
57
58    private(set) var state: LoadState<WikiPage> = .loading
59
60    private let client: GitbayClient
61    let repoPath: String
62    let page: String
63
64    init(client: GitbayClient, repoPath: String, page: String) {
65        self.client = client
66        self.repoPath = repoPath
67        self.page = page
68    }
69
70    func load() async {
71        do {
72            state = .loaded(try await client.read(
73                ["wiki", "show", repoPath, page], as: WikiPage.self))
74        } catch {
75            state = .from(error)
76        }
77    }
78}