import Shared import Models import Combine import XXClient import Countries import InputField import Foundation import CombineSchedulers import XXMessengerClient import DependencyInjection struct OnboardingPhoneViewState: Equatable { var input: String = "" var confirmation: AttributeConfirmation? var status: InputField.ValidationStatus = .unknown(nil) var country: Country = .fromMyPhone() } final class OnboardingPhoneViewModel { @Dependency var messenger: Messenger @Dependency var hudController: HUDController var state: AnyPublisher<OnboardingPhoneViewState, Never> { stateRelay.eraseToAnyPublisher() } private let stateRelay = CurrentValueSubject<OnboardingPhoneViewState, Never>(.init()) var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler() func clearUp() { stateRelay.value.confirmation = nil } func didInput(_ string: String) { stateRelay.value.input = string validate() } func didChooseCountry(_ country: Country) { stateRelay.value.country = country validate() } func didGoForward() { stateRelay.value.confirmation = nil } func didTapNext() { hudController.show() backgroundScheduler.schedule { [weak self] in guard let self = self else { return } let content = "\(self.stateRelay.value.input)\(self.stateRelay.value.country.code)" do { let confirmationId = try self.messenger.ud.get()!.sendRegisterFact( .init(type: .phone, value: content) ) self.hudController.dismiss() self.stateRelay.value.confirmation = .init( content: content, confirmationId: confirmationId ) } catch { let xxError = CreateUserFriendlyErrorMessage.live(error.localizedDescription) self.hudController.show(.init(content: xxError)) } } } private func validate() { switch Validator.phone.validate((stateRelay.value.country.regex, stateRelay.value.input)) { case .success: stateRelay.value.status = .valid(nil) case .failure(let error): stateRelay.value.status = .invalid(error) } } }