mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Fetch thumbnail when not available locally
// FREEBIE
This commit is contained in:
parent
42f454b075
commit
fa2e1ba89b
|
@ -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];
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue