mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Parse attachment pointers
This commit is contained in:
parent
7d207ddfb7
commit
961878f74c
|
@ -39,8 +39,8 @@ public final class MessageReceiveJob : NSObject, Job, NSCoding { // NSObject/NSC
|
||||||
Configuration.shared.storage.withAsync({ transaction in // Intentionally capture self
|
Configuration.shared.storage.withAsync({ transaction in // Intentionally capture self
|
||||||
Threading.workQueue.async {
|
Threading.workQueue.async {
|
||||||
do {
|
do {
|
||||||
let message = try MessageReceiver.parse(self.data, messageServerID: self.messageServerID, using: transaction)
|
let (message, proto) = try MessageReceiver.parse(self.data, messageServerID: self.messageServerID, using: transaction)
|
||||||
try MessageReceiver.handle(message, using: transaction)
|
try MessageReceiver.handle(message, associatedWithProto: proto, using: transaction)
|
||||||
self.handleSuccess()
|
self.handleSuccess()
|
||||||
} catch {
|
} catch {
|
||||||
SNLog("Couldn't parse message due to error: \(error).")
|
SNLog("Couldn't parse message due to error: \(error).")
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import CoreGraphics
|
||||||
|
import SessionUtilitiesKit
|
||||||
|
|
||||||
|
public extension VisibleMessage {
|
||||||
|
|
||||||
|
@objc(SNAttachment)
|
||||||
|
class Attachment : NSObject, NSCoding {
|
||||||
|
public var fileName: String?
|
||||||
|
public var contentType: String?
|
||||||
|
public var key: Data?
|
||||||
|
public var digest: Data?
|
||||||
|
public var kind: Kind?
|
||||||
|
public var caption: String?
|
||||||
|
public var size: CGSize?
|
||||||
|
public var sizeInBytes: UInt?
|
||||||
|
public var url: String?
|
||||||
|
|
||||||
|
public var isValid: Bool {
|
||||||
|
fileName != nil && contentType != nil && key != nil && digest != nil && kind != nil && size != nil && sizeInBytes != nil && url != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Kind : String {
|
||||||
|
case voiceMessage, generic
|
||||||
|
}
|
||||||
|
|
||||||
|
public override init() { super.init() }
|
||||||
|
|
||||||
|
public required init?(coder: NSCoder) {
|
||||||
|
if let fileName = coder.decodeObject(forKey: "fileName") as! String? { self.fileName = fileName }
|
||||||
|
if let contentType = coder.decodeObject(forKey: "contentType") as! String? { self.contentType = contentType }
|
||||||
|
if let key = coder.decodeObject(forKey: "key") as! Data? { self.key = key }
|
||||||
|
if let digest = coder.decodeObject(forKey: "digest") as! Data? { self.digest = digest }
|
||||||
|
if let rawKind = coder.decodeObject(forKey: "kind") as! String? { self.kind = Kind(rawValue: rawKind) }
|
||||||
|
if let caption = coder.decodeObject(forKey: "caption") as! String? { self.caption = caption }
|
||||||
|
if let size = coder.decodeObject(forKey: "size") as! CGSize? { self.size = size }
|
||||||
|
if let sizeInBytes = coder.decodeObject(forKey: "sizeInBytes") as! UInt? { self.sizeInBytes = sizeInBytes }
|
||||||
|
if let url = coder.decodeObject(forKey: "url") as! String? { self.url = url }
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(with coder: NSCoder) {
|
||||||
|
coder.encode(fileName, forKey: "fileName")
|
||||||
|
coder.encode(contentType, forKey: "contentType")
|
||||||
|
coder.encode(key, forKey: "key")
|
||||||
|
coder.encode(digest, forKey: "digest")
|
||||||
|
coder.encode(kind?.rawValue, forKey: "kind")
|
||||||
|
coder.encode(caption, forKey: "caption")
|
||||||
|
coder.encode(size, forKey: "size")
|
||||||
|
coder.encode(sizeInBytes, forKey: "sizeInBytes")
|
||||||
|
coder.encode(url, forKey: "url")
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func fromProto(_ proto: SNProtoAttachmentPointer) -> Attachment? {
|
||||||
|
preconditionFailure("Use MessageReceiverDelegate.parseAttachments(from:) instead.")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toProto() -> SNProtoDataMessageQuote? {
|
||||||
|
fatalError("Not implemented.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ public final class VisibleMessage : Message {
|
||||||
guard let dataMessage = proto.dataMessage else { return nil }
|
guard let dataMessage = proto.dataMessage else { return nil }
|
||||||
let result = VisibleMessage()
|
let result = VisibleMessage()
|
||||||
result.text = dataMessage.body
|
result.text = dataMessage.body
|
||||||
result.attachmentIDs = [] // TODO: Attachments
|
// Attachments are handled in MessageReceiver
|
||||||
if let quoteProto = dataMessage.quote, let quote = Quote.fromProto(quoteProto) { result.quote = quote }
|
if let quoteProto = dataMessage.quote, let quote = Quote.fromProto(quoteProto) { result.quote = quote }
|
||||||
if let linkPreviewProto = dataMessage.preview.first, let linkPreview = LinkPreview.fromProto(linkPreviewProto) { result.linkPreview = linkPreview }
|
if let linkPreviewProto = dataMessage.preview.first, let linkPreview = LinkPreview.fromProto(linkPreviewProto) { result.linkPreview = linkPreview }
|
||||||
// TODO: Contact
|
// TODO: Contact
|
||||||
|
|
|
@ -47,7 +47,7 @@ internal enum MessageReceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static func parse(_ data: Data, messageServerID: UInt64?, using transaction: Any) throws -> Message {
|
internal static func parse(_ data: Data, messageServerID: UInt64?, using transaction: Any) throws -> (Message, SNProtoContent) {
|
||||||
// Parse the envelope
|
// Parse the envelope
|
||||||
let envelope = try SNProtoEnvelope.parseData(data)
|
let envelope = try SNProtoEnvelope.parseData(data)
|
||||||
// Decrypt the contents
|
// Decrypt the contents
|
||||||
|
@ -90,13 +90,13 @@ internal enum MessageReceiver {
|
||||||
message.groupPublicKey = groupPublicKey
|
message.groupPublicKey = groupPublicKey
|
||||||
message.openGroupServerMessageID = messageServerID
|
message.openGroupServerMessageID = messageServerID
|
||||||
guard message.isValid else { throw Error.invalidMessage }
|
guard message.isValid else { throw Error.invalidMessage }
|
||||||
return message
|
return (message, proto)
|
||||||
} else {
|
} else {
|
||||||
throw Error.unknownMessage
|
throw Error.unknownMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static func handle(_ message: Message, using transaction: Any) throws {
|
internal static func handle(_ message: Message, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
|
||||||
switch message {
|
switch message {
|
||||||
case let message as ReadReceipt: handleReadReceipt(message, using: transaction)
|
case let message as ReadReceipt: handleReadReceipt(message, using: transaction)
|
||||||
case let message as SessionRequest: handleSessionRequest(message, using: transaction)
|
case let message as SessionRequest: handleSessionRequest(message, using: transaction)
|
||||||
|
@ -104,7 +104,7 @@ internal enum MessageReceiver {
|
||||||
case let message as TypingIndicator: handleTypingIndicator(message, using: transaction)
|
case let message as TypingIndicator: handleTypingIndicator(message, using: transaction)
|
||||||
case let message as ClosedGroupUpdate: handleClosedGroupUpdate(message, using: transaction)
|
case let message as ClosedGroupUpdate: handleClosedGroupUpdate(message, using: transaction)
|
||||||
case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction)
|
case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction)
|
||||||
case let message as VisibleMessage: try handleVisibleMessage(message, using: transaction)
|
case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, using: transaction)
|
||||||
default: fatalError()
|
default: fatalError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,14 +148,18 @@ internal enum MessageReceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func handleVisibleMessage(_ message: VisibleMessage, using transaction: Any) throws {
|
private static func handleVisibleMessage(_ message: VisibleMessage, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
|
||||||
let delegate = Configuration.shared.messageReceiverDelegate
|
let delegate = Configuration.shared.messageReceiverDelegate
|
||||||
|
let storage = Configuration.shared.storage
|
||||||
|
// Handle attachments
|
||||||
|
let attachments = delegate.parseAttachments(from: proto.dataMessage!.attachments)
|
||||||
|
message.attachmentIDs = storage.save(attachments, using: transaction)
|
||||||
// Update profile if needed
|
// Update profile if needed
|
||||||
if let profile = message.profile {
|
if let profile = message.profile {
|
||||||
delegate.updateProfile(for: message.sender!, from: profile, using: transaction)
|
delegate.updateProfile(for: message.sender!, from: profile, using: transaction)
|
||||||
}
|
}
|
||||||
// Persist the message
|
// Persist the message
|
||||||
guard let (threadID, tsIncomingMessage) = Configuration.shared.storage.persist(message, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread }
|
guard let (threadID, tsIncomingMessage) = storage.persist(message, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread }
|
||||||
message.threadID = threadID
|
message.threadID = threadID
|
||||||
// Cancel any typing indicators
|
// Cancel any typing indicators
|
||||||
delegate.cancelTypingIndicatorsIfNeeded(for: message.sender!)
|
delegate.cancelTypingIndicatorsIfNeeded(for: message.sender!)
|
||||||
|
|
|
@ -14,4 +14,5 @@ public protocol MessageReceiverDelegate {
|
||||||
func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any)
|
func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any)
|
||||||
func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any)
|
func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any)
|
||||||
func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any)
|
func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any)
|
||||||
|
func parseAttachments(from protos: [SNProtoAttachmentPointer]) -> [VisibleMessage.Attachment]
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ public protocol SessionMessagingKitStorageProtocol {
|
||||||
func setOpenGroupPublicKey(for server: String, to newValue: String, using transaction: Any)
|
func setOpenGroupPublicKey(for server: String, to newValue: String, using transaction: Any)
|
||||||
|
|
||||||
// MARK: - Last Message Server ID
|
// MARK: - Last Message Server ID
|
||||||
|
|
||||||
func getLastMessageServerID(for group: UInt64, on server: String) -> UInt64?
|
func getLastMessageServerID(for group: UInt64, on server: String) -> UInt64?
|
||||||
func setLastMessageServerID(for group: UInt64, on server: String, to newValue: UInt64, using transaction: Any)
|
func setLastMessageServerID(for group: UInt64, on server: String, to newValue: UInt64, using transaction: Any)
|
||||||
func removeLastMessageServerID(for group: UInt64, on server: String, using transaction: Any)
|
func removeLastMessageServerID(for group: UInt64, on server: String, using transaction: Any)
|
||||||
|
@ -64,4 +63,6 @@ public protocol SessionMessagingKitStorageProtocol {
|
||||||
|
|
||||||
/// Returns the ID of the thread the message was stored under along with the `TSIncomingMessage` that was constructed.
|
/// Returns the ID of the thread the message was stored under along with the `TSIncomingMessage` that was constructed.
|
||||||
func persist(_ message: VisibleMessage, groupPublicKey: String?, using transaction: Any) -> (String, Any)?
|
func persist(_ message: VisibleMessage, groupPublicKey: String?, using transaction: Any) -> (String, Any)?
|
||||||
|
/// Returns the IDs of the saved attachments.
|
||||||
|
func save(_ attachments: [VisibleMessage.Attachment], using transaction: Any) -> [String]
|
||||||
}
|
}
|
||||||
|
|
|
@ -585,6 +585,8 @@
|
||||||
C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAD2485E51D00ACB629 /* IP2Country.swift */; };
|
C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAD2485E51D00ACB629 /* IP2Country.swift */; };
|
||||||
C3645350252449260045C478 /* VoiceMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C364534F252449260045C478 /* VoiceMessageView.swift */; };
|
C3645350252449260045C478 /* VoiceMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C364534F252449260045C478 /* VoiceMessageView.swift */; };
|
||||||
C364535C252467900045C478 /* AudioUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C364535B252467900045C478 /* AudioUtilities.swift */; };
|
C364535C252467900045C478 /* AudioUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C364535B252467900045C478 /* AudioUtilities.swift */; };
|
||||||
|
C379DCF4256735770002D4EB /* VisibleMessage+Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C379DCF3256735770002D4EB /* VisibleMessage+Attachment.swift */; };
|
||||||
|
C379DCFE25673DBC0002D4EB /* Attachment+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C379DCFD25673DBC0002D4EB /* Attachment+Conversion.swift */; };
|
||||||
C37F5385255B94F6002AEA92 /* SelectRecipientViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF34E255B6DC8007E1867 /* SelectRecipientViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
C37F5385255B94F6002AEA92 /* SelectRecipientViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF34E255B6DC8007E1867 /* SelectRecipientViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
C37F5396255B95BD002AEA92 /* OWSAnyTouchGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF302255B6DBE007E1867 /* OWSAnyTouchGestureRecognizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
C37F5396255B95BD002AEA92 /* OWSAnyTouchGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF302255B6DBE007E1867 /* OWSAnyTouchGestureRecognizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
C37F53A7255B96E0002AEA92 /* OWSAudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2F5255B6DBC007E1867 /* OWSAudioPlayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
C37F53A7255B96E0002AEA92 /* OWSAudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2F5255B6DBC007E1867 /* OWSAudioPlayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
@ -1679,6 +1681,8 @@
|
||||||
C35E8AAD2485E51D00ACB629 /* IP2Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IP2Country.swift; sourceTree = "<group>"; };
|
C35E8AAD2485E51D00ACB629 /* IP2Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IP2Country.swift; sourceTree = "<group>"; };
|
||||||
C364534F252449260045C478 /* VoiceMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageView.swift; sourceTree = "<group>"; };
|
C364534F252449260045C478 /* VoiceMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageView.swift; sourceTree = "<group>"; };
|
||||||
C364535B252467900045C478 /* AudioUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioUtilities.swift; sourceTree = "<group>"; };
|
C364535B252467900045C478 /* AudioUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioUtilities.swift; sourceTree = "<group>"; };
|
||||||
|
C379DCF3256735770002D4EB /* VisibleMessage+Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VisibleMessage+Attachment.swift"; sourceTree = "<group>"; };
|
||||||
|
C379DCFD25673DBC0002D4EB /* Attachment+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Attachment+Conversion.swift"; sourceTree = "<group>"; };
|
||||||
C37F53E8255BA9BB002AEA92 /* Environment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Environment.h; sourceTree = "<group>"; };
|
C37F53E8255BA9BB002AEA92 /* Environment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Environment.h; sourceTree = "<group>"; };
|
||||||
C37F5402255BA9ED002AEA92 /* Environment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Environment.m; sourceTree = "<group>"; };
|
C37F5402255BA9ED002AEA92 /* Environment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Environment.m; sourceTree = "<group>"; };
|
||||||
C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SNProtoEnvelope+Conversion.swift"; sourceTree = "<group>"; };
|
C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SNProtoEnvelope+Conversion.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -2631,6 +2635,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C3C2A74C2553A39700C340D1 /* VisibleMessage.swift */,
|
C3C2A74C2553A39700C340D1 /* VisibleMessage.swift */,
|
||||||
|
C379DCF3256735770002D4EB /* VisibleMessage+Attachment.swift */,
|
||||||
C3C2A7552553A3AB00C340D1 /* VisibleMessage+Quote.swift */,
|
C3C2A7552553A3AB00C340D1 /* VisibleMessage+Quote.swift */,
|
||||||
C3C2A75E2553A3C500C340D1 /* VisibleMessage+LinkPreview.swift */,
|
C3C2A75E2553A3C500C340D1 /* VisibleMessage+LinkPreview.swift */,
|
||||||
C3C2A7672553A3D900C340D1 /* VisibleMessage+Contact.swift */,
|
C3C2A7672553A3D900C340D1 /* VisibleMessage+Contact.swift */,
|
||||||
|
@ -3279,6 +3284,7 @@
|
||||||
C38BBA0B255E31EC0041B9A3 /* Attachments */ = {
|
C38BBA0B255E31EC0041B9A3 /* Attachments */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C379DCFD25673DBC0002D4EB /* Attachment+Conversion.swift */,
|
||||||
C38EF224255B6D5D007E1867 /* SignalAttachment.swift */,
|
C38EF224255B6D5D007E1867 /* SignalAttachment.swift */,
|
||||||
C33FDC15255A581E00E217F9 /* TSAttachment.h */,
|
C33FDC15255A581E00E217F9 /* TSAttachment.h */,
|
||||||
C33FDAC2255A580200E217F9 /* TSAttachment.m */,
|
C33FDAC2255A580200E217F9 /* TSAttachment.m */,
|
||||||
|
@ -4957,6 +4963,7 @@
|
||||||
C33FDD3D255A582000E217F9 /* TSQuotedMessage.m in Sources */,
|
C33FDD3D255A582000E217F9 /* TSQuotedMessage.m in Sources */,
|
||||||
C38EF273255B6D7A007E1867 /* OWSDatabaseMigrationRunner.m in Sources */,
|
C38EF273255B6D7A007E1867 /* OWSDatabaseMigrationRunner.m in Sources */,
|
||||||
C33FDD12255A582000E217F9 /* OWSPrimaryStorage+Loki.m in Sources */,
|
C33FDD12255A582000E217F9 /* OWSPrimaryStorage+Loki.m in Sources */,
|
||||||
|
C379DCFE25673DBC0002D4EB /* Attachment+Conversion.swift in Sources */,
|
||||||
C38EF31A255B6DBF007E1867 /* OWSAnyTouchGestureRecognizer.m in Sources */,
|
C38EF31A255B6DBF007E1867 /* OWSAnyTouchGestureRecognizer.m in Sources */,
|
||||||
C33FDCFB255A582000E217F9 /* MIMETypeUtil.m in Sources */,
|
C33FDCFB255A582000E217F9 /* MIMETypeUtil.m in Sources */,
|
||||||
C38EF36C255B6DCC007E1867 /* SharingThreadPickerViewController.m in Sources */,
|
C38EF36C255B6DCC007E1867 /* SharingThreadPickerViewController.m in Sources */,
|
||||||
|
@ -5263,6 +5270,7 @@
|
||||||
C3BBE0B52554F0E10050F1E3 /* ProofOfWork.swift in Sources */,
|
C3BBE0B52554F0E10050F1E3 /* ProofOfWork.swift in Sources */,
|
||||||
C3A721902558C0CD0043A11F /* FileServerAPI.swift in Sources */,
|
C3A721902558C0CD0043A11F /* FileServerAPI.swift in Sources */,
|
||||||
C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */,
|
C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */,
|
||||||
|
C379DCF4256735770002D4EB /* VisibleMessage+Attachment.swift in Sources */,
|
||||||
C3C2A7842553AAF300C340D1 /* SNProto.swift in Sources */,
|
C3C2A7842553AAF300C340D1 /* SNProto.swift in Sources */,
|
||||||
C3C2A7682553A3D900C340D1 /* VisibleMessage+Contact.swift in Sources */,
|
C3C2A7682553A3D900C340D1 /* VisibleMessage+Contact.swift in Sources */,
|
||||||
C3A721392558BDFA0043A11F /* OpenGroupAPI.swift in Sources */,
|
C3A721392558BDFA0043A11F /* OpenGroupAPI.swift in Sources */,
|
||||||
|
|
|
@ -32,4 +32,12 @@ extension Storage {
|
||||||
message.save(with: transaction)
|
message.save(with: transaction)
|
||||||
return (thread.uniqueId!, message)
|
return (thread.uniqueId!, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func save(_ attachments: [VisibleMessage.Attachment], using transaction: Any) -> [String] {
|
||||||
|
return attachments.map { attachment in
|
||||||
|
let tsAttachment = TSAttachmentPointer.from(attachment)
|
||||||
|
tsAttachment.save(with: transaction as! YapDatabaseReadWriteTransaction)
|
||||||
|
return tsAttachment.uniqueId!
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
extension TSAttachmentPointer {
|
||||||
|
|
||||||
|
public static func from(_ attachment: VisibleMessage.Attachment) -> TSAttachmentPointer {
|
||||||
|
let kind: TSAttachmentType
|
||||||
|
switch attachment.kind! {
|
||||||
|
case .generic: kind = .default
|
||||||
|
case .voiceMessage: kind = .voiceMessage
|
||||||
|
}
|
||||||
|
return TSAttachmentPointer(
|
||||||
|
serverId: 0,
|
||||||
|
key: attachment.key,
|
||||||
|
digest: attachment.digest,
|
||||||
|
byteCount: UInt32(attachment.sizeInBytes!),
|
||||||
|
contentType: attachment.contentType!,
|
||||||
|
sourceFilename: attachment.fileName,
|
||||||
|
caption: attachment.caption,
|
||||||
|
albumMessageId: nil,
|
||||||
|
attachmentType: kind,
|
||||||
|
mediaSize: attachment.size!)
|
||||||
|
}
|
||||||
|
}
|
|
@ -312,4 +312,40 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: [])
|
let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: [])
|
||||||
Storage.shared.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: message.sender!, ratchet: ratchet, using: transaction)
|
Storage.shared.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: message.sender!, ratchet: ratchet, using: transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - Attachments
|
||||||
|
|
||||||
|
public func parseAttachments(from protos: [SNProtoAttachmentPointer]) -> [VisibleMessage.Attachment] {
|
||||||
|
return protos.compactMap { proto in
|
||||||
|
let result = VisibleMessage.Attachment()
|
||||||
|
result.fileName = proto.fileName
|
||||||
|
func inferContentType() -> String {
|
||||||
|
guard let fileName = result.fileName, let fileExtension = URL(string: fileName)?.pathExtension else { return OWSMimeTypeApplicationOctetStream }
|
||||||
|
return MIMETypeUtil.mimeType(forFileExtension: fileExtension) ?? OWSMimeTypeApplicationOctetStream
|
||||||
|
}
|
||||||
|
result.contentType = proto.contentType ?? inferContentType()
|
||||||
|
result.key = proto.key
|
||||||
|
result.digest = proto.digest
|
||||||
|
let kind: VisibleMessage.Attachment.Kind
|
||||||
|
if proto.hasFlags && (proto.flags & UInt32(SNProtoAttachmentPointer.SNProtoAttachmentPointerFlags.voiceMessage.rawValue)) > 0 {
|
||||||
|
kind = .voiceMessage
|
||||||
|
} else {
|
||||||
|
kind = .generic
|
||||||
|
}
|
||||||
|
result.kind = kind
|
||||||
|
result.caption = proto.hasCaption ? proto.caption : nil
|
||||||
|
let size: CGSize
|
||||||
|
if proto.hasWidth && proto.width > 0 && proto.hasHeight && proto.height > 0 {
|
||||||
|
size = CGSize(width: Int(proto.width), height: Int(proto.height))
|
||||||
|
} else {
|
||||||
|
size = CGSize.zero
|
||||||
|
}
|
||||||
|
result.size = size
|
||||||
|
result.sizeInBytes = proto.size > 0 ? UInt(proto.size) : nil
|
||||||
|
result.url = proto.url
|
||||||
|
return result.isValid ? result : nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue