// // EditListSearchResultsContainerViewController.swift // Tusker // // Created by Shadowfacts on 11/11/22. // Copyright © 2022 Shadowfacts. All rights reserved. // import UIKit import Combine class EditListSearchResultsContainerViewController: UIViewController { private let mastodonController: MastodonController private let didSelectAccount: (String) -> Void private let searchResultsController: SearchResultsViewController private let searchFollowingController: EditListSearchFollowingViewController var mode = Mode.search { willSet { currentViewController.removeViewAndController() } didSet { embedChild(currentViewController) } } var currentViewController: UIViewController { switch mode { case .search: return searchResultsController case .following: return searchFollowingController } } private var currentQuery: String? private var searchSubject = PassthroughSubject() private var cancellables = Set() init(mastodonController: MastodonController, didSelectAccount: @escaping (String) -> Void) { self.mastodonController = mastodonController self.didSelectAccount = didSelectAccount self.searchResultsController = SearchResultsViewController(mastodonController: mastodonController, resultTypes: [.accounts]) self.searchFollowingController = EditListSearchFollowingViewController(mastodonController: mastodonController, didSelectAccount: didSelectAccount) super.init(nibName: nil, bundle: nil) self.searchResultsController.delegate = self } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() embedChild(currentViewController) searchSubject .debounce(for: .milliseconds(500), scheduler: RunLoop.main) .sink { [unowned self] in self.performSearch(query: $0) } .store(in: &cancellables) } func performSearch(query: String?) { guard var query = query?.trimmingCharacters(in: .whitespacesAndNewlines) else { return } if query.starts(with: "@") { query = String(query.dropFirst()) } guard query != self.currentQuery else { return } self.currentQuery = query switch mode { case .search: searchResultsController.performSearch(query: query) case .following: searchFollowingController.updateQuery(query) } } enum Mode: Equatable { case search, following } } extension EditListSearchResultsContainerViewController: UISearchResultsUpdating { func updateSearchResults(for searchController: UISearchController) { searchSubject.send(searchController.searchBar.text) } } extension EditListSearchResultsContainerViewController: UISearchBarDelegate { func searchBarTextDidEndEditing(_ searchBar: UISearchBar) { performSearch(query: searchBar.text) } func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { mode = selectedScope == 0 ? .search : .following performSearch(query: searchBar.text) } } extension EditListSearchResultsContainerViewController: SearchResultsViewControllerDelegate { func selectedSearchResult(account accountID: String) { didSelectAccount(accountID) } }