Use QuotedReplyModel to access attachment data

This view model loads the attachment when it's build.

// FREEBIE
This commit is contained in:
Michael Kirk 2018-04-06 16:53:16 -04:00
parent 3334f2a063
commit cb5d3d4f85
16 changed files with 186 additions and 110 deletions

View File

@ -252,9 +252,8 @@ NS_ASSUME_NONNULL_BEGIN
if (self.isQuotedReply) { if (self.isQuotedReply) {
OWSAssert(!lastSubview); OWSAssert(!lastSubview);
TSMessage *message = (TSMessage *)self.viewItem.interaction;
OWSQuotedMessageView *quotedMessageView = [OWSQuotedMessageView OWSQuotedMessageView *quotedMessageView = [OWSQuotedMessageView
quotedMessageViewForConversation:message.quotedMessage quotedMessageViewForConversation:self.viewItem.quotedReply
displayableQuotedText:(self.viewItem.hasQuotedText ? self.viewItem.displayableQuotedText : nil)]; displayableQuotedText:(self.viewItem.hasQuotedText ? self.viewItem.displayableQuotedText : nil)];
self.quotedMessageView = quotedMessageView; self.quotedMessageView = quotedMessageView;
[quotedMessageView createContents]; [quotedMessageView createContents];
@ -903,9 +902,8 @@ NS_ASSUME_NONNULL_BEGIN
return CGSizeZero; return CGSizeZero;
} }
TSMessage *message = (TSMessage *)self.viewItem.interaction;
OWSQuotedMessageView *quotedMessageView = [OWSQuotedMessageView OWSQuotedMessageView *quotedMessageView = [OWSQuotedMessageView
quotedMessageViewForConversation:message.quotedMessage quotedMessageViewForConversation:self.viewItem.quotedReply
displayableQuotedText:(self.hasQuotedText ? self.viewItem.displayableQuotedText : nil)]; displayableQuotedText:(self.hasQuotedText ? self.viewItem.displayableQuotedText : nil)];
const int maxMessageWidth = [self maxMessageWidthForContentWidth:contentWidth]; const int maxMessageWidth = [self maxMessageWidthForContentWidth:contentWidth];
CGSize result = [quotedMessageView sizeForMaxWidth:maxMessageWidth - kBubbleThornSideInset]; CGSize result = [quotedMessageView sizeForMaxWidth:maxMessageWidth - kBubbleThornSideInset];

View File

@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
@class DisplayableText; @class DisplayableText;
@class OWSBubbleStrokeView; @class OWSBubbleStrokeView;
@class TSQuotedMessage; @class OWSQuotedReplyModel;
@interface OWSQuotedMessageView : UIView @interface OWSQuotedMessageView : UIView
@ -21,11 +21,11 @@ NS_ASSUME_NONNULL_BEGIN
- (CGSize)sizeForMaxWidth:(CGFloat)maxWidth; - (CGSize)sizeForMaxWidth:(CGFloat)maxWidth;
// Factory method for "message bubble" views. // Factory method for "message bubble" views.
+ (OWSQuotedMessageView *)quotedMessageViewForConversation:(TSQuotedMessage *)quotedMessage + (OWSQuotedMessageView *)quotedMessageViewForConversation:(OWSQuotedReplyModel *)quotedMessage
displayableQuotedText:(nullable DisplayableText *)displayableQuotedText; displayableQuotedText:(nullable DisplayableText *)displayableQuotedText;
// Factory method for "message compose" views. // Factory method for "message compose" views.
+ (OWSQuotedMessageView *)quotedMessageViewForPreview:(TSQuotedMessage *)quotedMessage; + (OWSQuotedMessageView *)quotedMessageViewForPreview:(OWSQuotedReplyModel *)quotedMessage;
@end @end

View File

@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSQuotedMessageView () @interface OWSQuotedMessageView ()
@property (nonatomic, readonly) TSQuotedMessage *quotedMessage; @property (nonatomic, readonly) OWSQuotedReplyModel *quotedMessage;
@property (nonatomic, nullable, readonly) DisplayableText *displayableQuotedText; @property (nonatomic, nullable, readonly) DisplayableText *displayableQuotedText;
@property (nonatomic, nullable) OWSBubbleStrokeView *boundsStrokeView; @property (nonatomic, nullable) OWSBubbleStrokeView *boundsStrokeView;
@ -30,7 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSQuotedMessageView @implementation OWSQuotedMessageView
+ (OWSQuotedMessageView *)quotedMessageViewForConversation:(TSQuotedMessage *)quotedMessage + (OWSQuotedMessageView *)quotedMessageViewForConversation:(OWSQuotedReplyModel *)quotedMessage
displayableQuotedText:(nullable DisplayableText *)displayableQuotedText displayableQuotedText:(nullable DisplayableText *)displayableQuotedText
{ {
OWSAssert(quotedMessage); OWSAssert(quotedMessage);
@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSQuotedMessageView alloc] initWithQuotedMessage:quotedMessage displayableQuotedText:displayableQuotedText]; [[OWSQuotedMessageView alloc] initWithQuotedMessage:quotedMessage displayableQuotedText:displayableQuotedText];
} }
+ (OWSQuotedMessageView *)quotedMessageViewForPreview:(TSQuotedMessage *)quotedMessage + (OWSQuotedMessageView *)quotedMessageViewForPreview:(OWSQuotedReplyModel *)quotedMessage
{ {
OWSAssert(quotedMessage); OWSAssert(quotedMessage);
@ -52,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSQuotedMessageView alloc] initWithQuotedMessage:quotedMessage displayableQuotedText:displayableQuotedText]; [[OWSQuotedMessageView alloc] initWithQuotedMessage:quotedMessage displayableQuotedText:displayableQuotedText];
} }
- (instancetype)initWithQuotedMessage:(TSQuotedMessage *)quotedMessage - (instancetype)initWithQuotedMessage:(OWSQuotedReplyModel *)quotedMessage
displayableQuotedText:(nullable DisplayableText *)displayableQuotedText displayableQuotedText:(nullable DisplayableText *)displayableQuotedText
{ {
self = [super init]; self = [super init];
@ -140,9 +140,6 @@ NS_ASSUME_NONNULL_BEGIN
[quotedAttachmentView autoSetDimension:ALDimensionHeight toSize:self.quotedAttachmentSize]; [quotedAttachmentView autoSetDimension:ALDimensionHeight toSize:self.quotedAttachmentSize];
[quotedAttachmentView setContentHuggingHigh]; [quotedAttachmentView setContentHuggingHigh];
[quotedAttachmentView setCompressionResistanceHigh]; [quotedAttachmentView setCompressionResistanceHigh];
if (quotedAttachmentView) {
}
} }
UILabel *quotedAuthorLabel = [self createQuotedAuthorLabel]; UILabel *quotedAuthorLabel = [self createQuotedAuthorLabel];
@ -210,14 +207,10 @@ NS_ASSUME_NONNULL_BEGIN
return nil; return nil;
} }
// FIXME // TODO: Possibly ignore data that is too large.
return nil; UIImage *_Nullable image = self.quotedMessage.thumbnailImage;
// TODO: Possibly ignore images that are too large.
// return image;
// // TODO: Possibly ignore data that is too large.
// UIImage *_Nullable image = self.quotedMessage.thumbnailImage;
// // TODO: Possibly ignore images that are too large.
// return image;
} }
- (UIImageView *)imageViewForImage:(UIImage *)image - (UIImageView *)imageViewForImage:(UIImage *)image

View File

@ -4,7 +4,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSQuotedReplyDraft; @class OWSQuotedReplyModel;
@class SignalAttachment; @class SignalAttachment;
@protocol ConversationInputToolbarDelegate <NSObject> @protocol ConversationInputToolbarDelegate <NSObject>
@ -58,7 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)cancelVoiceMemoIfNecessary; - (void)cancelVoiceMemoIfNecessary;
@property (nonatomic, nullable) OWSQuotedReplyDraft *quotedReplyDraft; @property (nonatomic, nullable) OWSQuotedReplyModel *quotedReplyDraft;
@end @end

View File

@ -250,7 +250,7 @@ static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5;
[self ensureContentConstraints]; [self ensureContentConstraints];
} }
- (void)setQuotedReplyDraft:(nullable OWSQuotedReplyDraft *)quotedReplyDraft - (void)setQuotedReplyDraft:(nullable OWSQuotedReplyModel *)quotedReplyDraft
{ {
if (quotedReplyDraft == _quotedReplyDraft) { if (quotedReplyDraft == _quotedReplyDraft) {
return; return;

View File

@ -2149,12 +2149,12 @@ typedef enum : NSUInteger {
return; return;
} }
__block OWSQuotedReplyDraft *quotedReplyDraft; __block OWSQuotedReplyModel *quotedReplyDraft;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
quotedReplyDraft = [OWSMessageUtils quotedReplyDraftForMessage:message transaction:transaction]; quotedReplyDraft = [OWSMessageUtils quotedReplyDraftForMessage:message transaction:transaction];
}]; }];
if (![quotedReplyDraft isKindOfClass:[OWSQuotedReplyDraft class]]) { if (![quotedReplyDraft isKindOfClass:[OWSQuotedReplyModel class]]) {
OWSFail(@"%@ unexpected quotedMessage: %@", self.logTag, quotedReplyDraft.class); OWSFail(@"%@ unexpected quotedMessage: %@", self.logTag, quotedReplyDraft.class);
return; return;
} }

View File

@ -26,6 +26,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
@class ConversationViewCell; @class ConversationViewCell;
@class DisplayableText; @class DisplayableText;
@class OWSAudioMessageView; @class OWSAudioMessageView;
@class OWSQuotedReplyModel;
@class TSAttachmentPointer; @class TSAttachmentPointer;
@class TSAttachmentStream; @class TSAttachmentStream;
@class TSInteraction; @class TSInteraction;
@ -41,11 +42,13 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
@interface ConversationViewItem : NSObject <ConversationViewLayoutItem, OWSAudioPlayerDelegate> @interface ConversationViewItem : NSObject <ConversationViewLayoutItem, OWSAudioPlayerDelegate>
@property (nonatomic, readonly) TSInteraction *interaction; @property (nonatomic, readonly) TSInteraction *interaction;
@property (nonatomic, readonly, nullable) OWSQuotedReplyModel *quotedReply;
@property (nonatomic, readonly) BOOL isGroupThread; @property (nonatomic, readonly) BOOL isGroupThread;
@property (nonatomic, readonly) BOOL hasBodyText; @property (nonatomic, readonly) BOOL hasBodyText;
// TODO drive these off of the quotedReply?
@property (nonatomic, readonly) BOOL isQuotedReply; @property (nonatomic, readonly) BOOL isQuotedReply;
@property (nonatomic, readonly) BOOL hasQuotedAttachment; @property (nonatomic, readonly) BOOL hasQuotedAttachment;
@property (nonatomic, readonly) BOOL hasQuotedText; @property (nonatomic, readonly) BOOL hasQuotedText;

View File

@ -57,8 +57,9 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
@property (nonatomic) OWSMessageCellType messageCellType; @property (nonatomic) OWSMessageCellType messageCellType;
@property (nonatomic, nullable) DisplayableText *displayableBodyText; @property (nonatomic, nullable) DisplayableText *displayableBodyText;
@property (nonatomic, nullable) DisplayableText *displayableQuotedText; @property (nonatomic, nullable) DisplayableText *displayableQuotedText;
@property (nonatomic, nullable) NSString *quotedAttachmentMimetype; @property (nonatomic, nullable) OWSQuotedReplyModel *quotedReply;
@property (nonatomic, nullable) NSString *quotedRecipientId; @property (nonatomic, readonly, nullable) NSString *quotedAttachmentMimetype;
@property (nonatomic, readonly, nullable) NSString *quotedRecipientId;
@property (nonatomic, nullable) TSAttachmentStream *attachmentStream; @property (nonatomic, nullable) TSAttachmentStream *attachmentStream;
@property (nonatomic, nullable) TSAttachmentPointer *attachmentPointer; @property (nonatomic, nullable) TSAttachmentPointer *attachmentPointer;
@property (nonatomic) CGSize mediaSize; @property (nonatomic) CGSize mediaSize;
@ -101,10 +102,8 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
self.attachmentStream = nil; self.attachmentStream = nil;
self.attachmentPointer = nil; self.attachmentPointer = nil;
self.mediaSize = CGSizeZero; self.mediaSize = CGSizeZero;
self.displayableQuotedText = nil; self.displayableQuotedText = nil;
self.quotedRecipientId = nil; self.quotedReply = nil;
self.quotedAttachmentMimetype = nil;
[self clearCachedLayoutState]; [self clearCachedLayoutState];
@ -471,17 +470,29 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
self.displayableBodyText = [[DisplayableText alloc] initWithFullText:@"" displayText:@"" isTextTruncated:NO]; self.displayableBodyText = [[DisplayableText alloc] initWithFullText:@"" displayText:@"" isTextTruncated:NO];
} }
if (message.quotedMessage && message.quotedMessage.authorId.length > 0 if (message.quotedMessage) {
&& (message.quotedMessage.body.length > 0 || message.quotedMessage.contentType.length > 0)) { self.quotedReply =
if (message.quotedMessage.body.length > 0) { [[OWSQuotedReplyModel alloc] initWithQuotedMessage:message.quotedMessage transaction:transaction];
// TODO move this to OWSQuotedReplyModel?
if (self.quotedReply.body.length > 0) {
self.displayableQuotedText = self.displayableQuotedText =
[self displayableQuotedTextForText:message.quotedMessage.body interactionId:message.uniqueId]; [self displayableQuotedTextForText:self.quotedReply.body interactionId:message.uniqueId];
} }
self.quotedAttachmentMimetype = message.quotedMessage.contentType;
self.quotedRecipientId = message.quotedMessage.authorId;
} }
} }
// TODO converge naming
- (nullable NSString *)quotedAttachmentMimetype
{
return self.quotedReply.contentType;
}
- (nullable NSString *)quotedRecipientId
{
return self.quotedReply.authorId;
}
- (OWSMessageCellType)messageCellType - (OWSMessageCellType)messageCellType
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();

View File

@ -17,7 +17,7 @@ class QuotedReplyPreview: UIView {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
init(quotedReplyDraft: OWSQuotedReplyDraft) { init(quotedReplyDraft: OWSQuotedReplyModel) {
super.init(frame: .zero) super.init(frame: .zero)
let isQuotingSelf = quotedReplyDraft.authorId == TSAccountManager.localNumber() let isQuotingSelf = quotedReplyDraft.authorId == TSAccountManager.localNumber()

View File

@ -48,6 +48,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface ThreadUtil : NSObject @interface ThreadUtil : NSObject
// TODO should these all take the quotedMessageViewModel?
+ (TSOutgoingMessage *)sendMessageWithText:(NSString *)text + (TSOutgoingMessage *)sendMessageWithText:(NSString *)text
inThread:(TSThread *)thread inThread:(TSThread *)thread
quotedMessage:(nullable TSQuotedMessage *)quotedMessage quotedMessage:(nullable TSQuotedMessage *)quotedMessage

View File

@ -480,11 +480,10 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
quotedAttachmentBuilder.contentType = attachment.contentType; quotedAttachmentBuilder.contentType = attachment.contentType;
quotedAttachmentBuilder.fileName = attachment.sourceFilename; quotedAttachmentBuilder.fileName = attachment.sourceFilename;
if (attachment.thumbnailAttachmentId) {
// FIXME handle thumbnail uploading. The proto changes for this are up in the air. quotedAttachmentBuilder.thumbnail =
// if (attachment.thumbnailAttachmentId) { [self buildProtoForAttachmentId:attachment.thumbnailAttachmentId];
// quotedAttachmentBuilder.thumbnail = [self buildProtoForAttachmentId:attachment.attachmentThumbnailId]; }
// }
[quoteBuilder addAttachments:[quotedAttachmentBuilder build]]; [quoteBuilder addAttachments:[quotedAttachmentBuilder build]];
} }
@ -522,6 +521,19 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
return !self.hasSyncedTranscript; return !self.hasSyncedTranscript;
} }
- (OWSSignalServiceProtosAttachmentPointer *)buildProtoForAttachmentId:(NSString *)attachmentId
{
OWSAssert(attachmentId.length > 0);
TSAttachment *attachment = [TSAttachmentStream fetchObjectWithUniqueID:attachmentId];
if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
DDLogError(@"Unexpected type for attachment builder: %@", attachment);
return nil;
}
TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment;
return [self buildProtoForAttachmentStream:attachmentStream filename:attachmentStream.sourceFilename];
}
- (OWSSignalServiceProtosAttachmentPointer *)buildProtoForAttachmentId:(NSString *)attachmentId - (OWSSignalServiceProtosAttachmentPointer *)buildProtoForAttachmentId:(NSString *)attachmentId
filename:(nullable NSString *)filename filename:(nullable NSString *)filename
{ {

View File

@ -11,7 +11,8 @@ NS_ASSUME_NONNULL_BEGIN
@class TSAttachmentStream; @class TSAttachmentStream;
@class TSQuotedMessage; @class TSQuotedMessage;
@interface OWSQuotedReplyDraft : NSObject // View model which has already fetched any attachments.
@interface OWSQuotedReplyModel : NSObject
@property (nonatomic, readonly) uint64_t timestamp; @property (nonatomic, readonly) uint64_t timestamp;
@property (nonatomic, readonly) NSString *authorId; @property (nonatomic, readonly) NSString *authorId;
@ -35,6 +36,9 @@ NS_ASSUME_NONNULL_BEGIN
body:(NSString *_Nullable)body body:(NSString *_Nullable)body
attachmentStream:(nullable TSAttachmentStream *)attachment; attachmentStream:(nullable TSAttachmentStream *)attachment;
- (instancetype)initWithQuotedMessage:(TSQuotedMessage *)quotedMessage
transaction:(YapDatabaseReadTransaction *)transaction;
- (TSQuotedMessage *)buildQuotedMessage; - (TSQuotedMessage *)buildQuotedMessage;
@end @end
@ -43,8 +47,18 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly, nullable) NSString *contentType; @property (nonatomic, readonly, nullable) NSString *contentType;
@property (nonatomic, readonly, nullable) NSString *sourceFilename; @property (nonatomic, readonly, nullable) NSString *sourceFilename;
// This is only set when sending a new attachment so we have a way
// to reference the original attachment when generating a thumbnail.
// We don't want to do this until the message is saved, when the user sends
// the message so as not to end up with an orphaned file.
//
// TODO: rename to pendingAttachmentId or maybe pendingAttachmentStream?
@property (nonatomic, readonly, nullable) NSString *attachmentId; @property (nonatomic, readonly, nullable) NSString *attachmentId;
// This is set once we've persisted a thumbnail
@property (atomic, nullable) NSString *thumbnailAttachmentId;
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithAttachmentId:(nullable NSString *)attachmentId - (instancetype)initWithAttachmentId:(nullable NSString *)attachmentId
@ -73,11 +87,13 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable NSString *)sourceFilename; - (nullable NSString *)sourceFilename;
@property (atomic, readonly) NSArray<OWSAttachmentInfo *> *quotedAttachments; @property (atomic, readonly) NSArray<OWSAttachmentInfo *> *quotedAttachments;
//- (void)addAttachment:(TSAttachmentStream *)attachment;
- (BOOL)hasAttachments;
- (nullable TSAttachment *)firstAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (nullable UIImage *)thumbnailImageWithTransaction:(YapDatabaseReadTransaction *)transaction; - (NSArray<TSAttachment *> *)fetchAttachmentsWithTransaction:(YapDatabaseReadTransaction *)transaction;
// Before sending, persist a thumbnail attachment derived from the quoted attachment
- (NSArray<TSAttachmentStream *> *)createThumbnailAttachmentsIfNecessaryWithTransaction:
(YapDatabaseReadWriteTransaction *)transaction;
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;

View File

