From 3822d536c86da85770545c2aec563a541fae1285 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 17 Sep 2020 19:38:49 -0400 Subject: [PATCH] Reduce redundant status database lookups when updating cell UI --- .../Status/BaseStatusTableViewCell.swift | 19 +++++++++----- .../ConversationMainStatusTableViewCell.swift | 11 ++++---- .../Status/TimelineStatusTableViewCell.swift | 26 ++++++++++--------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Tusker/Views/Status/BaseStatusTableViewCell.swift b/Tusker/Views/Status/BaseStatusTableViewCell.swift index 01bbfbea..b93e5b69 100644 --- a/Tusker/Views/Status/BaseStatusTableViewCell.swift +++ b/Tusker/Views/Status/BaseStatusTableViewCell.swift @@ -122,19 +122,25 @@ class BaseStatusTableViewCell: UITableViewCell { } } - func updateUI(statusID: String, state: StatusState) { + final func updateUI(statusID: String, state: StatusState) { createObserversIfNecessary() guard let status = mastodonController.persistentContainer.status(for: statusID) else { fatalError("Missing cached status") } + self.statusID = statusID + + doUpdateUI(status: status, state: state) + } + + func doUpdateUI(status: StatusMO, state: StatusState) { self.statusState = state let account = status.account self.accountID = account.id updateUI(account: account) - updateUIForPreferences(account: account) + updateUIForPreferences(account: account, status: status) attachmentsView.updateUI(status: status) attachmentsView.isAccessibilityElement = status.attachments.count > 0 @@ -213,18 +219,19 @@ class BaseStatusTableViewCell: UITableViewCell { } } - @objc func preferencesChanged() { + @objc private func preferencesChanged() { guard let mastodonController = mastodonController, let account = mastodonController.persistentContainer.account(for: accountID), let status = mastodonController.persistentContainer.status(for: statusID) else { return } - updateUIForPreferences(account: account) - updateStatusIconsForPreferences(status) + updateUIForPreferences(account: account, status: status) } - func updateUIForPreferences(account: AccountMO) { + func updateUIForPreferences(account: AccountMO, status: StatusMO) { avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView) displayNameLabel.updateForAccountDisplayName(account: account) attachmentsView.contentHidden = Preferences.shared.blurAllMedia || (mastodonController.persistentContainer.status(for: statusID)?.sensitive ?? false) + + updateStatusIconsForPreferences(status) } func updateStatusIconsForPreferences(_ status: StatusMO) { diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift index 43d9f382..e33cd339 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift @@ -38,10 +38,9 @@ class ConversationMainStatusTableViewCell: BaseStatusTableViewCell { contentTextView.defaultFont = .systemFont(ofSize: 18) } - override func updateUI(statusID: String, state: StatusState) { - super.updateUI(statusID: statusID, state: state) - guard let status = mastodonController.persistentContainer.status(for: statusID) else { fatalError() } - + override func doUpdateUI(status: StatusMO, state: StatusState) { + super.doUpdateUI(status: status, state: state) + var timestampAndClientText = ConversationMainStatusTableViewCell.dateFormatter.string(from: status.createdAt) if let application = status.applicationName { timestampAndClientText += " • \(application)" @@ -63,8 +62,8 @@ class ConversationMainStatusTableViewCell: BaseStatusTableViewCell { profileAccessibilityElement.accessibilityLabel = account.displayNameWithoutCustomEmoji } - override func updateUIForPreferences(account: AccountMO) { - super.updateUIForPreferences(account: account) + override func updateUIForPreferences(account: AccountMO, status: StatusMO) { + super.updateUIForPreferences(account: account, status: status) favoriteAndReblogCountStackView.isHidden = !Preferences.shared.showFavoriteAndReblogCounts } diff --git a/Tusker/Views/Status/TimelineStatusTableViewCell.swift b/Tusker/Views/Status/TimelineStatusTableViewCell.swift index 367f2429..1964d3b0 100644 --- a/Tusker/Views/Status/TimelineStatusTableViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusTableViewCell.swift @@ -68,10 +68,9 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell { } } - override func updateUI(statusID: String, state: StatusState) { - guard var status = mastodonController.persistentContainer.status(for: statusID) else { fatalError("Missing cached status \(statusID)") } - - let realStatusID: String + override func doUpdateUI(status: StatusMO, state: StatusState) { + var status = status + if let rebloggedStatus = status.reblog { reblogStatusID = statusID rebloggerID = status.account.id @@ -79,25 +78,24 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell { updateRebloggerLabel(reblogger: status.account) status = rebloggedStatus - realStatusID = rebloggedStatus.id + statusID = rebloggedStatus.id } else { reblogStatusID = nil rebloggerID = nil reblogLabel.isHidden = true - realStatusID = statusID } - super.updateUI(statusID: realStatusID, state: state) - - updateTimestamp() + super.doUpdateUI(status: status, state: state) + + doUpdateTimestamp(status: status) let pinned = showPinned && (status.pinned ?? false) timestampLabel.isHidden = pinned pinImageView.isHidden = !pinned } - @objc override func preferencesChanged() { - super.preferencesChanged() + override func updateUIForPreferences(account: AccountMO, status: StatusMO) { + super.updateUIForPreferences(account: account, status: status) if let rebloggerID = rebloggerID, let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) { @@ -121,12 +119,16 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell { replyImageView.isHidden = !Preferences.shared.showIsStatusReplyIcon || !showReplyIndicator || status.inReplyToID == nil } - func updateTimestamp() { + private func updateTimestamp() { // if the mastodonController is nil (i.e. the delegate is nil), then the screen this cell was a part of has been deallocated // so we bail out immediately, since there's nothing to update guard let mastodonController = mastodonController else { return } guard let status = mastodonController.persistentContainer.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") } + doUpdateTimestamp(status: status) + } + + private func doUpdateTimestamp(status: StatusMO) { timestampLabel.text = status.createdAt.timeAgoString() timestampLabel.accessibilityLabel = TimelineStatusTableViewCell.relativeDateFormatter.localizedString(for: status.createdAt, relativeTo: Date())