Fetch thumbnail when not available locally

// FREEBIE
This commit is contained in:
Michael Kirk 2018-04-07 13:59:49 -04:00
parent 42f454b075
commit fa2e1ba89b
11 changed files with 204 additions and 172 deletions

View file

@ -1657,14 +1657,13 @@ typedef enum : NSUInteger {
}];
[actionSheetController addAction:deleteMessageAction];
UIAlertAction *resendMessageAction = [UIAlertAction
UIAlertAction *retryAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"MESSAGES_VIEW_FAILED_DOWNLOAD_RETRY_ACTION", @"Action sheet button text")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
OWSAttachmentsProcessor *processor =
[[OWSAttachmentsProcessor alloc] initWithAttachmentPointer:attachmentPointer
networkManager:self.networkManager
primaryStorage:self.primaryStorage];
networkManager:self.networkManager];
[processor fetchAttachmentsForMessage:message
primaryStorage:self.primaryStorage
success:^(TSAttachmentStream *_Nonnull attachmentStream) {
@ -1676,7 +1675,7 @@ typedef enum : NSUInteger {
}];
}];
[actionSheetController addAction:resendMessageAction];
[actionSheetController addAction:retryAction];
[self dismissKeyBoard];
[self presentViewController:actionSheetController animated:YES completion:nil];

View file

