forked from shadowfacts/Tusker
parent
a75862b5cc
commit
a47b9c0c75
|
@ -41,7 +41,7 @@ class MainSidebarViewController: UIViewController {
|
|||
}
|
||||
|
||||
var exploreTabItems: [Item] {
|
||||
var items: [Item] = [.explore, .bookmarks, .trendingStatuses, .profileDirectory]
|
||||
var items: [Item] = [.explore, .bookmarks, .profileDirectory]
|
||||
let snapshot = dataSource.snapshot()
|
||||
for case let .list(list) in snapshot.itemIdentifiers(inSection: .lists) {
|
||||
items.append(.list(list))
|
||||
|
@ -195,9 +195,6 @@ class MainSidebarViewController: UIViewController {
|
|||
discoverSnapshot.append([
|
||||
.profileDirectory,
|
||||
], to: .discoverHeader)
|
||||
if mastodonController.instanceFeatures.trendingStatusesAndLinks {
|
||||
discoverSnapshot.insert([.trendingStatuses], before: .profileDirectory)
|
||||
}
|
||||
dataSource.apply(discoverSnapshot, to: .discover)
|
||||
}
|
||||
|
||||
|
@ -388,7 +385,7 @@ extension MainSidebarViewController {
|
|||
enum Item: Hashable {
|
||||
case tab(MainTabBarViewController.Tab)
|
||||
case explore, bookmarks
|
||||
case discoverHeader, trendingStatuses, profileDirectory
|
||||
case discoverHeader, profileDirectory
|
||||
case listsHeader, list(List), addList
|
||||
case savedHashtagsHeader, savedHashtag(Hashtag), addSavedHashtag
|
||||
case savedInstancesHeader, savedInstance(URL), addSavedInstance
|
||||
|
@ -403,8 +400,6 @@ extension MainSidebarViewController {
|
|||
return "Bookmarks"
|
||||
case .discoverHeader:
|
||||
return "Discover"
|
||||
case .trendingStatuses:
|
||||
return "Trending Posts"
|
||||
case .profileDirectory:
|
||||
return "Profile Directory"
|
||||
case .listsHeader:
|
||||
|
@ -436,8 +431,6 @@ extension MainSidebarViewController {
|
|||
return "magnifyingglass"
|
||||
case .bookmarks:
|
||||
return "bookmark"
|
||||
case .trendingStatuses:
|
||||
return "square.text.square"
|
||||
case .profileDirectory:
|
||||
return "person.2.fill"
|
||||
case .list(_):
|
||||
|
|
|
@ -232,7 +232,7 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
|||
|
||||
tabBarViewController.select(tab: .explore)
|
||||
|
||||
case .bookmarks, .trendingStatuses, .profileDirectory, .list(_), .savedHashtag(_), .savedInstance(_):
|
||||
case .bookmarks, .profileDirectory, .list(_), .savedHashtag(_), .savedInstance(_):
|
||||
tabBarViewController.select(tab: .explore)
|
||||
// Make sure the Explore VC doesn't show it's search bar when it appears, in case the user was previously
|
||||
// in compact mode and performing a search.
|
||||
|
@ -309,7 +309,7 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
|||
case let instanceVC as InstanceTimelineViewController:
|
||||
exploreItem = .savedInstance(instanceVC.instanceURL)
|
||||
case is TrendingStatusesViewController:
|
||||
exploreItem = .trendingStatuses
|
||||
exploreItem = .explore
|
||||
case is TrendingHashtagsViewController:
|
||||
exploreItem = .explore
|
||||
case is TrendingLinksViewController:
|
||||
|
@ -376,8 +376,6 @@ fileprivate extension MainSidebarViewController.Item {
|
|||
return SearchViewController(mastodonController: mastodonController)
|
||||
case .bookmarks:
|
||||
return BookmarksTableViewController(mastodonController: mastodonController)
|
||||
case .trendingStatuses:
|
||||
return TrendingStatusesViewController(mastodonController: mastodonController)
|
||||
case .profileDirectory:
|
||||
return ProfileDirectoryViewController(mastodonController: mastodonController)
|
||||
case let .list(list):
|
||||
|
|
|
@ -11,11 +11,11 @@ import Pachyderm
|
|||
import SafariServices
|
||||
import WebURLFoundationExtras
|
||||
|
||||
class SearchViewController: UIViewController {
|
||||
class SearchViewController: UIViewController, CollectionViewController {
|
||||
|
||||
weak var mastodonController: MastodonController!
|
||||
|
||||
private var collectionView: UICollectionView!
|
||||
var collectionView: UICollectionView!
|
||||
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
|
||||
|
||||
var resultsController: SearchResultsViewController!
|
||||
|
@ -23,6 +23,8 @@ class SearchViewController: UIViewController {
|
|||
|
||||
var searchControllerStatusOnAppearance: Bool? = nil
|
||||
|
||||
private var loadTask: Task<Void, Never>?
|
||||
|
||||
init(mastodonController: MastodonController) {
|
||||
self.mastodonController = mastodonController
|
||||
|
||||
|
@ -59,8 +61,14 @@ class SearchViewController: UIViewController {
|
|||
section.boundarySupplementaryItems = [
|
||||
NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(12)), elementKind: UICollectionView.elementKindSectionHeader, alignment: .topLeading)
|
||||
]
|
||||
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 16, trailing: 0)
|
||||
return section
|
||||
|
||||
case .trendingStatuses:
|
||||
var listConfig = UICollectionLayoutListConfiguration(appearance: .grouped)
|
||||
listConfig.headerMode = .supplementary
|
||||
return NSCollectionLayoutSection.list(using: listConfig, layoutEnvironment: environment)
|
||||
|
||||
default:
|
||||
fatalError("unimplemented")
|
||||
}
|
||||
|
@ -100,7 +108,10 @@ class SearchViewController: UIViewController {
|
|||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
Task(priority: .userInitiated) {
|
||||
clearSelectionOnAppear(animated: animated)
|
||||
|
||||
loadTask?.cancel()
|
||||
loadTask = Task(priority: .userInitiated) {
|
||||
if (try? await mastodonController.getOwnInstance()) != nil {
|
||||
await applySnapshot()
|
||||
}
|
||||
|
@ -133,6 +144,11 @@ class SearchViewController: UIViewController {
|
|||
let trendingLinkCell = UICollectionView.CellRegistration<TrendingLinkCardCollectionViewCell, Card>(cellNib: UINib(nibName: "TrendingLinkCardCollectionViewCell", bundle: .main)) { (cell, indexPath, card) in
|
||||
cell.updateUI(card: card)
|
||||
}
|
||||
let statusCell = UICollectionView.CellRegistration<TimelineStatusCollectionViewCell, (String, CollapseState)> { [unowned self] cell, indexPath, item in
|
||||
cell.delegate = self
|
||||
// TODO: filter trends
|
||||
cell.updateUI(statusID: item.0, state: item.1, filterResult: .allow, precomputedContent: nil)
|
||||
}
|
||||
|
||||
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
|
||||
switch item {
|
||||
|
@ -142,8 +158,8 @@ class SearchViewController: UIViewController {
|
|||
case let .link(card):
|
||||
return collectionView.dequeueConfiguredReusableCell(using: trendingLinkCell, for: indexPath, item: card)
|
||||
|
||||
default:
|
||||
fatalError("todo")
|
||||
case let .status(id, state):
|
||||
return collectionView.dequeueConfiguredReusableCell(using: statusCell, for: indexPath, item: (id, state))
|
||||
}
|
||||
}
|
||||
dataSource.supplementaryViewProvider = { (collectionView, elementKind, indexPath) in
|
||||
|
@ -168,24 +184,38 @@ class SearchViewController: UIViewController {
|
|||
|
||||
let hashtagsReq = Client.getTrendingHashtags(limit: 5)
|
||||
async let hashtags = try? mastodonController.run(hashtagsReq).0
|
||||
let linksReq = Client.getTrendingLinks(limit: 10)
|
||||
async let links = try? mastodonController.run(linksReq).0
|
||||
|
||||
if let hashtags = await hashtags {
|
||||
snapshot.appendSections([.trendingHashtags])
|
||||
snapshot.appendItems(hashtags.map { .tag($0) }, toSection: .trendingHashtags)
|
||||
}
|
||||
|
||||
if let links = await links {
|
||||
snapshot.appendSections([.trendingLinks])
|
||||
snapshot.appendItems(links.map { .link($0) }, toSection: .trendingLinks)
|
||||
if mastodonController.instanceFeatures.trendingStatusesAndLinks {
|
||||
let linksReq = Client.getTrendingLinks(limit: 10)
|
||||
async let links = try? mastodonController.run(linksReq).0
|
||||
let statusesReq = Client.getTrendingStatuses(limit: 10)
|
||||
async let statuses = try? mastodonController.run(statusesReq).0
|
||||
|
||||
if let links = await links {
|
||||
snapshot.appendSections([.trendingLinks])
|
||||
snapshot.appendItems(links.map { .link($0) }, toSection: .trendingLinks)
|
||||
}
|
||||
|
||||
if let statuses = await statuses {
|
||||
await mastodonController.persistentContainer.addAll(statuses: statuses)
|
||||
snapshot.appendSections([.trendingStatuses])
|
||||
snapshot.appendItems(statuses.map { .status($0.id, .unknown) }, toSection: .trendingStatuses)
|
||||
}
|
||||
}
|
||||
|
||||
await dataSource.apply(snapshot)
|
||||
if !Task.isCancelled {
|
||||
await dataSource.apply(snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func preferencesChanged() {
|
||||
Task {
|
||||
loadTask?.cancel()
|
||||
loadTask = Task {
|
||||
await applySnapshot()
|
||||
}
|
||||
}
|
||||
|
@ -196,8 +226,8 @@ extension SearchViewController {
|
|||
enum Section {
|
||||
case trendingHashtags
|
||||
case trendingLinks
|
||||
case trendingStatuses
|
||||
case profileSuggestions
|
||||
case trendingStatuses
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
|
@ -206,20 +236,20 @@ extension SearchViewController {
|
|||
case .trendingLinks:
|
||||
return "Trending Links"
|
||||
case .trendingStatuses:
|
||||
return "Trending Statuses"
|
||||
return "Trending Posts"
|
||||
case .profileSuggestions:
|
||||
return "Suggested Accounts"
|
||||
}
|
||||
}
|
||||
}
|
||||
enum Item: Equatable, Hashable {
|
||||
case status(String)
|
||||
case status(String, CollapseState)
|
||||
case tag(Hashtag)
|
||||
case link(Card)
|
||||
|
||||
static func == (lhs: SearchViewController.Item, rhs: SearchViewController.Item) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case let (.status(a), .status(b)):
|
||||
case let (.status(a, _), .status(b, _)):
|
||||
return a == b
|
||||
case let (.tag(a), .tag(b)):
|
||||
return a == b
|
||||
|
@ -232,7 +262,7 @@ extension SearchViewController {
|
|||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
switch self {
|
||||
case let .status(id):
|
||||
case let .status(id, _):
|
||||
hasher.combine("status")
|
||||
hasher.combine(id)
|
||||
case let .tag(tag):
|
||||
|
@ -260,8 +290,8 @@ extension SearchViewController: UICollectionViewDelegate {
|
|||
selected(url: url)
|
||||
}
|
||||
|
||||
default:
|
||||
fatalError("todo")
|
||||
case let .status(id, state):
|
||||
selected(status: id, state: state.copy())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,8 +378,16 @@ extension SearchViewController: UICollectionViewDragDelegate {
|
|||
}
|
||||
return [UIDragItem(itemProvider: NSItemProvider(object: url as NSURL))]
|
||||
|
||||
default:
|
||||
fatalError("todo")
|
||||
case let .status(id, _):
|
||||
guard let status = mastodonController.persistentContainer.status(for: id),
|
||||
let url = status.url else {
|
||||
return []
|
||||
}
|
||||
let provider = NSItemProvider(object: url as NSURL)
|
||||
let activity = UserActivityManager.showConversationActivity(mainStatusID: id, accountID: mastodonController.accountInfo!.id)
|
||||
activity.displaysAuxiliaryScene = true
|
||||
provider.registerObject(activity, visibility: .all)
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -363,3 +401,17 @@ extension SearchViewController: ToastableViewController {
|
|||
|
||||
extension SearchViewController: MenuActionProvider {
|
||||
}
|
||||
|
||||
extension SearchViewController: StatusCollectionViewCellDelegate {
|
||||
func statusCellNeedsReconfigure(_ cell: StatusCollectionViewCell, animated: Bool, completion: (() -> Void)?) {
|
||||
if let indexPath = collectionView.indexPath(for: cell) {
|
||||
var snapshot = dataSource.snapshot()
|
||||
snapshot.reconfigureItems([dataSource.itemIdentifier(for: indexPath)!])
|
||||
dataSource.apply(snapshot, animatingDifferences: animated, completion: completion)
|
||||
}
|
||||
}
|
||||
|
||||
func statusCellShowFiltered(_ cell: StatusCollectionViewCell) {
|
||||
// TODO: filtering
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue