mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			117 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			117 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Swift
		
	
| import PromiseKit
 | |
| 
 | |
| extension Storage {
 | |
|     
 | |
|     public func getOrGenerateRegistrationID(using transaction: Any) -> UInt32 {
 | |
|         SSKEnvironment.shared.tsAccountManager.getOrGenerateRegistrationId(transaction as! YapDatabaseReadWriteTransaction)
 | |
|     }
 | |
| 
 | |
|     /// Returns the ID of the thread.
 | |
|     public func getOrCreateThread(for publicKey: String, groupPublicKey: String?, openGroupID: String?, using transaction: Any) -> String? {
 | |
|         let transaction = transaction as! YapDatabaseReadWriteTransaction
 | |
|         var threadOrNil: TSThread?
 | |
|         if let openGroupID = openGroupID {
 | |
|             if let threadID = Storage.shared.getThreadID(for: openGroupID), let thread = TSGroupThread.fetch(uniqueId: threadID, transaction: transaction) {
 | |
|                 threadOrNil = thread
 | |
|             }
 | |
|         } else if let groupPublicKey = groupPublicKey {
 | |
|             guard Storage.shared.isClosedGroup(groupPublicKey) else { return nil }
 | |
|             let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey)
 | |
|             threadOrNil = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID), transaction: transaction)
 | |
|         } else {
 | |
|             threadOrNil = TSContactThread.getOrCreateThread(withContactId: publicKey, transaction: transaction)
 | |
|         }
 | |
|         return threadOrNil?.uniqueId
 | |
|     }
 | |
| 
 | |
|     /// Returns the ID of the `TSIncomingMessage` that was constructed.
 | |
|     public func persist(_ message: VisibleMessage, quotedMessage: TSQuotedMessage?, linkPreview: OWSLinkPreview?, groupPublicKey: String?, openGroupID: String?, using transaction: Any) -> String? {
 | |
|         let transaction = transaction as! YapDatabaseReadWriteTransaction
 | |
|         guard let threadID = getOrCreateThread(for: message.syncTarget ?? message.sender!, groupPublicKey: groupPublicKey, openGroupID: openGroupID, using: transaction),
 | |
|             let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) else { return nil }
 | |
|         let tsMessage: TSMessage
 | |
|         if message.sender == getUserPublicKey() {
 | |
|             let tsOutgoingMessage = TSOutgoingMessage.from(message, associatedWith: thread, using: transaction)
 | |
|             var recipients: [String] = []
 | |
|             if let syncTarget = message.syncTarget {
 | |
|                 recipients.append(syncTarget)
 | |
|             } else if let thread = thread as? TSGroupThread, thread.isClosedGroup {
 | |
|                 recipients = thread.groupModel.groupMemberIds
 | |
|             }
 | |
|             recipients.forEach { recipient in
 | |
|                 tsOutgoingMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction)
 | |
|             }
 | |
|             tsMessage = tsOutgoingMessage
 | |
|         } else {
 | |
|             tsMessage = TSIncomingMessage.from(message, quotedMessage: quotedMessage, linkPreview: linkPreview, associatedWith: thread)
 | |
|         }
 | |
|         tsMessage.save(with: transaction)
 | |
|         tsMessage.attachments(with: transaction).forEach { attachment in
 | |
|             attachment.albumMessageId = tsMessage.uniqueId!
 | |
|             attachment.save(with: transaction)
 | |
|         }
 | |
|         DispatchQueue.main.async { tsMessage.touch() } // FIXME: Hack for a thread updating issue
 | |
|         return tsMessage.uniqueId!
 | |
|     }
 | |
| 
 | |
|     /// Returns the IDs of the saved attachments.
 | |
|     public func persist(_ 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!
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /// Also touches the associated message.
 | |
|     public func setAttachmentState(to state: TSAttachmentPointerState, for pointer: TSAttachmentPointer, associatedWith tsMessageID: String, using transaction: Any) {
 | |
|         let transaction = transaction as! YapDatabaseReadWriteTransaction
 | |
|         // Workaround for some YapDatabase funkiness where pointer at this point can actually be a TSAttachmentStream
 | |
|         guard pointer.responds(to: #selector(setter: TSAttachmentPointer.state)) else { return }
 | |
|         pointer.state = state
 | |
|         pointer.save(with: transaction)
 | |
|         guard let tsMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) else { return }
 | |
|         tsMessage.touch(with: transaction)
 | |
|     }
 | |
|     
 | |
|     /// Also touches the associated message.
 | |
|     public func persist(_ stream: TSAttachmentStream, associatedWith tsMessageID: String, using transaction: Any) {
 | |
|         let transaction = transaction as! YapDatabaseReadWriteTransaction
 | |
|         stream.save(with: transaction)
 | |
|         guard let tsMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) else { return }
 | |
|         tsMessage.touch(with: transaction)
 | |
|     }
 | |
| 
 | |
|     private static let receivedMessageTimestampsCollection = "ReceivedMessageTimestampsCollection"
 | |
| 
 | |
|     public func getReceivedMessageTimestamps(using transaction: Any) -> [UInt64] {
 | |
|         var result: [UInt64] = []
 | |
|         let transaction = transaction as! YapDatabaseReadWriteTransaction
 | |
|         transaction.enumerateRows(inCollection: Storage.receivedMessageTimestampsCollection) { _, object, _, _ in
 | |
|             guard let timestamps = object as? [UInt64] else { return }
 | |
|             result = timestamps
 | |
|         }
 | |
|         return result
 | |
|     }
 | |
|     
 | |
|     public func removeReceivedMessageTimestamps(_ timestamps: Set<UInt64>, using transaction: Any) {
 | |
|         var receivedMessageTimestamps = getReceivedMessageTimestamps(using: transaction)
 | |
|         timestamps.forEach { timestamp in
 | |
|             guard let index = receivedMessageTimestamps.firstIndex(of: timestamp) else { return }
 | |
|             receivedMessageTimestamps.remove(at: index)
 | |
|         }
 | |
|         let transaction = transaction as! YapDatabaseReadWriteTransaction
 | |
|         transaction.setObject(receivedMessageTimestamps, forKey: "receivedMessageTimestamps", inCollection: Storage.receivedMessageTimestampsCollection)
 | |
|     }
 | |
| 
 | |
|     public func addReceivedMessageTimestamp(_ timestamp: UInt64, using transaction: Any) {
 | |
|         var receivedMessageTimestamps = getReceivedMessageTimestamps(using: transaction)
 | |
|         // TODO: Do we need to sort the timestamps here?
 | |
|         if receivedMessageTimestamps.count > 1000 { receivedMessageTimestamps.remove(at: 0) } // Limit the size of the collection to 1000
 | |
|         receivedMessageTimestamps.append(timestamp)
 | |
|         let transaction = transaction as! YapDatabaseReadWriteTransaction
 | |
|         transaction.setObject(receivedMessageTimestamps, forKey: "receivedMessageTimestamps", inCollection: Storage.receivedMessageTimestampsCollection)
 | |
|     }
 | |
| }
 | |
| 
 |