diff --git a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m index b19f66fe8..f7c0c053d 100644 --- a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m +++ b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m @@ -2186,7 +2186,7 @@ typedef enum : NSUInteger { { OWSAssert(!self.isUserScrolling); - BOOL hasMoreUnseenMessages = self.dynamicInteractions.hasMoreUnseenMessages; + BOOL hasEarlierUnseenMessages = self.dynamicInteractions.hasMoreUnseenMessages; // We want to restore the current scroll state after we update the range, update // the dynamic interactions and re-layout. Here we take a "before" snapshot. @@ -2234,7 +2234,10 @@ typedef enum : NSUInteger { self.collectionView.contentOffset = CGPointMake(0, self.collectionView.contentSize.height - scrollDistanceToBottom); [self.scrollLaterTimer invalidate]; - if (hasMoreUnseenMessages) { + // Don’t auto-scroll after “loading more messages” unless we have “more unseen messages”. + // + // Otherwise, tapping on "load more messages" autoscrolls you downward which is completely wrong. + if (hasEarlierUnseenMessages) { // We want to scroll to the bottom _after_ the layout has been updated. self.scrollLaterTimer = [NSTimer weakScheduledTimerWithTimeInterval:0.001f target:self diff --git a/Signal/src/util/ThreadUtil.h b/Signal/src/util/ThreadUtil.h index 5a4bf67e8..41c84ab78 100644 --- a/Signal/src/util/ThreadUtil.h +++ b/Signal/src/util/ThreadUtil.h @@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN // This is used by MessageViewController to increase the // range size of the mappings (the load window of the conversation) // to include the unread indicator. -@property (nonatomic, nullable) NSNumber *unreadIndicatorPosition; +@property (nonatomic, nullable, readonly) NSNumber *unreadIndicatorPosition; // If there are unseen messages in the thread, this is the timestamp // of the oldest unseen messaage. @@ -34,9 +34,9 @@ NS_ASSUME_NONNULL_BEGIN // repeatedly. The unread indicator should continue to show up until // it has been cleared, at which point hideUnreadMessagesIndicator is // YES in ensureDynamicInteractionsForThread:... -@property (nonatomic, nullable) NSNumber *firstUnseenInteractionTimestamp; +@property (nonatomic, nullable, readonly) NSNumber *firstUnseenInteractionTimestamp; -@property (nonatomic) BOOL hasMoreUnseenMessages; +@property (nonatomic, readonly) BOOL hasMoreUnseenMessages; - (void)clearUnreadIndicatorState; diff --git a/Signal/src/util/ThreadUtil.m b/Signal/src/util/ThreadUtil.m index 6b5ed208b..7dfb85018 100644 --- a/Signal/src/util/ThreadUtil.m +++ b/Signal/src/util/ThreadUtil.m @@ -18,6 +18,18 @@ NS_ASSUME_NONNULL_BEGIN +@interface ThreadDynamicInteractions () + +@property (nonatomic, nullable) NSNumber *unreadIndicatorPosition; + +@property (nonatomic, nullable) NSNumber *firstUnseenInteractionTimestamp; + +@property (nonatomic) BOOL hasMoreUnseenMessages; + +@end + +#pragma mark - + @implementation ThreadDynamicInteractions - (void)clearUnreadIndicatorState