2021-04-02 10:24:00 +02:00
|
|
|
//
|
|
|
|
// SearchResultSection.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by sxiaojian on 2021/4/6.
|
|
|
|
//
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
import os.log
|
2021-04-02 10:24:00 +02:00
|
|
|
import Foundation
|
|
|
|
import MastodonSDK
|
|
|
|
import UIKit
|
2021-04-07 13:49:33 +02:00
|
|
|
import CoreData
|
|
|
|
import CoreDataStack
|
2022-01-27 14:23:39 +01:00
|
|
|
import MastodonAsset
|
|
|
|
import MastodonLocalization
|
|
|
|
import MastodonUI
|
2021-04-02 10:24:00 +02:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
enum SearchResultSection: Hashable {
|
2021-07-14 14:28:41 +02:00
|
|
|
case main
|
2021-04-02 10:24:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
extension SearchResultSection {
|
2022-01-27 14:23:39 +01:00
|
|
|
|
|
|
|
static let logger = Logger(subsystem: "SearchResultSection", category: "logic")
|
|
|
|
|
|
|
|
struct Configuration {
|
|
|
|
weak var statusViewTableViewCellDelegate: StatusTableViewCellDelegate?
|
|
|
|
weak var userTableViewCellDelegate: UserTableViewCellDelegate?
|
|
|
|
}
|
|
|
|
|
2021-04-02 10:24:00 +02:00
|
|
|
static func tableViewDiffableDataSource(
|
2022-01-27 14:23:39 +01:00
|
|
|
tableView: UITableView,
|
|
|
|
context: AppContext,
|
|
|
|
configuration: Configuration
|
2021-04-02 10:24:00 +02:00
|
|
|
) -> UITableViewDiffableDataSource<SearchResultSection, SearchResultItem> {
|
2022-01-27 14:23:39 +01:00
|
|
|
tableView.register(UserTableViewCell.self, forCellReuseIdentifier: String(describing: UserTableViewCell.self))
|
|
|
|
tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: String(describing: StatusTableViewCell.self))
|
|
|
|
tableView.register(HashtagTableViewCell.self, forCellReuseIdentifier: String(describing: HashtagTableViewCell.self))
|
|
|
|
tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
|
|
|
|
|
|
|
|
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
|
2021-07-14 14:28:41 +02:00
|
|
|
switch item {
|
2022-01-27 14:23:39 +01:00
|
|
|
case .user(let record):
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell
|
|
|
|
context.managedObjectContext.performAndWait {
|
|
|
|
guard let user = record.object(in: context.managedObjectContext) else { return }
|
|
|
|
configure(
|
|
|
|
context: context,
|
|
|
|
tableView: tableView,
|
|
|
|
cell: cell,
|
|
|
|
viewModel: .init(value: .user(user)),
|
|
|
|
configuration: configuration
|
|
|
|
)
|
|
|
|
}
|
2021-04-06 09:25:04 +02:00
|
|
|
return cell
|
2022-01-27 14:23:39 +01:00
|
|
|
case .status(let record):
|
2021-07-14 14:28:41 +02:00
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: StatusTableViewCell.self), for: indexPath) as! StatusTableViewCell
|
2022-01-27 14:23:39 +01:00
|
|
|
context.managedObjectContext.performAndWait {
|
|
|
|
guard let status = record.object(in: context.managedObjectContext) else { return }
|
|
|
|
configure(
|
|
|
|
context: context,
|
2021-07-14 14:28:41 +02:00
|
|
|
tableView: tableView,
|
2022-01-27 14:23:39 +01:00
|
|
|
cell: cell,
|
|
|
|
viewModel: StatusTableViewCell.ViewModel(value: .status(status)),
|
|
|
|
configuration: configuration
|
2021-07-14 14:28:41 +02:00
|
|
|
)
|
|
|
|
}
|
2022-01-27 14:23:39 +01:00
|
|
|
return cell
|
|
|
|
case .hashtag(let tag):
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: HashtagTableViewCell.self)) as! HashtagTableViewCell
|
|
|
|
cell.primaryLabel.configure(content: PlaintextMetaContent(string: "#" + tag.name))
|
2021-04-07 13:49:33 +02:00
|
|
|
return cell
|
2021-07-15 11:26:04 +02:00
|
|
|
case .bottomLoader(let attribute):
|
2021-04-16 07:45:54 +02:00
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self)) as! TimelineBottomLoaderTableViewCell
|
2021-07-15 11:26:04 +02:00
|
|
|
if attribute.isNoResult {
|
|
|
|
cell.stopAnimating()
|
|
|
|
cell.loadMoreLabel.text = L10n.Scene.Search.Searching.EmptyState.noResults
|
|
|
|
cell.loadMoreLabel.textColor = Asset.Colors.Label.secondary.color
|
|
|
|
cell.loadMoreLabel.isHidden = false
|
|
|
|
} else {
|
|
|
|
cell.startAnimating()
|
|
|
|
cell.loadMoreLabel.isHidden = true
|
|
|
|
}
|
2021-04-06 09:25:04 +02:00
|
|
|
return cell
|
2022-01-27 14:23:39 +01:00
|
|
|
}
|
2021-07-14 14:28:41 +02:00
|
|
|
} // end UITableViewDiffableDataSource
|
|
|
|
} // end func
|
2021-04-02 10:24:00 +02:00
|
|
|
}
|
2022-01-27 14:23:39 +01:00
|
|
|
|
|
|
|
extension SearchResultSection {
|
|
|
|
|
|
|
|
static func configure(
|
|
|
|
context: AppContext,
|
|
|
|
tableView: UITableView,
|
|
|
|
cell: StatusTableViewCell,
|
|
|
|
viewModel: StatusTableViewCell.ViewModel,
|
|
|
|
configuration: Configuration
|
|
|
|
) {
|
|
|
|
StatusSection.setupStatusPollDataSource(
|
|
|
|
context: context,
|
|
|
|
statusView: cell.statusView
|
|
|
|
)
|
|
|
|
|
|
|
|
context.authenticationService.activeMastodonAuthenticationBox
|
|
|
|
.map { $0 as UserIdentifier? }
|
|
|
|
.assign(to: \.userIdentifier, on: cell.statusView.viewModel)
|
|
|
|
.store(in: &cell.disposeBag)
|
|
|
|
|
|
|
|
cell.configure(
|
|
|
|
tableView: tableView,
|
|
|
|
viewModel: viewModel,
|
|
|
|
delegate: configuration.statusViewTableViewCellDelegate
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func configure(
|
|
|
|
context: AppContext,
|
|
|
|
tableView: UITableView,
|
|
|
|
cell: UserTableViewCell,
|
|
|
|
viewModel: UserTableViewCell.ViewModel,
|
|
|
|
configuration: Configuration
|
|
|
|
) {
|
|
|
|
cell.configure(
|
|
|
|
tableView: tableView,
|
|
|
|
viewModel: viewModel,
|
|
|
|
delegate: configuration.userTableViewCellDelegate
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|