mastodon-ios/Mastodon/Diffiable/Section/NotificationSection.swift

148 lines
7.8 KiB
Swift
Raw Normal View History

2021-04-12 10:31:53 +02:00
//
// NotificationSection.swift
// Mastodon
//
// Created by sxiaojian on 2021/4/13.
//
2021-04-15 04:16:30 +02:00
import Combine
2021-04-12 10:31:53 +02:00
import CoreData
import CoreDataStack
import Foundation
import MastodonSDK
import UIKit
2021-07-02 13:48:56 +02:00
import Nuke
2021-04-12 10:31:53 +02:00
enum NotificationSection: Equatable, Hashable {
case main
}
extension NotificationSection {
static func tableViewDiffableDataSource(
for tableView: UITableView,
timestampUpdatePublisher: AnyPublisher<Date, Never>,
2021-04-14 09:00:48 +02:00
managedObjectContext: NSManagedObjectContext,
delegate: NotificationTableViewCellDelegate,
dependency: NeedsDependency
2021-04-12 10:31:53 +02:00
) -> UITableViewDiffableDataSource<NotificationSection, NotificationItem> {
2021-04-15 04:16:30 +02:00
UITableViewDiffableDataSource(tableView: tableView) {
[weak delegate, weak dependency]
2021-04-14 09:00:48 +02:00
(tableView, indexPath, notificationItem) -> UITableViewCell? in
guard let dependency = dependency else { return nil }
2021-04-12 10:31:53 +02:00
switch notificationItem {
case .notification(let objectID, let attribute):
guard let notification = try? managedObjectContext.existingObject(with: objectID) as? MastodonNotification else {
return UITableViewCell()
}
2021-04-19 11:00:51 +02:00
guard let type = Mastodon.Entity.Notification.NotificationType(rawValue: notification.typeRaw) else {
// filter out invalid type using predicate
2021-04-19 11:00:51 +02:00
assertionFailure()
return UITableViewCell()
2021-04-19 11:00:51 +02:00
}
let createAt = notification.createAt
let timeText = createAt.timeAgoSinceNow
2021-04-19 11:00:51 +02:00
let actionText = type.actionText
let actionImageName = type.actionImageName
let color = type.color
2021-04-12 10:31:53 +02:00
2021-04-14 09:00:48 +02:00
if let status = notification.status {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NotificationStatusTableViewCell.self), for: indexPath) as! NotificationStatusTableViewCell
cell.delegate = delegate
let activeMastodonAuthenticationBox = dependency.context.authenticationService.activeMastodonAuthenticationBox.value
let requestUserID = activeMastodonAuthenticationBox?.userID ?? ""
let frame = CGRect(x: 0, y: 0, width: tableView.readableContentGuide.layoutFrame.width - NotificationStatusTableViewCell.statusPadding.left - NotificationStatusTableViewCell.statusPadding.right, height: tableView.readableContentGuide.layoutFrame.height)
StatusSection.configure(
cell: cell,
tableView: tableView,
dependency: dependency,
readableLayoutFrame: frame,
status: status,
requestUserID: requestUserID,
statusItemAttribute: attribute
)
cell.actionImageBackground.backgroundColor = color
cell.nameLabel.configure(content: notification.account.displayNameWithFallback, emojiDict: notification.account.emojiDict)
cell.actionLabel.text = actionText + " · " + timeText
timestampUpdatePublisher
.sink { [weak cell] _ in
guard let cell = cell else { return }
let timeText = createAt.timeAgoSinceNow
cell.actionLabel.text = actionText + " · " + timeText
}
.store(in: &cell.disposeBag)
2021-04-19 11:00:51 +02:00
if let url = notification.account.avatarImageURL() {
2021-07-02 13:48:56 +02:00
cell.avatarImageViewTask = Nuke.loadImage(
with: url,
options: ImageLoadingOptions(
placeholder: UIImage.placeholder(color: .systemFill),
transition: .fadeIn(duration: 0.2)
),
into: cell.avatarImageView
2021-04-19 11:00:51 +02:00
)
}
cell.avatarImageView.gesture().sink { [weak cell] _ in
cell?.delegate?.userAvatarDidPressed(notification: notification)
}
.store(in: &cell.disposeBag)
if let actionImage = UIImage(systemName: actionImageName, withConfiguration: UIImage.SymbolConfiguration(pointSize: 12, weight: .semibold))?.withRenderingMode(.alwaysTemplate) {
cell.actionImageView.image = actionImage
}
return cell
2021-04-14 09:00:48 +02:00
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NotificationTableViewCell.self), for: indexPath) as! NotificationTableViewCell
cell.delegate = delegate
timestampUpdatePublisher
.sink { [weak cell] _ in
guard let cell = cell else { return }
let timeText = createAt.timeAgoSinceNow
cell.actionLabel.text = actionText + " · " + timeText
}
.store(in: &cell.disposeBag)
2021-04-27 10:54:23 +02:00
cell.acceptButton.publisher(for: .touchUpInside)
.sink { [weak cell] _ in
guard let cell = cell else { return }
cell.delegate?.notificationTableViewCell(cell, notification: notification, acceptButtonDidPressed: cell.acceptButton)
}
.store(in: &cell.disposeBag)
cell.rejectButton.publisher(for: .touchUpInside)
.sink { [weak cell] _ in
guard let cell = cell else { return }
2021-04-27 13:41:55 +02:00
cell.delegate?.notificationTableViewCell(cell, notification: notification, rejectButtonDidPressed: cell.rejectButton)
2021-04-27 10:54:23 +02:00
}
.store(in: &cell.disposeBag)
cell.actionImageBackground.backgroundColor = color
cell.actionLabel.text = actionText + " · " + timeText
cell.nameLabel.configure(content: notification.account.displayNameWithFallback, emojiDict: notification.account.emojiDict)
2021-04-19 11:00:51 +02:00
if let url = notification.account.avatarImageURL() {
2021-07-02 13:48:56 +02:00
cell.avatarImageViewTask = Nuke.loadImage(
with: url,
options: ImageLoadingOptions(
placeholder: UIImage.placeholder(color: .systemFill),
transition: .fadeIn(duration: 0.2)
),
into: cell.avatarImageView
2021-04-19 11:00:51 +02:00
)
}
cell.avatarImageView.gesture().sink { [weak cell] _ in
cell?.delegate?.userAvatarDidPressed(notification: notification)
}
.store(in: &cell.disposeBag)
if let actionImage = UIImage(systemName: actionImageName, withConfiguration: UIImage.SymbolConfiguration(pointSize: 12, weight: .semibold))?.withRenderingMode(.alwaysTemplate) {
cell.actionImageView.image = actionImage
}
cell.buttonStackView.isHidden = (type != .followRequest)
return cell
2021-04-13 15:31:49 +02:00
}
2021-04-12 10:31:53 +02:00
case .bottomLoader:
2021-04-16 07:45:54 +02:00
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self)) as! TimelineBottomLoaderTableViewCell
2021-04-12 10:31:53 +02:00
cell.startAnimating()
return cell
}
}
}
}
2021-04-14 09:00:48 +02:00