diff --git a/SessionMessagingKit/Messages/Visible Message/VisibleMessage+LinkPreview.swift b/SessionMessagingKit/Messages/Visible Message/VisibleMessage+LinkPreview.swift index d7e66a766..44fc13273 100644 --- a/SessionMessagingKit/Messages/Visible Message/VisibleMessage+LinkPreview.swift +++ b/SessionMessagingKit/Messages/Visible Message/VisibleMessage+LinkPreview.swift @@ -7,6 +7,8 @@ public extension VisibleMessage { public var title: String? public var url: String? + public var isValid: Bool { title != nil && url != nil } + internal init(title: String?, url: String) { self.title = title self.url = url diff --git a/SessionMessagingKit/Messages/Visible Message/VisibleMessage+Quote.swift b/SessionMessagingKit/Messages/Visible Message/VisibleMessage+Quote.swift index 51bef0eb1..85065906f 100644 --- a/SessionMessagingKit/Messages/Visible Message/VisibleMessage+Quote.swift +++ b/SessionMessagingKit/Messages/Visible Message/VisibleMessage+Quote.swift @@ -8,6 +8,8 @@ public extension VisibleMessage { public var publicKey: String? public var text: String? + public var isValid: Bool { timestamp != nil && publicKey != nil && text != nil } + internal init(timestamp: UInt64, publicKey: String, text: String) { self.timestamp = timestamp self.publicKey = publicKey diff --git a/SessionMessagingKit/Open Groups/OpenGroupMessage+Conversion.swift b/SessionMessagingKit/Open Groups/OpenGroupMessage+Conversion.swift new file mode 100644 index 000000000..be4515ce2 --- /dev/null +++ b/SessionMessagingKit/Open Groups/OpenGroupMessage+Conversion.swift @@ -0,0 +1,35 @@ + +internal extension OpenGroupMessage { + + static func from(_ message: VisibleMessage, for server: String) -> OpenGroupMessage? { + guard message.isValid else { preconditionFailure() } // Should be valid at this point + let storage = Configuration.shared.storage + let displayName = storage.getUserDisplayName() ?? "Anonymous" + guard let userPublicKey = storage.getUserPublicKey() else { return nil } + let quote: OpenGroupMessage.Quote? = { + if let quote = message.quote { + guard quote.isValid else { return nil } + return OpenGroupMessage.Quote(quotedMessageTimestamp: quote.timestamp!, quoteePublicKey: quote.publicKey!, quotedMessageBody: quote.text!, quotedMessageServerID: nil) // TODO: Server ID + } else { + return nil + } + }() + let body = message.text! + let result = OpenGroupMessage(serverID: nil, senderPublicKey: userPublicKey, displayName: displayName, profilePicture: nil, body: body, + type: OpenGroupAPI.openGroupMessageType, timestamp: message.sentTimestamp!, quote: quote, attachments: [], signature: nil, serverTimestamp: 0) + if let linkPreview: OpenGroupMessage.Attachment = { + if let linkPreview = message.linkPreview { + guard linkPreview.isValid else { return nil } + // TODO: Implement + return OpenGroupMessage.Attachment(kind: .linkPreview, server: server, serverID: 0, contentType: "", size: 0, fileName: "", + flags: 0, width: 0, height: 0, caption: "", url: "", linkPreviewURL: "", linkPreviewTitle: "") + } else { + return nil + } + }() { + result.attachments.append(linkPreview) + } + // TODO: Attachments + return result + } +} diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index d57b47f74..00f4ade7d 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -40,6 +40,7 @@ internal enum MessageReceiver { case .closedGroupCiphertext: (plaintext, _) = try decryptWithSharedSenderKeys(envelope: envelope, using: transaction) default: throw Error.unknownEnvelopeType } + // Parse the proto let proto: SNProtoContent do { proto = try SNProtoContent.parseData((plaintext as NSData).removePadding()) @@ -47,6 +48,7 @@ internal enum MessageReceiver { SNLog("Couldn't parse proto due to error: \(error).") throw error } + // Parse the message let message: Message? = { if let readReceipt = ReadReceipt.fromProto(proto) { return readReceipt } if let sessionRequest = SessionRequest.fromProto(proto) { return sessionRequest } diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index b6e2dd074..958f287cf 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -23,7 +23,7 @@ internal enum MessageSender { internal static func send(_ message: Message, to destination: Message.Destination, using transaction: Any) -> Promise { switch destination { case .contact(_), .closedGroup(_): return sendToSnodeDestination(destination, message: message, using: transaction) - default: fatalError("Not implemented.") + case .openGroup(_, _): return sendToOpenGroupDestination(destination, message: message, using: transaction) } } @@ -133,4 +133,24 @@ internal enum MessageSender { } return promise } + + internal static func sendToOpenGroupDestination(_ destination: Message.Destination, message: Message, using transaction: Any) -> Promise { + guard message.isValid else { return Promise(error: Error.invalidMessage) } + let (channel, server) = { () -> (UInt64, String) in + switch destination { + case .openGroup(let channel, let server): return (channel, server) + default: preconditionFailure() + } + }() + guard let message = message as? VisibleMessage, + let openGroupMessage = OpenGroupMessage.from(message, for: server) else { return Promise(error: Error.invalidMessage) } + let promise = OpenGroupAPI.sendMessage(openGroupMessage, to: channel, on: server) + let _ = promise.done(on: DispatchQueue.global(qos: .userInitiated)) { _ in + // TODO: Save server message ID + } + promise.catch(on: DispatchQueue.global(qos: .userInitiated)) { _ in + // TODO: Handle failure + } + return promise.map { _ in } + } } diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 284cd5a58..85b1da08f 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -664,6 +664,7 @@ C3A7225E2558C38D0043A11F /* AnyPromise+Retaining.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A7225D2558C38D0043A11F /* AnyPromise+Retaining.swift */; }; C3A722802558C4E10043A11F /* AttachmentStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A7227F2558C4E10043A11F /* AttachmentStream.swift */; }; C3A722922558C8940043A11F /* OpenGroupAPIDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A722912558C8940043A11F /* OpenGroupAPIDelegate.swift */; }; + C3A7229C2558E4310043A11F /* OpenGroupMessage+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A7229B2558E4310043A11F /* OpenGroupMessage+Conversion.swift */; }; C3AABDDF2553ECF00042FF4C /* Array+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D12553860800C340D1 /* Array+Description.swift */; }; C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BBE0752554CDA60050F1E3 /* Configuration.swift */; }; C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BBE07F2554CDD70050F1E3 /* Storage.swift */; }; @@ -1713,6 +1714,7 @@ C3A7225D2558C38D0043A11F /* AnyPromise+Retaining.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnyPromise+Retaining.swift"; sourceTree = ""; }; C3A7227F2558C4E10043A11F /* AttachmentStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentStream.swift; sourceTree = ""; }; C3A722912558C8940043A11F /* OpenGroupAPIDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPIDelegate.swift; sourceTree = ""; }; + C3A7229B2558E4310043A11F /* OpenGroupMessage+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenGroupMessage+Conversion.swift"; sourceTree = ""; }; C3AA6BB824CE8F1B002358B6 /* Migrating Translations from Android.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Migrating Translations from Android.md"; sourceTree = ""; }; C3AECBEA24EF5244005743DE /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = ""; }; C3BBE0752554CDA60050F1E3 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; @@ -3405,6 +3407,7 @@ C3A722912558C8940043A11F /* OpenGroupAPIDelegate.swift */, C3A721362558BDFA0043A11F /* OpenGroupInfo.swift */, C3A721342558BDF90043A11F /* OpenGroupMessage.swift */, + C3A7229B2558E4310043A11F /* OpenGroupMessage+Conversion.swift */, ); path = "Open Groups"; sourceTree = ""; @@ -5090,6 +5093,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C3A7229C2558E4310043A11F /* OpenGroupMessage+Conversion.swift in Sources */, C3471F4C25553AB000297E91 /* MessageReceiver+Decryption.swift in Sources */, C3A722802558C4E10043A11F /* AttachmentStream.swift in Sources */, C300A5D32554B05A00555489 /* TypingIndicator.swift in Sources */,