krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

remove-splash-highlighter: Hutch/Views/SystemStatus/SystemStatusViewModel.swift · raw

 1import Foundation
 2
 3@Observable
 4@MainActor
 5final class SystemStatusViewModel {
 6    private let repository: SystemStatusRepository
 7
 8    private(set) var snapshot: SystemStatusSnapshot?
 9    private(set) var recentIncidents: [StatusIncident] = []
10    private(set) var isLoading = false
11    private(set) var isShowingStaleData = false
12    private(set) var staleDataMessage: String?
13    var errorMessage: String?
14
15    init(repository: SystemStatusRepository) {
16        self.repository = repository
17    }
18
19    var hasContent: Bool {
20        snapshot != nil || !recentIncidents.isEmpty
21    }
22
23    func load(forceRefresh: Bool = false) async {
24        if !hasContent {
25            isLoading = true
26        }
27        defer { isLoading = false }
28
29        errorMessage = nil
30        staleDataMessage = nil
31        isShowingStaleData = false
32
33        async let snapshotTask = repository.snapshotResult(forceRefresh: forceRefresh)
34        async let incidentsTask = repository.recentIncidentsResult(forceRefresh: forceRefresh)
35
36        var refreshWarnings: [String] = []
37
38        do {
39            let result = try await snapshotTask
40            snapshot = result.value
41            if result.isStale {
42                isShowingStaleData = true
43                staleDataMessage = "Showing the last saved system status snapshot."
44                if let warning = result.refreshErrorMessage {
45                    refreshWarnings.append(warning)
46                }
47            }
48        } catch {
49            if snapshot == nil {
50                errorMessage = error.userFacingMessage
51            }
52        }
53
54        do {
55            let result = try await incidentsTask
56            recentIncidents = result.value
57            if result.isStale {
58                isShowingStaleData = true
59                staleDataMessage = staleDataMessage ?? "Showing the last saved incident history."
60                if let warning = result.refreshErrorMessage {
61                    refreshWarnings.append(warning)
62                }
63            }
64        } catch {
65            if errorMessage == nil && recentIncidents.isEmpty {
66                errorMessage = error.userFacingMessage
67            }
68        }
69
70        if hasContent, let firstWarning = refreshWarnings.first {
71            errorMessage = "Showing cached system status. \(firstWarning)"
72        }
73    }
74}