Tusker/Tusker/Screens/Lists/EditListSearchResultsContai...

116 lines
3.6 KiB
Swift

//
// 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<String?, Never>()
private var cancellables = Set<AnyCancellable>()
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)
}
}