Kurdtvs-Live-Kurdish-TV-Kur.../Mastodon/Scene/Search/SearchViewController.swift

254 lines
10 KiB
Swift
Raw Normal View History

2021-02-23 09:45:00 +01:00
//
// SearchViewController.swift
// Mastodon
//
2021-03-31 08:28:40 +02:00
// Created by sxiaojian on 2021/3/31.
2021-02-23 09:45:00 +01:00
//
2021-03-31 08:28:40 +02:00
import Combine
2021-04-06 09:25:04 +02:00
import GameplayKit
2021-04-01 14:54:57 +02:00
import MastodonSDK
import UIKit
2021-02-23 09:45:00 +01:00
final class SearchViewController: UIViewController, NeedsDependency {
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
2021-03-31 08:28:40 +02:00
var disposeBag = Set<AnyCancellable>()
private(set) lazy var viewModel = SearchViewModel(context: context, coordinator: coordinator)
2021-03-31 08:28:40 +02:00
let statusBar: UIView = {
let view = UIView()
view.backgroundColor = Asset.Colors.Background.navigationBar.color
return view
}()
2021-03-31 09:06:46 +02:00
let searchBar: UISearchBar = {
let searchBar = UISearchBar()
2021-03-31 13:29:54 +02:00
searchBar.placeholder = L10n.Scene.Search.Searchbar.placeholder
2021-04-06 10:42:45 +02:00
searchBar.tintColor = Asset.Colors.brandBlue.color
2021-03-31 13:29:54 +02:00
searchBar.translatesAutoresizingMaskIntoConstraints = false
let micImage = UIImage(systemName: "mic.fill")
searchBar.setImage(micImage, for: .bookmark, state: .normal)
searchBar.showsBookmarkButton = true
2021-04-06 09:25:04 +02:00
searchBar.scopeButtonTitles = [L10n.Scene.Search.Searching.Segment.all, L10n.Scene.Search.Searching.Segment.people, L10n.Scene.Search.Searching.Segment.hashtags]
searchBar.barTintColor = Asset.Colors.Background.navigationBar.color
2021-03-31 09:06:46 +02:00
return searchBar
}()
2021-03-31 13:29:54 +02:00
// recommend
2021-04-01 14:54:57 +02:00
let scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.showsVerticalScrollIndicator = false
scrollView.alwaysBounceVertical = true
scrollView.clipsToBounds = false
return scrollView
}()
let stackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fill
stackView.spacing = 0
stackView.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: 68, right: 0)
stackView.isLayoutMarginsRelativeArrangement = true
return stackView
}()
2021-04-07 15:01:32 +02:00
let hashtagCollectionView: UICollectionView = {
2021-04-01 14:54:57 +02:00
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
let view = ControlContainableCollectionView(frame: .zero, collectionViewLayout: flowLayout)
view.backgroundColor = .clear
view.showsHorizontalScrollIndicator = false
view.showsVerticalScrollIndicator = false
view.layer.masksToBounds = false
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let accountsCollectionView: UICollectionView = {
2021-03-31 13:29:54 +02:00
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
let view = ControlContainableCollectionView(frame: .zero, collectionViewLayout: flowLayout)
view.backgroundColor = .clear
view.showsHorizontalScrollIndicator = false
view.showsVerticalScrollIndicator = false
view.layer.masksToBounds = false
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// searching
let searchingTableView: UITableView = {
let tableView = UITableView()
2021-04-16 16:58:36 +02:00
tableView.backgroundColor = Asset.Colors.Background.systemBackground.color
tableView.rowHeight = UITableView.automaticDimension
tableView.separatorStyle = .singleLine
tableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
return tableView
}()
2021-04-07 13:49:33 +02:00
lazy var searchHeader: UIView = {
let view = UIView()
view.backgroundColor = Asset.Colors.Background.systemGroupedBackground.color
view.frame = CGRect(origin: .zero, size: CGSize(width: searchingTableView.frame.width, height: 56))
return view
}()
let recentSearchesLabel: UILabel = {
let label = UILabel()
label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold))
label.textColor = Asset.Colors.Label.primary.color
label.text = L10n.Scene.Search.Searching.recentSearch
return label
}()
let clearSearchHistoryButton: HighlightDimmableButton = {
let button = HighlightDimmableButton(type: .custom)
button.setTitleColor(Asset.Colors.brandBlue.color, for: .normal)
2021-04-07 13:49:33 +02:00
button.setTitle(L10n.Scene.Search.Searching.clear, for: .normal)
return button
}()
2021-02-23 09:45:00 +01:00
}
extension SearchViewController {
override func viewDidLoad() {
super.viewDidLoad()
let barAppearance = UINavigationBarAppearance()
barAppearance.configureWithTransparentBackground()
navigationItem.standardAppearance = barAppearance
navigationItem.compactAppearance = barAppearance
navigationItem.scrollEdgeAppearance = barAppearance
view.backgroundColor = Asset.Colors.Background.systemGroupedBackground.color
2021-03-31 13:29:54 +02:00
navigationItem.hidesBackButton = true
setupSearchBar()
2021-04-01 14:54:57 +02:00
setupScrollView()
setupHashTagCollectionView()
setupAccountsCollectionView()
setupSearchingTableView()
2021-04-06 09:25:04 +02:00
setupDataSource()
2021-04-07 13:49:33 +02:00
setupSearchHeader()
2021-04-01 14:54:57 +02:00
}
func setupSearchBar() {
searchBar.delegate = self
view.addSubview(searchBar)
2021-04-19 05:41:50 +02:00
searchBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
searchBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
searchBar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
searchBar.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
])
2021-04-19 05:41:50 +02:00
statusBar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(statusBar)
NSLayoutConstraint.activate([
statusBar.topAnchor.constraint(equalTo: view.topAnchor),
statusBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
statusBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
statusBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 3),
])
}
2021-04-01 14:54:57 +02:00
func setupScrollView() {
2021-04-19 05:41:50 +02:00
scrollView.translatesAutoresizingMaskIntoConstraints = false
2021-04-01 14:54:57 +02:00
view.addSubview(scrollView)
2021-04-19 05:41:50 +02:00
NSLayoutConstraint.activate([
scrollView.frameLayoutGuide.topAnchor.constraint(equalTo: searchBar.bottomAnchor),
2021-04-01 14:54:57 +02:00
scrollView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
scrollView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
scrollView.frameLayoutGuide.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: view.widthAnchor),
2021-04-01 14:54:57 +02:00
])
2021-04-19 05:41:50 +02:00
stackView.translatesAutoresizingMaskIntoConstraints = false
2021-04-01 14:54:57 +02:00
scrollView.addSubview(stackView)
2021-04-19 05:41:50 +02:00
NSLayoutConstraint.activate([
2021-04-01 14:54:57 +02:00
stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
stackView.widthAnchor.constraint(equalTo: scrollView.contentLayoutGuide.widthAnchor),
scrollView.contentLayoutGuide.bottomAnchor.constraint(equalTo: stackView.bottomAnchor),
])
2021-03-31 13:29:54 +02:00
}
2021-04-06 09:25:04 +02:00
func setupDataSource() {
2021-04-07 15:01:32 +02:00
viewModel.hashtagDiffableDataSource = RecommendHashTagSection.collectionViewDiffableDataSource(for: hashtagCollectionView)
2021-04-09 13:39:35 +02:00
viewModel.accountDiffableDataSource = RecommendAccountSection.collectionViewDiffableDataSource(for: accountsCollectionView, delegate: self, managedObjectContext: context.managedObjectContext)
2021-04-07 13:49:33 +02:00
viewModel.searchResultDiffableDataSource = SearchResultSection.tableViewDiffableDataSource(for: searchingTableView, dependency: self)
2021-04-06 09:25:04 +02:00
}
}
extension SearchViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == searchingTableView {
handleScrollViewDidScroll(scrollView)
}
}
2021-03-31 13:29:54 +02:00
}
2021-03-31 09:06:46 +02:00
2021-03-31 13:29:54 +02:00
extension SearchViewController: UISearchBarDelegate {
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(true, animated: true)
searchBar.showsScopeBar = true
viewModel.isSearching.value = true
2021-03-31 13:29:54 +02:00
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(false, animated: true)
searchBar.showsScopeBar = false
viewModel.isSearching.value = true
2021-03-31 13:29:54 +02:00
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(false, animated: true)
searchBar.showsScopeBar = false
2021-03-31 13:29:54 +02:00
searchBar.text = ""
searchBar.resignFirstResponder()
viewModel.isSearching.value = false
2021-03-31 13:29:54 +02:00
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
viewModel.searchText.send(searchText)
2021-02-23 09:45:00 +01:00
}
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
switch selectedScope {
case 0:
viewModel.searchScope.value = Mastodon.API.Search.SearchType.default
case 1:
viewModel.searchScope.value = Mastodon.API.Search.SearchType.accounts
case 2:
viewModel.searchScope.value = Mastodon.API.Search.SearchType.hashtags
default:
break
}
}
2021-04-06 09:25:04 +02:00
func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {}
2021-02-23 09:45:00 +01:00
}
2021-04-01 14:54:57 +02:00
2021-04-06 09:25:04 +02:00
extension SearchViewController: LoadMoreConfigurableTableViewContainer {
2021-04-16 07:45:54 +02:00
typealias BottomLoaderTableViewCell = TimelineBottomLoaderTableViewCell
2021-04-06 09:25:04 +02:00
typealias LoadingState = SearchViewModel.LoadOldestState.Loading
var loadMoreConfigurableTableView: UITableView { searchingTableView }
var loadMoreConfigurableStateMachine: GKStateMachine { viewModel.loadoldestStateMachine }
}
2021-04-01 14:54:57 +02:00
#if canImport(SwiftUI) && DEBUG
import SwiftUI
struct SearchViewController_Previews: PreviewProvider {
static var previews: some View {
UIViewControllerPreview {
let viewController = SearchViewController()
return viewController
}
.previewLayout(.fixed(width: 375, height: 800))
}
}
#endif