diff --git a/Signal/src/UIView+OWS.m b/Signal/src/UIView+OWS.m index 9531b793c..64143fc6e 100644 --- a/Signal/src/UIView+OWS.m +++ b/Signal/src/UIView+OWS.m @@ -167,11 +167,10 @@ CGFloat ScaleFromIPhone5(CGFloat iPhone5Value) { OWSAssert(self.superview); - self.frame = CGRectMake( - round(self.superview.bounds.origin.x + (self.superview.bounds.size.width - self.frame.size.width) * 0.5f), - round(self.superview.bounds.origin.y + (self.superview.bounds.size.height - self.frame.size.height) * 0.5f), - self.frame.size.width, - self.frame.size.height); + self.frame = CGRectMake(round(self.superview.left + (self.superview.width - self.width) * 0.5f), + round(self.superview.top + (self.superview.height - self.height) * 0.5f), + self.width, + self.height); } #pragma mark - Debugging diff --git a/Signal/src/ViewControllers/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUITableViewController.m index b890f92d8..c284b69cf 100644 --- a/Signal/src/ViewControllers/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUITableViewController.m @@ -1302,9 +1302,13 @@ NS_ASSUME_NONNULL_BEGIN if (counter < 1) { return; } - [ThreadUtil sendMessageWithText:[@(counter) description] - inThread:thread - messageSender:messageSender]; + [ThreadUtil + sendMessageWithText:[[@(counter) description] + stringByAppendingString:@" Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + @"Suspendisse rutrum, nulla vitae pretium hendrerit, tellus " + @"turpis pharetra libero, vitae sodales tortor ante vel sem."] + inThread:thread + messageSender:messageSender]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) 1.f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [self sendTextMessage:counter - 1 thread:thread]; diff --git a/Signal/src/ViewControllers/MessagesViewController.m b/Signal/src/ViewControllers/MessagesViewController.m index f2c4d846b..b2f720b4b 100644 --- a/Signal/src/ViewControllers/MessagesViewController.m +++ b/Signal/src/ViewControllers/MessagesViewController.m @@ -98,6 +98,8 @@ typedef enum : NSUInteger { - (void)didPasteAttachment:(SignalAttachment * _Nullable)attachment; +- (void)textViewDidChangeSize; + @end #pragma mark - @@ -146,6 +148,28 @@ typedef enum : NSUInteger { [super paste:sender]; } +- (void)setFrame:(CGRect)frame +{ + BOOL didChangeSize = !CGSizeEqualToSize(frame.size, self.frame.size); + + [super setFrame:frame]; + + if (didChangeSize) { + [self.textViewPasteDelegate textViewDidChangeSize]; + } +} + +- (void)setBounds:(CGRect)bounds +{ + BOOL didChangeSize = !CGSizeEqualToSize(bounds.size, self.bounds.size); + + [super setBounds:bounds]; + + if (didChangeSize) { + [self.textViewPasteDelegate textViewDidChangeSize]; + } +} + @end #pragma mark - @@ -782,6 +806,7 @@ typedef enum : NSUInteger { self.senderId = ME_MESSAGE_IDENTIFIER; self.senderDisplayName = ME_MESSAGE_IDENTIFIER; + self.automaticallyScrollsToMostRecentMessage = NO; [self initializeToolbars]; @@ -935,14 +960,6 @@ typedef enum : NSUInteger { [self setBarButtonItemsForDisappearingMessagesConfiguration:configuration]; [self setNavigationTitle]; - NSInteger numberOfMessages = (NSInteger)[self.messageMappings numberOfItemsInGroup:self.thread.uniqueId]; - if (numberOfMessages > 0) { - NSIndexPath *lastCellIndexPath = [NSIndexPath indexPathForRow:numberOfMessages - 1 inSection:0]; - [self.collectionView scrollToItemAtIndexPath:lastCellIndexPath - atScrollPosition:UICollectionViewScrollPositionBottom - animated:NO]; - } - // Other views might change these custom menu items, so we // need to set them every time we enter this view. SEL saveSelector = NSSelectorFromString(@"save:"); @@ -961,6 +978,35 @@ typedef enum : NSUInteger { [self resetContentAndLayout]; [((OWSMessagesToolbarContentView *)self.inputToolbar.contentView)ensureSubviews]; + + [self scrollToDefaultPosition]; + [self.collectionView.collectionViewLayout + invalidateLayoutWithContext:[JSQMessagesCollectionViewFlowLayoutInvalidationContext context]]; +} + +- (NSIndexPath *_Nullable)indexPathOfUnreadMessagesIndicator +{ + int numberOfMessages = (int)[self.messageMappings numberOfItemsInGroup:self.thread.uniqueId]; + for (int i = 0; i < numberOfMessages; i++) { + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; + id message = [self messageAtIndexPath:indexPath]; + if (message.messageType == TSUnreadIndicatorAdapter) { + return indexPath; + } + } + return nil; +} + +- (void)scrollToDefaultPosition +{ + NSIndexPath *_Nullable indexPath = [self indexPathOfUnreadMessagesIndicator]; + if (indexPath) { + [self.collectionView scrollToItemAtIndexPath:indexPath + atScrollPosition:UICollectionViewScrollPositionTop + animated:NO]; + } else { + [self scrollToBottomAnimated:NO]; + } } - (void)resetContentAndLayout @@ -3022,11 +3068,7 @@ typedef enum : NSUInteger { return; } - const CGFloat kIsAtBottomTolerancePts = 5; - BOOL wasAtBottom = (self.collectionView.contentOffset.y + - self.collectionView.bounds.size.height + - kIsAtBottomTolerancePts >= - self.collectionView.contentSize.height); + BOOL wasAtBottom = [self isScrolledToBottom]; // We want sending messages to feel snappy. So, if the only // update is a new outgoing message AND we're already scrolled to // the bottom of the conversation, skip the scroll animation. @@ -3052,11 +3094,11 @@ typedef enum : NSUInteger { } case YapDatabaseViewChangeInsert: { [self.collectionView insertItemsAtIndexPaths:@[ rowChange.newIndexPath ]]; - scrollToBottom = YES; TSInteraction *interaction = [self interactionAtIndexPath:rowChange.newIndexPath]; - if (![interaction isKindOfClass:[TSOutgoingMessage class]]) { - shouldAnimateScrollToBottom = YES; + if ([interaction isKindOfClass:[TSOutgoingMessage class]]) { + scrollToBottom = YES; + shouldAnimateScrollToBottom = NO; } break; } @@ -3088,6 +3130,13 @@ typedef enum : NSUInteger { }]; } +- (BOOL)isScrolledToBottom +{ + const CGFloat kIsAtBottomTolerancePts = 5; + return (self.collectionView.contentOffset.y + self.collectionView.bounds.size.height + kIsAtBottomTolerancePts + >= self.collectionView.contentSize.height); +} + #pragma mark - UICollectionView DataSource - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { @@ -3608,6 +3657,18 @@ typedef enum : NSUInteger { completion:nil]; } +- (void)textViewDidChangeSize +{ + OWSAssert([NSThread isMainThread]); + + BOOL wasAtBottom = [self isScrolledToBottom]; + if (wasAtBottom) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self scrollToBottomAnimated:NO]; + }); + } +} + #pragma mark - OWSMessagesToolbarContentDelegate - (void)voiceMemoGestureDidStart