@ -81,7 +81,6 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSAttachmentsProcessor alloc] initWithAttachmentProtos:transcript.attachmentPointerProtos
relay:transcript.relay
networkManager:self.networkManager
primaryStorage:self.primaryStorage
transaction:transaction];
// TODO group updates. Currently desktop doesn't support group updates, so not a problem yet.
@ -96,6 +95,7 @@ NS_ASSUME_NONNULL_BEGIN
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
// TODO synced quoted replies
if (transcript.isExpirationTimerUpdate) {
[OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage
contactsManager:self.contactsManager];

View file

@ -29,24 +29,22 @@ extern NSString *const kAttachmentDownloadAttachmentIDKey;
- (instancetype)init NS_UNAVAILABLE;
// TODO make this take one and loop over?
- (instancetype)initWithAttachmentProtos:(NSArray<OWSSignalServiceProtosAttachmentPointer *> *)attachmentProtos
relay:(nullable NSString *)relay
networkManager:(TSNetworkManager *)networkManager
primaryStorage:(OWSPrimaryStorage *)primaryStorage
transaction:(YapDatabaseReadWriteTransaction *)transaction NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithQuotedAttachmentProtos:(NSArray<OWSSignalServiceProtosAttachmentPointer *> *)attachmentProtos
relay:(nullable NSString *)relay
networkManager:(TSNetworkManager *)networkManager
primaryStorage:(OWSPrimaryStorage *)primaryStorage
transaction:(YapDatabaseReadWriteTransaction *)transaction NS_DESIGNATED_INITIALIZER;
/*
* Retry fetching failed attachment download
*/
- (instancetype)initWithAttachmentPointer:(TSAttachmentPointer *)attachmentPointer
networkManager:(TSNetworkManager *)networkManager
primaryStorage:(OWSPrimaryStorage *)primaryStorage NS_DESIGNATED_INITIALIZER;
networkManager:(TSNetworkManager *)networkManager NS_DESIGNATED_INITIALIZER;
+ (TSAttachmentPointer *)buildPointerFromProto:(OWSSignalServiceProtosAttachmentPointer *)attachmentProto
relay:(NSString *_Nullable)relay;
- (void)fetchAttachmentsForMessage:(nullable TSMessage *)message
primaryStorage:(OWSPrimaryStorage *)primaryStorage

View file

@ -35,7 +35,6 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f;
@interface OWSAttachmentsProcessor ()
@property (nonatomic, readonly) TSNetworkManager *networkManager;
@property (nonatomic, readonly) OWSPrimaryStorage *primaryStorage;
@end
@ -43,7 +42,6 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f;
- (instancetype)initWithAttachmentPointer:(TSAttachmentPointer *)attachmentPointer
networkManager:(TSNetworkManager *)networkManager
primaryStorage:(OWSPrimaryStorage *)primaryStorage
{
self = [super init];
if (!self) {
@ -51,7 +49,6 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f;
}
_networkManager = networkManager;
_primaryStorage = primaryStorage;
_attachmentPointers = @[ attachmentPointer ];
_attachmentIds = @[ attachmentPointer.uniqueId ];
@ -62,7 +59,6 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f;
- (instancetype)initWithAttachmentProtos:(NSArray<OWSSignalServiceProtosAttachmentPointer *> *)attachmentProtos
relay:(nullable NSString *)relay
networkManager:(TSNetworkManager *)networkManager
primaryStorage:(OWSPrimaryStorage *)primaryStorage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
self = [super init];
@ -71,35 +67,12 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f;
}
_networkManager = networkManager;
_primaryStorage = primaryStorage;
NSMutableArray<NSString *> *attachmentIds = [NSMutableArray new];
NSMutableArray<TSAttachmentPointer *> *attachmentPointers = [NSMutableArray new];
for (OWSSignalServiceProtosAttachmentPointer *attachmentProto in attachmentProtos) {
OWSAssert(attachmentProto.id != 0);
OWSAssert(attachmentProto.key != nil);
OWSAssert(attachmentProto.contentType != nil);
// digest will be empty for old clients.
NSData *digest = attachmentProto.hasDigest ? attachmentProto.digest : nil;
TSAttachmentType attachmentType = TSAttachmentTypeDefault;
if ([attachmentProto hasFlags]) {
UInt32 flags = attachmentProto.flags;
if ((flags & (UInt32)OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage) > 0) {
attachmentType = TSAttachmentTypeVoiceMessage;
}
}
TSAttachmentPointer *pointer = [[TSAttachmentPointer alloc] initWithServerId:attachmentProto.id
key:attachmentProto.key
digest:digest
byteCount:attachmentProto.size
contentType:attachmentProto.contentType
relay:relay
sourceFilename:attachmentProto.fileName
attachmentType:attachmentType];
TSAttachmentPointer *pointer = [self.class buildPointerFromProto:attachmentProto relay:relay];
[attachmentIds addObject:pointer.uniqueId];
[pointer saveWithTransaction:transaction];
@ -112,7 +85,36 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f;
return self;
}
// Remove this?
+ (TSAttachmentPointer *)buildPointerFromProto:(OWSSignalServiceProtosAttachmentPointer *)attachmentProto
relay:(NSString *_Nullable)relay
{
OWSAssert(attachmentProto.id != 0);
OWSAssert(attachmentProto.key != nil);
OWSAssert(attachmentProto.contentType != nil);
// digest will be empty for old clients.
NSData *digest = attachmentProto.hasDigest ? attachmentProto.digest : nil;
TSAttachmentType attachmentType = TSAttachmentTypeDefault;
if ([attachmentProto hasFlags]) {
UInt32 flags = attachmentProto.flags;
if ((flags & (UInt32)OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage) > 0) {
attachmentType = TSAttachmentTypeVoiceMessage;
}
}
TSAttachmentPointer *pointer = [[TSAttachmentPointer alloc] initWithServerId:attachmentProto.id
key:attachmentProto.key
digest:digest
byteCount:attachmentProto.size
contentType:attachmentProto.contentType
relay:relay
sourceFilename:attachmentProto.fileName
attachmentType:attachmentType];
return pointer;
}
// PERF: Remove this and use a pre-existing dbConnection
- (void)fetchAttachmentsForMessage:(nullable TSMessage *)message
primaryStorage:(OWSPrimaryStorage *)primaryStorage
success:(void (^)(TSAttachmentStream *attachmentStream))successHandler

View file

@ -11,7 +11,9 @@ NS_ASSUME_NONNULL_BEGIN
*/
@class TSAttachment;
@class TSAttachmentStream;
@class TSQuotedMessage;
@class YapDatabaseReadWriteTransaction;
@interface TSMessage : TSInteraction
@ -38,6 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)hasAttachments;
- (nullable TSAttachment *)attachmentWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (void)setQuotedMessageThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream;
- (BOOL)shouldStartExpireTimer;
- (BOOL)shouldStartExpireTimer:(YapDatabaseReadTransaction *)transaction;

View file

