mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Changed the min OS version to iOS 13.0 (support for 'Identifiable') Removed the alternate approaches to fetching the userKeyPair and userPublicKeyHexString (no consistently routed through the caching method) Migrated the 'OWSIdentityManager' logic to use the new 'Identity' type Added the 'Setting' table and got the pattern working fairly nicely (unfortunately there isn't a good way to avoid key collision without proper enums) Updated the SessionSnodeKit to migration it's data from YDB to GRDB Updated the SessionSnodeKit to use GRDB throughout it's logic
116 lines
6.6 KiB
Swift
116 lines
6.6 KiB
Swift
import PromiseKit
|
|
|
|
extension Storage {
|
|
|
|
/// 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.v2GetThreadID(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(withContactSessionID: 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 == getUserHexEncodedPublicKey() {
|
|
if TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) != nil { return nil }
|
|
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 {
|
|
if thread.isClosedGroup { recipients = thread.groupModel.groupMemberIds }
|
|
else { recipients.append(LKGroupUtilities.getDecodedGroupID(thread.groupModel.groupId)) }
|
|
}
|
|
recipients.forEach { recipient in
|
|
tsOutgoingMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction)
|
|
}
|
|
tsMessage = tsOutgoingMessage
|
|
} else {
|
|
if TSIncomingMessage.find(withAuthorId: message.sender!, timestamp: message.sentTimestamp!, transaction: transaction) != nil { return nil }
|
|
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)
|
|
}
|
|
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 }
|
|
MessageInvalidator.invalidate(tsMessage, 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 }
|
|
MessageInvalidator.invalidate(tsMessage, 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)
|
|
}
|
|
}
|
|
|