diff --git a/Session/Signal/ConversationView/ConversationViewController.m b/Session/Signal/ConversationView/ConversationViewController.m index d6a51e945..07a03c0fc 100644 --- a/Session/Signal/ConversationView/ConversationViewController.m +++ b/Session/Signal/ConversationView/ConversationViewController.m @@ -3760,7 +3760,7 @@ typedef enum : NSUInteger { [tsMessage saveWithTransaction:transaction]; }]; [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [SNMessageSender send:message inThread:thread usingTransaction:transaction]; + [SNMessageSender send:message withAttachments:@[] inThread:thread usingTransaction:transaction]; [thread setDraft:@"" transaction:transaction]; }]; [self messageWasSent:tsMessage]; diff --git a/SessionMessagingKit/Database/Storage+Messaging.swift b/SessionMessagingKit/Database/Storage+Messaging.swift index 7afb97b55..5896a5fa8 100644 --- a/SessionMessagingKit/Database/Storage+Messaging.swift +++ b/SessionMessagingKit/Database/Storage+Messaging.swift @@ -16,8 +16,8 @@ extension Storage { return try! promise.wait() } - /// Returns the ID of the thread the message was stored under along with the ID of the `TSIncomingMessage` that was constructed. - public func persist(_ message: VisibleMessage, groupPublicKey: String?, using transaction: Any) -> (String, String)? { + /// Returns the ID of the thread. + public func getOrCreateThread(for publicKey: String, groupPublicKey: String?, using transaction: Any) -> String? { let transaction = transaction as! YapDatabaseReadWriteTransaction var threadOrNil: TSThread? if let groupPublicKey = groupPublicKey { @@ -25,13 +25,20 @@ extension Storage { let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) threadOrNil = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID), transaction: transaction) } else { - threadOrNil = TSContactThread.getOrCreateThread(withContactId: message.sender!, transaction: transaction) + threadOrNil = TSContactThread.getOrCreateThread(withContactId: publicKey, transaction: transaction) } - guard let thread = threadOrNil else { return nil } - let message = TSIncomingMessage.from(message, associatedWith: thread) + return threadOrNil?.uniqueId + } + + /// Returns the ID of the `TSIncomingMessage` that was constructed. + public func persist(_ message: VisibleMessage, withQuotedMessage quotedMessage: TSQuotedMessage?, groupPublicKey: String?, using transaction: Any) -> String? { + let transaction = transaction as! YapDatabaseReadWriteTransaction + guard let threadID = getOrCreateThread(for: message.sender!, groupPublicKey: groupPublicKey, using: transaction), + let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) else { return nil } + let message = TSIncomingMessage.from(message, withQuotedMessage: quotedMessage, associatedWith: thread) message.save(with: transaction) DispatchQueue.main.async { message.touch() } // FIXME: Hack for a thread updating issue - return (thread.uniqueId!, message.uniqueId!) + return message.uniqueId! } /// Returns the IDs of the saved attachments. diff --git a/SessionMessagingKit/Messages/Signal/TSIncomingMessage+Conversion.swift b/SessionMessagingKit/Messages/Signal/TSIncomingMessage+Conversion.swift index c28b77bf9..e487ef726 100644 --- a/SessionMessagingKit/Messages/Signal/TSIncomingMessage+Conversion.swift +++ b/SessionMessagingKit/Messages/Signal/TSIncomingMessage+Conversion.swift @@ -1,7 +1,7 @@ public extension TSIncomingMessage { - static func from(_ visibleMessage: VisibleMessage, associatedWith thread: TSThread) -> TSIncomingMessage { + static func from(_ visibleMessage: VisibleMessage, withQuotedMessage quotedMessage: TSQuotedMessage?, associatedWith thread: TSThread) -> TSIncomingMessage { let sender = visibleMessage.sender! var expiration: UInt32 = 0 Storage.read { transaction in @@ -15,7 +15,7 @@ public extension TSIncomingMessage { messageBody: visibleMessage.text, attachmentIds: visibleMessage.attachmentIDs, expiresInSeconds: expiration, - quotedMessage: TSQuotedMessage.from(visibleMessage.quote), + quotedMessage: quotedMessage, linkPreview: OWSLinkPreview.from(visibleMessage.linkPreview), serverTimestamp: nil, wasReceivedByUD: true diff --git a/SessionMessagingKit/Messages/Visible Messages/VisibleMessage+Quote.swift b/SessionMessagingKit/Messages/Visible Messages/VisibleMessage+Quote.swift index d19893194..b096b7192 100644 --- a/SessionMessagingKit/Messages/Visible Messages/VisibleMessage+Quote.swift +++ b/SessionMessagingKit/Messages/Visible Messages/VisibleMessage+Quote.swift @@ -13,7 +13,7 @@ public extension VisibleMessage { public override init() { super.init() } - internal init(timestamp: UInt64, publicKey: String, text: String, attachmentID: String?) { + internal init(timestamp: UInt64, publicKey: String, text: String?, attachmentID: String?) { self.timestamp = timestamp self.publicKey = publicKey self.text = text @@ -37,8 +37,8 @@ public extension VisibleMessage { public static func fromProto(_ proto: SNProtoDataMessageQuote) -> Quote? { let timestamp = proto.id let publicKey = proto.author - guard let text = proto.text else { return nil } - return Quote(timestamp: timestamp, publicKey: publicKey, text: text, attachmentID: nil) // TODO: attachmentID + let text = proto.text + return Quote(timestamp: timestamp, publicKey: publicKey, text: text, attachmentID: nil) } public func toProto() -> SNProtoDataMessageQuote? { diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index b5631a540..98031f360 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -157,16 +157,16 @@ extension MessageReceiver { profileManager.setProfileKeyData(profileKey, forRecipientId: message.sender!, avatarURL: profilePictureURL) } } - // Persist the message - guard let (threadID, tsIncomingMessageID) = storage.persist(message, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread } - message.threadID = threadID - // Handle quoted attachment if needed + // Get or create thread + guard let threadID = storage.getOrCreateThread(for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread } + // Parse quote if needed + var tsQuotedMessage: TSQuotedMessage? = nil if message.quote != nil && proto.dataMessage?.quote != nil, let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) { - let tsQuote = TSQuotedMessage(for: proto.dataMessage!, thread: thread, transaction: transaction) - if let thumbnailID = tsQuote?.thumbnailAttachmentStreamId() ?? tsQuote?.thumbnailAttachmentPointerId() { - message.quote?.attachmentID = thumbnailID - } + tsQuotedMessage = TSQuotedMessage(for: proto.dataMessage!, thread: thread, transaction: transaction) } + // Persist the message + guard let tsIncomingMessageID = storage.persist(message, withQuotedMessage: tsQuotedMessage, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread } + message.threadID = threadID // Start attachment downloads if needed storage.withAsync({ transaction in DispatchQueue.main.async { diff --git a/SessionMessagingKit/Sending & Receiving/Quotes/TSQuotedMessage+Conversion.swift b/SessionMessagingKit/Sending & Receiving/Quotes/TSQuotedMessage+Conversion.swift index 3b36356fe..3bb505360 100644 --- a/SessionMessagingKit/Sending & Receiving/Quotes/TSQuotedMessage+Conversion.swift +++ b/SessionMessagingKit/Sending & Receiving/Quotes/TSQuotedMessage+Conversion.swift @@ -1,6 +1,7 @@ extension TSQuotedMessage { + /// To be used for outgoing messages only. @objc(from:) public static func from(_ quote: VisibleMessage.Quote?) -> TSQuotedMessage? { guard let quote = quote else { return nil } diff --git a/SessionMessagingKit/Storage.swift b/SessionMessagingKit/Storage.swift index 5b2974483..3f551397f 100644 --- a/SessionMessagingKit/Storage.swift +++ b/SessionMessagingKit/Storage.swift @@ -73,8 +73,10 @@ public protocol SessionMessagingKitStorageProtocol { func getReceivedMessageTimestamps(using transaction: Any) -> [UInt64] func addReceivedMessageTimestamp(_ timestamp: UInt64, using transaction: Any) - /// Returns the ID of the thread the message was stored under along with the ID of the `TSIncomingMessage` that was constructed. - func persist(_ message: VisibleMessage, groupPublicKey: String?, using transaction: Any) -> (String, String)? + /// Returns the ID of the thread. + func getOrCreateThread(for publicKey: String, groupPublicKey: String?, using transaction: Any) -> String? + /// Returns the ID of the `TSIncomingMessage` that was constructed. + func persist(_ message: VisibleMessage, withQuotedMessage quotedMessage: TSQuotedMessage?, groupPublicKey: String?, using transaction: Any) -> String? /// Returns the IDs of the saved attachments. func persist(_ attachments: [VisibleMessage.Attachment], using transaction: Any) -> [String] /// Also touches the associated message. diff --git a/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Handling.swift b/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Handling.swift index f67ed9e3a..a31d4f138 100644 --- a/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Handling.swift +++ b/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Handling.swift @@ -5,8 +5,7 @@ extension MessageSender : SharedSenderKeysDelegate { // MARK: - Sending Convenience - private static func prep(_ attachments: [SignalAttachment], for message: Message, using transaction: YapDatabaseReadWriteTransaction) { - guard let message = message as? VisibleMessage else { return } + private static func prep(_ attachments: [SignalAttachment], for message: VisibleMessage, using transaction: YapDatabaseReadWriteTransaction) { guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else { #if DEBUG preconditionFailure() @@ -32,14 +31,13 @@ extension MessageSender : SharedSenderKeysDelegate { } @objc(send:withAttachments:inThread:usingTransaction:) - public static func send(_ message: Message, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) { + public static func send(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) { prep(attachments, for: message, using: transaction) send(message, in: thread, using: transaction) } @objc(send:inThread:usingTransaction:) public static func send(_ message: Message, in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) { - if message is VisibleMessage { prep([], for: message, using: transaction) } // To handle quotes & link previews message.threadID = thread.uniqueId! let destination = Message.Destination.from(thread) let job = MessageSendJob(message: message, destination: destination) @@ -47,7 +45,7 @@ extension MessageSender : SharedSenderKeysDelegate { } @objc(sendNonDurably:withAttachments:inThread:usingTransaction:) - public static func objc_sendNonDurably(_ message: Message, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise { + public static func objc_sendNonDurably(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise { return AnyPromise.from(sendNonDurably(message, with: attachments, in: thread, using: transaction)) } @@ -56,7 +54,7 @@ extension MessageSender : SharedSenderKeysDelegate { return AnyPromise.from(sendNonDurably(message, in: thread, using: transaction)) } - public static func sendNonDurably(_ message: Message, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> Promise { + public static func sendNonDurably(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> Promise { prep(attachments, for: message, using: transaction) return sendNonDurably(message, in: thread, using: transaction) } diff --git a/SignalUtilitiesKit/UI/SharingThreadPickerViewController.m b/SignalUtilitiesKit/UI/SharingThreadPickerViewController.m index add5095c8..0789020a7 100644 --- a/SignalUtilitiesKit/UI/SharingThreadPickerViewController.m +++ b/SignalUtilitiesKit/UI/SharingThreadPickerViewController.m @@ -263,7 +263,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion); [tsMessage saveWithTransaction:transaction]; }]; [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [SNMessageSender sendNonDurably:message inThread:self.thread usingTransaction:transaction] + [SNMessageSender sendNonDurably:message withAttachments:@[] inThread:self.thread usingTransaction:transaction] .then(^(id object) { sendCompletion(nil, tsMessage); }).catch(^(NSError *error) {