|  |  |  | 
 | 
					
						
							|  |  |  | internal extension OpenGroupMessage { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static func from(_ message: VisibleMessage, for server: String, using transaction: YapDatabaseReadWriteTransaction) -> OpenGroupMessage? { | 
					
						
							|  |  |  |         let storage = SNMessagingKitConfiguration.shared.storage | 
					
						
							|  |  |  |         guard let userPublicKey = storage.getUserPublicKey() else { return nil } | 
					
						
							|  |  |  |         var attachmentIDs = message.attachmentIDs | 
					
						
							|  |  |  |         // Validation | 
					
						
							|  |  |  |         guard message.isValid else { return nil } // Should be valid at this point | 
					
						
							|  |  |  |         // Quote | 
					
						
							|  |  |  |         let quote: OpenGroupMessage.Quote? = { | 
					
						
							|  |  |  |             if let quote = message.quote { | 
					
						
							|  |  |  |                 guard quote.isValid else { return nil } | 
					
						
							|  |  |  |                 let quotedMessageBody = quote.text ?? String(quote.timestamp!) // The back-end doesn't accept messages without a body so we use this as a workaround | 
					
						
							|  |  |  |                 if let quotedAttachmentID = quote.attachmentID, let index = attachmentIDs.firstIndex(of: quotedAttachmentID) { | 
					
						
							|  |  |  |                     attachmentIDs.remove(at: index) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 // FIXME: For some reason the server always returns a 500 if quotedMessageServerID is set... | 
					
						
							|  |  |  |                 return OpenGroupMessage.Quote(quotedMessageTimestamp: quote.timestamp!, quoteePublicKey: quote.publicKey!, quotedMessageBody: quotedMessageBody, quotedMessageServerID: nil) | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 return nil | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }() | 
					
						
							|  |  |  |         // Message | 
					
						
							|  |  |  |         let displayName = storage.getUserDisplayName() ?? "Anonymous" | 
					
						
							|  |  |  |         let body = message.text ?? String(message.sentTimestamp!) // The back-end doesn't accept messages without a body so we use this as a workaround | 
					
						
							|  |  |  |         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) | 
					
						
							|  |  |  |         // Link preview | 
					
						
							|  |  |  |         if let linkPreview = message.linkPreview { | 
					
						
							|  |  |  |             guard linkPreview.isValid, let attachmentID = linkPreview.attachmentID, | 
					
						
							|  |  |  |                 let attachment = TSAttachmentStream.fetch(uniqueId: attachmentID, transaction: transaction) else { return nil } | 
					
						
							|  |  |  |             if let index = attachmentIDs.firstIndex(of: attachmentID) { | 
					
						
							|  |  |  |                 attachmentIDs.remove(at: index) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             let fileName = attachment.sourceFilename ?? UUID().uuidString | 
					
						
							|  |  |  |             let width = attachment.shouldHaveImageSize() ? attachment.imageSize().width : 0 | 
					
						
							|  |  |  |             let height = attachment.shouldHaveImageSize() ? attachment.imageSize().height : 0 | 
					
						
							|  |  |  |             let openGroupLinkPreview = OpenGroupMessage.Attachment( | 
					
						
							|  |  |  |                 kind: .linkPreview, | 
					
						
							|  |  |  |                 server: server, | 
					
						
							|  |  |  |                 serverID: attachment.serverId, | 
					
						
							|  |  |  |                 contentType: attachment.contentType, | 
					
						
							|  |  |  |                 size: UInt(attachment.byteCount), | 
					
						
							|  |  |  |                 fileName: fileName, | 
					
						
							|  |  |  |                 flags: 0, | 
					
						
							|  |  |  |                 width: UInt(width), | 
					
						
							|  |  |  |                 height: UInt(height), | 
					
						
							|  |  |  |                 caption: attachment.caption, | 
					
						
							|  |  |  |                 url: attachment.downloadURL, | 
					
						
							|  |  |  |                 linkPreviewURL: linkPreview.url, | 
					
						
							|  |  |  |                 linkPreviewTitle: linkPreview.title | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             result.attachments.append(openGroupLinkPreview) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // Attachments | 
					
						
							|  |  |  |         let attachments: [OpenGroupMessage.Attachment] = attachmentIDs.compactMap { attachmentID in | 
					
						
							|  |  |  |             guard let attachment = TSAttachmentStream.fetch(uniqueId: attachmentID, transaction: transaction) else { return nil } // Should never occur | 
					
						
							|  |  |  |             let fileName = attachment.sourceFilename ?? UUID().uuidString | 
					
						
							|  |  |  |             let width = attachment.shouldHaveImageSize() ? attachment.imageSize().width : 0 | 
					
						
							|  |  |  |             let height = attachment.shouldHaveImageSize() ? attachment.imageSize().height : 0 | 
					
						
							|  |  |  |             return OpenGroupMessage.Attachment( | 
					
						
							|  |  |  |                 kind: .attachment, | 
					
						
							|  |  |  |                 server: server, | 
					
						
							|  |  |  |                 serverID: attachment.serverId, | 
					
						
							|  |  |  |                 contentType: attachment.contentType, | 
					
						
							|  |  |  |                 size: UInt(attachment.byteCount), | 
					
						
							|  |  |  |                 fileName: fileName, | 
					
						
							|  |  |  |                 flags: 0, | 
					
						
							|  |  |  |                 width: UInt(width), | 
					
						
							|  |  |  |                 height: UInt(height), | 
					
						
							|  |  |  |                 caption: attachment.caption, | 
					
						
							|  |  |  |                 url: attachment.downloadURL, | 
					
						
							|  |  |  |                 linkPreviewURL: nil, | 
					
						
							|  |  |  |                 linkPreviewTitle: nil | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         result.attachments += attachments | 
					
						
							|  |  |  |         // Return | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |