2
2
mirror of https://github.com/mastodon/mastodon-ios synced 2025-04-11 22:58:02 +02:00
mastodon-ios/Mastodon/Scene/Notification/NotificationSection.swift
shannon d2b4d7b6b4 Refactor: Filter and Content Warning display and management
A large amount of change primarily to the view model layer, to make reasoning about the content reveal/hide state easier.

To prevent terrible scrolling jags while allowing the cells to be shorter when hiding content, the layout changes for content display state now happen before the cell is returned by the datasource provider and the tableview is reloaded when a status’s display mode changes.
2024-11-28 13:08:01 -05:00

112 lines
4.4 KiB
Swift

//
// NotificationSection.swift
// Mastodon
//
// Created by sxiaojian on 2021/4/13.
//
import Combine
import CoreData
import CoreDataStack
import Foundation
import MastodonSDK
import UIKit
import MetaTextKit
import MastodonMeta
import MastodonAsset
import MastodonCore
import MastodonUI
import MastodonLocalization
enum NotificationSection: Equatable, Hashable {
case main
}
extension NotificationSection {
struct Configuration {
let authenticationBox: MastodonAuthenticationBox
weak var notificationTableViewCellDelegate: NotificationTableViewCellDelegate?
let filterContext: Mastodon.Entity.FilterContext?
}
static func diffableDataSource(
tableView: UITableView,
context: AppContext,
configuration: Configuration
) -> UITableViewDiffableDataSource<NotificationSection, NotificationItem> {
tableView.register(NotificationTableViewCell.self, forCellReuseIdentifier: String(describing: NotificationTableViewCell.self))
tableView.register(AccountWarningNotificationCell.self, forCellReuseIdentifier: AccountWarningNotificationCell.reuseIdentifier)
tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
tableView.register(NotificationFilteringBannerTableViewCell.self, forCellReuseIdentifier: NotificationFilteringBannerTableViewCell.reuseIdentifier)
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
switch item {
case .feed(let feed):
if let notification = feed.notification, let accountWarning = notification.accountWarning {
let cell = tableView.dequeueReusableCell(withIdentifier: AccountWarningNotificationCell.reuseIdentifier, for: indexPath) as! AccountWarningNotificationCell
cell.configure(with: accountWarning)
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NotificationTableViewCell.self), for: indexPath) as! NotificationTableViewCell
configure(
context: context,
tableView: tableView,
cell: cell,
viewModel: NotificationTableViewCell.ViewModel(value: .feed(feed)),
configuration: configuration
)
return cell
}
case .feedLoader:
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self), for: indexPath) as! TimelineBottomLoaderTableViewCell
cell.activityIndicatorView.startAnimating()
return cell
case .bottomLoader:
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self), for: indexPath) as! TimelineBottomLoaderTableViewCell
cell.activityIndicatorView.startAnimating()
return cell
case .filteredNotifications(let policy):
let cell = tableView.dequeueReusableCell(withIdentifier: NotificationFilteringBannerTableViewCell.reuseIdentifier, for: indexPath) as! NotificationFilteringBannerTableViewCell
cell.configure(with: policy)
return cell
}
}
}
}
extension NotificationSection {
static func configure(
context: AppContext,
tableView: UITableView,
cell: NotificationTableViewCell,
viewModel: NotificationTableViewCell.ViewModel,
configuration: Configuration
) {
StatusSection.setupStatusPollDataSource(
context: context,
authenticationBox: configuration.authenticationBox,
statusView: cell.notificationView.statusView
)
StatusSection.setupStatusPollDataSource(
context: context,
authenticationBox: configuration.authenticationBox,
statusView: cell.notificationView.quoteStatusView
)
cell.configure(
tableView: tableView,
viewModel: viewModel,
delegate: configuration.notificationTableViewCellDelegate,
authenticationBox: configuration.authenticationBox
)
}
}