Files
element-x-ios/ElementX/Sources/AppHooks/HealthChat/HealthChatAccountStatusLoader.swift
T
Sedat Qaja be803d0542 fix(healthchat): refresh the account status whenever settings appears
The banner kept telling the user to complete a profile they had just
completed, and nothing was fetched until the screen was actually shown.
2026-10-12 13:13:00 +02:00

64 lines
2.1 KiB
Swift

//
// Copyright 2026 Novaloop AG
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Foundation
import Observation
/// Loads the own account's status for the banners that advertise it.
/// Nothing is fetched until ``load()`` is called, so the settings screen decides when.
@Observable
final class HealthChatAccountStatusLoader {
private(set) var status: HealthChatAccountStatus = .unknown
@ObservationIgnored private let apiService: HealthChatAPIServiceProtocol?
/// The load in flight — await this in tests before asserting.
@ObservationIgnored @CancellableTask private(set) var loadingTask: Task<Void, Never>?
init(apiService: HealthChatAPIServiceProtocol) {
self.apiService = apiService
}
/// Creates a loader with a fixed status, for previews.
init(status: HealthChatAccountStatus) {
self.status = status
apiService = nil
}
/// Fetches the status again, replacing a load still in flight.
func load() {
guard let apiService else { return }
loadingTask = Task { await load(from: apiService) }
}
// MARK: - Private
private func load(from apiService: HealthChatAPIServiceProtocol) async {
// Every failure below leaves the status untouched: a banner must not report an error.
guard case let .success(profile) = await apiService.ownProfile(), !Task.isCancelled else {
return
}
guard profile.isApproved else {
status = .pendingApproval
return
}
guard case let .success(completeness) = await apiService.profileCompleteness(), !Task.isCancelled else {
return
}
// The server words the hint itself; without one there is nothing to show.
guard !completeness.isComplete, let message = completeness.message else {
status = .ok
return
}
status = .incompleteProfile(message: message)
}
}