diff options
| author | Christian Cleberg <[email protected]> | 2026-04-12 00:15:13 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-12 00:15:13 -0500 |
| commit | cb1ea5ea4f163d87053285d3fb7999b12a3558b9 (patch) | |
| tree | 84b562d12e642ff494194387b1b4e1d15b065eb0 /Hutch/Views/More | |
| parent | 1c5a417277d986ee6fb7dc9dff0332338bdf6f3e (diff) | |
| download | hutch-2.13.1.tar.gz hutch-2.13.1.tar.bz2 hutch-2.13.1.zip | |
harden system status and app reliabilityv2.13.1
Diffstat (limited to 'Hutch/Views/More')
| -rw-r--r-- | Hutch/Views/More/MoreView.swift | 27 | ||||
| -rw-r--r-- | Hutch/Views/More/MoreViewModel.swift | 39 |
2 files changed, 64 insertions, 2 deletions
diff --git a/Hutch/Views/More/MoreView.swift b/Hutch/Views/More/MoreView.swift index 284b1ad..6325954 100644 --- a/Hutch/Views/More/MoreView.swift +++ b/Hutch/Views/More/MoreView.swift @@ -7,6 +7,7 @@ struct MoreView: View { ("chat.sr.ht", SRHTWebURL.chat) ] + @State private var viewModel: MoreViewModel? @State private var showAccountSwitcher = false var body: some View { @@ -29,9 +30,14 @@ struct MoreView: View { NavigationLink(value: MoreRoute.pastes) { Label("Pastes", systemImage: "doc.on.clipboard") } - + NavigationLink(value: MoreRoute.systemStatus) { - Label("System Status", systemImage: "server.rack") + SystemStatusSummaryRow( + snapshot: viewModel?.systemStatusSnapshot, + isLoading: viewModel?.isLoadingSystemStatus ?? true, + errorMessage: viewModel?.systemStatusErrorMessage, + isShowingStaleData: viewModel?.isShowingStaleSystemStatus ?? false + ) } } @@ -58,6 +64,12 @@ struct MoreView: View { } } .navigationTitle("More") + .refreshable { + await ensureViewModel().loadSystemStatus(forceRefresh: true) + } + .task { + await ensureViewModel().loadIfNeeded() + } .toolbar { ToolbarItem(placement: .topBarTrailing) { Button { @@ -71,4 +83,15 @@ struct MoreView: View { AccountSwitcherView() } } + + @MainActor + private func ensureViewModel() -> MoreViewModel { + if let viewModel { + return viewModel + } + + let newViewModel = MoreViewModel(repository: appState.systemStatusRepository) + viewModel = newViewModel + return newViewModel + } } diff --git a/Hutch/Views/More/MoreViewModel.swift b/Hutch/Views/More/MoreViewModel.swift new file mode 100644 index 0000000..8f23975 --- /dev/null +++ b/Hutch/Views/More/MoreViewModel.swift @@ -0,0 +1,39 @@ +import Foundation + +@Observable +@MainActor +final class MoreViewModel { + private let repository: SystemStatusRepository + + private(set) var systemStatusSnapshot: SystemStatusSnapshot? + private(set) var isLoadingSystemStatus = false + private(set) var isShowingStaleSystemStatus = false + private(set) var systemStatusErrorMessage: String? + + init(repository: SystemStatusRepository) { + self.repository = repository + } + + func loadIfNeeded() async { + guard systemStatusSnapshot == nil, !isLoadingSystemStatus else { return } + await loadSystemStatus() + } + + func loadSystemStatus(forceRefresh: Bool = false) async { + isLoadingSystemStatus = true + defer { isLoadingSystemStatus = false } + isShowingStaleSystemStatus = false + systemStatusErrorMessage = nil + + do { + let result = try await repository.snapshotResult(forceRefresh: forceRefresh) + systemStatusSnapshot = result.value + isShowingStaleSystemStatus = result.isStale + systemStatusErrorMessage = result.isStale ? result.refreshErrorMessage : nil + } catch { + if systemStatusSnapshot == nil { + systemStatusErrorMessage = error.userFacingMessage + } + } + } +} |
