diff --git a/Signal/src/Models/ThreadMapping.swift b/Signal/src/Models/ThreadMapping.swift index ff0bae1371..524d3b5d9b 100644 --- a/Signal/src/Models/ThreadMapping.swift +++ b/Signal/src/Models/ThreadMapping.swift @@ -136,10 +136,10 @@ class ThreadMapping: NSObject { } func update(isViewingArchive: Bool, transaction: SDSAnyReadTransaction) throws { - archiveCount = try threadFinder.threadCount(isArchived: true, transaction: transaction) - inboxCount = try threadFinder.threadCount(isArchived: false, transaction: transaction) + archiveCount = try threadFinder.visibleThreadCount(isArchived: true, transaction: transaction) + inboxCount = try threadFinder.visibleThreadCount(isArchived: false, transaction: transaction) var newThreads: [TSThread] = [] - try threadFinder.enumerateThreads(isArchived: isViewingArchive, transaction: transaction) { thread in + try threadFinder.enumerateVisibleThreads(isArchived: isViewingArchive, transaction: transaction) { thread in newThreads.append(thread) } threads = newThreads diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index 1e8f869caf..fe657b1475 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -391,7 +391,16 @@ isArchivedByLegacyTimestampForSorting:(BOOL)isArchivedByLegacyTimestampForSortin { OWSAssertDebug(interaction); + if (!interaction.shouldBeSaved) { + OWSFailDebug(@"Unexpected interaction type: %@", interaction.class); + return NO; + } if (interaction.isDynamicInteraction) { + OWSFailDebug(@"Unexpected interaction type: %@", interaction.class); + return NO; + } + if ([interaction isKindOfClass:[OWSOutgoingSyncMessage class]]) { + OWSFailDebug(@"Unexpected interaction type: %@", interaction.class); return NO; } diff --git a/SignalServiceKit/src/SignalServiceKit.h b/SignalServiceKit/src/SignalServiceKit.h index 1abfb09b56..87d1b7a9f1 100644 --- a/SignalServiceKit/src/SignalServiceKit.h +++ b/SignalServiceKit/src/SignalServiceKit.h @@ -21,6 +21,7 @@ #import #import #import +#import #import #import #import diff --git a/SignalServiceKit/src/Storage/Database/Records/ThreadFinder.swift b/SignalServiceKit/src/Storage/Database/Records/ThreadFinder.swift index 4d2a635428..ba137d4766 100644 --- a/SignalServiceKit/src/Storage/Database/Records/ThreadFinder.swift +++ b/SignalServiceKit/src/Storage/Database/Records/ThreadFinder.swift @@ -8,8 +8,8 @@ import GRDBCipher public protocol ThreadFinder { associatedtype ReadTransaction - func threadCount(isArchived: Bool, transaction: ReadTransaction) throws -> UInt - func enumerateThreads(isArchived: Bool, transaction: ReadTransaction, block: @escaping (TSThread) -> Void) throws + func visibleThreadCount(isArchived: Bool, transaction: ReadTransaction) throws -> UInt + func enumerateVisibleThreads(isArchived: Bool, transaction: ReadTransaction, block: @escaping (TSThread) -> Void) throws } public class AnyThreadFinder: ThreadFinder { @@ -20,21 +20,21 @@ public class AnyThreadFinder: ThreadFinder { public init() { } - public func threadCount(isArchived: Bool, transaction: SDSAnyReadTransaction) throws -> UInt { + public func visibleThreadCount(isArchived: Bool, transaction: SDSAnyReadTransaction) throws -> UInt { switch transaction.readTransaction { case .grdbRead(let grdb): - return try grdbAdapter.threadCount(isArchived: isArchived, transaction: grdb.database) + return try grdbAdapter.visibleThreadCount(isArchived: isArchived, transaction: grdb.database) case .yapRead(let yap): - return yapAdapter.threadCount(isArchived: isArchived, transaction: yap) + return yapAdapter.visibleThreadCount(isArchived: isArchived, transaction: yap) } } - public func enumerateThreads(isArchived: Bool, transaction: SDSAnyReadTransaction, block: @escaping (TSThread) -> Void) throws { + public func enumerateVisibleThreads(isArchived: Bool, transaction: SDSAnyReadTransaction, block: @escaping (TSThread) -> Void) throws { switch transaction.readTransaction { case .grdbRead(let grdb): - try grdbAdapter.enumerateThreads(isArchived: isArchived, transaction: grdb.database, block: block) + try grdbAdapter.enumerateVisibleThreads(isArchived: isArchived, transaction: grdb.database, block: block) case .yapRead(let yap): - yapAdapter.enumerateThreads(isArchived: isArchived, transaction: yap, block: block) + yapAdapter.enumerateVisibleThreads(isArchived: isArchived, transaction: yap, block: block) } } } @@ -42,14 +42,14 @@ public class AnyThreadFinder: ThreadFinder { struct YAPDBThreadFinder: ThreadFinder { typealias ReadTransaction = YapDatabaseReadTransaction - func threadCount(isArchived: Bool, transaction: YapDatabaseReadTransaction) -> UInt { + func visibleThreadCount(isArchived: Bool, transaction: YapDatabaseReadTransaction) -> UInt { guard let view = ext(transaction) else { return 0 } return view.numberOfItems(inGroup: group(isArchived: isArchived)) } - func enumerateThreads(isArchived: Bool, transaction: YapDatabaseReadTransaction, block: @escaping (TSThread) -> Void) { + func enumerateVisibleThreads(isArchived: Bool, transaction: YapDatabaseReadTransaction, block: @escaping (TSThread) -> Void) { guard let view = ext(transaction) else { return } @@ -82,11 +82,12 @@ struct GRDBThreadFinder: ThreadFinder { static let cn = ThreadRecord.columnName - func threadCount(isArchived: Bool, transaction: Database) throws -> UInt { + func visibleThreadCount(isArchived: Bool, transaction: Database) throws -> UInt { guard let count = try UInt.fetchOne(transaction, sql: """ SELECT COUNT(*) FROM ( SELECT + \( threadColumn: .shouldThreadBeVisible), CASE maxInteractionId <= \(threadColumn: .archivedAsOfMessageSortId) WHEN 1 THEN 1 ELSE 0 @@ -102,16 +103,17 @@ struct GRDBThreadFinder: ThreadFinder { ON latestInteractions.\(interactionColumn: .threadUniqueId) = \(threadColumn: .uniqueId) ) WHERE isArchived = ? - """, - arguments: [isArchived]) else { - owsFailDebug("count was unexpectedly nil") - return 0 + AND \(threadColumn: .shouldThreadBeVisible) = 1 + """, + arguments: [isArchived]) else { + owsFailDebug("count was unexpectedly nil") + return 0 } return count } - func enumerateThreads(isArchived: Bool, transaction: Database, block: @escaping (TSThread) -> Void) throws { + func enumerateVisibleThreads(isArchived: Bool, transaction: Database, block: @escaping (TSThread) -> Void) throws { try ThreadRecord.fetchCursor(transaction, sql: """ SELECT * FROM ( @@ -133,9 +135,10 @@ struct GRDBThreadFinder: ThreadFinder { ORDER BY maxInteractionId DESC ) WHERE isArchived = ? - """, - arguments: [isArchived]).forEach { threadRecord in - block(try TSThread.fromRecord(threadRecord)) + AND \( threadColumn: .shouldThreadBeVisible) = 1 + """, + arguments: [isArchived]).forEach { threadRecord in + block(try TSThread.fromRecord(threadRecord)) } } } diff --git a/SignalServiceKit/src/Storage/TSDatabaseView.m b/SignalServiceKit/src/Storage/TSDatabaseView.m index c914c21211..c07f6459c9 100644 --- a/SignalServiceKit/src/Storage/TSDatabaseView.m +++ b/SignalServiceKit/src/Storage/TSDatabaseView.m @@ -319,10 +319,12 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup" OWSAssertDebug(viewTransaction); NSUInteger threadMessageCount = [viewTransaction numberOfItemsInGroup:thread.uniqueId]; if (threadMessageCount < 1) { + OWSAssertDebug(!thread.shouldThreadBeVisible); return nil; } } + OWSAssertDebug(thread.shouldThreadBeVisible); return [thread isArchivedWithTransaction:transaction.asAnyRead] ? TSArchiveGroup : TSInboxGroup; }];