From b688631937accf584942972969b731cee8c1dc15 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 6 Oct 2022 22:36:55 -0400 Subject: [PATCH] Update status cells on status changes --- .../Timeline/TimelineViewController.swift | 12 ------ .../Status/StatusCollectionViewCell.swift | 40 ++++++++++++++++--- .../TimelineStatusCollectionViewCell.swift | 25 +++++++++++- 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/Tusker/Screens/Timeline/TimelineViewController.swift b/Tusker/Screens/Timeline/TimelineViewController.swift index 28becf56..97090f88 100644 --- a/Tusker/Screens/Timeline/TimelineViewController.swift +++ b/Tusker/Screens/Timeline/TimelineViewController.swift @@ -10,8 +10,6 @@ import UIKit import Pachyderm import Combine -import SwiftSoup - // TODO: gonna need a thing to replicate all of EnhancedTableViewController class TimelineViewController: UIViewController, TimelineLikeCollectionViewController { @@ -91,16 +89,6 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro } private func createDataSource() -> UICollectionViewDiffableDataSource { -// let listCell = UICollectionView.CellRegistration { [unowned self] cell, indexPath, item in -// guard case .status(id: let id, state: _) = item, -// let status = mastodonController.persistentContainer.status(for: id) else { -// fatalError() -// } -// var config = cell.defaultContentConfiguration() -// let doc = try! SwiftSoup.parseBodyFragment(status.content) -// config.text = try! doc.text() -// cell.contentConfiguration = config -// } let statusCell = UICollectionView.CellRegistration { [unowned self] cell, indexPath, item in guard case .status(id: let id, state: let state) = item, let status = mastodonController.persistentContainer.status(for: id) else { diff --git a/Tusker/Views/Status/StatusCollectionViewCell.swift b/Tusker/Views/Status/StatusCollectionViewCell.swift index 295aa13d..50a5d0b1 100644 --- a/Tusker/Views/Status/StatusCollectionViewCell.swift +++ b/Tusker/Views/Status/StatusCollectionViewCell.swift @@ -8,6 +8,7 @@ import UIKit import Pachyderm +import Combine @MainActor protocol StatusCollectionViewCellDelegate: AnyObject, TuskerNavigationDelegate, MenuActionProvider { @@ -40,6 +41,7 @@ protocol StatusCollectionViewCell: UICollectionViewCell { var accountID: String! { get set } var isGrayscale: Bool { get set } + var cancellables: Set { get set } func updateUIForPreferences(status: StatusMO) } @@ -48,17 +50,37 @@ protocol StatusCollectionViewCell: UICollectionViewCell { extension StatusCollectionViewCell { static var avatarImageViewSize: CGFloat { 50 } + func baseCreateObservers() { + mastodonController.persistentContainer.statusSubject + .receive(on: DispatchQueue.main) + .filter { [unowned self] in $0 == self.statusID } + .sink { [unowned self] in + if let mastodonController = self.mastodonController, + let status = mastodonController.persistentContainer.status(for: $0) { + self.updateStatusState(status: status) + } + } + .store(in: &cancellables) + + mastodonController.persistentContainer.accountSubject + .receive(on: DispatchQueue.main) + .filter { [unowned self] in $0 == self.accountID } + .sink { [unowned self] in + if let mastodonController = self.mastodonController, + let account = mastodonController.persistentContainer.account(for: $0) { + self.updateAccountUI(account: account) + } + } + .store(in: &cancellables) + } + func doUpdateUI(status: StatusMO) { statusID = status.id accountID = status.account.id - let account = status.account - avatarImageView.update(for: account.avatar) - displayNameLabel.updateForAccountDisplayName(account: account) - usernameLabel.text = "@\(account.acct)" - contentContainer.contentTextView.setTextFrom(status: status) - + updateAccountUI(account: status.account) updateUIForPreferences(status: status) + contentContainer.contentTextView.setTextFrom(status: status) contentContainer.cardView.card = status.card contentContainer.cardView.isHidden = status.card == nil @@ -105,6 +127,12 @@ extension StatusCollectionViewCell { } } + func updateAccountUI(account: AccountMO) { + avatarImageView.update(for: account.avatar) + displayNameLabel.updateForAccountDisplayName(account: account) + usernameLabel.text = "@\(account.acct)" + } + func baseUpdateUIForPreferences(status: StatusMO) { avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * Self.avatarImageViewSize contentContainer.attachmentsView.contentHidden = Preferences.shared.blurAllMedia || status.sensitive diff --git a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift index 6d884904..17078852 100644 --- a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift @@ -8,6 +8,7 @@ import UIKit import Pachyderm +import Combine class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollectionViewCell { @@ -238,8 +239,9 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti private var firstLayout = true var isGrayscale = false - private var updateTimestampWorkItem: DispatchWorkItem? + private var hasCreatedObservers = false + var cancellables = Set() override init(frame: CGRect) { super.init(frame: frame) @@ -336,6 +338,8 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti fatalError() } + createObservers() + self.statusState = state if let rebloggedStatus = status.reblog { @@ -362,6 +366,25 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti pinImageView.isHidden = !showPinned } + func createObservers() { + guard !hasCreatedObservers else { + return + } + hasCreatedObservers = true + baseCreateObservers() + + mastodonController.persistentContainer.accountSubject + .receive(on: DispatchQueue.main) + .filter { [unowned self] in $0 == self.rebloggerID } + .sink { [unowned self] in + if let mastodonController = self.mastodonController, + let reblogger = mastodonController.persistentContainer.account(for: $0) { + self.updateRebloggerLabel(reblogger: reblogger) + } + } + .store(in: &cancellables) + } + func updateUIForPreferences(status: StatusMO) { baseUpdateUIForPreferences(status: status)