Respond to CR.

pull/1/head
Matthew Chen 7 years ago
parent 89523f556b
commit 16a1dcfb77

@ -465,6 +465,12 @@ typedef enum : NSUInteger {
return; return;
} }
[self.messageMappings setCellDrawingDependencyOffsets:[NSSet setWithArray:@[
@(-1),
@(+1),
]]
forGroup:self.thread.uniqueId];
// We need to impose the range restrictions on the mappings immediately to avoid // We need to impose the range restrictions on the mappings immediately to avoid
// doing a great deal of unnecessary work and causing a perf hotspot. // doing a great deal of unnecessary work and causing a perf hotspot.
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
@ -3303,8 +3309,13 @@ typedef enum : NSUInteger {
case YapDatabaseViewChangeUpdate: { case YapDatabaseViewChangeUpdate: {
YapCollectionKey *collectionKey = rowChange.collectionKey; YapCollectionKey *collectionKey = rowChange.collectionKey;
if (collectionKey.key) { if (collectionKey.key) {
ConversationViewItem *viewItem = self.viewItemCache[collectionKey.key]; ConversationViewItem *_Nullable viewItem = self.viewItemCache[collectionKey.key];
if (viewItem) {
[self reloadInteractionForViewItem:viewItem]; [self reloadInteractionForViewItem:viewItem];
}
} else if (rowChange.indexPath && rowChange.originalIndex < self.viewItems.count) {
// Do nothing, this is a pseudo-update generated due to
// setCellDrawingDependencyOffsets.
} else { } else {
hasMalformedRowChange = YES; hasMalformedRowChange = YES;
} }
@ -3332,7 +3343,8 @@ typedef enum : NSUInteger {
if (hasMalformedRowChange) { if (hasMalformedRowChange) {
// These errors seems to be very rare; they can only be reproduced // These errors seems to be very rare; they can only be reproduced
// using the more extreme actions in the debug UI. // using the more extreme actions in the debug UI.
DDLogError(@"%@ hasMalformedRowChange", self.logTag); OWSProdLogAndFail(@"%@ hasMalformedRowChange", self.logTag);
[self reloadViewItems];
[self.collectionView reloadData]; [self.collectionView reloadData];
[self updateLastVisibleTimestamp]; [self updateLastVisibleTimestamp];
[self cleanUpUnreadIndicatorIfNecessary]; [self cleanUpUnreadIndicatorIfNecessary];
@ -3340,7 +3352,7 @@ typedef enum : NSUInteger {
} }
NSUInteger oldViewItemCount = self.viewItems.count; NSUInteger oldViewItemCount = self.viewItems.count;
NSMutableSet<NSNumber *> *rowsThatChangedSize = [[self reloadViewItems] mutableCopy]; [self reloadViewItems];
BOOL wasAtBottom = [self isScrolledToBottom]; BOOL wasAtBottom = [self isScrolledToBottom];
// We want sending messages to feel snappy. So, if the only // We want sending messages to feel snappy. So, if the only
@ -3372,8 +3384,6 @@ typedef enum : NSUInteger {
rowChange.newIndexPath, rowChange.newIndexPath,
rowChange.finalIndex); rowChange.finalIndex);
[self.collectionView insertItemsAtIndexPaths:@[ rowChange.newIndexPath ]]; [self.collectionView insertItemsAtIndexPaths:@[ rowChange.newIndexPath ]];
// We don't want to reload a row that we just inserted.
[rowsThatChangedSize removeObject:@(rowChange.originalIndex)];
ConversationViewItem *_Nullable viewItem = [self viewItemForIndex:(NSInteger)rowChange.finalIndex]; ConversationViewItem *_Nullable viewItem = [self viewItemForIndex:(NSInteger)rowChange.finalIndex];
if ([viewItem.interaction isKindOfClass:[TSOutgoingMessage class]]) { if ([viewItem.interaction isKindOfClass:[TSOutgoingMessage class]]) {
@ -3392,8 +3402,6 @@ typedef enum : NSUInteger {
rowChange.newIndexPath, rowChange.newIndexPath,
rowChange.finalIndex); rowChange.finalIndex);
[self.collectionView moveItemAtIndexPath:rowChange.indexPath toIndexPath:rowChange.newIndexPath]; [self.collectionView moveItemAtIndexPath:rowChange.indexPath toIndexPath:rowChange.newIndexPath];
// We don't want to reload a row that we just moved.
[rowsThatChangedSize removeObject:@(rowChange.originalIndex)];
break; break;
} }
case YapDatabaseViewChangeUpdate: { case YapDatabaseViewChangeUpdate: {
@ -3402,23 +3410,10 @@ typedef enum : NSUInteger {
rowChange.indexPath, rowChange.indexPath,
rowChange.finalIndex); rowChange.finalIndex);
[self.collectionView reloadItemsAtIndexPaths:@[ rowChange.indexPath ]]; [self.collectionView reloadItemsAtIndexPaths:@[ rowChange.indexPath ]];
// We don't want to reload a row that we've already reloaded.
[rowsThatChangedSize removeObject:@(rowChange.originalIndex)];
break; break;
} }
} }
} }
// The changes performed above may affect the size of neighboring cells,
// as they may affect which cells show "date" headers or "status" footers.
NSMutableArray<NSIndexPath *> *rowsToReload = [NSMutableArray new];
for (NSNumber *row in rowsThatChangedSize) {
DDLogVerbose(@"rowsToReload: %@", row);
[rowsToReload addObject:[NSIndexPath indexPathForRow:row.integerValue inSection:0]];
}
if (rowsToReload.count > 0) {
[self.collectionView reloadItemsAtIndexPaths:rowsToReload];
}
}; };
DDLogVerbose(@"self.viewItems.count: %zd -> %zd", oldViewItemCount, self.viewItems.count); DDLogVerbose(@"self.viewItems.count: %zd -> %zd", oldViewItemCount, self.viewItems.count);
@ -4775,11 +4770,7 @@ typedef enum : NSUInteger {
// This is a key method. It builds or rebuilds the list of // This is a key method. It builds or rebuilds the list of
// cell view models. // cell view models.
// - (void)reloadViewItems
// Returns a list of the rows which may have changed size and
// need to be reloaded if we're doing an incremental update
// of the view.
- (NSSet<NSNumber *> *)reloadViewItems
{ {
NSMutableArray<ConversationViewItem *> *viewItems = [NSMutableArray new]; NSMutableArray<ConversationViewItem *> *viewItems = [NSMutableArray new];
NSMutableDictionary<NSString *, ConversationViewItem *> *viewItemCache = [NSMutableDictionary new]; NSMutableDictionary<NSString *, ConversationViewItem *> *viewItemCache = [NSMutableDictionary new];
@ -4809,9 +4800,7 @@ typedef enum : NSUInteger {
} }
ConversationViewItem *_Nullable viewItem = self.viewItemCache[interaction.uniqueId]; ConversationViewItem *_Nullable viewItem = self.viewItemCache[interaction.uniqueId];
if (viewItem) { if (!viewItem) {
viewItem.previousRow = viewItem.row;
} else {
viewItem = [[ConversationViewItem alloc] initWithInteraction:interaction viewItem = [[ConversationViewItem alloc] initWithInteraction:interaction
isGroupThread:isGroupThread isGroupThread:isGroupThread
transaction:transaction transaction:transaction
@ -4824,8 +4813,6 @@ typedef enum : NSUInteger {
} }
}]; }];
NSMutableSet<NSNumber *> *rowsThatChangedSize = [NSMutableSet new];
// Update the "shouldShowDate" property of the view items. // Update the "shouldShowDate" property of the view items.
BOOL shouldShowDateOnNextViewItem = YES; BOOL shouldShowDateOnNextViewItem = YES;
uint64_t previousViewItemTimestamp = 0; uint64_t previousViewItemTimestamp = 0;
@ -4865,12 +4852,6 @@ typedef enum : NSUInteger {
shouldShowDateOnNextViewItem = NO; shouldShowDateOnNextViewItem = NO;
} }
// If this is an existing view item and it has changed size,
// note that so that we can reload this cell while doing
// incremental updates.
if (viewItem.shouldShowDate != shouldShowDate && viewItem.previousRow != NSNotFound) {
[rowsThatChangedSize addObject:@(viewItem.previousRow)];
}
viewItem.shouldShowDate = shouldShowDate; viewItem.shouldShowDate = shouldShowDate;
previousViewItemTimestamp = viewItem.interaction.timestampForSorting; previousViewItemTimestamp = viewItem.interaction.timestampForSorting;
@ -4910,22 +4891,12 @@ typedef enum : NSUInteger {
} }
lastInteractionType = interactionType; lastInteractionType = interactionType;
// When `shouldHideRecipientStatus` changes, reload the cell if necessary.
if (viewItem.shouldHideRecipientStatus != shouldHideRecipientStatus && viewItem.previousRow != NSNotFound) {
[rowsThatChangedSize addObject:@(viewItem.previousRow)];
}
viewItem.shouldHideRecipientStatus = shouldHideRecipientStatus; viewItem.shouldHideRecipientStatus = shouldHideRecipientStatus;
// When `shouldHideAvatar` changes, reload the cell if necessary.
if (viewItem.shouldHideAvatar != shouldHideAvatar && viewItem.previousRow != NSNotFound) {
[rowsThatChangedSize addObject:@(viewItem.previousRow)];
}
viewItem.shouldHideAvatar = shouldHideAvatar; viewItem.shouldHideAvatar = shouldHideAvatar;
} }
self.viewItems = viewItems; self.viewItems = viewItems;
self.viewItemCache = viewItemCache; self.viewItemCache = viewItemCache;
return [rowsThatChangedSize copy];
} }
// Whenever an interaction is modified, we need to reload it from the DB // Whenever an interaction is modified, we need to reload it from the DB

