|
|
@ -113,12 +113,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
[storageManager.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
[storageManager.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
const int kMaxBlockOfferOutgoingMessageCount = 10;
|
|
|
|
const int kMaxBlockOfferOutgoingMessageCount = 10;
|
|
|
|
|
|
|
|
|
|
|
|
// Find any existing "dynamic" interactions.
|
|
|
|
// Find any "dynamic" interactions and safety number changes.
|
|
|
|
__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 *> *blockingSafetyNumberChanges = [NSMutableArray new];
|
|
|
|
|
|
|
|
NSMutableArray<TSInteraction *> *nonBlockingSafetyNumberChanges = [NSMutableArray new];
|
|
|
|
// We use different views for performance reasons.
|
|
|
|
// We use different views for performance reasons.
|
|
|
|
[[transaction ext:TSDynamicMessagesDatabaseViewExtensionName]
|
|
|
|
[[transaction ext:TSThreadSpecialMessagesDatabaseViewExtensionName]
|
|
|
|
enumerateRowsInGroup:thread.uniqueId
|
|
|
|
enumerateRowsInGroup:thread.uniqueId
|
|
|
|
usingBlock:^(
|
|
|
|
usingBlock:^(
|
|
|
|
NSString *collection, NSString *key, id object, id metadata, NSUInteger index, BOOL *stop) {
|
|
|
|
NSString *collection, NSString *key, id object, id metadata, NSUInteger index, BOOL *stop) {
|
|
|
@ -132,30 +134,14 @@ 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 {
|
|
|
|
} else if ([object isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
|
|
|
|
DDLogError(@"Unexpected dynamic interaction type: %@", [object class]);
|
|
|
|
|
|
|
|
OWSAssert(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Find any existing safety number changes.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// We use different views for performance reasons.
|
|
|
|
|
|
|
|
NSMutableArray<TSInvalidIdentityKeyErrorMessage *> *blockingSafetyNumberChanges = [NSMutableArray new];
|
|
|
|
|
|
|
|
NSMutableArray<TSInteraction *> *nonBlockingSafetyNumberChanges = [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]]) {
|
|
|
|
|
|
|
|
[blockingSafetyNumberChanges addObject:object];
|
|
|
|
[blockingSafetyNumberChanges addObject:object];
|
|
|
|
} else if ([object isKindOfClass:[TSErrorMessage class]]) {
|
|
|
|
} else if ([object isKindOfClass:[TSErrorMessage class]]) {
|
|
|
|
TSErrorMessage *errorMessage = (TSErrorMessage *)object;
|
|
|
|
TSErrorMessage *errorMessage = (TSErrorMessage *)object;
|
|
|
|
OWSAssert(errorMessage.errorType == TSErrorMessageNonBlockingIdentityChange);
|
|
|
|
OWSAssert(errorMessage.errorType == TSErrorMessageNonBlockingIdentityChange);
|
|
|
|
[nonBlockingSafetyNumberChanges addObject:errorMessage];
|
|
|
|
[nonBlockingSafetyNumberChanges addObject:errorMessage];
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
DDLogError(@"Unexpected interaction type: %@", [object class]);
|
|
|
|
DDLogError(@"Unexpected dynamic interaction type: %@", [object class]);
|
|
|
|
OWSAssert(0);
|
|
|
|
OWSAssert(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
}];
|
|
|
@ -177,10 +163,21 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TSIncomingMessage *firstIncomingMessage =
|
|
|
|
__block TSMessage *firstMessage = nil;
|
|
|
|
[[transaction ext:TSThreadIncomingMessageDatabaseViewExtensionName] firstObjectInGroup:thread.uniqueId];
|
|
|
|
[[transaction ext:TSMessageDatabaseViewExtensionName]
|
|
|
|
TSOutgoingMessage *firstOutgoingMessage =
|
|
|
|
enumerateRowsInGroup:thread.uniqueId
|
|
|
|
[[transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName] firstObjectInGroup:thread.uniqueId];
|
|
|
|
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]]) {
|
|
|
|
|
|
|
|
firstMessage = (TSMessage *)object;
|
|
|
|
|
|
|
|
*stop = YES;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
NSUInteger outgoingMessageCount =
|
|
|
|
NSUInteger outgoingMessageCount =
|
|
|
|
[[transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName] numberOfItemsInGroup:thread.uniqueId];
|
|
|
|
[[transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName] numberOfItemsInGroup:thread.uniqueId];
|
|
|
|
NSUInteger threadMessageCount =
|
|
|
|
NSUInteger threadMessageCount =
|
|
|
@ -270,12 +267,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OWSAssert((result.firstUnseenInteractionTimestamp != nil) == (result.unreadIndicatorPosition != nil));
|
|
|
|
OWSAssert((result.firstUnseenInteractionTimestamp != nil) == (result.unreadIndicatorPosition != nil));
|
|
|
|
|
|
|
|
|
|
|
|
TSMessage *firstMessage = firstIncomingMessage;
|
|
|
|
|
|
|
|
if (!firstMessage
|
|
|
|
|
|
|
|
|| (firstOutgoingMessage && [firstOutgoingMessage compareForSorting:firstMessage] == NSOrderedAscending)) {
|
|
|
|
|
|
|
|
firstMessage = firstOutgoingMessage;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL shouldHaveBlockOffer = YES;
|
|
|
|
BOOL shouldHaveBlockOffer = YES;
|
|
|
|
BOOL shouldHaveAddToContactsOffer = YES;
|
|
|
|
BOOL shouldHaveAddToContactsOffer = YES;
|
|
|
|
|
|
|
|
|
|
|
@ -314,9 +305,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
shouldHaveBlockOffer = NO;
|
|
|
|
shouldHaveBlockOffer = NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL hasOutgoingBeforeIncomingInteraction = (firstOutgoingMessage
|
|
|
|
BOOL hasOutgoingBeforeIncomingInteraction = [firstMessage isKindOfClass:[TSOutgoingMessage class]];
|
|
|
|
&& (!firstIncomingMessage ||
|
|
|
|
|
|
|
|
[firstOutgoingMessage compareForSorting:firstIncomingMessage] == 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.
|
|
|
|