// // RecipientsViewController.swift // GME Remit // // Created by InKwon James Kim on 08/08/2019. //Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. // import UIKit import RxSwift import RxCocoa import Localize_Swift class RecipientsViewController: UIViewController { struct StringConstant { static let swipeText = "" static let sendMoneyText = "Send Money" static let newRecipeintText = "New Recipient" static let navBarTitle = "Select Recipient" } // MARK: Properties var viewModel: RecipientsViewModel! private let disposeBag = DisposeBag() private lazy var editTrigger = PublishSubject() private lazy var deleteTrigger = PublishSubject() private let impact = UISelectionFeedbackGenerator() // MARK: Computed Properties // MARK: IBOutlets @IBOutlet private weak var tableView: UITableView! @IBOutlet private weak var viewAddRecipient: UIView! @IBOutlet private weak var newRecipeintLabel: UILabel! @IBOutlet private weak var noRecipientLabel: UILabel! @IBOutlet private var addRecipientTapGestureRecognizer: UITapGestureRecognizer! @IBOutlet private weak var searchBar: UISearchBar! // MARK: VC's Life cycle override func viewDidLoad() { super.viewDidLoad() setup() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationItem.title = "recipient_listing_title_text".localized() setupNormalNavigation() setupNavigationShadow(isUse: false) configureLanguage() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.navigationItem.title = "" setupNavigationShadow(isUse: true) view.endEditing(true) } // MARK: IBActions override func setupTabItem() { let image = UIImage.init(named: "ic-sendmoney") self.tabBarItem = UITabBarItem( title: "send_money_title_text".localized(), image: image, selectedImage: nil ) self.tabBarItem.titlePositionAdjustment = UIOffset( horizontal: 0, vertical: UI_USER_INTERFACE_IDIOM() == .pad ? 2 : -6 ) } } // MARK: Other Functions extension RecipientsViewController { func configureLanguage() { self.newRecipeintLabel.text = "new_recipient".localized() self.searchBar.placeholder = "search_text".localized() } private func setup() { // all setup should be done here viewAddRecipient.hero.id = "setupRecipient" let colorOption = [NSAttributedString.Key.foregroundColor : UIColor.themeWhite] let title = NSAttributedString(string: "pull to refresh", attributes: colorOption) let refreshControl = UIRefreshControl() refreshControl.attributedTitle = title refreshControl.backgroundColor = .themeBlue refreshControl.tintColor = .themeWhite refreshControl.layer.cornerRadius = 5 tableView.refreshControl = refreshControl tableView.separatorColor = .themeBorderColor setBinding() NotificationCenter.default.addObserver( self, selector: #selector(setupTabItem), name: NSNotification.Name(LCLLanguageChangeNotification), object: nil ) } private func setBinding() { let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:))) .mapToVoid() .asDriverOnErrorJustComplete() let needEditTrigger = PublishSubject() let input = RecipientsViewModel.Input( fetchTrigger: viewWillAppear, refreshTrigger: tableView.refreshControl!.rx.controlEvent(.valueChanged).asDriver(), addTrigger: addRecipientTapGestureRecognizer.rx.event.mapToVoid().asDriverOnErrorJustComplete(), selectTrigger: tableView.rx.itemSelected.asDriver(), editTrigger: editTrigger.asDriverOnErrorJustComplete(), deleteTrigger: deleteTrigger.asDriverOnErrorJustComplete(), needEditTrigger: needEditTrigger.asDriverOnErrorJustComplete(), filterText: searchBar.rx.text.asDriverOnErrorJustComplete() ) addRecipientTapGestureRecognizer.rx.event.mapToVoid().asDriverOnErrorJustComplete() .drive(onNext: { [weak self] in guard let `self` = self else { return } self.impact.selectionChanged() }) .disposed(by: disposeBag) let output = viewModel.transform(input: input) output .recipients .map { $0.count != 0 } .drive(onNext: { [weak self] in guard let `self` = self else { return } self.noRecipientLabel.isHidden = $0 }) .disposed(by: disposeBag) output .recipients.drive( tableView.rx.items(cellIdentifier: "RecipientCell") ) { [weak self] (_, element: Recipient, cell: RecipientCell) in guard let `self` = self else { return } cell.setModel(with: element) cell.hero.modifiers = [.fade, .scale(0.7)] cell.delegate = self } .disposed(by: disposeBag) output .isError.drive( onNext: { [weak self] in guard let `self` = self else { return } self.alert(type: .error, message: $0.localizedDescription) } ).disposed(by: disposeBag) output .isProgress.drive( onNext: { [weak self] in guard let `self` = self else { return } $0 ? self.showProgressHud() : self.hideProgressHud() if !$0 && self.tableView.refreshControl!.isRefreshing { self.tableView.refreshControl?.endRefreshing() } } ).disposed(by: disposeBag) output .isNeedEdit .drive( onNext: { DispatchQueue.main.async { [weak self] in guard let `self` = self else { return } self.alertWithOkCancel( type: .normal, message: "recipient_profile_update_prompt_text".localized(), okTitle: "yes_text".localized(), cancelTitle: "no_text".localized(), okAction: { needEditTrigger.onNext(()) }, cancelAction: nil ) } }) .disposed(by: disposeBag) output .isPartnerChanged.drive( onNext: { DispatchQueue.main.async { [weak self] in guard let `self` = self else { return } self.alertWithOkCancel( type: .normal, message: "recipient_bank_update_prompt_text".localized(), okTitle: "ok_text".localized(), cancelTitle: "cancel_text".localized(), okAction: { needEditTrigger.onNext(()) }, cancelAction: nil ) } }) .disposed(by: disposeBag) tableView.rx.setDelegate(self).disposed(by: disposeBag) } } // MARK: - UITableViewDelegate extension RecipientsViewController: UITableViewDelegate { func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { view.endEditing(true) } } // MARK: - RecipientCellDelegate extension RecipientsViewController: RecipientCellDelegate { func edit(didSelect model: Recipient?) { guard let model = model else { return } self.editTrigger.onNext(model) } func delete(didSelect model: Recipient?) { self.alertWithOkCancel( message: "delete_recipient_confirmation_text".localized(), title: "alert_text".localized(), okAction: { guard let model = model else { return } self.deleteTrigger.onNext(model) }) } }