From 999e8c8e31297deb9ef761ad620910921fa11554 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 12 Jun 2018 09:43:59 -0400 Subject: [PATCH] Respond to CR. --- .../ConversationViewController.m | 22 ++++++---- SignalMessaging/utils/ThreadUtil.h | 4 ++ SignalMessaging/utils/ThreadUtil.m | 40 +++++++++++-------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 70525279d..55f436262 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -708,15 +708,23 @@ typedef enum : NSUInteger { - (NSIndexPath *_Nullable)indexPathOfMessageOnOpen { OWSAssert(self.focusMessageIdOnOpen); + OWSAssert(self.dynamicInteractions.focusMessagePosition); - NSInteger row = 0; - for (ConversationViewItem *viewItem in self.viewItems) { - if ([viewItem.interaction.uniqueId isEqualToString:self.focusMessageIdOnOpen]) { - return [NSIndexPath indexPathForRow:row inSection:0]; - } - row++; + if (!self.dynamicInteractions.focusMessagePosition) { + // This might happen if the focus message has disappeared + // before this view could appear. + OWSFail(@"%@ focus message has unknown position.", self.logTag); + return nil; } - return nil; + NSUInteger focusMessagePosition = self.dynamicInteractions.focusMessagePosition.unsignedIntegerValue; + if (focusMessagePosition >= self.viewItems.count) { + // This might happen if the focus message is outside the maximum + // valid load window size for this view. + OWSFail(@"%@ focus message has invalid position.", self.logTag); + return nil; + } + NSInteger row = (NSInteger)((self.viewItems.count - 1) - focusMessagePosition); + return [NSIndexPath indexPathForRow:row inSection:0]; } - (void)scrollToDefaultPosition diff --git a/SignalMessaging/utils/ThreadUtil.h b/SignalMessaging/utils/ThreadUtil.h index 9d65f4520..32833f0ad 100644 --- a/SignalMessaging/utils/ThreadUtil.h +++ b/SignalMessaging/utils/ThreadUtil.h @@ -25,6 +25,10 @@ NS_ASSUME_NONNULL_BEGIN // to include the unread indicator. @property (nonatomic, nullable, readonly) NSNumber *unreadIndicatorPosition; +// Represents the "reverse index" of the focus message, if any. +// The "reverse index" is the distance of this interaction from +// the last interaction in the thread. Therefore the last interaction +// will have a "reverse index" of zero. @property (nonatomic, nullable, readonly) NSNumber *focusMessagePosition; // If there are unseen messages in the thread, this is the timestamp diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index 41d7f6889..ad516915a 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -639,23 +639,29 @@ NS_ASSUME_NONNULL_BEGIN OWSAssert(transaction); OWSAssert(focusMessageId); - // Enumerate in reverse to count the number of messages after the "focus message". - __block NSUInteger count = 0; - __block BOOL didMatch = NO; - [[transaction ext:TSMessageDatabaseViewExtensionName] - enumerateKeysInGroup:thread.uniqueId - withOptions:NSEnumerationReverse - usingBlock:^(NSString *collection, NSString *key, NSUInteger index, BOOL *stop) { - if ([key isEqualToString:focusMessageId]) { - didMatch = YES; - *stop = YES; - return; - } - - count++; - }]; - - return didMatch ? @(count) : nil; + YapDatabaseViewTransaction *databaseView = [transaction ext:TSMessageDatabaseViewExtensionName]; + + NSString *_Nullable group = nil; + NSUInteger index; + BOOL success = + [databaseView getGroup:&group index:&index forKey:focusMessageId inCollection:TSInteraction.collection]; + if (!success) { + // This might happen if the focus message has disappeared + // before this view could appear. + OWSFail(@"%@ failed to find focus message index.", self.logTag); + return nil; + } + if (![group isEqualToString:thread.uniqueId]) { + OWSFail(@"%@ focus message has invalid group.", self.logTag); + return nil; + } + NSUInteger count = [databaseView numberOfItemsInGroup:thread.uniqueId]; + if (index >= count) { + OWSFail(@"%@ focus message has invalid index.", self.logTag); + return nil; + } + NSUInteger position = (count - index) - 1; + return @(position); } + (BOOL)shouldShowGroupProfileBannerInThread:(TSThread *)thread blockingManager:(OWSBlockingManager *)blockingManager