@ -7,7 +7,8 @@
#import "NSDate+OWS.h"
#import "NSString+SSK.h"
#import "TSAttachment.h"
#import "TSAttachmentPointer.h"
#import "TSAttachmentStream.h"
#import "TSQuotedMessage.h"
#import "TSThread.h"
#import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseTransaction.h>
@ -50,8 +51,6 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
// they were received & decrypted, not by when they were sent.
@property (nonatomic) uint64_t receivedAtTimestamp;
@property (nonatomic, nullable) TSQuotedMessage *quotedMessage;
@end
#pragma mark -
@ -311,6 +310,15 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
return _body.filterStringForDisplay;
}
- (void)setQuotedMessageThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream
{
OWSAssert([attachmentStream isKindOfClass:[TSAttachmentStream class]]);
OWSAssert(self.quotedMessage);
OWSAssert(self.quotedMessage.quotedAttachments.count == 1);
[self.quotedMessage setThumbnailAttachmentStream:attachmentStream];
}
#pragma mark - Update With... Methods
- (void)updateWithExpireStartedAt:(uint64_t)expireStartedAt transaction:(YapDatabaseReadWriteTransaction *)transaction

View file

@ -480,9 +480,9 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
quotedAttachmentBuilder.contentType = attachment.contentType;
quotedAttachmentBuilder.fileName = attachment.sourceFilename;
if (attachment.thumbnailAttachmentId) {
if (attachment.thumbnailAttachmentStreamId) {
quotedAttachmentBuilder.thumbnail =
[self buildProtoForAttachmentId:attachment.thumbnailAttachmentId];
[self buildProtoForAttachmentId:attachment.thumbnailAttachmentStreamId];
}
[quoteBuilder addAttachments:[quotedAttachmentBuilder build]];

View file

@ -56,8 +56,11 @@ NS_ASSUME_NONNULL_BEGIN
// TODO: rename to pendingAttachmentId or maybe pendingAttachmentStream?
@property (nonatomic, readonly, nullable) NSString *attachmentId;
// This is set once we've persisted a thumbnail
@property (atomic, nullable) NSString *thumbnailAttachmentId;
// References a yet-to-be downloaded thumbnail file
@property (atomic, nullable) NSString *thumbnailAttachmentPointerId;
// References an already downloaded or locally generated thumbnail file
@property (atomic, nullable) NSString *thumbnailAttachmentStreamId;
- (instancetype)init NS_UNAVAILABLE;
@ -88,11 +91,15 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable NSString *)contentType;
- (nullable NSString *)sourceFilename;
// References a yet-to-be downloaded thumbnail file
- (nullable NSString *)thumbnailAttachmentPointerId;
// References an already downloaded or locally generated thumbnail file
- (nullable NSString *)thumbnailAttachmentStreamId;
- (void)setThumbnailAttachmentStream:(TSAttachment *)thumbnailAttachmentStream;
@property (atomic, readonly) NSArray<OWSAttachmentInfo *> *quotedAttachments;
- (NSArray<TSAttachment *> *)fetchAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction;
// Before sending, persist a thumbnail attachment derived from the quoted attachment
- (NSArray<TSAttachmentStream *> *)createThumbnailAttachmentsIfNecessaryWithTransaction:
(YapDatabaseReadWriteTransaction *)transaction;

View file

