// // 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 Combine import SwiftUI typealias HealthChatInviteMemberScreenViewModelType = StateStoreViewModelV2 class HealthChatInviteMemberScreenViewModel: HealthChatInviteMemberScreenViewModelType, HealthChatInviteMemberScreenViewModelProtocol { private let apiService: HealthChatAPIServiceProtocol private let userIndicatorController: UserIndicatorControllerProtocol private let actionsSubject: PassthroughSubject = .init() var actionsPublisher: AnyPublisher { actionsSubject.eraseToAnyPublisher() } init(apiService: HealthChatAPIServiceProtocol, userIndicatorController: UserIndicatorControllerProtocol) { self.apiService = apiService self.userIndicatorController = userIndicatorController super.init(initialViewState: HealthChatInviteMemberScreenViewState(), mediaProvider: nil) } // MARK: - Public override func process(viewAction: HealthChatInviteMemberScreenViewAction) { switch viewAction { case .send: Task { await sendInvitation() } case .cancel: actionsSubject.send(.dismiss) } } // MARK: - Private private func sendInvitation() async { let indicatorID = "\(Self.self)-Sending" defer { userIndicatorController.retractIndicatorWithId(indicatorID) } userIndicatorController.submitIndicator(UserIndicator(id: indicatorID, type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false), title: L10n.commonLoading, persistent: true), delay: .milliseconds(100)) let email = state.bindings.email.trimmingCharacters(in: .whitespaces) let personalNote = state.bindings.personalNote.trimmingCharacters(in: .whitespacesAndNewlines) switch await apiService.inviteMember(email: email, personalNote: personalNote) { case .success: userIndicatorController.submitIndicator(UserIndicator(title: HealthChatL10n.screenInviteMemberSuccess, icon: \.check)) actionsSubject.send(.dismiss) case .failure: state.bindings.alertInfo = .init(id: .sendFailed) } } }