120 lines
5.1 KiB
Swift
120 lines
5.1 KiB
Swift
//
|
|
// ReportSection.swift
|
|
// Mastodon
|
|
//
|
|
// Created by ihugo on 2021/4/20.
|
|
//
|
|
|
|
import Combine
|
|
import CoreData
|
|
import CoreDataStack
|
|
import Foundation
|
|
import MastodonSDK
|
|
import UIKit
|
|
import os.log
|
|
import MastodonAsset
|
|
import MastodonCore
|
|
import MastodonUI
|
|
import MastodonLocalization
|
|
|
|
enum ReportSection: Equatable, Hashable {
|
|
case main
|
|
}
|
|
|
|
extension ReportSection {
|
|
|
|
struct Configuration {
|
|
let authContext: AuthContext
|
|
}
|
|
|
|
static func diffableDataSource(
|
|
tableView: UITableView,
|
|
context: AppContext,
|
|
configuration: Configuration
|
|
) -> UITableViewDiffableDataSource<ReportSection, ReportItem> {
|
|
|
|
tableView.register(ReportHeadlineTableViewCell.self, forCellReuseIdentifier: String(describing: ReportHeadlineTableViewCell.self))
|
|
tableView.register(ReportStatusTableViewCell.self, forCellReuseIdentifier: String(describing: ReportStatusTableViewCell.self))
|
|
tableView.register(ReportCommentTableViewCell.self, forCellReuseIdentifier: String(describing: ReportCommentTableViewCell.self))
|
|
tableView.register(ReportResultActionTableViewCell.self, forCellReuseIdentifier: String(describing: ReportResultActionTableViewCell.self))
|
|
tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
|
|
|
|
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
|
|
switch item {
|
|
case .header(let headerContext):
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ReportHeadlineTableViewCell.self), for: indexPath) as! ReportHeadlineTableViewCell
|
|
cell.primaryLabel.text = headerContext.primaryLabelText
|
|
cell.secondaryLabel.text = headerContext.secondaryLabelText
|
|
return cell
|
|
case .status(let record):
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ReportStatusTableViewCell.self), for: indexPath) as! ReportStatusTableViewCell
|
|
context.managedObjectContext.performAndWait {
|
|
guard let status = record.object(in: context.managedObjectContext) else { return }
|
|
configure(
|
|
context: context,
|
|
tableView: tableView,
|
|
cell: cell,
|
|
viewModel: .init(value: status),
|
|
configuration: configuration
|
|
)
|
|
}
|
|
return cell
|
|
case .comment(let commentContext):
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ReportCommentTableViewCell.self), for: indexPath) as! ReportCommentTableViewCell
|
|
cell.commentTextView.text = commentContext.comment
|
|
NotificationCenter.default.publisher(for: UITextView.textDidChangeNotification, object: cell.commentTextView)
|
|
.receive(on: DispatchQueue.main)
|
|
.sink { [weak cell] notification in
|
|
guard let cell = cell else { return }
|
|
commentContext.comment = cell.commentTextView.text
|
|
|
|
// fix shadow get animation issue when cell height changes
|
|
UIView.performWithoutAnimation {
|
|
tableView.beginUpdates()
|
|
tableView.endUpdates()
|
|
}
|
|
}
|
|
.store(in: &cell.disposeBag)
|
|
return cell
|
|
case .result(let record):
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ReportResultActionTableViewCell.self), for: indexPath) as! ReportResultActionTableViewCell
|
|
context.managedObjectContext.performAndWait {
|
|
guard let user = record.object(in: context.managedObjectContext) else { return }
|
|
cell.avatarImageView.configure(configuration: .init(url: user.avatarImageURL()))
|
|
}
|
|
return cell
|
|
case .bottomLoader:
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self), for: indexPath) as! TimelineBottomLoaderTableViewCell
|
|
cell.activityIndicatorView.startAnimating()
|
|
return cell
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ReportSection {
|
|
|
|
static func configure(
|
|
context: AppContext,
|
|
tableView: UITableView,
|
|
cell: ReportStatusTableViewCell,
|
|
viewModel: ReportStatusTableViewCell.ViewModel,
|
|
configuration: Configuration
|
|
) {
|
|
StatusSection.setupStatusPollDataSource(
|
|
context: context,
|
|
authContext: configuration.authContext,
|
|
statusView: cell.statusView
|
|
)
|
|
|
|
cell.statusView.viewModel.context = context
|
|
cell.statusView.viewModel.authContext = configuration.authContext
|
|
|
|
cell.configure(
|
|
tableView: tableView,
|
|
viewModel: viewModel
|
|
)
|
|
}
|
|
|
|
}
|