Send quoted messages

MVP

- [x] populate from menu
- [x] send quoted message

TODO

- [] thumbnail
- [] paperclip icon showing for text message
- [] cancel button asset
- [] fonts
- [] colors
- [] adjust content inset/offset when showing quote edit

NICE TO HAVE

- [] animate presentation
- [] animate dismiss
- [] non-paperclip icon for generic attachments

// FREEBIE
pull/1/head
Michael Kirk 7 years ago
parent d99054d895
commit bf401bad90

@ -58,8 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)cancelVoiceMemoIfNecessary;
- (void)setQuotedMessage:(TSQuotedMessage *)quotedMessage;
- (void)clearQuotedMessage;
@property (nonatomic, nullable) TSQuotedMessage *quotedMessage;
@end

@ -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

@ -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];

@ -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();

@ -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

@ -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?

@ -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."];
}

@ -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);

@ -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;

@ -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

Loading…
Cancel
Save