From 6c742349bd6d29731f83bc342c4f2f932308a54f Mon Sep 17 00:00:00 2001 From: Mikunj Date: Mon, 16 Sep 2019 15:56:03 +1000 Subject: [PATCH] Added link previews for outgoing messages. Refactoring. Moved link preview generation to messages. --- .../src/Messages/Interactions/TSMessage.h | 4 ++ .../src/Messages/Interactions/TSMessage.m | 50 +++++++++++++++++++ .../src/Messages/OWSMessageManager.m | 47 +---------------- .../src/Messages/OWSMessageSender.m | 9 ++++ 4 files changed, 65 insertions(+), 45 deletions(-) diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.h b/SignalServiceKit/src/Messages/Interactions/TSMessage.h index 4c703d5de..8359d7cdc 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.h @@ -98,6 +98,10 @@ typedef NS_ENUM(NSInteger, LKMessageFriendRequestStatus) { - (void)saveGroupChatMessageID:(uint64_t)serverMessageID in:(YapDatabaseReadWriteTransaction *_Nullable)transaction; +#pragma mark - Link preview + +- (void)generateLinkPreviewIfNeededFromURL:(NSString *)url; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index da7a20a17..98ec481f1 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -512,6 +512,56 @@ static const NSUInteger OWSMessageSchemaVersion = 4; } } +#pragma mark - Link preview + + +- (void)generateLinkPreviewIfNeededFromURL:(NSString *)url { + // If we already have previews or attachments then don't bother making link previews + if (self.linkPreview != nil || self.hasAttachments) { return; } + + [OWSLinkPreview tryToBuildPreviewInfoObjcWithPreviewUrl:url] + .thenOn(dispatch_get_main_queue(), ^(OWSLinkPreviewDraft *linkPreviewDraft) { + [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + OWSLinkPreview *linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft transaction:transaction error:nil]; + self.linkPreview = linkPreview; + [self saveWithTransaction:transaction]; + }]; + }) + .catchOn(dispatch_get_main_queue(), ^(NSError *error) { + // If we failed to get link preview due to invalid content then maybe it's a link to a direct image? + if ([OWSLinkPreview isInvalidContentError:error]) { + __block AnyPromise *promise; + [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + promise = [OWSLinkPreview getImagePreviewFromUrl:url transaction:transaction]; + }]; + return promise; + } + + // Return the error + return [AnyPromise promiseWithValue:error]; + }) + .thenOn(dispatch_get_main_queue(), ^(OWSLinkPreview *linkPreview) { + // If we managed to get direct previews then render them + [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + if (linkPreview.isDirectAttachment) { + if (!self.hasAttachments) { + [self addAttachmentId:linkPreview.imageAttachmentId transaction:transaction]; + + // Set the message id in attachment + TSAttachmentStream *linkPreviewAttachment = [TSAttachmentStream fetchObjectWithUniqueID:linkPreview.imageAttachmentId transaction:transaction]; + linkPreviewAttachment.albumMessageId = self.uniqueId; + linkPreviewAttachment.isUploaded = true; + [linkPreviewAttachment saveWithTransaction:transaction]; + } + } else { + self.linkPreview = linkPreview; + [self saveWithTransaction:transaction]; + } + + }]; + }); +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 12185abc4..6c88dd9ab 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -1409,7 +1409,7 @@ NS_ASSUME_NONNULL_BEGIN dispatch_async(dispatch_get_main_queue(), ^{ NSString *url = [OWSLinkPreview previewURLForRawBodyText:incomingMessage.body]; if (url != nil) { - [self handleLinkPreviewsIfNeededWithUrl:url message:incomingMessage]; + [incomingMessage generateLinkPreviewIfNeededFromURL:url]; } }); @@ -1511,7 +1511,7 @@ NS_ASSUME_NONNULL_BEGIN linkPreviewURL = [OWSLinkPreview previewURLForRawBodyText:incomingMessage.body]; } if (linkPreviewURL != nil) { - [self handleLinkPreviewsIfNeededWithUrl:linkPreviewURL message:incomingMessage]; + [incomingMessage generateLinkPreviewIfNeededFromURL:linkPreviewURL]; } }); @@ -1519,49 +1519,6 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)handleLinkPreviewsIfNeededWithUrl:(NSString *)linkPreviewURL message:(TSMessage *)message { - [OWSLinkPreview tryToBuildPreviewInfoObjcWithPreviewUrl:linkPreviewURL] - .thenOn(dispatch_get_main_queue(), ^(OWSLinkPreviewDraft *linkPreviewDraft) { - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - OWSLinkPreview *linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft transaction:transaction error:nil]; - message.linkPreview = linkPreview; - [message saveWithTransaction:transaction]; - }]; - }) - .catchOn(dispatch_get_main_queue(), ^(NSError *error) { - // If we failed to get link preview due to invalid content then maybe it's a link to a direct image? - if ([OWSLinkPreview isInvalidContentError:error]) { - __block AnyPromise *promise; - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - promise = [OWSLinkPreview getImagePreviewFromUrl:linkPreviewURL transaction:transaction]; - }]; - return promise; - } - - // Return the error - return [AnyPromise promiseWithValue:error]; - }) - .thenOn(dispatch_get_main_queue(), ^(OWSLinkPreview *linkPreview) { - // If we managed to get direct previews then render them - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - if (linkPreview.isDirectAttachment) { - if (!message.hasAttachments) { - [message addAttachmentId:linkPreview.imageAttachmentId transaction:transaction]; - - // Set the message id in attachment - TSAttachment *linkPreviewAttachment = [TSAttachment fetchObjectWithUniqueID:linkPreview.imageAttachmentId transaction:transaction]; - linkPreviewAttachment.albumMessageId = message.uniqueId; - [linkPreviewAttachment saveWithTransaction:transaction]; - } - } else { - message.linkPreview = linkPreview; - [message saveWithTransaction:transaction]; - } - - }]; - }); -} - // The difference between this function and `handleFriendRequestAcceptIfNeededWithEnvelope:` is that this will setup the incoming message for display to the user // While `handleFriendRequestAcceptIfNeededWithEnvelope:` handles friend request accepting logic and doesn't need a message - (void)handleFriendRequestMessageIfNeededWithEnvelope:(SSKProtoEnvelope *)envelope message:(TSIncomingMessage *)message thread:(TSThread *)thread transaction:(YapDatabaseReadWriteTransaction *)transaction { diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index ebde64588..50e83aae3 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1239,6 +1239,15 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // have a valid Signal account. [SignalRecipient markRecipientAsRegisteredAndGet:recipient.recipientId transaction:transaction]; }]; + + // Check if we need to generate link previews + TSMessage *message = messageSend.message; + if (message.linkPreview == nil && !message.hasAttachments) { + dispatch_async(dispatch_get_main_queue(), ^{ + NSString *url = [OWSLinkPreview previewURLForRawBodyText:message.body]; + if (url) { [message generateLinkPreviewIfNeededFromURL:url]; } + }); + } messageSend.success(); });