You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

180 lines
5.5 KiB

//
// RecipientsViewModel.swift
// GME Remit
//
// Created by InKwon James Kim on 08/08/2019.
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
//
import RxSwift
import RxCocoa
class RecipientsViewModel: ViewModelType {
var presenter: RecipientsModuleInterface?
struct Input {
let fetchTrigger: Driver<Void>
let refreshTrigger: Driver<Void>
let addTrigger: Driver<Void>
let selectTrigger: Driver<IndexPath>
let editTrigger: Driver<Recipient>
let deleteTrigger: Driver<Recipient>
let needEditTrigger: Driver<Void>
let filterText: Driver<String?>
}
struct Output {
let recipients: Driver<[Recipient]>
let isNeedEdit: Driver<Void>
let isPartnerChanged: Driver<Void>
let isError: Driver<Error>
let isProgress: Driver<Bool>
}
private let disposeBag = DisposeBag()
private var selectedRecipientID: String?
private let recipientsLinker = BehaviorSubject<[Recipient]>(value: [])
private let filteredRecipientLinker = BehaviorSubject<[Recipient]>(value: [])
private let accountsLinker = BehaviorSubject<[Account]>(value: [])
private let editLinker = PublishSubject<Recipient>()
private let deleteLinker = PublishSubject<Recipient>()
private let progressLinker = PublishSubject<Bool>()
private let errorLinker = PublishSubject<Error>()
private var selectedRecipient: Recipient?
private var isNeedEditRecipient = PublishSubject<Void>()
private var isPartnerChanged = PublishSubject<Void>()
func transform(input: Input) -> Output {
input
.fetchTrigger
.drive(onNext: { [weak self] in guard let `self` = self else { return }
self.presenter?.fetchRecipients(isRefresh: false)
})
.disposed(by: disposeBag)
input
.refreshTrigger
.drive(onNext: { [weak self] in guard let `self` = self else { return }
self.presenter?.fetchRecipients(isRefresh: true)
})
.disposed(by: disposeBag)
let recipients = Observable.combineLatest(
recipientsLinker, input.filterText.asObservable()
) { recipients, searchText -> [Recipient] in
guard let searchText = searchText, searchText != "" else {
return recipients
}
return recipients.filter {( $0.fullName?.lowercased().contains(searchText.lowercased()) ?? false )}
}.asDriverOnErrorJustComplete()
input.selectTrigger
.withLatestFrom(recipients) { (indexPath, recipients) -> Recipient in
return recipients[indexPath.row]
}
.drive(onNext: { [weak self] in guard let `self` = self else { return }
self.selectedRecipient = $0
guard let paymentMode = self.selectedRecipient?.paymentMethod else {
self.isNeedEditRecipient.onNext(())
return
}
if paymentMode.id == nil {
self.isNeedEditRecipient.onNext(())
return
}
if self.selectedRecipient?.isPartnerChanged == "1" {
self.isPartnerChanged.onNext(())
return
}
let accounts = try? self.accountsLinker.value()
self.presenter?.openSelectAccount(with: accounts ?? [])
})
.disposed(by: disposeBag)
input.editTrigger
.drive(onNext: { [weak self] in guard let `self` = self else { return }
self.presenter?.openEditRecipient(who: $0, with: self)
})
.disposed(by: disposeBag)
input.deleteTrigger
.drive(onNext: { [weak self] in guard let `self` = self else { return }
self.presenter?.deleteRecipient(who: $0)
})
.disposed(by: disposeBag)
input.addTrigger
.drive(onNext: { [weak self] in guard let `self` = self else { return }
self.presenter?.openAddRecipient(with: self)
})
.disposed(by: disposeBag)
input.needEditTrigger
.drive(onNext: { [weak self] in guard let `self` = self else { return }
guard let recipient = self.selectedRecipient else {return}
self.presenter?.openEditRecipient(who: recipient, with: self)
})
.disposed(by: disposeBag)
return Output(
recipients: recipients,
isNeedEdit: isNeedEditRecipient.asDriverOnErrorJustComplete(),
isPartnerChanged: isPartnerChanged.asDriverOnErrorJustComplete(),
isError: errorLinker.asDriverOnErrorJustComplete(),
isProgress: progressLinker.asDriverOnErrorJustComplete()
)
}
}
// MARK: - RecipientsViewModelInterface
extension RecipientsViewModel: RecipientsViewModelInterface {
func setSelectedAccount(_ account: Account) {
guard let recipient = selectedRecipient else { return }
presenter?.goNextStep(who: recipient, with: account)
}
func setRecipients(using model: [Recipient]) {
recipientsLinker.onNext(model)
guard let selectedID = selectedRecipientID else {
return
}
selectedRecipient = model.filter({$0.receiverID == selectedID}).first
let accounts = try? self.accountsLinker.value()
presenter?.openSelectAccount(with: accounts ?? [])
selectedRecipientID = nil
}
func setAccounts(using model: [Account]) {
accountsLinker.onNext(model)
}
func setError(with error: Error) {
errorLinker.onNext(error)
}
func progress(isShow: Bool) {
progressLinker.onNext(isShow)
}
}
extension RecipientsViewModel: SetupRecipientDelegate {
func setupRecieient(_ viewController: SetupRecipientViewController, didSelectRecipientID: String?) {
selectedRecipientID = didSelectRecipientID
presenter?.fetchRecipients(isRefresh: true)
}
}