SuggestedSearchViewController

mail@pastecode.io avatar
unknown
plain_text
2 years ago
4.7 kB
2
Indexable
Never
// Created for Kimia Farma Member App. By @overheardswift.
// Copyright © 2021. All rights reserved.

import Declayout

class SuggestedSearchViewController: UIViewController {
  
  private var pendingRequestWorkItem: DispatchWorkItem?
  
  var searchView: SearchBarItemView?
  
  var searchQuery: String? {
    didSet {
      guard let query = searchQuery else { return }
      perform { [weak self] in
        self?.load(query: query)
      }
    }
  }
  
  var presenter: SuggestedSearchPresenter!
  
  private var suggestionListHeight: NSLayoutConstraint?
  
  private lazy var scrollView = ScrollViewContainer.make {
    $0.setBackgroundColor(color: R.color.kfmWhite())
    $0.setSpacingBetweenItems(to: 5)
    $0.top(to: view, of: .top(true))
    $0.horizontalPadding(to: view)
    $0.bottom(to: view)
  }
  
  private lazy var suggestionList = UITableView.make {
    $0.register(SuggestionCell.self, forCellReuseIdentifier: SuggestionCell.identifier)
    $0.separatorStyle = .none
    $0.isScrollEnabled = false
  }
    
    private lazy var subscribedPharmacyView = UIView.make {
        $0.backgroundColor = .clear
        $0.isHidden = true
    }
    
    private lazy var subscribedPharmacyStackView = UIStackView.make {
        $0.backgroundColor = .clear
        $0.axis = .vertical
        $0.distribution = .fill
        $0.alignment = .fill
        $0.spacing = 4
        $0.horizontalPadding(to: subscribedPharmacyView, 24)
        $0.verticalPadding(to: subscribedPharmacyView, 8)
    }
    
    private lazy var titleLabel = UILabel.make {
        $0.font = .systemFont(ofSize: 14, weight: .regular)
        $0.textColor = .kfmBlack
    }
    
    private lazy var subtitleLabel = UILabel.make {
        $0.font = .systemFont(ofSize: 14, weight: .regular)
        $0.textColor = .kfmBlueSea
    }
  
  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.suggestionListHeight?.constant = self.suggestionList.contentSize.height
    self.scrollView.layoutIfNeeded()
  }
  
  override func viewDidLoad() {
    super.viewDidLoad()
    configureSubviews()
    configureCallbacks()
  }
  
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    suggestionList.addObserver(self, forKeyPath: UITableView.contentSizeKeyPath, options: .new, context: nil)
  }
  
  override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let newvalue = change?[.newKey], keyPath == UITableView.contentSizeKeyPath {
      let newsize  = newvalue as! CGSize
      self.updateTableViewContentSize(size: newsize.height)
    }
  }
  
  // MARK: - Helpers
  private func updateTableViewContentSize(size: CGFloat) {
    DispatchQueue.main.async {
      self.scrollView.layoutIfNeeded()
      self.suggestionListHeight?.constant = size
      if let constraint = self.suggestionListHeight {
        self.suggestionList.addConstraint(constraint)
        constraint.activated()
      }
    }
  }
  
  private func configureSubviews() {
    suggestionListHeight = suggestionList.heightAnchor.constraint(equalToConstant: 0)
    view.addSubviews([
      scrollView.addArrangedSubViews([
        suggestionList,
        subscribedPharmacyView.addSubviews([
            subscribedPharmacyStackView.addArrangedSubviews([
                titleLabel,
                subtitleLabel
            ])
        ])
      ])
    ])
  }
  
  private func configureCallbacks() {
    self.scrollView.touchCallback = { [weak self] in
      self?.searchView?.searchController.searchBar.resignFirstResponder()
    }
  }
  
  private func load(query: String) {
    self.presenter.loadSuggestion(query: query)
    self.presenter.searchQuery.value = query
    self.presenter.dataSource.observe(on: self) { [weak self] dataSource in
      guard let self = self, let dataSource = dataSource else { return }
      self.suggestionList.dataSourceDelegate(dataSource).reloads()
    }
      self.titleLabel.text = "Cari \"\(query)\""
      self.subtitleLabel.text = "di Apotek Langganan"
      let profile = SharedProfile.shared.userProfile
      if let subscribedPharmacy = profile?.subscribedPharmacy, subscribedPharmacy.isNotEmpty {
          self.subscribedPharmacyView.isHidden = false
      }
  }

  private func perform(withDelay milliseconds: Int = 1000, completion: @escaping () -> Void) {
    pendingRequestWorkItem?.cancel()
    
    let requestWorkItem = DispatchWorkItem { completion() }
    
    pendingRequestWorkItem = requestWorkItem
    DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(milliseconds), execute: requestWorkItem)
  }
}