Merge pull request #402 from oxen-io/deletion-handling
Fix Deletion Handling Corner Case
This commit is contained in:
commit
2e9eb3b925
|
@ -178,7 +178,6 @@ extension Storage {
|
|||
// MARK: - Metadata
|
||||
|
||||
private static let openGroupUserCountCollection = "SNOpenGroupUserCountCollection"
|
||||
private static let openGroupMessageIDCollection = "LKMessageIDCollection"
|
||||
private static let openGroupImageCollection = "SNOpenGroupImageCollection"
|
||||
|
||||
public func getUserCount(forV2OpenGroupWithID openGroupID: String) -> UInt64? {
|
||||
|
@ -192,18 +191,6 @@ extension Storage {
|
|||
public func setUserCount(to newValue: UInt64, forV2OpenGroupWithID openGroupID: String, using transaction: Any) {
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: openGroupID, inCollection: Storage.openGroupUserCountCollection)
|
||||
}
|
||||
|
||||
public func getIDForMessage(withServerID serverID: UInt64) -> String? {
|
||||
var result: String? = nil
|
||||
Storage.read { transaction in
|
||||
result = transaction.object(forKey: String(serverID), inCollection: Storage.openGroupMessageIDCollection) as? String
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func setIDForMessage(withServerID serverID: UInt64, to messageID: String, using transaction: Any) {
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(messageID, forKey: String(serverID), inCollection: Storage.openGroupMessageIDCollection)
|
||||
}
|
||||
|
||||
public func setLastProfilePictureUploadDate(_ date: Date) {
|
||||
UserDefaults.standard[.lastProfilePictureUpload] = date
|
||||
|
|
|
@ -121,11 +121,6 @@ public final class OpenGroupAPI : DotNetAPI {
|
|||
SNLog("Ignoring open group message with invalid signature.")
|
||||
return nil
|
||||
}
|
||||
let existingMessageID = storage.getIDForMessage(withServerID: result.serverID!)
|
||||
guard existingMessageID == nil else {
|
||||
SNLog("Ignoring duplicate open group message.")
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
}.sorted { $0.serverTimestamp < $1.serverTimestamp}
|
||||
}
|
||||
|
|
|
@ -294,8 +294,9 @@ extension MessageReceiver {
|
|||
cancelTypingIndicatorsIfNeeded(for: message.sender!)
|
||||
}
|
||||
// Keep track of the open group server message ID ↔ message ID relationship
|
||||
if let serverID = message.openGroupServerMessageID {
|
||||
storage.setIDForMessage(withServerID: serverID, to: tsMessageID, using: transaction)
|
||||
if let serverID = message.openGroupServerMessageID, let tsMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) {
|
||||
tsMessage.openGroupServerMessageID = serverID
|
||||
tsMessage.save(with: transaction)
|
||||
}
|
||||
// Notify the user if needed
|
||||
guard (isMainAppAndActive || isBackgroundPoll), let tsIncomingMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) as? TSIncomingMessage,
|
||||
|
|
|
@ -350,7 +350,6 @@ public final class MessageSender : NSObject {
|
|||
|
||||
// MARK: Success & Failure Handling
|
||||
public static func handleSuccessfulMessageSend(_ message: Message, to destination: Message.Destination, isSyncMessage: Bool = false, using transaction: Any) {
|
||||
let storage = SNMessagingKitConfiguration.shared.storage
|
||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||
// Ignore future self-sends
|
||||
Storage.shared.addReceivedMessageTimestamp(message.sentTimestamp!, using: transaction)
|
||||
|
@ -359,9 +358,6 @@ public final class MessageSender : NSObject {
|
|||
// Track the open group server message ID
|
||||
tsMessage.openGroupServerMessageID = message.openGroupServerMessageID ?? 0
|
||||
tsMessage.save(with: transaction)
|
||||
if let serverID = message.openGroupServerMessageID {
|
||||
storage.setIDForMessage(withServerID: serverID, to: tsMessage.uniqueId!, using: transaction)
|
||||
}
|
||||
// Mark the message as sent
|
||||
var recipients = [ message.recipient! ]
|
||||
if case .closedGroup(_) = destination, let threadID = message.threadID, // threadID should always be set at this point
|
||||
|
|
|
@ -176,13 +176,18 @@ public final class OpenGroupPoller : NSObject {
|
|||
|
||||
private func pollForDeletedMessages() {
|
||||
let openGroup = self.openGroup
|
||||
let storage = SNMessagingKitConfiguration.shared.storage
|
||||
OpenGroupAPI.getDeletedMessageServerIDs(for: openGroup.channel, on: openGroup.server).done(on: DispatchQueue.global(qos: .default)) { deletedMessageServerIDs in
|
||||
let deletedMessageIDs = deletedMessageServerIDs.compactMap { Storage.shared.getIDForMessage(withServerID: UInt64($0)) }
|
||||
SNMessagingKitConfiguration.shared.storage.write { transaction in
|
||||
deletedMessageIDs.forEach { messageID in
|
||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||
TSMessage.fetch(uniqueId: messageID, transaction: transaction)?.remove(with: transaction)
|
||||
storage.write { transaction in
|
||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||
guard let threadID = storage.getThreadID(for: openGroup.id),
|
||||
let thread = TSGroupThread.fetch(uniqueId: threadID, transaction: transaction) else { return }
|
||||
var messagesToRemove: [TSMessage] = []
|
||||
thread.enumerateInteractions(with: transaction) { interaction, stop in
|
||||
guard let message = interaction as? TSMessage, deletedMessageServerIDs.contains(message.openGroupServerMessageID) else { return }
|
||||
messagesToRemove.append(message)
|
||||
}
|
||||
messagesToRemove.forEach { $0.remove(with: transaction) }
|
||||
}
|
||||
}.retainUntilComplete()
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public final class OpenGroupPollerV2 : NSObject {
|
|||
}
|
||||
|
||||
private func handleCompactPollBody(_ body: OpenGroupAPIV2.CompactPollResponseBody, isBackgroundPoll: Bool) {
|
||||
let storage = SNMessagingKitConfiguration.shared.storage
|
||||
// - Messages
|
||||
// Sorting the messages by server ID before importing them fixes an issue where messages that quote older messages can't find those older messages
|
||||
let openGroupID = "\(server).\(body.room)"
|
||||
|
@ -80,17 +81,22 @@ public final class OpenGroupPollerV2 : NSObject {
|
|||
envelope.setSource(message.sender!) // Safe because messages with a nil sender are filtered out
|
||||
envelope.setServerTimestamp(message.sentTimestamp)
|
||||
let job = MessageReceiveJob(data: try! envelope.buildSerializedData(), openGroupMessageServerID: UInt64(message.serverID!), openGroupID: openGroupID, isBackgroundPoll: isBackgroundPoll)
|
||||
SNMessagingKitConfiguration.shared.storage.write { transaction in
|
||||
storage.write { transaction in
|
||||
SessionMessagingKit.JobQueue.shared.add(job, using: transaction)
|
||||
}
|
||||
}
|
||||
// - Deletions
|
||||
let deletedMessageIDs = body.deletions.compactMap { Storage.shared.getIDForMessage(withServerID: UInt64($0.deletedMessageID)) }
|
||||
SNMessagingKitConfiguration.shared.storage.write { transaction in
|
||||
let deletedMessageServerIDs = Set(body.deletions.map { UInt64($0.deletedMessageID) })
|
||||
storage.write { transaction in
|
||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||
deletedMessageIDs.forEach { messageID in
|
||||
TSMessage.fetch(uniqueId: messageID, transaction: transaction)?.remove(with: transaction)
|
||||
guard let threadID = storage.v2GetThreadID(for: openGroupID),
|
||||
let thread = TSGroupThread.fetch(uniqueId: threadID, transaction: transaction) else { return }
|
||||
var messagesToRemove: [TSMessage] = []
|
||||
thread.enumerateInteractions(with: transaction) { interaction, stop in
|
||||
guard let message = interaction as? TSMessage, deletedMessageServerIDs.contains(message.openGroupServerMessageID) else { return }
|
||||
messagesToRemove.append(message)
|
||||
}
|
||||
messagesToRemove.forEach { $0.remove(with: transaction) }
|
||||
}
|
||||
// - Moderators
|
||||
if var x = OpenGroupAPIV2.moderators[server] {
|
||||
|
|
|
@ -47,6 +47,7 @@ public protocol SessionMessagingKitStorageProtocol {
|
|||
|
||||
func getAllV2OpenGroups() -> [String:OpenGroupV2]
|
||||
func getV2OpenGroup(for threadID: String) -> OpenGroupV2?
|
||||
func v2GetThreadID(for v2OpenGroupID: String) -> String?
|
||||
func getThreadID(for openGroupID: String) -> String?
|
||||
func updateMessageIDCollectionByPruningMessagesWithIDs(_ messageIDs: Set<String>, using transaction: Any)
|
||||
|
||||
|
@ -70,8 +71,6 @@ public protocol SessionMessagingKitStorageProtocol {
|
|||
// MARK: - Open Group Metadata
|
||||
|
||||
func setUserCount(to newValue: UInt64, forV2OpenGroupWithID openGroupID: String, using transaction: Any)
|
||||
func getIDForMessage(withServerID serverID: UInt64) -> String?
|
||||
func setIDForMessage(withServerID serverID: UInt64, to messageID: String, using transaction: Any)
|
||||
func setOpenGroupDisplayName(to displayName: String, for publicKey: String, inOpenGroupWithID openGroupID: String, using transaction: Any)
|
||||
func setLastProfilePictureUploadDate(_ date: Date) // Stored in user defaults so no transaction is needed
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ BOOL IsNoteToSelfEnabled(void);
|
|||
|
||||
#pragma mark Interactions
|
||||
|
||||
- (void)enumerateInteractionsWithTransaction:(YapDatabaseReadTransaction *)transaction usingBlock:(void (^)(TSInteraction *interaction, YapDatabaseReadTransaction *transaction))block;
|
||||
- (void)enumerateInteractionsWithTransaction:(YapDatabaseReadTransaction *)transaction usingBlock:(void (^)(TSInteraction *interaction, BOOL *stop))block;
|
||||
|
||||
- (void)enumerateInteractionsUsingBlock:(void (^)(TSInteraction *interaction))block;
|
||||
|
||||
|
|
|
@ -158,15 +158,14 @@ BOOL IsNoteToSelfEnabled(void)
|
|||
* Iterate over this thread's interactions
|
||||
*/
|
||||
- (void)enumerateInteractionsWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||
usingBlock:(void (^)(TSInteraction *interaction,
|
||||
YapDatabaseReadTransaction *transaction))block
|
||||
usingBlock:(void (^)(TSInteraction *interaction, BOOL *stop))block
|
||||
{
|
||||
YapDatabaseViewTransaction *interactionsByThread = [transaction ext:TSMessageDatabaseViewExtensionName];
|
||||
[interactionsByThread
|
||||
enumerateKeysAndObjectsInGroup:self.uniqueId
|
||||
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
|
||||
TSInteraction *interaction = object;
|
||||
block(interaction, transaction);
|
||||
block(interaction, stop);
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -179,7 +178,7 @@ BOOL IsNoteToSelfEnabled(void)
|
|||
[self.dbReadWriteConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
[self enumerateInteractionsWithTransaction:transaction
|
||||
usingBlock:^(
|
||||
TSInteraction *interaction, YapDatabaseReadTransaction *t) {
|
||||
TSInteraction *interaction, BOOL *stop) {
|
||||
|
||||
block(interaction);
|
||||
}];
|
||||
|
|
Loading…
Reference in New Issue