diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index b12153673..c76303fb6 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -33,9 +33,6 @@ const CGFloat kTypingCellHeight = 24; { // Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. id kThemeServiceDidChangeThemeNotificationObserver; - - // Observe URL preview updates to refresh cells. - id kURLPreviewDidUpdateNotificationObserver; } // Observe key verification request changes @@ -96,20 +93,6 @@ const CGFloat kTypingCellHeight = 24; }]; - // Observe URL preview updates. - kURLPreviewDidUpdateNotificationObserver = [NSNotificationCenter.defaultCenter addObserverForName:URLPreviewDidUpdateNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull notification) { - - if (![(NSString*)notification.userInfo[@"roomId"] isEqualToString:self.roomId] || !self.delegate) - { - return; - } - - // Refresh the updated cell. - // Note - it doesn't appear as though MXKRoomViewController actually uses the index path. - NSInteger index = [self indexOfCellDataWithEventId:(NSString*)notification.userInfo[@"eventId"]]; - [self.delegate dataSource:self didCellChange:[NSIndexPath indexPathWithIndex:index]]; - }]; - [self registerKeyVerificationRequestNotification]; [self registerKeyVerificationTransactionNotification]; [self registerTrustLevelDidChangeNotifications]; @@ -178,12 +161,6 @@ const CGFloat kTypingCellHeight = 24; kThemeServiceDidChangeThemeNotificationObserver = nil; } - if (kURLPreviewDidUpdateNotificationObserver) - { - [NSNotificationCenter.defaultCenter removeObserver:kURLPreviewDidUpdateNotificationObserver]; - kURLPreviewDidUpdateNotificationObserver = nil; - } - if (self.keyVerificationRequestDidChangeNotificationObserver) { [[NSNotificationCenter defaultCenter] removeObserver:self.keyVerificationRequestDidChangeNotificationObserver]; diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 8d9688c8e..5d6f42ec7 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -206,6 +206,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. id kThemeServiceDidChangeThemeNotificationObserver; + // Observe URL preview updates to refresh cells. + id URLPreviewDidUpdateNotificationObserver; + // Listener for `m.room.tombstone` event type id tombstoneEventNotificationsListener; @@ -438,6 +441,45 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]; [self userInterfaceThemeDidChange]; + // Observe URL preview updates. + URLPreviewDidUpdateNotificationObserver = [NSNotificationCenter.defaultCenter addObserverForName:URLPreviewDidUpdateNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull notification) { + + // Ensure this is the correct room + if (![(NSString*)notification.userInfo[@"roomId"] isEqualToString:self.roomDataSource.roomId]) + { + return; + } + + // Get the indexPath for the updated cell. + NSString *updatedEventId = notification.userInfo[@"eventId"]; + NSInteger updatedEventIndex = [self.roomDataSource indexOfCellDataWithEventId:updatedEventId]; + NSIndexPath *updatedIndexPath = [NSIndexPath indexPathForRow:updatedEventIndex inSection:0]; + + // Store the content size and offset before reloading the cell + CGFloat originalContentSize = self.bubblesTableView.contentSize.height; + CGPoint contentOffset = self.bubblesTableView.contentOffset; + + // Only update the content offset if the cell is visible or above the current visible cells. + BOOL shouldUpdateContentOffset = NO; + NSIndexPath *lastVisibleIndexPath = [self.bubblesTableView indexPathsForVisibleRows].lastObject; + if (lastVisibleIndexPath && updatedIndexPath.row < lastVisibleIndexPath.row) + { + shouldUpdateContentOffset = YES; + } + + // Note: Despite passing in the index path, this reloads the whole table. + [self dataSource:self.roomDataSource didCellChange:updatedIndexPath]; + + // Update the content offset to include any changes to the scroll view's height. + if (shouldUpdateContentOffset) + { + CGFloat delta = self.bubblesTableView.contentSize.height - originalContentSize; + contentOffset.y += delta; + + self.bubblesTableView.contentOffset = contentOffset; + } + }]; + [self setupActions]; } @@ -1356,6 +1398,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [[NSNotificationCenter defaultCenter] removeObserver:mxEventDidDecryptNotificationObserver]; mxEventDidDecryptNotificationObserver = nil; } + if (URLPreviewDidUpdateNotificationObserver) + { + [NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver]; + URLPreviewDidUpdateNotificationObserver = nil; + } [self removeCallNotificationsListeners]; [self removeWidgetNotificationsListeners];