@ -61,12 +61,6 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
@property (nonatomic) BOOL shouldHideAvatar; @property (nonatomic) BOOL shouldHideAvatar;
@property (nonatomic) NSInteger row; @property (nonatomic) NSInteger row;
// During updates, we sometimes need the previous row index
// (before this update) of this item.
//
// If NSNotFound, this view item was just created in the
// previous update.
@property (nonatomic) NSInteger previousRow;
@property (nonatomic, readonly) ConversationStyle *conversationStyle; @property (nonatomic, readonly) ConversationStyle *conversationStyle;

@ -93,7 +93,6 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
_isGroupThread = isGroupThread; _isGroupThread = isGroupThread;
_conversationStyle = conversationStyle; _conversationStyle = conversationStyle;
self.row = NSNotFound; self.row = NSNotFound;
self.previousRow = NSNotFound;
[self ensureViewState:transaction]; [self ensureViewState:transaction];

@ -526,7 +526,7 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_
NSError *error; NSError *error;
BOOL wasScheduled = [self.websocket sendDataNoCopy:messageData error:&error]; BOOL wasScheduled = [self.websocket sendDataNoCopy:messageData error:&error];
if (!wasScheduled || error) { if (!wasScheduled || error) {
OWSProdLogAndFail(@"%@ could not serialize request JSON: %@", self.logTag, error); OWSProdLogAndFail(@"%@ could not send socket request: %@", self.logTag, error);
[socketMessage didFailBeforeSending]; [socketMessage didFailBeforeSending];
return; return;
} }

Loading…
Cancel
Save