Merge branch 'charlesmchen/unreadLayoutEdgeCases'

pull/1/head
Matthew Chen 8 years ago
commit 0029b6854f

@ -2859,6 +2859,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
// We need to reload any modified interactions _before_ we call // We need to reload any modified interactions _before_ we call
// reloadViewItems. // reloadViewItems.
BOOL hasDeletions = NO;
for (YapDatabaseViewRowChange *rowChange in rowChanges) { for (YapDatabaseViewRowChange *rowChange in rowChanges) {
switch (rowChange.type) { switch (rowChange.type) {
case YapDatabaseViewChangeUpdate: { case YapDatabaseViewChangeUpdate: {
@ -2877,6 +2878,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
if (collectionKey.key) { if (collectionKey.key) {
[self.viewItemMap removeObjectForKey:collectionKey.key]; [self.viewItemMap removeObjectForKey:collectionKey.key];
} }
hasDeletions = YES;
break; break;
} }
default: default:
@ -2974,6 +2976,9 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
[self.collectionView reloadData]; [self.collectionView reloadData];
}]; }];
[self updateLastVisibleTimestamp]; [self updateLastVisibleTimestamp];
if (hasDeletions) {
[self cleanUpUnreadIndicatorIfNecessary];
}
} else { } else {
BOOL shouldAnimateUpdates = [self shouldAnimateRowUpdates:rowChanges oldViewItemCount:oldViewItemCount]; BOOL shouldAnimateUpdates = [self shouldAnimateRowUpdates:rowChanges oldViewItemCount:oldViewItemCount];
void (^batchUpdatesCompletion)(BOOL) = ^(BOOL finished) { void (^batchUpdatesCompletion)(BOOL) = ^(BOOL finished) {
@ -2988,6 +2993,9 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
if (scrollToBottom) { if (scrollToBottom) {
[self scrollToBottomAnimated:shouldAnimateScrollToBottom && shouldAnimateUpdates]; [self scrollToBottomAnimated:shouldAnimateScrollToBottom && shouldAnimateUpdates];
} }
if (hasDeletions) {
[self cleanUpUnreadIndicatorIfNecessary];
}
}; };
if (shouldAnimateUpdates) { if (shouldAnimateUpdates) {
[self.collectionView performBatchUpdates:batchUpdates completion:batchUpdatesCompletion]; [self.collectionView performBatchUpdates:batchUpdates completion:batchUpdatesCompletion];
@ -3413,12 +3421,6 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
if (lastVisibleViewItem) { if (lastVisibleViewItem) {
uint64_t lastVisibleTimestamp = lastVisibleViewItem.interaction.timestampForSorting; uint64_t lastVisibleTimestamp = lastVisibleViewItem.interaction.timestampForSorting;
self.lastVisibleTimestamp = MAX(self.lastVisibleTimestamp, lastVisibleTimestamp); self.lastVisibleTimestamp = MAX(self.lastVisibleTimestamp, lastVisibleTimestamp);
// If we delete the last unread message (manually or due to disappearing messages)
// we may need to clean up an obsolete unread indicator.
if (lastVisibleViewItem.interaction.interactionType == OWSInteractionType_UnreadIndicator) {
[self ensureDynamicInteractions];
}
} }
[self ensureScrollDownButton]; [self ensureScrollDownButton];
@ -3431,6 +3433,25 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
self.hasUnreadMessages = numberOfUnreadMessages > 0; self.hasUnreadMessages = numberOfUnreadMessages > 0;
} }
- (void)cleanUpUnreadIndicatorIfNecessary
{
BOOL hasUnreadIndicator = self.dynamicInteractions.unreadIndicatorPosition != nil;
if (!hasUnreadIndicator) {
return;
}
__block BOOL hasUnseenInteractions = NO;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
hasUnseenInteractions =
[[transaction ext:TSUnreadDatabaseViewExtensionName] numberOfItemsInGroup:self.thread.uniqueId] > 0;
}];
if (hasUnseenInteractions) {
return;
}
// If the last unread message was deleted (manually or due to disappearing messages)
// we may need to clean up an obsolete unread indicator.
[self ensureDynamicInteractions];
}
- (void)updateLastVisibleTimestamp:(uint64_t)timestamp - (void)updateLastVisibleTimestamp:(uint64_t)timestamp
{ {
OWSAssert(timestamp > 0); OWSAssert(timestamp > 0);

@ -239,18 +239,40 @@ NS_ASSUME_NONNULL_BEGIN
// Due to disappearing messages or manual deletion, // Due to disappearing messages or manual deletion,
// firstUnseenInteractionTimestampParameter may refer to an obsolete // firstUnseenInteractionTimestampParameter may refer to an obsolete
// interaction in which case we want to discard it. // interaction in which case we want to discard it.
TSInteraction *_Nullable lastInteraction = //
[[transaction ext:TSMessageDatabaseViewExtensionName] lastObjectInGroup:thread.uniqueId]; // Therefore, we should discard the existing unread indicator
if (!lastInteraction // position if there are no "unreadable" messages after it.
|| lastInteraction.timestampForSorting __block TSInteraction *lastCallOrMessage = nil;
< firstUnseenInteractionTimestampParameter.unsignedLongLongValue) { [[transaction ext:TSMessageDatabaseViewExtensionName]
enumerateRowsInGroup:thread.uniqueId
withOptions:NSEnumerationReverse
usingBlock:^(NSString *collection,
NSString *key,
id object,
id metadata,
NSUInteger index,
BOOL *stop) {
OWSAssert([object isKindOfClass:[TSInteraction class]]);
if ([object isKindOfClass:[TSIncomingMessage class]] ||
[object isKindOfClass:[TSOutgoingMessage class]] ||
[object isKindOfClass:[TSCall class]]) {
lastCallOrMessage = object;
*stop = YES;
}
if ([object isKindOfClass:[TSUnreadIndicatorInteraction class]]) {
*stop = YES;
}
}];
if (!lastCallOrMessage) {
firstUnseenInteractionTimestampParameter = nil; firstUnseenInteractionTimestampParameter = nil;
} }
} }
if (firstUnseenInteractionTimestampParameter) { if (firstUnseenInteractionTimestampParameter) {
result.firstUnseenInteractionTimestamp = firstUnseenInteractionTimestampParameter; result.firstUnseenInteractionTimestamp = firstUnseenInteractionTimestampParameter;
} else { } else {
TSInteraction *firstUnseenInteraction = TSInteraction *_Nullable firstUnseenInteraction =
[[TSDatabaseView unseenDatabaseViewExtension:transaction] firstObjectInGroup:thread.uniqueId]; [[TSDatabaseView unseenDatabaseViewExtension:transaction] firstObjectInGroup:thread.uniqueId];
if (firstUnseenInteraction) { if (firstUnseenInteraction) {
result.firstUnseenInteractionTimestamp = @(firstUnseenInteraction.timestampForSorting); result.firstUnseenInteractionTimestamp = @(firstUnseenInteraction.timestampForSorting);

Loading…
Cancel
Save