diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index 679cd182d..0deb3a50d 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -541,16 +541,25 @@ NS_ASSUME_NONNULL_BEGIN return message.isFriendRequest; } else { if (message.isFriendRequest) { - // Only show an incoming friend request if the user isn't yet friends with any of the other user's devices + // Only show the first friend request that was received NSString *senderID = ((TSIncomingMessage *)message).authorId; - __block NSSet *linkedDeviceThreads; + __block NSMutableSet *linkedDeviceThreads; [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - linkedDeviceThreads = [LKDatabaseUtilities getLinkedDeviceThreadsFor:senderID in:transaction]; + linkedDeviceThreads = [LKDatabaseUtilities getLinkedDeviceThreadsFor:senderID in:transaction].mutableCopy; }]; - BOOL isFriend = [linkedDeviceThreads contains:^BOOL(TSContactThread *thread) { - return thread.isContactFriend; + NSMutableArray *allFriendRequestMessages = @[].mutableCopy; + for (TSContactThread *thread in linkedDeviceThreads) { + [thread enumerateInteractionsUsingBlock:^(TSInteraction *interaction) { + TSIncomingMessage *message = [interaction as:TSIncomingMessage.class]; + if (message != nil && message.isFriendRequest) { + [allFriendRequestMessages addObject:message]; + } + }]; + } + [allFriendRequestMessages sortUsingComparator:^NSComparisonResult(TSIncomingMessage *lhs, TSIncomingMessage *rhs) { + return [@(lhs.timestamp) compare:@(rhs.timestamp)] == NSOrderedDescending; }]; - return !isFriend; + return [message.uniqueId isEqual:allFriendRequestMessages.firstObject.uniqueId]; } else { return NO; } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 6267e2c31..36b5f5191 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -4451,8 +4451,6 @@ typedef enum : NSUInteger { - (void)acceptFriendRequest:(TSIncomingMessage *)friendRequest { - // Update the thread's friend request status - [self.thread saveFriendRequestStatus:LKThreadFriendRequestStatusFriends withTransaction:nil]; // Accept all outstanding friend requests associated with this user and try to establish sessions with the // subset of their devices that haven't sent a friend request. NSString *senderID = friendRequest.authorId; @@ -4466,9 +4464,13 @@ typedef enum : NSUInteger { } else { OWSMessageSender *messageSender = SSKEnvironment.shared.messageSender; OWSMessageSend *automatedFriendRequestMessage = [messageSender getMultiDeviceFriendRequestMessageForHexEncodedPublicKey:thread.contactIdentifier]; - [messageSender sendMessage:automatedFriendRequestMessage]; + dispatch_async(OWSDispatch.sendingQueue, ^{ + [messageSender sendMessage:automatedFriendRequestMessage]; + }); } } + // Update the thread's friend request status + [self.thread saveFriendRequestStatus:LKThreadFriendRequestStatusFriends withTransaction:nil]; } - (void)declineFriendRequest:(TSIncomingMessage *)friendRequest diff --git a/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift b/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift index 0a56f1e0f..debad3b84 100644 --- a/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift +++ b/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift @@ -24,12 +24,13 @@ public final class LokiDatabaseUtilities : NSObject { // MARK: Device Links @objc(getLinkedDeviceHexEncodedPublicKeysFor:in:) public static func getLinkedDeviceHexEncodedPublicKeys(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadWriteTransaction) -> Set { - var result = Set() let storage = OWSPrimaryStorage.shared() let masterHexEncodedPublicKey = storage.getMasterHexEncodedPublicKey(for: hexEncodedPublicKey, in: transaction) ?? hexEncodedPublicKey - return Set(storage.getDeviceLinks(for: masterHexEncodedPublicKey, in: transaction).flatMap { deviceLink in + var result = Set(storage.getDeviceLinks(for: masterHexEncodedPublicKey, in: transaction).flatMap { deviceLink in return [ deviceLink.master.hexEncodedPublicKey, deviceLink.slave.hexEncodedPublicKey ] }) + result.insert(hexEncodedPublicKey) + return result } @objc(getLinkedDeviceThreadsFor:in:) diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 863a14920..1e1528534 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -498,9 +498,15 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; OWSAssertDebug(message); OWSAssertDebug(errorHandle); - NSMutableSet *recipientIds = [NSMutableSet new]; + __block NSMutableSet *recipientIds = [NSMutableSet new]; if ([message isKindOfClass:[OWSOutgoingSyncMessage class]]) { - [recipientIds addObject:self.tsAccountManager.localNumber]; + NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey; + [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + NSString *masterHexEncodedPublicKey = [LKDatabaseUtilities getMasterHexEncodedPublicKeyFor:userHexEncodedPublicKey in:transaction] ?: userHexEncodedPublicKey; + NSMutableSet *linkedDeviceHexEncodedPublicKeys = [LKDatabaseUtilities getLinkedDeviceHexEncodedPublicKeysFor:userHexEncodedPublicKey in:transaction].mutableCopy; + [linkedDeviceHexEncodedPublicKeys removeObject:userHexEncodedPublicKey]; + recipientIds = [recipientIds setByAddingObjectsFromSet:linkedDeviceHexEncodedPublicKeys].mutableCopy; + }]; } else if (thread.isGroupThread) { [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { LKPublicChat *publicChat = [LKDatabaseUtilities getPublicChatForThreadID:thread.uniqueId transaction:transaction]; @@ -935,7 +941,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (isGroupMessage || isDeviceLinkMessage) { [self sendMessage:messageSend]; } else { - BOOL isSilentMessage = message.isSilent || [message isKindOfClass:LKEphemeralMessage.class]; + BOOL isSilentMessage = message.isSilent || [message isKindOfClass:LKEphemeralMessage.class] || [message isKindOfClass:OWSOutgoingSyncMessage.class]; BOOL isFriendRequestMessage = [message isKindOfClass:LKFriendRequestMessage.class]; [[LKAPI getDestinationsFor:contactID] .thenOn(OWSDispatch.sendingQueue, ^(NSArray *destinations) {