2019-12-17 05:22:25 +00:00
|
|
|
//
|
|
|
|
// ExploreViewController.swift
|
|
|
|
// Tusker
|
|
|
|
//
|
|
|
|
// Created by Shadowfacts on 12/14/19.
|
|
|
|
// Copyright © 2019 Shadowfacts. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
import Combine
|
2019-12-17 23:48:29 +00:00
|
|
|
import Pachyderm
|
2019-12-17 05:22:25 +00:00
|
|
|
|
|
|
|
class ExploreViewController: EnhancedTableViewController {
|
|
|
|
|
|
|
|
var dataSource: UITableViewDiffableDataSource<Section, Item>!
|
|
|
|
|
|
|
|
var resultsController: SearchResultsViewController!
|
|
|
|
var searchController: UISearchController!
|
|
|
|
|
|
|
|
let searchSubject = PassthroughSubject<String?, Never>()
|
|
|
|
|
|
|
|
init() {
|
|
|
|
super.init(style: .insetGrouped)
|
|
|
|
|
|
|
|
title = NSLocalizedString("Explore", comment: "explore tab title")
|
|
|
|
tabBarItem.image = UIImage(systemName: "magnifyingglass")
|
|
|
|
}
|
|
|
|
|
|
|
|
required init?(coder: NSCoder) {
|
|
|
|
fatalError("init(coder:) has not been implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
override func viewDidLoad() {
|
|
|
|
super.viewDidLoad()
|
|
|
|
|
|
|
|
tableView.register(UINib(nibName: "BasicTableViewCell", bundle: .main), forCellReuseIdentifier: "basicCell")
|
|
|
|
|
|
|
|
dataSource = DataSource(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in
|
|
|
|
switch item {
|
|
|
|
case .bookmarks:
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: "basicCell", for: indexPath)
|
|
|
|
cell.imageView!.image = UIImage(systemName: "bookmark.fill")
|
|
|
|
cell.textLabel!.text = NSLocalizedString("Bookmarks", comment: "bookmarks nav item title")
|
|
|
|
cell.accessoryType = .disclosureIndicator
|
|
|
|
return cell
|
|
|
|
|
2019-12-17 23:48:29 +00:00
|
|
|
case let .list(list):
|
2019-12-17 05:22:25 +00:00
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: "basicCell", for: indexPath)
|
|
|
|
cell.imageView!.image = nil
|
2019-12-17 23:48:29 +00:00
|
|
|
cell.textLabel!.text = list.title
|
2019-12-17 05:22:25 +00:00
|
|
|
cell.accessoryType = .disclosureIndicator
|
|
|
|
return cell
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
|
|
|
snapshot.appendSections([.bookmarks, .lists])
|
|
|
|
snapshot.appendItems([.bookmarks], toSection: .bookmarks)
|
|
|
|
// the initial, static items should not be displayed with an animation
|
|
|
|
UIView.performWithoutAnimation {
|
|
|
|
dataSource.apply(snapshot)
|
|
|
|
}
|
|
|
|
|
|
|
|
resultsController = SearchResultsViewController()
|
|
|
|
resultsController.exploreNavigationController = self.navigationController!
|
|
|
|
searchController = UISearchController(searchResultsController: resultsController)
|
|
|
|
searchController.searchResultsUpdater = resultsController
|
|
|
|
searchController.searchBar.autocapitalizationType = .none
|
|
|
|
searchController.searchBar.delegate = resultsController
|
|
|
|
definesPresentationContext = true
|
|
|
|
|
|
|
|
navigationItem.searchController = searchController
|
|
|
|
navigationItem.hidesSearchBarWhenScrolling = false
|
2019-12-17 23:48:29 +00:00
|
|
|
|
|
|
|
let request = MastodonController.client.getLists()
|
|
|
|
MastodonController.client.run(request) { (response) in
|
|
|
|
guard case let .success(lists, _) = response else {
|
|
|
|
fatalError()
|
|
|
|
}
|
|
|
|
|
|
|
|
var snapshot = self.dataSource.snapshot()
|
|
|
|
snapshot.appendItems(lists.map { .list($0) }, toSection: .lists)
|
|
|
|
|
|
|
|
DispatchQueue.main.async {
|
|
|
|
self.dataSource.apply(snapshot)
|
|
|
|
}
|
|
|
|
}
|
2019-12-17 05:22:25 +00:00
|
|
|
}
|
2019-12-17 23:48:29 +00:00
|
|
|
|
2019-12-17 05:22:25 +00:00
|
|
|
// MARK: - Table view delegate
|
|
|
|
|
|
|
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
|
|
switch dataSource.itemIdentifier(for: indexPath) {
|
|
|
|
case nil:
|
|
|
|
return
|
|
|
|
|
|
|
|
case .bookmarks:
|
|
|
|
show(BookmarksTableViewController(), sender: nil)
|
|
|
|
|
2019-12-17 23:48:29 +00:00
|
|
|
case let .list(list):
|
|
|
|
show(ListTimelineViewController(for: list), sender: nil)
|
2019-12-17 05:22:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
extension ExploreViewController {
|
|
|
|
enum Section: CaseIterable {
|
|
|
|
case bookmarks
|
|
|
|
case lists
|
|
|
|
}
|
|
|
|
enum Item: Hashable {
|
|
|
|
case bookmarks
|
2019-12-17 23:48:29 +00:00
|
|
|
case list(List)
|
|
|
|
|
|
|
|
static func == (lhs: ExploreViewController.Item, rhs: ExploreViewController.Item) -> Bool {
|
|
|
|
switch (lhs, rhs) {
|
|
|
|
case (.bookmarks, .bookmarks):
|
|
|
|
return true
|
|
|
|
case let (.list(a), .list(b)):
|
|
|
|
return a.id == b.id
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func hash(into hasher: inout Hasher) {
|
|
|
|
switch self {
|
|
|
|
case .bookmarks:
|
|
|
|
hasher.combine("bookmarks")
|
|
|
|
case let .list(list):
|
|
|
|
hasher.combine("list")
|
|
|
|
hasher.combine(list.id)
|
|
|
|
}
|
|
|
|
}
|
2019-12-17 05:22:25 +00:00
|
|
|
}
|
|
|
|
class DataSource: UITableViewDiffableDataSource<Section, Item> {
|
|
|
|
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
|
|
|
switch section {
|
|
|
|
case 1:
|
|
|
|
return NSLocalizedString("Lists", comment: "explore lists section title")
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|