Skip to content
Snippets Groups Projects
RequestsFailedViewModel.swift 1.87 KiB
Newer Older
Bruno Muniz's avatar
Bruno Muniz committed
import HUD
import UIKit
Bruno Muniz's avatar
Bruno Muniz committed
import Models
import Combine
Bruno Muniz's avatar
Bruno Muniz committed
import Integration
import CombineSchedulers
import DependencyInjection

final class RequestsFailedViewModel {
    @Dependency private var session: SessionType

    var hudPublisher: AnyPublisher<HUDStatus, Never> {
        hudSubject.eraseToAnyPublisher()
Bruno Muniz's avatar
Bruno Muniz committed
    }

    var itemsPublisher: AnyPublisher<NSDiffableDataSourceSnapshot<Section, Request>, Never> {
        itemsSubject.eraseToAnyPublisher()
Bruno Muniz's avatar
Bruno Muniz committed
    }

    private var cancellables = Set<AnyCancellable>()
    private let hudSubject = CurrentValueSubject<HUDStatus, Never>(.none)
    private let itemsSubject = CurrentValueSubject<NSDiffableDataSourceSnapshot<Section, Request>, Never>(.init())
Bruno Muniz's avatar
Bruno Muniz committed

    var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler()

    init() {
        session.dbManager.fetchContactsPublisher(.init(authStatus: [.requestFailed]))
            .assertNoFailure()
            .map { data -> NSDiffableDataSourceSnapshot<Section, Request> in
                var snapshot = NSDiffableDataSourceSnapshot<Section, Request>()
                snapshot.appendSections([.appearing])
                snapshot.appendItems(data.map { Request.contact($0) }, toSection: .appearing)
                return snapshot
            }.sink { [unowned self] in itemsSubject.send($0) }
Bruno Muniz's avatar
Bruno Muniz committed
            .store(in: &cancellables)
    }

    func didTapStateButtonFor(request: Request) {
        guard case let .contact(contact) = request, request.status == .failedToRequest else { return }
Bruno Muniz's avatar
Bruno Muniz committed

        hudSubject.send(.on(nil))
Bruno Muniz's avatar
Bruno Muniz committed
        backgroundScheduler.schedule { [weak self] in
            guard let self = self else { return }

            do {
                try self.session.retryRequest(contact)
                self.hudSubject.send(.none)
Bruno Muniz's avatar
Bruno Muniz committed
            } catch {
                self.hudSubject.send(.error(.init(with: error)))