SearchResultSection.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. //
  2. // SearchResultSection.swift
  3. // Mastodon
  4. //
  5. // Created by sxiaojian on 2021/4/6.
  6. //
  7. import os.log
  8. import Foundation
  9. import MastodonSDK
  10. import UIKit
  11. import CoreData
  12. import CoreDataStack
  13. import MastodonAsset
  14. import MastodonCore
  15. import MastodonLocalization
  16. import MastodonUI
  17. enum SearchResultSection: Hashable {
  18. case main
  19. }
  20. extension SearchResultSection {
  21. static let logger = Logger(subsystem: "SearchResultSection", category: "logic")
  22. struct Configuration {
  23. let authContext: AuthContext
  24. weak var statusViewTableViewCellDelegate: StatusTableViewCellDelegate?
  25. weak var userTableViewCellDelegate: UserTableViewCellDelegate?
  26. }
  27. static func tableViewDiffableDataSource(
  28. tableView: UITableView,
  29. context: AppContext,
  30. configuration: Configuration
  31. ) -> UITableViewDiffableDataSource<SearchResultSection, SearchResultItem> {
  32. tableView.register(UserTableViewCell.self, forCellReuseIdentifier: String(describing: UserTableViewCell.self))
  33. tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: String(describing: StatusTableViewCell.self))
  34. tableView.register(HashtagTableViewCell.self, forCellReuseIdentifier: String(describing: HashtagTableViewCell.self))
  35. tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
  36. return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
  37. switch item {
  38. case .user(let record):
  39. let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell
  40. context.managedObjectContext.performAndWait {
  41. guard let user = record.object(in: context.managedObjectContext) else { return }
  42. configure(
  43. context: context,
  44. tableView: tableView,
  45. cell: cell,
  46. viewModel: .init(value: .user(user)),
  47. configuration: configuration
  48. )
  49. }
  50. return cell
  51. case .status(let record):
  52. let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: StatusTableViewCell.self), for: indexPath) as! StatusTableViewCell
  53. context.managedObjectContext.performAndWait {
  54. guard let status = record.object(in: context.managedObjectContext) else { return }
  55. configure(
  56. context: context,
  57. tableView: tableView,
  58. cell: cell,
  59. viewModel: StatusTableViewCell.ViewModel(value: .status(status)),
  60. configuration: configuration
  61. )
  62. }
  63. return cell
  64. case .hashtag(let tag):
  65. let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: HashtagTableViewCell.self)) as! HashtagTableViewCell
  66. cell.primaryLabel.configure(content: PlaintextMetaContent(string: "#" + tag.name))
  67. return cell
  68. case .bottomLoader(let attribute):
  69. let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self)) as! TimelineBottomLoaderTableViewCell
  70. if attribute.isNoResult {
  71. cell.stopAnimating()
  72. cell.loadMoreLabel.text = L10n.Scene.Search.Searching.EmptyState.noResults
  73. cell.loadMoreLabel.textColor = Asset.Colors.Label.secondary.color
  74. cell.loadMoreLabel.isHidden = false
  75. } else {
  76. cell.startAnimating()
  77. cell.loadMoreLabel.isHidden = true
  78. }
  79. return cell
  80. }
  81. } // end UITableViewDiffableDataSource
  82. } // end func
  83. }
  84. extension SearchResultSection {
  85. static func configure(
  86. context: AppContext,
  87. tableView: UITableView,
  88. cell: StatusTableViewCell,
  89. viewModel: StatusTableViewCell.ViewModel,
  90. configuration: Configuration
  91. ) {
  92. StatusSection.setupStatusPollDataSource(
  93. context: context,
  94. authContext: configuration.authContext,
  95. statusView: cell.statusView
  96. )
  97. cell.statusView.viewModel.authContext = configuration.authContext
  98. cell.configure(
  99. tableView: tableView,
  100. viewModel: viewModel,
  101. delegate: configuration.statusViewTableViewCellDelegate
  102. )
  103. }
  104. static func configure(
  105. context: AppContext,
  106. tableView: UITableView,
  107. cell: UserTableViewCell,
  108. viewModel: UserTableViewCell.ViewModel,
  109. configuration: Configuration
  110. ) {
  111. cell.configure(
  112. tableView: tableView,
  113. viewModel: viewModel,
  114. delegate: configuration.userTableViewCellDelegate
  115. )
  116. }
  117. }