mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge branch 'mkirk/long-text-nondurable'
This commit is contained in:
commit
e6ad6c85bf
5 changed files with 195 additions and 167 deletions
|
@ -660,14 +660,20 @@ class NotificationActionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ThreadUtil {
|
extension ThreadUtil {
|
||||||
|
static var dbReadConnection: YapDatabaseConnection {
|
||||||
|
return OWSPrimaryStorage.shared().dbReadConnection
|
||||||
|
}
|
||||||
|
|
||||||
class func sendMessageNonDurably(text: String, thread: TSThread, quotedReplyModel: OWSQuotedReplyModel?, messageSender: MessageSender) -> Promise<Void> {
|
class func sendMessageNonDurably(text: String, thread: TSThread, quotedReplyModel: OWSQuotedReplyModel?, messageSender: MessageSender) -> Promise<Void> {
|
||||||
return Promise { resolver in
|
return Promise { resolver in
|
||||||
self.sendMessageNonDurably(withText: text,
|
self.dbReadConnection.read { transaction in
|
||||||
in: thread,
|
_ = self.sendMessageNonDurably(withText: text,
|
||||||
quotedReplyModel: quotedReplyModel,
|
in: thread,
|
||||||
messageSender: messageSender,
|
quotedReplyModel: quotedReplyModel,
|
||||||
success: resolver.fulfill,
|
transaction: transaction,
|
||||||
failure: resolver.reject)
|
messageSender: messageSender,
|
||||||
|
completion: resolver.resolve)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
|
||||||
@property (nonatomic) TSThread *thread;
|
@property (nonatomic) TSThread *thread;
|
||||||
@property (nonatomic, readonly, weak) id<ShareViewDelegate> shareViewDelegate;
|
@property (nonatomic, readonly, weak) id<ShareViewDelegate> shareViewDelegate;
|
||||||
@property (nonatomic, readonly) UIProgressView *progressView;
|
@property (nonatomic, readonly) UIProgressView *progressView;
|
||||||
@property (nonatomic, readonly) YapDatabaseConnection *editingDBConnection;
|
|
||||||
@property (atomic, nullable) TSOutgoingMessage *outgoingMessage;
|
@property (atomic, nullable) TSOutgoingMessage *outgoingMessage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -46,13 +45,26 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
_editingDBConnection = [OWSPrimaryStorage.sharedManager newDatabaseConnection];
|
|
||||||
_shareViewDelegate = shareViewDelegate;
|
_shareViewDelegate = shareViewDelegate;
|
||||||
self.selectThreadViewDelegate = self;
|
self.selectThreadViewDelegate = self;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Dependencies
|
||||||
|
|
||||||
|
- (YapDatabaseConnection *)dbReadWriteConnection
|
||||||
|
{
|
||||||
|
return OWSPrimaryStorage.sharedManager.dbReadWriteConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (YapDatabaseConnection *)dbReadConnection
|
||||||
|
{
|
||||||
|
return OWSPrimaryStorage.sharedManager.dbReadConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - UIViewController overrides
|
||||||
|
|
||||||
- (void)loadView
|
- (void)loadView
|
||||||
{
|
{
|
||||||
[super loadView];
|
[super loadView];
|
||||||
|
@ -274,14 +286,18 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
|
||||||
// the sending operation. Alternatively, we could use a durable send, but do more to make sure the
|
// the sending operation. Alternatively, we could use a durable send, but do more to make sure the
|
||||||
// SAE runs as long as it needs.
|
// SAE runs as long as it needs.
|
||||||
// TODO ALBUMS - send album via SAE
|
// TODO ALBUMS - send album via SAE
|
||||||
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithAttachments:attachments
|
|
||||||
inThread:self.thread
|
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
|
||||||
messageBody:messageText
|
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithText:messageText
|
||||||
quotedReplyModel:nil
|
mediaAttachments:attachments
|
||||||
messageSender:self.messageSender
|
inThread:self.thread
|
||||||
completion:^(NSError *_Nullable error) {
|
quotedReplyModel:nil
|
||||||
sendCompletion(error, outgoingMessage);
|
transaction:transaction
|
||||||
}];
|
messageSender:self.messageSender
|
||||||
|
completion:^(NSError *_Nullable error) {
|
||||||
|
sendCompletion(error, outgoingMessage);
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
|
||||||
// This is necessary to show progress.
|
// This is necessary to show progress.
|
||||||
self.outgoingMessage = outgoingMessage;
|
self.outgoingMessage = outgoingMessage;
|
||||||
|
@ -310,19 +326,22 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
|
||||||
// DURABLE CLEANUP - SAE uses non-durable sending to make sure the app is running long enough to complete
|
// DURABLE CLEANUP - SAE uses non-durable sending to make sure the app is running long enough to complete
|
||||||
// the sending operation. Alternatively, we could use a durable send, but do more to make sure the
|
// the sending operation. Alternatively, we could use a durable send, but do more to make sure the
|
||||||
// SAE runs as long as it needs.
|
// SAE runs as long as it needs.
|
||||||
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithText:messageText
|
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
|
||||||
inThread:self.thread
|
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithText:messageText
|
||||||
quotedReplyModel:nil
|
inThread:self.thread
|
||||||
messageSender:self.messageSender
|
quotedReplyModel:nil
|
||||||
success:^{
|
transaction:transaction
|
||||||
sendCompletion(nil, outgoingMessage);
|
messageSender:self.messageSender
|
||||||
}
|
completion:^(NSError *_Nullable error) {
|
||||||
failure:^(NSError *_Nonnull error) {
|
if (error) {
|
||||||
sendCompletion(error, outgoingMessage);
|
sendCompletion(error, outgoingMessage);
|
||||||
}];
|
} else {
|
||||||
|
sendCompletion(nil, outgoingMessage);
|
||||||
// This is necessary to show progress.
|
}
|
||||||
self.outgoingMessage = outgoingMessage;
|
}];
|
||||||
|
// This is necessary to show progress.
|
||||||
|
self.outgoingMessage = outgoingMessage;
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
fromViewController:approvalViewController];
|
fromViewController:approvalViewController];
|
||||||
}
|
}
|
||||||
|
@ -344,11 +363,12 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
|
||||||
OWSAssertIsOnMainThread();
|
OWSAssertIsOnMainThread();
|
||||||
// TODO - in line with QuotedReply and other message attachments, saving should happen as part of sending
|
// TODO - in line with QuotedReply and other message attachments, saving should happen as part of sending
|
||||||
// preparation rather than duplicated here and in the SAE
|
// preparation rather than duplicated here and in the SAE
|
||||||
[self.editingDBConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
[self.dbReadWriteConnection
|
||||||
if (contactShare.avatarImage) {
|
asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
||||||
[contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction];
|
if (contactShare.avatarImage) {
|
||||||
|
[contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
completionBlock:^{
|
completionBlock:^{
|
||||||
__block TSOutgoingMessage *outgoingMessage = nil;
|
__block TSOutgoingMessage *outgoingMessage = nil;
|
||||||
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithContactShare:contactShare.dbRecord
|
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithContactShare:contactShare.dbRecord
|
||||||
|
@ -521,8 +541,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
|
||||||
|
|
||||||
OWSLogDebug(@"Confirming identity for recipient: %@", recipientId);
|
OWSLogDebug(@"Confirming identity for recipient: %@", recipientId);
|
||||||
|
|
||||||
[OWSPrimaryStorage.sharedManager.newDatabaseConnection asyncReadWriteWithBlock:^(
|
[self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||||
YapDatabaseReadWriteTransaction *transaction) {
|
|
||||||
OWSVerificationState verificationState =
|
OWSVerificationState verificationState =
|
||||||
[[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId transaction:transaction];
|
[[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId transaction:transaction];
|
||||||
switch (verificationState) {
|
switch (verificationState) {
|
||||||
|
|
|
@ -63,26 +63,27 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
#pragma mark - Non-Durable Sending
|
#pragma mark - Non-Durable Sending
|
||||||
|
|
||||||
// Used by SAE and "reply from lockscreen", otherwise we should use the durable `enqueue` counterpart
|
// Used by SAE and "reply from lockscreen", otherwise we should use the durable `enqueue` counterpart
|
||||||
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)text
|
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
|
||||||
inThread:(TSThread *)thread
|
inThread:(TSThread *)thread
|
||||||
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
||||||
|
transaction:(YapDatabaseReadTransaction *)transaction
|
||||||
messageSender:(OWSMessageSender *)messageSender
|
messageSender:(OWSMessageSender *)messageSender
|
||||||
success:(void (^)(void))successHandler
|
completion:(void (^)(NSError *_Nullable error))completion;
|
||||||
failure:(void (^)(NSError *error))failureHandler;
|
|
||||||
|
|
||||||
// Used by SAE, otherwise we should use the durable `enqueue` counterpart
|
// Used by SAE, otherwise we should use the durable `enqueue` counterpart
|
||||||
+ (TSOutgoingMessage *)sendMessageNonDurablyWithAttachments:(NSArray<SignalAttachment *> *)attachments
|
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
|
||||||
inThread:(TSThread *)thread
|
mediaAttachments:(NSArray<SignalAttachment *> *)attachments
|
||||||
messageBody:(nullable NSString *)messageBody
|
inThread:(TSThread *)thread
|
||||||
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
||||||
messageSender:(OWSMessageSender *)messageSender
|
transaction:(YapDatabaseReadTransaction *)transaction
|
||||||
completion:(void (^_Nullable)(NSError *_Nullable error))completion;
|
messageSender:(OWSMessageSender *)messageSender
|
||||||
|
completion:(void (^)(NSError *_Nullable error))completion;
|
||||||
|
|
||||||
// Used by SAE, otherwise we should use the durable `enqueue` counterpart
|
// Used by SAE, otherwise we should use the durable `enqueue` counterpart
|
||||||
+ (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare
|
+ (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare
|
||||||
inThread:(TSThread *)thread
|
inThread:(TSThread *)thread
|
||||||
messageSender:(OWSMessageSender *)messageSender
|
messageSender:(OWSMessageSender *)messageSender
|
||||||
completion:(void (^_Nullable)(NSError *_Nullable error))completion;
|
completion:(void (^)(NSError *_Nullable error))completion;
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - dynamic interactions
|
#pragma mark - dynamic interactions
|
||||||
|
|
|
@ -65,6 +65,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
|
typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMessage,
|
||||||
|
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos,
|
||||||
|
YapDatabaseReadWriteTransaction *writeTransaction);
|
||||||
|
|
||||||
@implementation ThreadUtil
|
@implementation ThreadUtil
|
||||||
|
|
||||||
#pragma mark - Dependencies
|
#pragma mark - Dependencies
|
||||||
|
@ -95,26 +99,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
transaction:transaction];
|
transaction:transaction];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (nullable OWSLinkPreview *)linkPreviewForLinkPreviewDraft:(nullable OWSLinkPreviewDraft *)linkPreviewDraft
|
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
||||||
{
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
if (!linkPreviewDraft) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
NSError *linkPreviewError;
|
|
||||||
OWSLinkPreview *_Nullable linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft
|
|
||||||
transaction:transaction
|
|
||||||
error:&linkPreviewError];
|
|
||||||
if (linkPreviewError && ![OWSLinkPreview isNoPreviewError:linkPreviewError]) {
|
|
||||||
OWSLogError(@"linkPreviewError: %@", linkPreviewError);
|
|
||||||
}
|
|
||||||
return linkPreview;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (TSOutgoingMessage *)enqueueMessageWithText:(nullable NSString *)fullMessageText
|
+ (TSOutgoingMessage *)enqueueMessageWithText:(nullable NSString *)fullMessageText
|
||||||
mediaAttachments:(NSArray<SignalAttachment *> *)attachmentsParam
|
mediaAttachments:(NSArray<SignalAttachment *> *)mediaAttachments
|
||||||
inThread:(TSThread *)thread
|
inThread:(TSThread *)thread
|
||||||
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
||||||
linkPreviewDraft:(nullable nullable OWSLinkPreviewDraft *)linkPreviewDraft
|
linkPreviewDraft:(nullable nullable OWSLinkPreviewDraft *)linkPreviewDraft
|
||||||
|
@ -123,8 +109,36 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
OWSAssertIsOnMainThread();
|
OWSAssertIsOnMainThread();
|
||||||
OWSAssertDebug(thread);
|
OWSAssertDebug(thread);
|
||||||
|
|
||||||
|
return [self
|
||||||
|
buildOutgoingMessageWithText:fullMessageText
|
||||||
|
mediaAttachments:mediaAttachments
|
||||||
|
thread:thread
|
||||||
|
quotedReplyModel:quotedReplyModel
|
||||||
|
linkPreviewDraft:linkPreviewDraft
|
||||||
|
transaction:transaction
|
||||||
|
completion:^(TSOutgoingMessage *savedMessage,
|
||||||
|
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos,
|
||||||
|
YapDatabaseReadWriteTransaction *writeTransaction) {
|
||||||
|
if (attachmentInfos.count == 0) {
|
||||||
|
[self.messageSenderJobQueue addMessage:savedMessage transaction:writeTransaction];
|
||||||
|
} else {
|
||||||
|
[self.messageSenderJobQueue addMediaMessage:savedMessage
|
||||||
|
attachmentInfos:attachmentInfos
|
||||||
|
isTemporaryAttachment:NO];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (TSOutgoingMessage *)buildOutgoingMessageWithText:(nullable NSString *)fullMessageText
|
||||||
|
mediaAttachments:(NSArray<SignalAttachment *> *)mediaAttachments
|
||||||
|
thread:(TSThread *)thread
|
||||||
|
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
||||||
|
linkPreviewDraft:(nullable OWSLinkPreviewDraft *)linkPreviewDraft
|
||||||
|
transaction:(YapDatabaseReadTransaction *)transaction
|
||||||
|
completion:(BuildOutgoingMessageCompletionBlock)completionBlock;
|
||||||
|
{
|
||||||
NSString *_Nullable truncatedText;
|
NSString *_Nullable truncatedText;
|
||||||
NSArray<SignalAttachment *> *attachments = attachmentsParam;
|
NSArray<SignalAttachment *> *attachments = mediaAttachments;
|
||||||
if ([fullMessageText lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) {
|
if ([fullMessageText lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) {
|
||||||
truncatedText = fullMessageText;
|
truncatedText = fullMessageText;
|
||||||
} else {
|
} else {
|
||||||
|
@ -141,7 +155,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
if (dataSource) {
|
if (dataSource) {
|
||||||
SignalAttachment *oversizeTextAttachment =
|
SignalAttachment *oversizeTextAttachment =
|
||||||
[SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI];
|
[SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI];
|
||||||
attachments = [attachmentsParam arrayByAddingObject:oversizeTextAttachment];
|
attachments = [mediaAttachments arrayByAddingObject:oversizeTextAttachment];
|
||||||
} else {
|
} else {
|
||||||
OWSFailDebug(@"dataSource was unexpectedly nil");
|
OWSFailDebug(@"dataSource was unexpectedly nil");
|
||||||
}
|
}
|
||||||
|
@ -188,21 +202,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[message updateWithLinkPreview:linkPreview transaction:writeTransaction];
|
[message updateWithLinkPreview:linkPreview transaction:writeTransaction];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachments.count == 0) {
|
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos = [NSMutableArray new];
|
||||||
[self.messageSenderJobQueue addMessage:message transaction:writeTransaction];
|
for (SignalAttachment *attachment in attachments) {
|
||||||
} else {
|
OWSOutgoingAttachmentInfo *attachmentInfo =
|
||||||
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos =
|
[attachment buildOutgoingAttachmentInfoWithMessage:message];
|
||||||
[NSMutableArray new];
|
[attachmentInfos addObject:attachmentInfo];
|
||||||
for (SignalAttachment *attachment in attachments) {
|
|
||||||
OWSOutgoingAttachmentInfo *attachmentInfo =
|
|
||||||
[attachment buildOutgoingAttachmentInfoWithMessage:message];
|
|
||||||
[attachmentInfos addObject:attachmentInfo];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self.messageSenderJobQueue addMediaMessage:message
|
|
||||||
attachmentInfos:attachmentInfos
|
|
||||||
isTemporaryAttachment:NO];
|
|
||||||
}
|
}
|
||||||
|
completionBlock(message, attachmentInfos, writeTransaction);
|
||||||
}
|
}
|
||||||
completionBlock:benchmarkCompletion];
|
completionBlock:benchmarkCompletion];
|
||||||
}];
|
}];
|
||||||
|
@ -257,104 +263,86 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
// MARK: Non-Durable Sending
|
// MARK: Non-Durable Sending
|
||||||
|
|
||||||
// We might want to generate a link preview here.
|
// We might want to generate a link preview here.
|
||||||
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)text
|
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
|
||||||
inThread:(TSThread *)thread
|
inThread:(TSThread *)thread
|
||||||
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
||||||
|
transaction:(YapDatabaseReadTransaction *)transaction
|
||||||
messageSender:(OWSMessageSender *)messageSender
|
messageSender:(OWSMessageSender *)messageSender
|
||||||
success:(void (^)(void))successHandler
|
completion:(void (^)(NSError *_Nullable error))completion
|
||||||
failure:(void (^)(NSError *error))failureHandler
|
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
OWSAssertDebug(completion);
|
||||||
OWSAssertDebug(text.length > 0);
|
|
||||||
OWSAssertDebug(thread);
|
|
||||||
OWSAssertDebug(messageSender);
|
|
||||||
|
|
||||||
OWSDisappearingMessagesConfiguration *configuration =
|
return [self sendMessageNonDurablyWithText:fullMessageText
|
||||||
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
|
mediaAttachments:@[]
|
||||||
uint32_t expiresInSeconds = (configuration.isEnabled ? configuration.durationSeconds : 0);
|
inThread:thread
|
||||||
TSOutgoingMessage *message =
|
quotedReplyModel:quotedReplyModel
|
||||||
[TSOutgoingMessage outgoingMessageInThread:thread
|
transaction:transaction
|
||||||
messageBody:text
|
messageSender:messageSender
|
||||||
attachmentId:nil
|
completion:completion];
|
||||||
expiresInSeconds:expiresInSeconds
|
|
||||||
quotedMessage:[quotedReplyModel buildQuotedMessageForSending]
|
|
||||||
linkPreview:nil];
|
|
||||||
|
|
||||||
[messageSender sendMessage:message success:successHandler failure:failureHandler];
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (TSOutgoingMessage *)sendMessageNonDurablyWithAttachments:(NSArray<SignalAttachment *> *)attachments
|
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
|
||||||
inThread:(TSThread *)thread
|
mediaAttachments:(NSArray<SignalAttachment *> *)mediaAttachments
|
||||||
messageBody:(nullable NSString *)messageBody
|
inThread:(TSThread *)thread
|
||||||
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
||||||
messageSender:(OWSMessageSender *)messageSender
|
transaction:(YapDatabaseReadTransaction *)transaction
|
||||||
completion:(void (^_Nullable)(NSError *_Nullable error))completion
|
messageSender:(OWSMessageSender *)messageSender
|
||||||
|
completion:(void (^)(NSError *_Nullable error))completion
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
OWSAssertIsOnMainThread();
|
||||||
OWSAssertDebug(attachments.count > 0);
|
|
||||||
OWSAssertDebug(thread);
|
OWSAssertDebug(thread);
|
||||||
OWSAssertDebug(messageSender);
|
OWSAssertDebug(completion);
|
||||||
|
|
||||||
OWSDisappearingMessagesConfiguration *configuration =
|
return
|
||||||
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
|
[self buildOutgoingMessageWithText:fullMessageText
|
||||||
|
mediaAttachments:mediaAttachments
|
||||||
uint32_t expiresInSeconds = (configuration.isEnabled ? configuration.durationSeconds : 0);
|
thread:thread
|
||||||
BOOL isVoiceMessage = (attachments.count == 1 && attachments.firstObject.isVoiceMessage);
|
quotedReplyModel:quotedReplyModel
|
||||||
// MJK TODO - remove senderTimestamp
|
linkPreviewDraft:nil
|
||||||
TSOutgoingMessage *message =
|
transaction:transaction
|
||||||
[[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
|
completion:^(TSOutgoingMessage *_Nonnull savedMessage,
|
||||||
inThread:thread
|
NSMutableArray<OWSOutgoingAttachmentInfo *> *_Nonnull attachmentInfos,
|
||||||
messageBody:messageBody
|
YapDatabaseReadWriteTransaction *_Nonnull writeTransaction) {
|
||||||
attachmentIds:[NSMutableArray new]
|
if (attachmentInfos.count == 0) {
|
||||||
expiresInSeconds:expiresInSeconds
|
[messageSender sendMessage:savedMessage
|
||||||
expireStartedAt:0
|
success:^{
|
||||||
isVoiceMessage:isVoiceMessage
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||||
groupMetaMessage:TSGroupMetaMessageUnspecified
|
completion(nil);
|
||||||
quotedMessage:[quotedReplyModel buildQuotedMessageForSending]
|
});
|
||||||
contactShare:nil
|
}
|
||||||
linkPreview:nil];
|
failure:^(NSError *error) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||||
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos = [NSMutableArray new];
|
completion(error);
|
||||||
for (SignalAttachment *attachment in attachments) {
|
});
|
||||||
OWSAssertDebug([attachment mimeType].length > 0);
|
}];
|
||||||
|
} else {
|
||||||
[attachmentInfos addObject:[attachment buildOutgoingAttachmentInfoWithMessage:message]];
|
[messageSender sendAttachments:attachmentInfos
|
||||||
}
|
inMessage:savedMessage
|
||||||
|
success:^{
|
||||||
[messageSender sendAttachments:attachmentInfos
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||||
inMessage:message
|
completion(nil);
|
||||||
success:^{
|
});
|
||||||
OWSLogDebug(@"Successfully sent message attachment.");
|
}
|
||||||
if (completion) {
|
failure:^(NSError *error) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||||
completion(nil);
|
completion(error);
|
||||||
});
|
});
|
||||||
}
|
}];
|
||||||
}
|
}
|
||||||
failure:^(NSError *error) {
|
}];
|
||||||
OWSLogError(@"Failed to send message attachment with error: %@", error);
|
|
||||||
if (completion) {
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
|
||||||
completion(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare
|
+ (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare
|
||||||
inThread:(TSThread *)thread
|
inThread:(TSThread *)thread
|
||||||
messageSender:(OWSMessageSender *)messageSender
|
messageSender:(OWSMessageSender *)messageSender
|
||||||
completion:(void (^_Nullable)(NSError *_Nullable error))completion
|
completion:(void (^)(NSError *_Nullable error))completion
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
OWSAssertIsOnMainThread();
|
||||||
OWSAssertDebug(contactShare);
|
OWSAssertDebug(contactShare);
|
||||||
OWSAssertDebug(contactShare.ows_isValid);
|
OWSAssertDebug(contactShare.ows_isValid);
|
||||||
OWSAssertDebug(thread);
|
OWSAssertDebug(thread);
|
||||||
OWSAssertDebug(messageSender);
|
OWSAssertDebug(messageSender);
|
||||||
|
OWSAssertDebug(completion);
|
||||||
|
|
||||||
OWSDisappearingMessagesConfiguration *configuration =
|
OWSDisappearingMessagesConfiguration *configuration =
|
||||||
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
|
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
|
||||||
|
@ -377,24 +365,38 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[messageSender sendMessage:message
|
[messageSender sendMessage:message
|
||||||
success:^{
|
success:^{
|
||||||
OWSLogDebug(@"Successfully sent contact share.");
|
OWSLogDebug(@"Successfully sent contact share.");
|
||||||
if (completion) {
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
completion(nil);
|
||||||
completion(nil);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
failure:^(NSError *error) {
|
failure:^(NSError *error) {
|
||||||
OWSLogError(@"Failed to send contact share with error: %@", error);
|
OWSLogError(@"Failed to send contact share with error: %@", error);
|
||||||
if (completion) {
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
completion(error);
|
||||||
completion(error);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (nullable OWSLinkPreview *)linkPreviewForLinkPreviewDraft:(nullable OWSLinkPreviewDraft *)linkPreviewDraft
|
||||||
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
|
{
|
||||||
|
OWSAssertDebug(transaction);
|
||||||
|
|
||||||
|
if (!linkPreviewDraft) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
NSError *linkPreviewError;
|
||||||
|
OWSLinkPreview *_Nullable linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft
|
||||||
|
transaction:transaction
|
||||||
|
error:&linkPreviewError];
|
||||||
|
if (linkPreviewError && ![OWSLinkPreview isNoPreviewError:linkPreviewError]) {
|
||||||
|
OWSLogError(@"linkPreviewError: %@", linkPreviewError);
|
||||||
|
}
|
||||||
|
return linkPreview;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Dynamic Interactions
|
#pragma mark - Dynamic Interactions
|
||||||
|
|
||||||
+ (ThreadDynamicInteractions *)ensureDynamicInteractionsForThread:(TSThread *)thread
|
+ (ThreadDynamicInteractions *)ensureDynamicInteractionsForThread:(TSThread *)thread
|
||||||
|
|
|
@ -234,7 +234,7 @@ void AssertIsOnSendingQueue()
|
||||||
|
|
||||||
- (void)didFailWithError:(NSError *)error
|
- (void)didFailWithError:(NSError *)error
|
||||||
{
|
{
|
||||||
OWSLogDebug(@"failed with error: %@", error);
|
OWSLogError(@"failed with error: %@", error);
|
||||||
self.failureHandler(error);
|
self.failureHandler(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue