diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index 4c140aea9..589f1f5a0 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -6,10 +6,8 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv private var threads: YapDatabaseViewMappings! private var threadViewModelCache: [String:ThreadViewModel] = [:] // Thread ID to ThreadViewModel private var tableViewTopConstraint: NSLayoutConstraint! - private var unreadMessageRequestCount: UInt = 0 - - private var messageRequestCount: UInt { - threads.numberOfItems(inGroup: TSMessageRequestGroup) + private var unreadMessageRequestCount: UInt { + OWSMessageUtils.sharedManager().unreadMessageRequestCount() } private var threadCount: UInt { @@ -182,7 +180,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch section { case 0: - if messageRequestCount > 0 && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] { + if unreadMessageRequestCount > 0 && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] { return 1 } @@ -264,9 +262,6 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv } } - // Update the number of unread message requests - unreadMessageRequestCount = OWSMessageUtils.sharedManager().unreadMessageRequestCount() - // If there are no unread message requests then hide the message request banner if unreadMessageRequestCount == 0 { CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] = true @@ -295,8 +290,6 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv // If we need to unhide the message request row and then re-insert it if !messageRequestChanges.isEmpty { - // Update the number of unread message requests - unreadMessageRequestCount = OWSMessageUtils.sharedManager().unreadMessageRequestCount() // If there are no unread message requests then hide the message request banner if unreadMessageRequestCount == 0 && tableView.numberOfRows(inSection: 0) == 1 { @@ -304,10 +297,10 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .automatic) } else { - if tableView.numberOfRows(inSection: 0) == 1 && Int(messageRequestCount) <= 0 { + if tableView.numberOfRows(inSection: 0) == 1 && Int(unreadMessageRequestCount) <= 0 { tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .automatic) } - else if tableView.numberOfRows(inSection: 0) == 0 && Int(messageRequestCount) > 0 && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] { + else if tableView.numberOfRows(inSection: 0) == 0 && Int(unreadMessageRequestCount) > 0 && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] { tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .automatic) } } diff --git a/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage+Convenience.swift b/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage+Convenience.swift index ba7c9b485..7bc727311 100644 --- a/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage+Convenience.swift +++ b/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage+Convenience.swift @@ -1,3 +1,4 @@ +import SessionUtilitiesKit extension ConfigurationMessage { @@ -10,8 +11,7 @@ extension ConfigurationMessage { let profileKey = user.profileEncryptionKey?.keyData var closedGroups: Set = [] var openGroups: Set = [] - var contacts: Set = [] - var contactCount = 0 + var contacts: Set = [] let populateDataClosure: (YapDatabaseReadTransaction) -> () = { transaction in TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in @@ -48,47 +48,48 @@ extension ConfigurationMessage { } let currentUserPublicKey: String = getUserHexEncodedPublicKey() - var truncatedContacts = storage.getAllContacts(with: transaction) - if truncatedContacts.count > 200 { - truncatedContacts = Set(Array(truncatedContacts)[0..<200]) - } - - truncatedContacts.forEach { contact in - let publicKey = contact.sessionID - let threadID = TSContactThread.threadID(fromContactSessionID: publicKey) - - // Want to sync contacts for visible threads and blocked contacts between devices - guard - publicKey != currentUserPublicKey && ( - TSContactThread.fetch(uniqueId: threadID, transaction: transaction)?.shouldBeVisible == true || - SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(publicKey) + contacts = storage.getAllContacts(with: transaction) + .filter { contact -> Bool in + let threadID = TSContactThread.threadID(fromContactSessionID: contact.sessionID) + + return ( + // Skip the current user + contact.sessionID != currentUserPublicKey && ( + + // Include already approved contacts + contact.isApproved || + contact.didApproveMe || + + // Sync blocked contacts + SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(contact.sessionID) || + + // Contacts which have visible threads (sanity check - should be included as already approved) + TSContactThread.fetch(uniqueId: threadID, transaction: transaction)?.shouldBeVisible == true + ) ) - else { - return } - - // Can just default the 'hasX' values to true as they will be set to this - // when converting to proto anyway - let profilePictureURL = contact.profilePictureURL - let profileKey = contact.profileEncryptionKey?.keyData - let contact = ConfigurationMessage.Contact( - publicKey: publicKey, - displayName: (contact.name ?? publicKey), - profilePictureURL: profilePictureURL, - profileKey: profileKey, - hasIsApproved: true, - isApproved: contact.isApproved, - hasIsBlocked: true, - isBlocked: contact.isBlocked, - hasDidApproveMe: true, - didApproveMe: contact.didApproveMe - ) - - contacts.insert(contact) - contactCount += 1 + .map { contact -> ConfigurationMessage.Contact in + // Can just default the 'hasX' values to true as they will be set to this + // when converting to proto anyway + let profilePictureURL = contact.profilePictureURL + let profileKey = contact.profileEncryptionKey?.keyData + + return ConfigurationMessage.Contact( + publicKey: contact.sessionID, + displayName: (contact.name ?? contact.sessionID), + profilePictureURL: profilePictureURL, + profileKey: profileKey, + hasIsApproved: true, + isApproved: contact.isApproved, + hasIsBlocked: true, + isBlocked: contact.isBlocked, + hasDidApproveMe: true, + didApproveMe: contact.didApproveMe + ) + } + .asSet() } - } // If we are provided with a transaction then read the data based on the state of the database // from within the transaction rather than the state in disk diff --git a/SessionMessagingKit/Utilities/ContactUtilities.swift b/SessionMessagingKit/Utilities/ContactUtilities.swift index 12de6d358..751a55e0a 100644 --- a/SessionMessagingKit/Utilities/ContactUtilities.swift +++ b/SessionMessagingKit/Utilities/ContactUtilities.swift @@ -16,6 +16,7 @@ public enum ContactUtilities { // Collect all contacts var result: [Contact] = [] Storage.read { transaction in + // FIXME: If a user deletes a contact thread they will no longer appear in this list (ie. won't be an option for closed group conversations) TSContactThread.enumerateCollectionObjects(with: transaction) { object, _ in guard let contact: Contact = approvedContact(in: object, using: transaction) else { return } diff --git a/SessionUtilitiesKit/General/Array+Utilities.swift b/SessionUtilitiesKit/General/Array+Utilities.swift index 3a22fc210..0b4d8b7fd 100644 --- a/SessionUtilitiesKit/General/Array+Utilities.swift +++ b/SessionUtilitiesKit/General/Array+Utilities.swift @@ -6,18 +6,8 @@ public extension Array where Element : CustomStringConvertible { } } -public extension Array { - func appending(_ other: Element) -> [Element] { - var updatedArray: [Element] = self - updatedArray.append(other) - - return updatedArray - } - - func appending(_ other: [Element]) -> [Element] { - var updatedArray: [Element] = self - updatedArray.append(contentsOf: other) - - return updatedArray +public extension Array where Element: Hashable { + func asSet() -> Set { + return Set(self) } }