gitbay/Builds/BuildListViewModel.swift

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

51 lines · 1474 bytes

 1import Foundation
 2import Observation
 3
 4/// `build list <repo>`.
 5@Observable
 6@MainActor
 7final class BuildListViewModel {
 8
 9    private(set) var state: LoadState<[Build]> = .loading
10    private(set) var actionError: String?
11    private(set) var working = false
12
13    private let client: GitbayClient
14    let repoPath: String
15
16    init(client: GitbayClient, repoPath: String) {
17        self.client = client
18        self.repoPath = repoPath
19    }
20
21    func load() async {
22        do {
23            let builds = try await client.readList(["build", "list", repoPath], of: Build.self)
24            state = builds.isEmpty
25                ? .empty("No builds. Builds run when a push touches a repo with a .gitbay/ job file.")
26                : .loaded(builds.sorted { $0.number > $1.number })
27        } catch {
28            state = .from(error)
29        }
30    }
31
32    /// The most recent job name, to prefill the trigger sheet.
33    var latestJob: String? {
34        state.value?.first?.job
35    }
36
37    /// `build trigger <owner/name> <job>` — queue a job now.
38    func trigger(job: String) async {
39        working = true
40        actionError = nil
41        defer { working = false }
42        do {
43            try await client.run(["build", "trigger", repoPath, job])
44            await load()
45        } catch let error as GitbayError {
46            actionError = error.userFacingMessage
47        } catch {
48            actionError = GitbayError.transport(error).userFacingMessage
49        }
50    }
51}