From 897d4a925b6784006279ce833e2c663e0ab6cff0 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Sat, 21 Apr 2018 13:00:58 -0400 Subject: [PATCH] HomeView caches thread models // FREEBIE --- Signal/src/Models/ThreadModel.swift | 61 ------------------- .../HomeView/HomeViewController.m | 31 +++++++--- .../src/Messages/Interactions/TSInteraction.m | 7 ++- .../src/Messages/Interactions/TSMessage.m | 7 --- .../src/Storage/TSYapDatabaseObject.m | 6 +- 5 files changed, 31 insertions(+), 81 deletions(-) diff --git a/Signal/src/Models/ThreadModel.swift b/Signal/src/Models/ThreadModel.swift index 7e5bc685b..1722ac69c 100644 --- a/Signal/src/Models/ThreadModel.swift +++ b/Signal/src/Models/ThreadModel.swift @@ -20,67 +20,6 @@ public class ThreadModel: NSObject { let lastMessageText: String? -// func attributedSnippet(blockedPhoneNumberSet: Set) { -// let isBlocked: Bool = { -// guard let contactIdentifier = self.contactIdentifier else { -// return false -// } -// assert(isContactThread) -// return blockedPhoneNumberSet.contains(self.contactIdentifier) -// }() -// -// -// -//// BOOL hasUnreadMessages = thread.hasUnreadMessages; -// -//// NSMutableAttributedString *snippetText = [NSMutableAttributedString new]; -// var snippetText = NSMutableAttributedString() -// if isBlocked { -// // If thread is blocked, don't show a snippet or mute status. -// let append = NSAttributedString(string: NSLocalizedString("HOME_VIEW_BLOCKED_CONTACT_CONVERSATION", -// comment: "A label for conversations with blocked users."), -// attributes: <#T##[String : Any]?#>) -// -//// if (isBlocked) { -//// // If thread is blocked, don't show a snippet or mute status. -//// [snippetText -//// appendAttributedString:[[NSAttributedString alloc] -//// initWithString:NSLocalizedString(@"HOME_VIEW_BLOCKED_CONTACT_CONVERSATION", -//// @"A label for conversations with blocked users.") -//// attributes:@{ -//// NSFontAttributeName : self.snippetFont.ows_mediumWeight, -//// NSForegroundColorAttributeName : [UIColor ows_blackColor], -//// }]]; -//// } else { -//// if ([thread isMuted]) { -//// [snippetText appendAttributedString:[[NSAttributedString alloc] -//// initWithString:@"\ue067 " -//// attributes:@{ -//// NSFontAttributeName : [UIFont ows_elegantIconsFont:9.f], -//// NSForegroundColorAttributeName : (hasUnreadMessages -//// ? [UIColor colorWithWhite:0.1f alpha:1.f] -//// : [UIColor lightGrayColor]), -//// }]]; -//// } -//// NSString *displayableText = thread.lastMessageText; -//// if (displayableText) { -//// [snippetText appendAttributedString:[[NSAttributedString alloc] -//// initWithString:displayableText -//// attributes:@{ -//// NSFontAttributeName : -//// (hasUnreadMessages ? self.snippetFont.ows_mediumWeight -//// : self.snippetFont), -//// NSForegroundColorAttributeName : -//// (hasUnreadMessages ? [UIColor ows_blackColor] -//// : [UIColor lightGrayColor]), -//// }]]; -//// } -//// } -//// -//// return snippetText; -// } -// } - init(thread: TSThread, transaction: YapDatabaseReadTransaction) { self.threadRecord = thread self.lastMessageDate = thread.lastMessageDate() diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.m b/Signal/src/ViewControllers/HomeView/HomeViewController.m index 361f38516..71ed8b6a4 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.m @@ -47,7 +47,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState }; @property (nonatomic) UISegmentedControl *segmentedControl; @property (nonatomic) id previewingContext; @property (nonatomic) NSSet *blockedPhoneNumberSet; - +@property (nonatomic, readonly) NSCache *threadModelCache; @property (nonatomic) BOOL isViewVisible; @property (nonatomic) BOOL isAppInBackground; @property (nonatomic) BOOL shouldObserveDBModifications; @@ -108,6 +108,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState }; _messageSender = [Environment current].messageSender; _blockingManager = [OWSBlockingManager sharedManager]; _blockedPhoneNumberSet = [NSSet setWithArray:[_blockingManager blockedPhoneNumbers]]; + _threadModelCache = [NSCache new]; // Ensure ExperienceUpgradeFinder has been initialized. [ExperienceUpgradeFinder sharedManager]; @@ -595,17 +596,29 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState }; return (NSInteger)[self.threadMappings numberOfItemsInSection:(NSUInteger)section]; } -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +- (ThreadModel *)threadModelForIndexPath:(NSIndexPath *)indexPath { - HomeViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:HomeViewCell.cellReuseIdentifier]; - OWSAssert(cell); - TSThread *threadRecord = [self threadForIndexPath:indexPath]; - __block ThreadModel *thread; + + ThreadModel *_Nullable cachedThreadModel = [self.threadModelCache objectForKey:threadRecord.uniqueId]; + if (cachedThreadModel) { + return cachedThreadModel; + } + + __block ThreadModel *_Nullable newThreadModel; [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - thread = [[ThreadModel alloc] initWithThread:threadRecord transaction:transaction]; + newThreadModel = [[ThreadModel alloc] initWithThread:threadRecord transaction:transaction]; }]; + [self.threadModelCache setObject:newThreadModel forKey:threadRecord.uniqueId]; + return newThreadModel; +} +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + HomeViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:HomeViewCell.cellReuseIdentifier]; + OWSAssert(cell); + + ThreadModel *thread = [self threadModelForIndexPath:indexPath]; [cell configureWithThread:thread contactsManager:self.contactsManager blockedPhoneNumberSet:self.blockedPhoneNumberSet]; @@ -1016,6 +1029,10 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState }; } for (YapDatabaseViewRowChange *rowChange in rowChanges) { + NSString *key = rowChange.collectionKey.key; + OWSAssert(key); + [self.threadModelCache removeObjectForKey:key]; + switch (rowChange.type) { case YapDatabaseViewChangeDelete: { [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ] diff --git a/SignalServiceKit/src/Messages/Interactions/TSInteraction.m b/SignalServiceKit/src/Messages/Interactions/TSInteraction.m index fc796947e..bd6a53662 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInteraction.m +++ b/SignalServiceKit/src/Messages/Interactions/TSInteraction.m @@ -127,9 +127,10 @@ NS_ASSUME_NONNULL_BEGIN return OWSInteractionType_Unknown; } -- (NSString *)description { - OWSFail(@"Abstract Method"); - return @"Interaction description"; +- (NSString *)description +{ + return [NSString + stringWithFormat:@"%@ in thread: %@ timestamp: %tu", [super description], self.uniqueThreadId, self.timestamp]; } - (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index da06a35ab..071aada16 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -265,13 +265,6 @@ static const NSUInteger OWSMessageSchemaVersion = 4; } } -- (NSString *)description -{ - // TODO verify this isn't exposed in the UI - OWSFail(@"%@ in %s verify this isn't being used anywhere except logging.", self.logTag, __PRETTY_FUNCTION__); - return [super description]; -} - - (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { [super removeWithTransaction:transaction]; diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m index a11ac3d4e..260e31d50 100644 --- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m +++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m @@ -109,8 +109,8 @@ NS_ASSUME_NONNULL_BEGIN + (YapDatabaseConnection *)dbReadConnection { - OWSAssert(![NSThread isMainThread]); - + // OWSAssert(![NSThread isMainThread]); + // We use TSYapDatabaseObject's dbReadWriteConnection (not OWSPrimaryStorage's // dbReadConnection) for consistency, since we tend to [TSYapDatabaseObject // save] and want to write to the same connection we read from. To get true @@ -121,7 +121,7 @@ NS_ASSUME_NONNULL_BEGIN + (YapDatabaseConnection *)dbReadWriteConnection { - OWSAssert(![NSThread isMainThread]); + // OWSAssert(![NSThread isMainThread]); // Use a dedicated connection for model reads & writes. static YapDatabaseConnection *dbReadWriteConnection = nil;