| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -104,7 +104,6 @@ NS_ASSUME_NONNULL_BEGIN
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        __block OWSAddToContactsOfferMessage *existingAddToContactsOffer = nil;
 | 
					 | 
					 | 
					 | 
					        __block OWSAddToContactsOfferMessage *existingAddToContactsOffer = nil;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        __block OWSUnknownContactBlockOfferMessage *existingBlockOffer = nil;
 | 
					 | 
					 | 
					 | 
					        __block OWSUnknownContactBlockOfferMessage *existingBlockOffer = nil;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        __block TSUnreadIndicatorInteraction *existingUnreadIndicator = nil;
 | 
					 | 
					 | 
					 | 
					        __block TSUnreadIndicatorInteraction *existingUnreadIndicator = nil;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        NSMutableArray<TSInvalidIdentityKeyErrorMessage *> *safetyNumberChanges = [NSMutableArray new];
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        __block TSIncomingMessage *firstIncomingMessage = nil;
 | 
					 | 
					 | 
					 | 
					        __block TSIncomingMessage *firstIncomingMessage = nil;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        __block TSOutgoingMessage *firstOutgoingMessage = nil;
 | 
					 | 
					 | 
					 | 
					        __block TSOutgoingMessage *firstOutgoingMessage = nil;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        __block long outgoingMessageCount = 0;
 | 
					 | 
					 | 
					 | 
					        __block long outgoingMessageCount = 0;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -124,14 +123,27 @@ NS_ASSUME_NONNULL_BEGIN
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                          } else if ([object isKindOfClass:[TSUnreadIndicatorInteraction class]]) {
 | 
					 | 
					 | 
					 | 
					                          } else if ([object isKindOfClass:[TSUnreadIndicatorInteraction class]]) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              OWSAssert(!existingUnreadIndicator);
 | 
					 | 
					 | 
					 | 
					                              OWSAssert(!existingUnreadIndicator);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              existingUnreadIndicator = (TSUnreadIndicatorInteraction *)object;
 | 
					 | 
					 | 
					 | 
					                              existingUnreadIndicator = (TSUnreadIndicatorInteraction *)object;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                          } else if ([object isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              [safetyNumberChanges addObject:object];
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                          } else {
 | 
					 | 
					 | 
					 | 
					                          } else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              DDLogError(@"Unexpected dynamic interaction type: %@", [object class]);
 | 
					 | 
					 | 
					 | 
					                              DDLogError(@"Unexpected dynamic interaction type: %@", [object class]);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              OWSAssert(0);
 | 
					 | 
					 | 
					 | 
					                              OWSAssert(0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                          }
 | 
					 | 
					 | 
					 | 
					                          }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                      }];
 | 
					 | 
					 | 
					 | 
					                      }];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        // We use different views for performance reasons.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        NSMutableArray<TSInvalidIdentityKeyErrorMessage *> *safetyNumberChanges = [NSMutableArray new];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        [[transaction ext:TSSafetyNumberChangeDatabaseViewExtensionName]
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            enumerateRowsInGroup:thread.uniqueId
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                      usingBlock:^(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                          NSString *collection, NSString *key, id object, id metadata, NSUInteger index, BOOL *stop) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                          if ([object isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                              [safetyNumberChanges addObject:object];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                          } else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                              DDLogError(@"Unexpected interaction type: %@", [object class]);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                              OWSAssert(0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                          }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                      }];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // IFF this variable is non-null, there are unseen messages in the thread.
 | 
					 | 
					 | 
					 | 
					        // IFF this variable is non-null, there are unseen messages in the thread.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        __block NSNumber *firstUnseenInteractionTimestamp;
 | 
					 | 
					 | 
					 | 
					        __block NSNumber *firstUnseenInteractionTimestamp;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (firstUnseenInteractionTimestampParameter) {
 | 
					 | 
					 | 
					 | 
					        if (firstUnseenInteractionTimestampParameter) {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -169,8 +181,7 @@ NS_ASSUME_NONNULL_BEGIN
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                  firstIncomingMessage = incomingMessage;
 | 
					 | 
					 | 
					 | 
					                                  firstIncomingMessage = incomingMessage;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              } else {
 | 
					 | 
					 | 
					 | 
					                              } else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                  OWSAssert(
 | 
					 | 
					 | 
					 | 
					                                  OWSAssert(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                      [[firstIncomingMessage dateForSorting] compare:[incomingMessage dateForSorting]]
 | 
					 | 
					 | 
					 | 
					                                      [firstIncomingMessage compareForSorting:incomingMessage] == NSOrderedAscending);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                      == NSOrderedAscending);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              }
 | 
					 | 
					 | 
					 | 
					                              }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                          } else if ([object isKindOfClass:[TSOutgoingMessage class]]) {
 | 
					 | 
					 | 
					 | 
					                          } else if ([object isKindOfClass:[TSOutgoingMessage class]]) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)object;
 | 
					 | 
					 | 
					 | 
					                              TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)object;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -178,8 +189,7 @@ NS_ASSUME_NONNULL_BEGIN
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                  firstOutgoingMessage = outgoingMessage;
 | 
					 | 
					 | 
					 | 
					                                  firstOutgoingMessage = outgoingMessage;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              } else {
 | 
					 | 
					 | 
					 | 
					                              } else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                  OWSAssert(
 | 
					 | 
					 | 
					 | 
					                                  OWSAssert(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                      [[firstOutgoingMessage dateForSorting] compare:[outgoingMessage dateForSorting]]
 | 
					 | 
					 | 
					 | 
					                                      [firstOutgoingMessage compareForSorting:outgoingMessage] == NSOrderedAscending);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                      == NSOrderedAscending);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              }
 | 
					 | 
					 | 
					 | 
					                              }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              outgoingMessageCount++;
 | 
					 | 
					 | 
					 | 
					                              outgoingMessageCount++;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              if (outgoingMessageCount >= kMaxBlockOfferOutgoingMessageCount) {
 | 
					 | 
					 | 
					 | 
					                              if (outgoingMessageCount >= kMaxBlockOfferOutgoingMessageCount) {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -268,9 +278,7 @@ NS_ASSUME_NONNULL_BEGIN
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        TSMessage *firstMessage = firstIncomingMessage;
 | 
					 | 
					 | 
					 | 
					        TSMessage *firstMessage = firstIncomingMessage;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (!firstMessage
 | 
					 | 
					 | 
					 | 
					        if (!firstMessage
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            || (firstOutgoingMessage &&
 | 
					 | 
					 | 
					 | 
					            || (firstOutgoingMessage && [firstOutgoingMessage compareForSorting:firstMessage] == NSOrderedAscending)) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                   [[firstOutgoingMessage dateForSorting] compare:[firstMessage dateForSorting]]
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                       == NSOrderedAscending)) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            firstMessage = firstOutgoingMessage;
 | 
					 | 
					 | 
					 | 
					            firstMessage = firstOutgoingMessage;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -314,8 +322,7 @@ NS_ASSUME_NONNULL_BEGIN
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        BOOL hasOutgoingBeforeIncomingInteraction = (firstOutgoingMessage
 | 
					 | 
					 | 
					 | 
					        BOOL hasOutgoingBeforeIncomingInteraction = (firstOutgoingMessage
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            && (!firstIncomingMessage ||
 | 
					 | 
					 | 
					 | 
					            && (!firstIncomingMessage ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                   [[firstOutgoingMessage dateForSorting] compare:[firstIncomingMessage dateForSorting]]
 | 
					 | 
					 | 
					 | 
					                   [firstOutgoingMessage compareForSorting:firstIncomingMessage] == NSOrderedAscending));
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                       == NSOrderedAscending));
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (hasOutgoingBeforeIncomingInteraction) {
 | 
					 | 
					 | 
					 | 
					        if (hasOutgoingBeforeIncomingInteraction) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // If there is an outgoing message before an incoming message
 | 
					 | 
					 | 
					 | 
					            // If there is an outgoing message before an incoming message
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // the local user initiated this conversation, don't show a block offer.
 | 
					 | 
					 | 
					 | 
					            // the local user initiated this conversation, don't show a block offer.
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |