diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h index bf79c50a6..5bc60452a 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.h @@ -58,8 +58,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)cancelVoiceMemoIfNecessary; -- (void)setQuotedMessage:(TSQuotedMessage *)quotedMessage; -- (void)clearQuotedMessage; +@property (nonatomic, nullable) TSQuotedMessage *quotedMessage; @end diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m index 791c1938b..dcc93f06c 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m @@ -250,14 +250,25 @@ static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5; [self ensureContentConstraints]; } -- (void)setQuotedMessage:(TSQuotedMessage *)quotedMessage +- (void)setQuotedMessage:(nullable TSQuotedMessage *)quotedMessage { + if (quotedMessage == _quotedMessage) { + return; + } + // TODO update existing preview with message in case we switch which message we're quoting. if (self.quotedMessagePreview) { - [self clearQuotedMessage]; + [self clearQuotedMessagePreview]; } OWSAssert(self.quotedMessagePreview == nil); + _quotedMessage = quotedMessage; + + if (!quotedMessage) { + [self clearQuotedMessagePreview]; + return; + } + self.quotedMessagePreview = [[QuotedReplyPreview alloc] initWithQuotedMessage:quotedMessage]; self.quotedMessagePreview.delegate = self; @@ -265,7 +276,7 @@ static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5; [self.contentStackView insertArrangedSubview:self.quotedMessagePreview atIndex:0]; } -- (void)clearQuotedMessage +- (void)clearQuotedMessagePreview { // TODO animate if (self.quotedMessagePreview) { @@ -749,7 +760,7 @@ static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5; - (void)quotedReplyPreviewDidPressCancel:(QuotedReplyPreview *)preview { - [self clearQuotedMessage]; + self.quotedMessage = nil; } @end diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 5cb47cac5..51cddef2f 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -1052,21 +1052,6 @@ typedef enum : NSUInteger { [self becomeFirstResponder]; } } - - // FIXME DO NOT COMMIT. Just for developing. - TSInteraction *lastInteraction = self.viewItems.lastObject.interaction; - if ([lastInteraction isKindOfClass:[TSMessage class]]) { - TSMessage *lastMessage = (TSMessage *)lastInteraction; - [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - DDLogDebug(@"%@ setting quoted message: %llu", self.logTag, (unsigned long long)lastMessage.timestamp); - TSQuotedMessage *_Nullable quotedMessage = - [OWSMessageUtils quotedMessageForMessage:lastMessage transaction:transaction]; - [self.inputToolbar setQuotedMessage:quotedMessage]; - }]; - [self reloadInputViews]; - } else { - DDLogDebug(@"%@ not setting quoted message for message: %@", self.logTag, lastInteraction.class); - } } // `viewWillDisappear` is called whenever the view *starts* to disappear, @@ -2449,6 +2434,7 @@ typedef enum : NSUInteger { [self updateLastVisibleTimestamp:message.timestampForSorting]; self.lastMessageSentDate = [NSDate new]; [self clearUnreadMessagesIndicator]; + self.inputToolbar.quotedMessage = nil; if ([Environment.preferences soundInForeground]) { [JSQSystemSoundPlayer jsq_playMessageSentSound]; @@ -2785,6 +2771,7 @@ typedef enum : NSUInteger { BOOL didAddToProfileWhitelist = [ThreadUtil addThreadToProfileWhitelistIfEmptyContactThread:self.thread]; TSOutgoingMessage *message = [ThreadUtil sendMessageWithAttachment:attachment inThread:self.thread + quotedMessage:self.inputToolbar.quotedMessage messageSender:self.messageSender completion:nil]; @@ -4055,10 +4042,14 @@ typedef enum : NSUInteger { [SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI]; message = [ThreadUtil sendMessageWithAttachment:attachment inThread:self.thread + quotedMessage:self.inputToolbar.quotedMessage messageSender:self.messageSender completion:nil]; } else { - message = [ThreadUtil sendMessageWithText:text inThread:self.thread messageSender:self.messageSender]; + message = [ThreadUtil sendMessageWithText:text + inThread:self.thread + quotedMessage:self.inputToolbar.quotedMessage + messageSender:self.messageSender]; } [self messageWasSent:message]; diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 6b3c8aa68..012ffe73e 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -280,7 +280,8 @@ NS_ASSUME_NONNULL_BEGIN NSString *randomText = [self randomText]; NSString *text = [[[@(counter) description] stringByAppendingString:@" "] stringByAppendingString:randomText]; OWSMessageSender *messageSender = [Environment current].messageSender; - TSOutgoingMessage *message = [ThreadUtil sendMessageWithText:text inThread:thread messageSender:messageSender]; + TSOutgoingMessage *message = + [ThreadUtil sendMessageWithText:text inThread:thread quotedMessage:nil messageSender:messageSender]; DDLogError(@"%@ sendTextMessageInThread timestamp: %llu.", self.logTag, message.timestamp); } @@ -342,7 +343,11 @@ NS_ASSUME_NONNULL_BEGIN [DDLog flushLog]; } OWSAssert(![attachment hasError]); - [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender completion:nil]; + [ThreadUtil sendMessageWithAttachment:attachment + inThread:thread + quotedMessage:nil + messageSender:messageSender + completion:nil]; success(); } @@ -1709,7 +1714,11 @@ NS_ASSUME_NONNULL_BEGIN SignalAttachment *attachment = [self signalAttachmentForFilePath:filePath]; OWSMessageSender *messageSender = [Environment current].messageSender; - [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender completion:nil]; + [ThreadUtil sendMessageWithAttachment:attachment + inThread:thread + quotedMessage:nil + messageSender:messageSender + completion:nil]; success(); } @@ -2696,7 +2705,11 @@ isQuotedMessageAttachmentDownloaded:(BOOL)isQuotedMessageAttachmentDownloaded DataSource *_Nullable dataSource = [DataSourceValue dataSourceWithOversizeText:message]; SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI]; - [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender completion:nil]; + [ThreadUtil sendMessageWithAttachment:attachment + inThread:thread + quotedMessage:nil + messageSender:messageSender + completion:nil]; } + (NSData *)createRandomNSDataOfSize:(size_t)size @@ -2731,6 +2744,7 @@ isQuotedMessageAttachmentDownloaded:(BOOL)isQuotedMessageAttachmentDownloaded } [ThreadUtil sendMessageWithAttachment:attachment inThread:thread + quotedMessage:nil messageSender:messageSender ignoreErrors:YES completion:nil]; @@ -3148,7 +3162,10 @@ isQuotedMessageAttachmentDownloaded:(BOOL)isQuotedMessageAttachmentDownloaded OWSMessageSender *messageSender = [Environment current].messageSender; void (^completion)(void) = ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)1.f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [ThreadUtil sendMessageWithText:[@(counter) description] inThread:thread messageSender:messageSender]; + [ThreadUtil sendMessageWithText:[@(counter) description] + inThread:thread + quotedMessage:nil + messageSender:messageSender]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)1.f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [self createNewGroups:counter - 1 recipientId:recipientId]; }); @@ -3678,7 +3695,11 @@ isQuotedMessageAttachmentDownloaded:(BOOL)isQuotedMessageAttachmentDownloaded [DDLog flushLog]; } OWSAssert(![attachment hasError]); - [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender completion:nil]; + [ThreadUtil sendMessageWithAttachment:attachment + inThread:thread + quotedMessage:nil + messageSender:messageSender + completion:nil]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ sendUnsafeFile(); diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m index b8f4c9c35..9fa45e324 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m @@ -219,7 +219,11 @@ NS_ASSUME_NONNULL_BEGIN OWSFail(@"%@ attachment[%@]: %@", self.logTag, [attachment sourceFilename], [attachment errorName]); return; } - [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender completion:nil]; + [ThreadUtil sendMessageWithAttachment:attachment + inThread:thread + quotedMessage:nil + messageSender:messageSender + completion:nil]; } + (void)sendUnencryptedDatabase:(TSThread *)thread @@ -242,7 +246,11 @@ NS_ASSUME_NONNULL_BEGIN OWSFail(@"%@ attachment[%@]: %@", self.logTag, [attachment sourceFilename], [attachment errorName]); return; } - [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender completion:nil]; + [ThreadUtil sendMessageWithAttachment:attachment + inThread:thread + quotedMessage:nil + messageSender:messageSender + completion:nil]; } @end diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index b6762add4..812df552c 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -193,6 +193,7 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe [ThreadUtil sendMessageWithText:replyText inThread:thread + quotedMessage:nil // TODO we could do an actual quoted reply here, but most apps don't. messageSender:self.messageSender success:^{ // TODO do we really want to mark them all as read? diff --git a/Signal/src/util/Pastelog.m b/Signal/src/util/Pastelog.m index c94eb3275..f4f938f8e 100644 --- a/Signal/src/util/Pastelog.m +++ b/Signal/src/util/Pastelog.m @@ -516,7 +516,10 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { thread = [TSContactThread getOrCreateThreadWithContactId:recipientId transaction:transaction]; }]; - [ThreadUtil sendMessageWithText:url.absoluteString inThread:thread messageSender:messageSender]; + [ThreadUtil sendMessageWithText:url.absoluteString + inThread:thread + quotedMessage:nil + messageSender:messageSender]; }); // Also copy to pasteboard. @@ -536,7 +539,10 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error DispatchMainThreadSafe(^{ if (thread) { OWSMessageSender *messageSender = Environment.current.messageSender; - [ThreadUtil sendMessageWithText:url.absoluteString inThread:thread messageSender:messageSender]; + [ThreadUtil sendMessageWithText:url.absoluteString + inThread:thread + quotedMessage:nil + messageSender:messageSender]; } else { [Pastelog showFailureAlertWithMessage:@"Could not find last thread."]; } diff --git a/SignalMessaging/attachments/SharingThreadPickerViewController.m b/SignalMessaging/attachments/SharingThreadPickerViewController.m index 4afb06581..6cfa81d0e 100644 --- a/SignalMessaging/attachments/SharingThreadPickerViewController.m +++ b/SignalMessaging/attachments/SharingThreadPickerViewController.m @@ -201,6 +201,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion); __block TSOutgoingMessage *outgoingMessage = nil; outgoingMessage = [ThreadUtil sendMessageWithAttachment:attachment inThread:self.thread + quotedMessage:nil messageSender:self.messageSender completion:^(NSError *_Nullable error) { sendCompletion(error, outgoingMessage); @@ -232,6 +233,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion); __block TSOutgoingMessage *outgoingMessage = nil; outgoingMessage = [ThreadUtil sendMessageWithText:messageText inThread:self.thread + quotedMessage:nil messageSender:self.messageSender success:^{ sendCompletion(nil, outgoingMessage); diff --git a/SignalMessaging/utils/ThreadUtil.h b/SignalMessaging/utils/ThreadUtil.h index f68c08f9c..7225e3a84 100644 --- a/SignalMessaging/utils/ThreadUtil.h +++ b/SignalMessaging/utils/ThreadUtil.h @@ -44,27 +44,32 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - @class TSOutgoingMessage; +@class TSQuotedMessage; @interface ThreadUtil : NSObject + (TSOutgoingMessage *)sendMessageWithText:(NSString *)text inThread:(TSThread *)thread + quotedMessage:(nullable TSQuotedMessage *)quotedMessage messageSender:(OWSMessageSender *)messageSender success:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler; + (TSOutgoingMessage *)sendMessageWithText:(NSString *)text inThread:(TSThread *)thread + quotedMessage:(nullable TSQuotedMessage *)quotedMessage messageSender:(OWSMessageSender *)messageSender; + (TSOutgoingMessage *)sendMessageWithAttachment:(SignalAttachment *)attachment inThread:(TSThread *)thread + quotedMessage:quotedMessage messageSender:(OWSMessageSender *)messageSender completion:(void (^_Nullable)(NSError *_Nullable error))completion; // We only should set ignoreErrors in debug or test code. + (TSOutgoingMessage *)sendMessageWithAttachment:(SignalAttachment *)attachment inThread:(TSThread *)thread + quotedMessage:(nullable TSQuotedMessage *)quotedMessage messageSender:(OWSMessageSender *)messageSender ignoreErrors:(BOOL)ignoreErrors completion:(void (^_Nullable)(NSError *_Nullable error))completion; diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index 6c863fa3c..a445a3584 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -55,10 +55,12 @@ NS_ASSUME_NONNULL_BEGIN + (TSOutgoingMessage *)sendMessageWithText:(NSString *)text inThread:(TSThread *)thread + quotedMessage:(nullable TSQuotedMessage *)quotedMessage messageSender:(OWSMessageSender *)messageSender { return [self sendMessageWithText:text inThread:thread + quotedMessage:quotedMessage messageSender:messageSender success:^{ DDLogInfo(@"%@ Successfully sent message.", self.logTag); @@ -71,6 +73,7 @@ NS_ASSUME_NONNULL_BEGIN + (TSOutgoingMessage *)sendMessageWithText:(NSString *)text inThread:(TSThread *)thread + quotedMessage:(nullable TSQuotedMessage *)quotedMessage messageSender:(OWSMessageSender *)messageSender success:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler @@ -87,11 +90,10 @@ NS_ASSUME_NONNULL_BEGIN inThread:thread messageBody:text attachmentIds:[NSMutableArray new] - expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0) - expireStartedAt:0 + expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)expireStartedAt:0 isVoiceMessage:NO groupMetaMessage:TSGroupMessageNone - quotedMessage:nil]; + quotedMessage:quotedMessage]; [messageSender enqueueMessage:message success:successHandler failure:failureHandler]; @@ -100,11 +102,13 @@ NS_ASSUME_NONNULL_BEGIN + (TSOutgoingMessage *)sendMessageWithAttachment:(SignalAttachment *)attachment inThread:(TSThread *)thread + quotedMessage:(nullable TSQuotedMessage *)quotedMessage messageSender:(OWSMessageSender *)messageSender completion:(void (^_Nullable)(NSError *_Nullable error))completion { return [self sendMessageWithAttachment:attachment inThread:thread + quotedMessage:quotedMessage messageSender:messageSender ignoreErrors:NO completion:completion]; @@ -112,6 +116,7 @@ NS_ASSUME_NONNULL_BEGIN + (TSOutgoingMessage *)sendMessageWithAttachment:(SignalAttachment *)attachment inThread:(TSThread *)thread + quotedMessage:(nullable TSQuotedMessage *)quotedMessage messageSender:(OWSMessageSender *)messageSender ignoreErrors:(BOOL)ignoreErrors completion:(void (^_Nullable)(NSError *_Nullable error))completion