2021-01-28 09:10:30 +01:00
|
|
|
//
|
|
|
|
// TimelineSection.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by sxiaojian on 2021/1/27.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Combine
|
|
|
|
import CoreData
|
|
|
|
import CoreDataStack
|
|
|
|
import os.log
|
|
|
|
import UIKit
|
|
|
|
|
|
|
|
enum TimelineSection: Equatable, Hashable {
|
|
|
|
case main
|
|
|
|
}
|
|
|
|
|
|
|
|
extension TimelineSection {
|
|
|
|
static func tableViewDiffableDataSource(
|
|
|
|
for tableView: UITableView,
|
|
|
|
dependency: NeedsDependency,
|
|
|
|
managedObjectContext: NSManagedObjectContext,
|
|
|
|
timestampUpdatePublisher: AnyPublisher<Date, Never>,
|
2021-02-04 08:09:58 +01:00
|
|
|
timelinePostTableViewCellDelegate: TimelinePostTableViewCellDelegate,
|
2021-02-05 10:08:51 +01:00
|
|
|
timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate?
|
2021-01-28 09:10:30 +01:00
|
|
|
) -> UITableViewDiffableDataSource<TimelineSection, Item> {
|
2021-02-04 08:09:58 +01:00
|
|
|
UITableViewDiffableDataSource(tableView: tableView) { [weak timelinePostTableViewCellDelegate, weak timelineMiddleLoaderTableViewCellDelegate] tableView, indexPath, item -> UITableViewCell? in
|
2021-01-28 09:10:30 +01:00
|
|
|
guard let timelinePostTableViewCellDelegate = timelinePostTableViewCellDelegate else { return UITableViewCell() }
|
|
|
|
|
|
|
|
switch item {
|
|
|
|
case .toot(let objectID):
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelinePostTableViewCell.self), for: indexPath) as! TimelinePostTableViewCell
|
|
|
|
|
|
|
|
// configure cell
|
|
|
|
managedObjectContext.performAndWait {
|
|
|
|
let toot = managedObjectContext.object(with: objectID) as! Toot
|
2021-02-04 08:09:58 +01:00
|
|
|
TimelineSection.configure(cell: cell, timestampUpdatePublisher: timestampUpdatePublisher, toot: toot)
|
2021-01-28 09:10:30 +01:00
|
|
|
}
|
|
|
|
cell.delegate = timelinePostTableViewCellDelegate
|
|
|
|
return cell
|
2021-02-04 08:09:58 +01:00
|
|
|
case .middleLoader(let upperTimelineTootID):
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineMiddleLoaderTableViewCell.self), for: indexPath) as! TimelineMiddleLoaderTableViewCell
|
|
|
|
cell.delegate = timelineMiddleLoaderTableViewCellDelegate
|
|
|
|
timelineMiddleLoaderTableViewCellDelegate?.configure(cell: cell, upperTimelineTootID: upperTimelineTootID)
|
|
|
|
return cell
|
2021-02-03 06:01:50 +01:00
|
|
|
case .bottomLoader:
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self), for: indexPath) as! TimelineBottomLoaderTableViewCell
|
|
|
|
cell.activityIndicatorView.startAnimating()
|
|
|
|
return cell
|
2021-01-28 09:10:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func configure(
|
|
|
|
cell: TimelinePostTableViewCell,
|
2021-02-02 07:10:25 +01:00
|
|
|
timestampUpdatePublisher: AnyPublisher<Date, Never>,
|
2021-01-28 09:10:30 +01:00
|
|
|
toot: Toot
|
|
|
|
) {
|
2021-02-01 11:06:29 +01:00
|
|
|
// set name username avatar
|
2021-01-28 09:10:30 +01:00
|
|
|
cell.timelinePostView.nameLabel.text = toot.author.displayName
|
2021-02-01 11:06:29 +01:00
|
|
|
cell.timelinePostView.usernameLabel.text = "@" + toot.author.username
|
|
|
|
cell.timelinePostView.avatarImageView.af.setImage(
|
|
|
|
withURL: URL(string: toot.author.avatar)!,
|
|
|
|
placeholderImage: UIImage.placeholder(color: .systemFill),
|
|
|
|
imageTransition: .crossDissolve(0.2)
|
|
|
|
)
|
|
|
|
// set text
|
2021-01-29 09:47:32 +01:00
|
|
|
cell.timelinePostView.activeTextLabel.config(content: toot.content)
|
2021-02-01 11:06:29 +01:00
|
|
|
// set date
|
2021-02-02 07:10:25 +01:00
|
|
|
let createdAt = (toot.reblog ?? toot).createdAt
|
|
|
|
timestampUpdatePublisher
|
|
|
|
.sink { _ in
|
|
|
|
cell.timelinePostView.dateLabel.text = createdAt.shortTimeAgoSinceNow
|
|
|
|
}
|
|
|
|
.store(in: &cell.disposeBag)
|
2021-01-28 09:10:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension TimelineSection {
|
|
|
|
private static func formattedNumberTitleForActionButton(_ number: Int?) -> String {
|
|
|
|
guard let number = number, number > 0 else { return "" }
|
|
|
|
return String(number)
|
|
|
|
}
|
|
|
|
}
|