@ -40,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
// View Model which has already fetched any thumbnail attachment. // View Model which has already fetched any thumbnail attachment.
@implementation OWSQuotedReplyDraft @implementation OWSQuotedReplyModel
// This is a MIME type. // This is a MIME type.
// //
@ -78,6 +78,24 @@ NS_ASSUME_NONNULL_BEGIN
return self; return self;
} }
- (instancetype)initWithQuotedMessage:(TSQuotedMessage *)quotedMessage
transaction:(YapDatabaseReadTransaction *)transaction
{
TSAttachment *attachment =
[TSAttachment fetchObjectWithUniqueID:quotedMessage.quotedAttachments.firstObject.attachmentId
transaction:transaction];
TSAttachmentStream *attachmentStream;
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
attachmentStream = (TSAttachmentStream *)attachment;
}
return [self initWithTimestamp:quotedMessage.timestamp
authorId:quotedMessage.authorId
body:quotedMessage.body
attachmentStream:attachmentStream];
}
- (TSQuotedMessage *)buildQuotedMessage - (TSQuotedMessage *)buildQuotedMessage
{ {
NSArray *attachments = self.attachmentStream ? @[ self.attachmentStream ] : @[]; NSArray *attachments = self.attachmentStream ? @[ self.attachmentStream ] : @[];
@ -167,6 +185,17 @@ NS_ASSUME_NONNULL_BEGIN
return firstAttachment.sourceFilename; 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];
//
// }
//}
#pragma mark - Thumbnail #pragma mark - Thumbnail
//- (nullable TSAttachment *)firstAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction //- (nullable TSAttachment *)firstAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction
@ -212,40 +241,49 @@ NS_ASSUME_NONNULL_BEGIN
// //
//} //}
// //
- (void)createThumbnailAttachmentIfNecessaryWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (NSArray<TSAttachmentStream *> *)createThumbnailAttachmentsIfNecessaryWithTransaction:
(YapDatabaseReadWriteTransaction *)transaction
{ {
// for (OWSAttachmentInfo *info in self.quotedAttachments) { NSMutableArray<TSAttachmentStream *> *thumbnailAttachments = [NSMutableArray new];
// // TODO should we just cach an optional TSAttachment on the info?
// OWSAssert(info.attachmentId); for (OWSAttachmentInfo *info in self.quotedAttachments) {
// TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:info.attachmentId transaction:transaction];
// if (![attachment isKindOfClass:[TSAttachmentStream class]]) { OWSAssert(info.attachmentId);
// return; TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:info.attachmentId transaction:transaction];
// } if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
// continue;
// TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachmentStream; }
// NSData *thumbnailData = attachmentStream.thumbnailData;
// // Only some media types have thumbnails TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment;
// if (thumbnailData) { NSData *thumbnailData = attachmentStream.thumbnailData;
// // Copy the thumbnail to a new attachment. // Only some media types have thumbnails
// NSString *thumbnailName = if (thumbnailData) {
// [NSString stringWithFormat:@"quoted-thumbnail-%@", attachmentStream.sourceFilename]; // Copy the thumbnail to a new attachment.
// TSAttachmentStream *thumbnailAttachment = NSString *thumbnailName =
// [[TSAttachmentStream alloc] initWithContentType:OWSMimeTypeJpeg [NSString stringWithFormat:@"quoted-thumbnail-%@", attachmentStream.sourceFilename];
// byteCount:attachmentStream.byteCount TSAttachmentStream *thumbnailAttachment =
// sourceFilename:thumbnailName]; [[TSAttachmentStream alloc] initWithContentType:@"image/jpeg"
// byteCount:attachmentStream.byteCount
// NSError *error; sourceFilename:thumbnailName];
// [thumbnailAttachment writeData:thumbnailData error:&error];
// if (error) { NSError *error;
// DDLogError(@"%@ Couldn't copy attachment data for message sent to self: %@.", self.logTag, error); [thumbnailAttachment writeData:thumbnailData error:&error];
// } else { if (error) {
// [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { DDLogError(@"%@ Couldn't copy attachment data for message sent to self: %@.", self.logTag, error);
// [thumbnailAttachment saveWithTransaction:transaction]; } else {
// quotedMessage.attachments = [message saveWithTransaction:transaction]; [thumbnailAttachment saveWithTransaction:transaction];
// }]; info.thumbnailAttachmentId = thumbnailAttachment.uniqueId;
// } [thumbnailAttachments addObject:thumbnailAttachment];
// } }
// } }
}
if (thumbnailAttachments.count > 0) {
// Save to record any self.quotedAttachments[].thumbnailAttachmentId
[self saveWithTransaction:transaction];
}
return [thumbnailAttachments copy];
} }
@end @end

View File

@ -324,28 +324,32 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[sendingQueue addOperation:uploadAttachmentOperation]; [sendingQueue addOperation:uploadAttachmentOperation];
} }
//
// if (message.quotedMessage) { if (message.quotedMessage) {
//
// // TODO do we want a different thumbnail size for quotes vs the gallery? This seems reasonable, // 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. // and has the advantage of already having been generated.
// __block TSAttachmentStream *attachment; __block NSArray<TSAttachmentStream *> *thumbnailAttachments;
// [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
// [message.quotedMessage createThumbnailAttachmentIfNecessaryWithTransaction:transaction]; thumbnailAttachments =
// attachment = (TSAttachmentStream *)[message.quotedMessage [message.quotedMessage createThumbnailAttachmentsIfNecessaryWithTransaction:transaction];
// thumbnailAttachmentWithTransaction:transaction]; }];
// }];
// // Though we currently only ever expect at most one thumbnail, the proto data model
// if (attachment) { // suggests this could change. The logic is intended to work with multiple, but
// OWSUploadOperation *uploadQuoteThumbnailOperation = // if we ever actually want to send multiple, we should do more testing.
// [[OWSUploadOperation alloc] initWithAttachmentId:thumbnailAttachment.uniqueId OWSAssert(thumbnailAttachments.count <= 1);
// dbConnection:self.dbConnection];
// for (TSAttachmentStream *thumbnailAttachment in thumbnailAttachments) {
// // TODO put attachment uploads on a (lowly) concurrent queue OWSUploadOperation *uploadQuoteThumbnailOperation =
// [sendMessageOperation addDependency:uploadQuoteThumbnailOperation]; [[OWSUploadOperation alloc] initWithAttachmentId:thumbnailAttachment.uniqueId
// [sendingQueue addOperation:uploadQuoteThumbnailOperation]; dbConnection:self.dbConnection];
// }
// } // TODO put attachment uploads on a (lowly) concurrent queue
[sendMessageOperation addDependency:uploadQuoteThumbnailOperation];
[sendingQueue addOperation:uploadQuoteThumbnailOperation];
}
}
[sendingQueue addOperation:sendMessageOperation]; [sendingQueue addOperation:sendMessageOperation];
}); });

View File

@ -4,7 +4,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSQuotedReplyDraft; @class OWSQuotedReplyModel;
@class TSMessage; @class TSMessage;
@class TSThread; @class TSThread;
@class YapDatabaseReadTransaction; @class YapDatabaseReadTransaction;
@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)updateApplicationBadgeCount; - (void)updateApplicationBadgeCount;
+ (nullable OWSQuotedReplyDraft *)quotedReplyDraftForMessage:(TSMessage *)message + (nullable OWSQuotedReplyModel *)quotedReplyDraftForMessage:(TSMessage *)message
transaction:(YapDatabaseReadTransaction *)transaction; transaction:(YapDatabaseReadTransaction *)transaction;
@end @end

View File

@ -104,7 +104,7 @@ NS_ASSUME_NONNULL_BEGIN
return numberOfItems; return numberOfItems;
} }
+ (nullable OWSQuotedReplyDraft *)quotedReplyDraftForMessage:(TSMessage *)message + (nullable OWSQuotedReplyModel *)quotedReplyDraftForMessage:(TSMessage *)message
transaction:(YapDatabaseReadTransaction *)transaction; transaction:(YapDatabaseReadTransaction *)transaction;
{ {
OWSAssert(message); OWSAssert(message);
@ -127,7 +127,7 @@ NS_ASSUME_NONNULL_BEGIN
return [self quotedReplyDraftForMessage:message authorId:authorId thread:thread transaction:transaction]; return [self quotedReplyDraftForMessage:message authorId:authorId thread:thread transaction:transaction];
} }
+ (nullable OWSQuotedReplyDraft *)quotedReplyDraftForMessage:(TSMessage *)message + (nullable OWSQuotedReplyModel *)quotedReplyDraftForMessage:(TSMessage *)message
authorId:(NSString *)authorId authorId:(NSString *)authorId
thread:(TSThread *)thread thread:(TSThread *)thread
transaction:(YapDatabaseReadTransaction *)transaction transaction:(YapDatabaseReadTransaction *)transaction
@ -198,7 +198,7 @@ NS_ASSUME_NONNULL_BEGIN
return nil; return nil;
} }
return [[OWSQuotedReplyDraft alloc] initWithTimestamp:timestamp return [[OWSQuotedReplyModel alloc] initWithTimestamp:timestamp
authorId:authorId authorId:authorId
body:quotedText body:quotedText
attachmentStream:quotedAttachment]; attachmentStream:quotedAttachment];