@ -90,9 +90,9 @@ NS_ASSUME_NONNULL_BEGIN
OWSAttachmentInfo *attachmentInfo = quotedMessage.quotedAttachments.firstObject;
UIImage *_Nullable thumbnailImage;
if (attachmentInfo.thumbnailAttachmentId) {
if (attachmentInfo.thumbnailAttachmentStreamId) {
TSAttachment *attachment =
[TSAttachment fetchObjectWithUniqueID:attachmentInfo.thumbnailAttachmentId transaction:transaction];
[TSAttachment fetchObjectWithUniqueID:attachmentInfo.thumbnailAttachmentStreamId transaction:transaction];
TSAttachmentStream *attachmentStream;
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
@ -182,6 +182,7 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable OWSAttachmentInfo *)firstAttachmentInfo
{
OWSAssert(self.quotedAttachments.count <= 1);
return self.quotedAttachments.firstObject;
}
@ -199,62 +200,29 @@ NS_ASSUME_NONNULL_BEGIN
return firstAttachment.sourceFilename;
}
//- (NSArray<TSAttachment *> *)fetchThumbnailAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction
//{
// NSMutableArray<TSAttachment *> *attachments = [NSMutableArray new];
//
// for (OWSAttachmentInfo *attachmentInfo in self.quotedAttachments) {
// TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentInfo.attachmentId
// transaction:transaction];
//
// }
//}
- (nullable NSString *)thumbnailAttachmentStreamId
{
OWSAttachmentInfo *firstAttachment = self.firstAttachmentInfo;
#pragma mark - Thumbnail
return firstAttachment.thumbnailAttachmentStreamId;
}
- (nullable NSString *)thumbnailAttachmentPointerId
{
OWSAttachmentInfo *firstAttachment = self.firstAttachmentInfo;
return firstAttachment.thumbnailAttachmentPointerId;
}
- (void)setThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream
{
OWSAssert([attachmentStream isKindOfClass:[TSAttachmentStream class]]);
OWSAssert(self.quotedAttachments.count == 1);
OWSAttachmentInfo *firstAttachment = self.firstAttachmentInfo;
firstAttachment.thumbnailAttachmentStreamId = attachmentStream.uniqueId;
}
//- (nullable TSAttachment *)firstAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction
//{
// OWSAttachmentInfo *attachmentInfo = self.firstAttachmentInfo;
// if (!attachmentInfo) {
// return nil;
// }
//
// return [TSAttachment fetchObjectWithUniqueID:attachmentInfo.attachmentId];
//}
//- (nullable UIImage *)thumbnailImageWithTransaction:(YapDatabaseReadTransaction *)transaction
//{
// TSAttachmentStream *firstAttachment = (TSAttachmentStream *)self.firstAttachmentIn;
// if (![firstAttachment isKindOfClass:[TSAttachmentStream class]]) {
// return nil;
// }
//
// return firstAttachment.thumbnailImage;
//}
//- (BOOL)hasThumbnailAttachments
//{
// return self.thumbnailAttachments.count > 0;
//}
//
//- (void)addThumbnailAttachment:(TSAttachmentStream *)attachment
//{
// NSMutableArray<OWSAttachmentInfo *> *existingAttachments = [self.thumbnailAttachments mutableCopy];
//
// OWSAttachmentInfo *attachmentInfo = [[OWSAttachmentInfo alloc] initWithAttachment:attachment];
// [existingAttachments addObject:attachmentInfo];
//
// self.thumbnailAttachments = [existingAttachments copy];
//}
//
//- (nullable OWSAttachmentInfo *)firstThumbnailAttachment
//{
// return self.thumbnailAttachments.firstObject;
//}
//
//- (TSAttachmentStream *)thumbnailAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction
//{
//
//}
//
- (NSArray<TSAttachmentStream *> *)createThumbnailAttachmentsIfNecessaryWithTransaction:
(YapDatabaseReadWriteTransaction *)transaction
{
@ -275,7 +243,7 @@ NS_ASSUME_NONNULL_BEGIN
}
[thumbnailStream saveWithTransaction:transaction];
info.thumbnailAttachmentId = thumbnailStream.uniqueId;
info.thumbnailAttachmentStreamId = thumbnailStream.uniqueId;
[thumbnailAttachments addObject:thumbnailStream];
}

View file

@ -517,7 +517,6 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSAttachmentsProcessor alloc] initWithAttachmentProtos:@[ dataMessage.group.avatar ]
relay:envelope.relay
networkManager:self.networkManager
primaryStorage:self.primaryStorage
transaction:transaction];
if (!attachmentsProcessor.hasSupportedAttachments) {
@ -555,7 +554,6 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSAttachmentsProcessor alloc] initWithAttachmentProtos:dataMessage.attachments
relay:envelope.relay
networkManager:self.networkManager
primaryStorage:self.primaryStorage
transaction:transaction];
if (!attachmentsProcessor.hasSupportedAttachments) {
DDLogWarn(@"%@ received unsupported media envelope", self.logTag);
@ -1052,6 +1050,7 @@ NS_ASSUME_NONNULL_BEGIN
attachmentIds:attachmentIds
expiresInSeconds:dataMessage.expireTimer
quotedMessage:quotedMessage];
[self finalizeIncomingMessage:incomingMessage
thread:thread
envelope:envelope
@ -1102,73 +1101,42 @@ NS_ASSUME_NONNULL_BEGIN
contentType:quotedAttachment.contentType
sourceFilename:quotedAttachment.fileName];
TSMessage *_Nullable quotedMessage = (TSMessage *)[TSInteraction
interactionsWithTimestamp:timestamp
filter:^BOOL(TSInteraction *interaction) {
// We prefer deriving any thumbnail locally rather than fetching one from the network.
TSAttachmentStream *_Nullable thumbnailStream =
[self tryToDeriveLocalThumbnailWithAttachmentInfo:attachmentInfo
timestamp:timestamp
threadId:thread.uniqueId
authorId:authorId
transaction:transaction];
if (![thread.uniqueId isEqual:interaction.uniqueThreadId]) {
return NO;
}
if (thumbnailStream) {
DDLogDebug(@"%@ Generated local thumbnail for quoted quoted message: %@:%zu",
self.logTag,
thread.uniqueId,
timestamp);
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)interaction;
return [authorId isEqual:incomingMessage.messageAuthorId];
} else if ([interaction isKindOfClass:[TSOutgoingMessage class]]) {
return [authorId isEqual:[TSAccountManager localNumber]];
} else {
// ignore other interaction types
return NO;
}
[thumbnailStream saveWithTransaction:transaction];
}
withTransaction:transaction]
.firstObject;
attachmentInfo.thumbnailAttachmentStreamId = thumbnailStream.uniqueId;
} else if (quotedAttachment.hasThumbnail) {
DDLogDebug(@"%@ Saving reference for fetching remote thumbnail for quoted message: %@:%zu",
self.logTag,
thread.uniqueId,
timestamp);
// We still have the existing quoted message locally.
// Derive any thumbnail locally rather than fetching one over the network.
if (quotedMessage) {
TSAttachment *attachment = [quotedMessage attachmentWithTransaction:transaction];
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
TSAttachmentStream *sourceStream = (TSAttachmentStream *)attachment;
OWSSignalServiceProtosAttachmentPointer *thumbnailAttachmentProto = quotedAttachment.thumbnail;
TSAttachmentPointer *thumbnailPointer =
[OWSAttachmentsProcessor buildPointerFromProto:thumbnailAttachmentProto relay:envelope.relay];
[thumbnailPointer saveWithTransaction:transaction];
TSAttachmentStream *thumbnailStream = [sourceStream cloneAsThumbnail];
[thumbnailStream saveWithTransaction:transaction];
attachmentInfo.thumbnailAttachmentId = thumbnailStream.uniqueId;
}
attachmentInfo.thumbnailAttachmentPointerId = thumbnailPointer.uniqueId;
} else {
DDLogDebug(@"%@ No thumbnail for quoted message: %@:%zu", self.logTag, thread.uniqueId, timestamp);
}
[attachmentInfos addObject:attachmentInfo];
}
// TODO - but only if the attachment can't be found locally.
// OWSAttachmentsProcessor *attachmentsProcessor =
// [[OWSAttachmentsProcessor alloc] initWithAttachmentProtos:quoteProto.attachments
// relay:envelope.relay
// networkManager:self.networkManager
// primaryStorage:self.primaryStorage
// transaction:transaction];
//
// if (!attachmentsProcessor.hasSupportedAttachments) {
// attachments = @[];
// } else {
// attachments = attachmentsProcessor.attachmentPointers;
// }
//
// [attachmentsProcessor fetchAttachmentsForMessage:nil
// transaction:transaction
// success:^(TSAttachmentStream *attachmentStream) {
// [groupThread
// updateAvatarWithAttachmentStream:attachmentStream];
// }
// failure:^(NSError *error) {
// DDLogError(@"%@ failed to fetch attachments for group
// avatar sent at: %llu. with error: %@",
// self.logTag,
// envelope.timestamp,
// error);
// }];
if (!hasText && !hasAttachment) {
OWSFail(@"%@ quoted message has neither text nor attachment", self.logTag);
return nil;
@ -1180,6 +1148,58 @@ NS_ASSUME_NONNULL_BEGIN
quotedAttachmentInfos:attachmentInfos];
}
- (nullable TSAttachmentStream *)tryToDeriveLocalThumbnailWithAttachmentInfo:(OWSAttachmentInfo *)attachmentInfo
timestamp:(uint64_t)timestamp
threadId:(NSString *)threadId
authorId:(NSString *)authorId
transaction:
(YapDatabaseReadWriteTransaction *)transaction
{
if (![TSAttachmentStream hasThumbnailForMimeType:attachmentInfo.contentType]) {
return nil;
}
NSArray<TSMessage *> *quotedMessages = (NSArray<TSMessage *> *)[TSInteraction
interactionsWithTimestamp:timestamp
filter:^BOOL(TSInteraction *interaction) {
if (![threadId isEqual:interaction.uniqueThreadId]) {
return NO;
}
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)interaction;
return [authorId isEqual:incomingMessage.messageAuthorId];
} else if ([interaction isKindOfClass:[TSOutgoingMessage class]]) {
return [authorId isEqual:[TSAccountManager localNumber]];
} else {
// ignore other interaction types
return NO;
}
}
withTransaction:transaction];
TSMessage *_Nullable quotedMessage = quotedMessages.firstObject;
if (!quotedMessage) {
return nil;
}
TSAttachment *attachment = [quotedMessage attachmentWithTransaction:transaction];
if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
return nil;
}
TSAttachmentStream *sourceStream = (TSAttachmentStream *)attachment;
TSAttachmentStream *_Nullable thumbnailStream = [sourceStream cloneAsThumbnail];
if (!thumbnailStream) {
return nil;
}
return thumbnailStream;
}
- (void)finalizeIncomingMessage:(TSIncomingMessage *)incomingMessage
thread:(TSThread *)thread
envelope:(OWSSignalServiceProtosEnvelope *)envelope
@ -1212,7 +1232,36 @@ NS_ASSUME_NONNULL_BEGIN
[incomingMessage markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:YES];
}
DDLogDebug(@"%@ shouldMarkMessageAsRead: %d (%@)", self.logTag, shouldMarkMessageAsRead, envelope.source);
TSQuotedMessage *_Nullable quotedMessage = incomingMessage.quotedMessage;
if (quotedMessage && quotedMessage.thumbnailAttachmentPointerId) {
// We weren't able to derive a local thumbnail, so we'll fetch the referenced attachment.
TSAttachmentPointer *attachmentPointer =
[TSAttachmentPointer fetchObjectWithUniqueID:quotedMessage.thumbnailAttachmentPointerId
transaction:transaction];
if ([attachmentPointer isKindOfClass:[TSAttachmentPointer class]]) {
OWSAttachmentsProcessor *attachmentProcessor =
[[OWSAttachmentsProcessor alloc] initWithAttachmentPointer:attachmentPointer
networkManager:self.networkManager];
DDLogDebug(@"%@ downloading thumbnail for message: %tu", self.logTag, incomingMessage.timestamp);
[attachmentProcessor fetchAttachmentsForMessage:incomingMessage
transaction:transaction
success:^(TSAttachmentStream *_Nonnull attachmentStream) {
[self.dbConnection
asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[incomingMessage setQuotedMessageThumbnailAttachmentStream:attachmentStream];
[incomingMessage saveWithTransaction:transaction];
}];
}
failure:^(NSError *_Nonnull error) {
DDLogWarn(@"%@ failed to fetch thumbnail for message: %tu with error: %@",
self.logTag,
incomingMessage.timestamp,
error);
}];
}
}
// In case we already have a read receipt for this new message (this happens sometimes).
[OWSReadReceiptManager.sharedManager applyEarlyReadReceiptsForIncomingMessage:incomingMessage

View file

@ -326,7 +326,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
if (message.quotedMessage) {
// TODO do we want a different thumbnail size for quotes vs the gallery? This seems reasonable,
// and has the advantage of already having been generated.
__block NSArray<TSAttachmentStream *> *thumbnailAttachments;
@ -338,7 +337,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
}
}];
// Though we currently only ever expect at most one thumbnail, the proto data model
// suggests this could change. The logic is intended to work with multiple, but
// if we ever actually want to send multiple, we should do more testing.