From 59645cd456c19775175f83308b25fbbb85b279ae Mon Sep 17 00:00:00 2001 From: Michelle Linington Date: Mon, 1 Nov 2021 23:29:25 -0700 Subject: [PATCH] Simplify reconfigure API --- .../Group/GroupCallMemberSheet.swift | 1 - .../Group/GroupCallMemberView.swift | 4 +- .../IndividualCallViewController.swift | 1 - .../Payments/PaymentModelCell.swift | 1 - .../PaymentsDetailViewController.swift | 1 - .../ProfileSettingsViewController.swift | 1 - .../CV/CVComponents/CVComponentMessage.swift | 3 +- .../CVComponentThreadDetails.swift | 2 +- .../CVComponentTypingIndicator.swift | 2 +- .../ConversationHeaderView.swift | 5 +- .../EmojiReactorsTableView.swift | 1 - .../GroupMigrationActionSheet.swift | 1 - .../HomeView/HomeViewCell.swift | 4 +- .../HomeView/HomeViewController.swift | 3 +- .../NewGroupView/NewGroupMembersBar.swift | 1 - .../ReturnToCallViewController.swift | 1 - .../ConversationHeaderBuilder.swift | 1 - Signal/src/views/GroupTableViewCell.swift | 1 - .../src/views/NameCollisionReviewCell.swift | 1 - SignalUI/Views/ContactCellView.swift | 1 - SignalUI/Views/ConversationAvatarView.swift | 122 ++++++++++-------- SignalUI/Views/Mentions/MentionPicker.swift | 1 - 22 files changed, 81 insertions(+), 78 deletions(-) diff --git a/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift b/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift index e93b01af02..088b00358f 100644 --- a/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift +++ b/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift @@ -305,7 +305,6 @@ private class GroupCallMemberCell: UITableViewCell { nameLabel.text = item.displayName avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .address(item.address) - return .asynchronously } } } diff --git a/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift b/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift index c5ac3b355d..1f0aac4cc3 100644 --- a/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift +++ b/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift @@ -254,7 +254,7 @@ class GroupCallRemoteMemberView: GroupCallMemberView { var deferredReconfigTimer: Timer? let errorView = GroupCallErrorView() let spinner = UIActivityIndicatorView(style: .whiteLarge) - let avatarView = ConversationAvatarView(sizeClass: .customDiameter(0)) + let avatarView = ConversationAvatarView() var isCallMinimized: Bool = false { didSet { @@ -329,7 +329,6 @@ class GroupCallRemoteMemberView: GroupCallMemberView { avatarView.update(transaction) { config in config.dataSource = .address(device.address) config.sizeClass = .customDiameter(updatedSize) - return .asynchronously } return self.contactsManagerImpl.avatarImage(forAddress: device.address, @@ -412,7 +411,6 @@ class GroupCallRemoteMemberView: GroupCallMemberView { avatarView.updateWithSneakyTransactionIfNecessary { config in config.sizeClass = .customDiameter(avatarDiameter) - return .asynchronously } } diff --git a/Signal/src/Calls/UserInterface/Individual/IndividualCallViewController.swift b/Signal/src/Calls/UserInterface/Individual/IndividualCallViewController.swift index b4a6aba13f..f900f9680e 100644 --- a/Signal/src/Calls/UserInterface/Individual/IndividualCallViewController.swift +++ b/Signal/src/Calls/UserInterface/Individual/IndividualCallViewController.swift @@ -500,7 +500,6 @@ class IndividualCallViewController: OWSViewController, CallObserver, CallAudioSe databaseStorage.read { transaction in contactAvatarView.update(transaction) { config in config.dataSource = .thread(thread) - return .asynchronously } backgroundAvatarView.image = contactsManagerImpl.avatarImage(forAddress: thread.contactAddress, shouldValidate: true, diff --git a/Signal/src/ViewControllers/AppSettings/Payments/PaymentModelCell.swift b/Signal/src/ViewControllers/AppSettings/Payments/PaymentModelCell.swift index 3df493e2d6..283ca38bd1 100644 --- a/Signal/src/ViewControllers/AppSettings/Payments/PaymentModelCell.swift +++ b/Signal/src/ViewControllers/AppSettings/Payments/PaymentModelCell.swift @@ -74,7 +74,6 @@ public class PaymentModelCell: UITableViewCell { if let address = paymentItem.address { contactAvatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .address(address) - return .asynchronously } avatarView = contactAvatarView } else { diff --git a/Signal/src/ViewControllers/AppSettings/Payments/PaymentsDetailViewController.swift b/Signal/src/ViewControllers/AppSettings/Payments/PaymentsDetailViewController.swift index 96ed3de03e..13e5c893e6 100644 --- a/Signal/src/ViewControllers/AppSettings/Payments/PaymentsDetailViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Payments/PaymentsDetailViewController.swift @@ -368,7 +368,6 @@ class PaymentsDetailViewController: OWSTableViewController2 { databaseStorage.read { transaction in avatarView.update(transaction) { config in config.dataSource = .address(address) - return .asynchronously } let username = Self.contactsManager.displayName(for: address, transaction: transaction) diff --git a/Signal/src/ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift index db6b868918..4ea0e09d32 100644 --- a/Signal/src/ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift @@ -252,7 +252,6 @@ class ProfileSettingsViewController: OWSTableViewController2 { } else { config.dataSource = nil } - return .asynchronously } cell.contentView.addSubview(badgedAvatarView) diff --git a/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentMessage.swift b/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentMessage.swift index d460d00842..78d2b82168 100644 --- a/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentMessage.swift +++ b/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentMessage.swift @@ -375,7 +375,7 @@ public class CVComponentMessage: CVComponentBase, CVRootComponent { // No transaction will be necessary since our data source is preloaded componentView.avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = senderAvatar.avatarDataSource - return .synchronously + config.applyConfigurationSynchronously() } } // Add the view wrapper, not the view. @@ -2173,7 +2173,6 @@ public class CVComponentMessage: CVComponentBase, CVRootComponent { let avatarView = ConversationAvatarView(sizeClass: componentView.avatarView.configuration.sizeClass) avatarView.updateWithSneakyTransactionIfNecessary { newConfig in newConfig = componentView.avatarView.configuration - return .synchronously } avatarView.frame = componentView.avatarView.bounds let isRTL = CurrentAppContext().isRTL diff --git a/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentThreadDetails.swift b/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentThreadDetails.swift index 8d16515019..1af3461573 100644 --- a/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentThreadDetails.swift +++ b/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentThreadDetails.swift @@ -79,7 +79,7 @@ public class CVComponentThreadDetails: CVComponentBase, CVRootComponent { avatarView.updateWithSneakyTransactionIfNecessary { configuration in // Transaction isn't necessary since we pre-fetched our data source configuration.dataSource = avatarDataSource - return .synchronously + configuration.applyConfigurationSynchronously() } componentView.avatarView = avatarView if threadDetails.isAvatarBlurred { diff --git a/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentTypingIndicator.swift b/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentTypingIndicator.swift index 52ae0b52c2..376afbc967 100644 --- a/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentTypingIndicator.swift +++ b/Signal/src/ViewControllers/ConversationView/CV/CVComponents/CVComponentTypingIndicator.swift @@ -64,7 +64,7 @@ public class CVComponentTypingIndicator: CVComponentBase, CVRootComponent { // No transaction is necessary since our data source is already loaded avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = avatarDataSource - return .synchronously + config.applyConfigurationSynchronously() } outerViews.append(avatarView) } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationHeaderView.swift b/Signal/src/ViewControllers/ConversationView/ConversationHeaderView.swift index ab444a47de..e1ef2be761 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationHeaderView.swift +++ b/Signal/src/ViewControllers/ConversationView/ConversationHeaderView.swift @@ -121,7 +121,7 @@ public class ConversationHeaderView: UIStackView { public func configure(thread: TSThread) { avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .thread(thread) - return .synchronously + config.applyConfigurationSynchronously() } } @@ -137,7 +137,7 @@ public class ConversationHeaderView: UIStackView { } public func updateAvatar() { - avatarView.updateWithSneakyTransactionIfNecessary { _ in .asynchronously } + avatarView.updateWithSneakyTransactionIfNecessary { _ in } } public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { @@ -145,7 +145,6 @@ public class ConversationHeaderView: UIStackView { avatarView.updateWithSneakyTransactionIfNecessary { config in config.sizeClass = avatarSizeClass config.addBadgeIfApplicable = shouldBadgeAvatar - return .asynchronously } } diff --git a/Signal/src/ViewControllers/ConversationView/Reactions Details/EmojiReactorsTableView.swift b/Signal/src/ViewControllers/ConversationView/Reactions Details/EmojiReactorsTableView.swift index 31a83b587e..3cdb9eb2db 100644 --- a/Signal/src/ViewControllers/ConversationView/Reactions Details/EmojiReactorsTableView.swift +++ b/Signal/src/ViewControllers/ConversationView/Reactions Details/EmojiReactorsTableView.swift @@ -115,7 +115,6 @@ private class EmojiReactorCell: UITableViewCell { avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .address(item.address) - return .asynchronously } } } diff --git a/Signal/src/ViewControllers/GroupMigrationActionSheet.swift b/Signal/src/ViewControllers/GroupMigrationActionSheet.swift index 8e8afcc758..c19c994cd9 100644 --- a/Signal/src/ViewControllers/GroupMigrationActionSheet.swift +++ b/Signal/src/ViewControllers/GroupMigrationActionSheet.swift @@ -165,7 +165,6 @@ public class GroupMigrationActionSheet: UIView { let avatarView = ConversationAvatarView(sizeClass: .customDiameter(28)) avatarView.update(transaction) { config in config.dataSource = .address(address) - return .asynchronously } let label = buildLabel() diff --git a/Signal/src/ViewControllers/HomeView/HomeViewCell.swift b/Signal/src/ViewControllers/HomeView/HomeViewCell.swift index 710763e758..494ac159df 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewCell.swift +++ b/Signal/src/ViewControllers/HomeView/HomeViewCell.swift @@ -313,7 +313,9 @@ public class HomeViewCell: UITableViewCell { avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .thread(cellContentToken.thread) - return cellContentToken.shouldLoadAvatarAsync ? .asynchronously : .synchronously + if !cellContentToken.shouldLoadAvatarAsync { + config.applyConfigurationSynchronously() + } } typingIndicatorView.configureForHomeView() diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.swift b/Signal/src/ViewControllers/HomeView/HomeViewController.swift index bf3836623e..c98be4d413 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.swift +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.swift @@ -80,7 +80,6 @@ public extension HomeViewController { let avatarView = ConversationAvatarView(sizeClass: .customDiameter(Self.paymentsBannerAvatarSize)) avatarView.update(transaction) { config in config.dataSource = .address(address) - return .asynchronously } let paymentsHistoryItem = PaymentsHistoryItem(paymentModel: paymentModel, @@ -240,8 +239,8 @@ public extension HomeViewController { avatarView.update(readTx) { config in if let address = tsAccountManager.localAddress(with: readTx) { config.dataSource = .address(address) + config.applyConfigurationSynchronously() } - return .synchronously } } return avatarView diff --git a/Signal/src/ViewControllers/NewGroupView/NewGroupMembersBar.swift b/Signal/src/ViewControllers/NewGroupView/NewGroupMembersBar.swift index 3839031913..af0711ccdb 100644 --- a/Signal/src/ViewControllers/NewGroupView/NewGroupMembersBar.swift +++ b/Signal/src/ViewControllers/NewGroupView/NewGroupMembersBar.swift @@ -228,7 +228,6 @@ private class NewGroupMemberCell: UICollectionViewCell { self.member = member avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .address(member.address) - return .asynchronously } textLabel.text = member.shortName } diff --git a/Signal/src/ViewControllers/ReturnToCallViewController.swift b/Signal/src/ViewControllers/ReturnToCallViewController.swift index 2e282d382c..4de158a074 100644 --- a/Signal/src/ViewControllers/ReturnToCallViewController.swift +++ b/Signal/src/ViewControllers/ReturnToCallViewController.swift @@ -58,7 +58,6 @@ public class ReturnToCallViewController: UIViewController { let profileImage = databaseStorage.read { transaction -> UIImage? in avatarView.update(transaction) { config in config.dataSource = .address(callViewController.remoteVideoAddress) - return .asynchronously } return self.profileManagerImpl.profileAvatar(for: callViewController.remoteVideoAddress, transaction: transaction) diff --git a/Signal/src/ViewControllers/ThreadSettings/ConversationHeaderBuilder.swift b/Signal/src/ViewControllers/ThreadSettings/ConversationHeaderBuilder.swift index 3d823fc53d..622f16f68d 100644 --- a/Signal/src/ViewControllers/ThreadSettings/ConversationHeaderBuilder.swift +++ b/Signal/src/ViewControllers/ThreadSettings/ConversationHeaderBuilder.swift @@ -443,7 +443,6 @@ struct ConversationHeaderBuilder: Dependencies { avatarView.update(transaction) { $0.dataSource = .thread(delegate.thread) - return .asynchronously } // Track the most recent avatar view. diff --git a/Signal/src/views/GroupTableViewCell.swift b/Signal/src/views/GroupTableViewCell.swift index c4707258e8..6c68232da6 100644 --- a/Signal/src/views/GroupTableViewCell.swift +++ b/Signal/src/views/GroupTableViewCell.swift @@ -63,7 +63,6 @@ import SignalUI self.avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .thread(thread) - return .asynchronously } if let accessoryMessage = accessoryMessage, !accessoryMessage.isEmpty { diff --git a/Signal/src/views/NameCollisionReviewCell.swift b/Signal/src/views/NameCollisionReviewCell.swift index ede6f85287..07d740ceb7 100644 --- a/Signal/src/views/NameCollisionReviewCell.swift +++ b/Signal/src/views/NameCollisionReviewCell.swift @@ -226,7 +226,6 @@ class NameCollisionCell: UITableViewCell { avatarView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .address(model.address) - return .asynchronously } if model.address.isLocalAddress { nameLabel.text = NSLocalizedString( diff --git a/SignalUI/Views/ContactCellView.swift b/SignalUI/Views/ContactCellView.swift index fd851c23f4..e57fee939d 100644 --- a/SignalUI/Views/ContactCellView.swift +++ b/SignalUI/Views/ContactCellView.swift @@ -163,7 +163,6 @@ public class ContactCellView: ManualStackView { config.dataSource = avatarDataSource config.addBadgeIfApplicable = configuration.badged config.localUserDisplayMode = configuration.localUserDisplayMode - return .asynchronously } // Update fonts to reflect changes to dynamic type. diff --git a/SignalUI/Views/ConversationAvatarView.swift b/SignalUI/Views/ConversationAvatarView.swift index 8ae240991b..3ed16acf27 100644 --- a/SignalUI/Views/ConversationAvatarView.swift +++ b/SignalUI/Views/ConversationAvatarView.swift @@ -8,7 +8,7 @@ import SignalMessaging public class ConversationAvatarView: UIView, CVView, PrimaryImageView { public required init( - sizeClass: Configuration.SizeClass, + sizeClass: Configuration.SizeClass = .customDiameter(0), localUserDisplayMode: LocalUserDisplayMode = .asUser, badged: Bool = false, shape: Configuration.Shape = .circular, @@ -78,13 +78,33 @@ public class ConversationAvatarView: UIView, CVView, PrimaryImageView { case circular } + /// The preferred size class of the avatar. Used for avatar generation and autolayout (if enabled) + /// If a predefined size class is used, a badge can optionally be placed by specifying `addBadgeIfApplicable` public var sizeClass: SizeClass + /// The data provider used to fetch an avatar and badge public var dataSource: ConversationAvatarDataSource? + /// Adjusts how the local user profile avatar is generated (Note to Self or Avatar?) public var localUserDisplayMode: LocalUserDisplayMode + /// Places the user's badge (if they have one) over the avatar. Only supported for predefined size classes public var addBadgeIfApplicable: Bool + /// Adjusts the mask of the avatar view public var shape: Shape + /// If set `true`, adds constraints to the view to ensure that it's sized for the provided size class + /// Otherwise, it's the superview's responsibility to ensure this view is sized appropriately public var useAutolayout: Bool + + // Adopters that'd like to fetch the image synchronously can set this to perform + // the next model update synchronously if necessary. + fileprivate var updateSynchronously: Bool = false + public mutating func applyConfigurationSynchronously() { + updateSynchronously = true + } + fileprivate mutating func checkForSyncUpdateAndClear() -> Bool { + let shouldUpdateSync = updateSynchronously + updateSynchronously = false + return shouldUpdateSync + } } public private(set) var configuration: Configuration { @@ -94,67 +114,74 @@ public class ConversationAvatarView: UIView, CVView, PrimaryImageView { owsFailDebug("Invalid configuration. Badging not supported with custom size classes") configuration.addBadgeIfApplicable = false } - - // We may need to update our model, layout, or constraints based on the changes to the configuration - let sizeClassDidChange = configuration.sizeClass != oldValue.sizeClass - let dataSourceDidChange = configuration.dataSource != oldValue.dataSource - let localUserDisplayModeDidChange = configuration.localUserDisplayMode != oldValue.localUserDisplayMode - let shouldShowBadgeDidChange = configuration.addBadgeIfApplicable != oldValue.addBadgeIfApplicable - let shapeDidChange = configuration.shape != oldValue.shape - let autolayoutDidChange = configuration.useAutolayout != oldValue.useAutolayout - - // Any changes to avatar size or provider will trigger a model update - if sizeClassDidChange || dataSourceDidChange || localUserDisplayModeDidChange || shouldShowBadgeDidChange { - setNeedsModelUpdate() - } - - // If autolayout was toggled, or the size changed while autolayout is enabled we need to update our constraints - if autolayoutDidChange || (configuration.useAutolayout && sizeClassDidChange) { - setNeedsUpdateConstraints() - } - - if sizeClassDidChange || shouldShowBadgeDidChange || shapeDidChange { - setNeedsLayout() + if configuration.dataSource != oldValue.dataSource { + ensureObservers() } } } - public enum UpdateBehavior { - case synchronously - case asynchronously + func updateConfigurationAndSetDirtyIfNecessary(_ newValue: Configuration) { + let oldValue = configuration + configuration = newValue + + // We may need to update our model, layout, or constraints based on the changes to the configuration + let sizeClassDidChange = configuration.sizeClass != oldValue.sizeClass + let dataSourceDidChange = configuration.dataSource != oldValue.dataSource + let localUserDisplayModeDidChange = configuration.localUserDisplayMode != oldValue.localUserDisplayMode + let shouldShowBadgeDidChange = configuration.addBadgeIfApplicable != oldValue.addBadgeIfApplicable + let shapeDidChange = configuration.shape != oldValue.shape + let autolayoutDidChange = configuration.useAutolayout != oldValue.useAutolayout + + // Any changes to avatar size or provider will trigger a model update + if sizeClassDidChange || dataSourceDidChange || localUserDisplayModeDidChange || shouldShowBadgeDidChange { + setNeedsModelUpdate() + } + + // If autolayout was toggled, or the size changed while autolayout is enabled we need to update our constraints + if autolayoutDidChange || (configuration.useAutolayout && sizeClassDidChange) { + setNeedsUpdateConstraints() + } + + if sizeClassDidChange || shouldShowBadgeDidChange || shapeDidChange { + setNeedsLayout() + } } - public func updateWithSneakyTransactionIfNecessary(_ block: (inout Configuration) -> UpdateBehavior) { - update(optionalTransaction: nil, block) + // MARK: Configuration updates + + public func updateWithSneakyTransactionIfNecessary(_ updateBlock: (inout Configuration) -> Void) { + update(optionalTransaction: nil, updateBlock) } /// To reduce the occurrence of unnecessary avatar fetches, updates to the view configuration occur in a closure - /// Callers can specify a synchronous or asynchronous model update through the closure's return value - public func update(_ transaction: SDSAnyReadTransaction, _ block: (inout Configuration) -> UpdateBehavior) { + /// Configuration updates will be applied all at once + public func update(_ transaction: SDSAnyReadTransaction, _ updateBlock: (inout Configuration) -> Void) { AssertIsOnMainThread() - update(optionalTransaction: transaction, block) + update(optionalTransaction: transaction, updateBlock) } - private func update(optionalTransaction transaction: SDSAnyReadTransaction?, _ block: (inout Configuration) -> UpdateBehavior) { + private func update(optionalTransaction transaction: SDSAnyReadTransaction?, _ updateBlock: (inout Configuration) -> Void) { AssertIsOnMainThread() let oldConfiguration = configuration var mutableConfig = oldConfiguration - let updateBehavior = block(&mutableConfig) - configuration = mutableConfig - updateModelIfNecessary(updateBehavior, transaction: transaction) + updateBlock(&mutableConfig) + updateConfigurationAndSetDirtyIfNecessary(mutableConfig) + updateModelIfNecessary(transaction: transaction) } + // MARK: Model Updates + // Forces a model update - private func updateModel(_ behavior: UpdateBehavior, transaction readTx: SDSAnyReadTransaction) { + private func updateModel(transaction readTx: SDSAnyReadTransaction?) { setNeedsModelUpdate() - updateModelIfNecessary(behavior, transaction: readTx) + updateModelIfNecessary(transaction: readTx) } // If the model has been dirtied, performs an update // If an async update is requested, the model is updated immediately with any available chached content // followed by enqueueing a full model update on a background thread. - private func updateModelIfNecessary(_ behavior: UpdateBehavior, transaction readTx: SDSAnyReadTransaction?) { + private func updateModelIfNecessary(transaction readTx: SDSAnyReadTransaction?) { AssertIsOnMainThread() guard nextModelGeneration.get() > currentModelGeneration else { return } @@ -163,17 +190,15 @@ public class ConversationAvatarView: UIView, CVView, PrimaryImageView { return } - switch behavior { - case .synchronously: + let updateSynchronously = configuration.checkForSyncUpdateAndClear() + if updateSynchronously { let avatarImage = dataSource.buildImage(configuration: configuration, transaction: readTx) let badgeImage = dataSource.fetchBadge(configuration: configuration, transaction: readTx) updateViewContent(avatarImage: avatarImage, badgeImage: badgeImage) - - case .asynchronously: + } else { let avatarImage = dataSource.fetchCachedImage(configuration: configuration, transaction: readTx) let badgeImage = dataSource.fetchBadge(configuration: configuration, transaction: readTx) updateViewContent(avatarImage: avatarImage, badgeImage: badgeImage) - enqueueAsyncModelUpdate() } } @@ -346,10 +371,7 @@ public class ConversationAvatarView: UIView, CVView, PrimaryImageView { @objc private func themeDidChange() { AssertIsOnMainThread() - - databaseStorage.read { readTx in - updateModel(.asynchronously, transaction: readTx) - } + updateModel(transaction: nil) } @objc @@ -358,9 +380,7 @@ public class ConversationAvatarView: UIView, CVView, PrimaryImageView { // PERF: It would be nice if we could do this only if *this* user's SignalAccount changed, // but currently this is only a course grained notification. - databaseStorage.read { readTx in - updateModel(.asynchronously, transaction: readTx) - } + updateModel(transaction: nil) } @objc @@ -393,7 +413,7 @@ public class ConversationAvatarView: UIView, CVView, PrimaryImageView { } if providerAddress == address { - databaseStorage.read { updateModel(.asynchronously, transaction: $0) } + updateModel(transaction: nil) } } @@ -429,7 +449,7 @@ public class ConversationAvatarView: UIView, CVView, PrimaryImageView { if contentThreadId == changedThreadId { databaseStorage.read { dataSource.reload(transaction: $0) - updateModel(.asynchronously, transaction: $0) + updateModel(transaction: $0) } } } diff --git a/SignalUI/Views/Mentions/MentionPicker.swift b/SignalUI/Views/Mentions/MentionPicker.swift index 84fc792022..e4a4ca9f5e 100644 --- a/SignalUI/Views/Mentions/MentionPicker.swift +++ b/SignalUI/Views/Mentions/MentionPicker.swift @@ -352,7 +352,6 @@ private class MentionableUserCell: UITableViewCell { avatarView.updateWithSneakyTransactionIfNecessary { configuration in configuration.dataSource = .address(mentionableUser.address) - return .asynchronously } } }