From 2cff251e8d4365ba3e10a095d0a2e2ac7e120b4f Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 3 Oct 2023 13:43:09 +1100 Subject: [PATCH] Fixed a bug with the blocked contacts list Fixed a bug where blocked contacts without profile information wouldn't be included in the blocked contacts list Fixed broken test build issues Increased build and version numbers --- Session.xcodeproj/project.pbxproj | 24 +++---- .../Settings/BlockedContactsViewModel.swift | 71 +++++++++++-------- .../Settings/Views/BlockedContactCell.swift | 7 +- .../Types/PagedDatabaseObserver.swift | 2 +- _SharedTestUtilities/SynchronousStorage.swift | 18 ++++- 5 files changed, 74 insertions(+), 48 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index af3a72fbe..d6ca85f8d 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -6594,7 +6594,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 426; + CURRENT_PROJECT_VERSION = 427; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6618,7 +6618,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6666,7 +6666,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 426; + CURRENT_PROJECT_VERSION = 427; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6695,7 +6695,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6731,7 +6731,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 426; + CURRENT_PROJECT_VERSION = 427; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6754,7 +6754,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -6805,7 +6805,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 426; + CURRENT_PROJECT_VERSION = 427; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6833,7 +6833,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -7765,7 +7765,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 426; + CURRENT_PROJECT_VERSION = 427; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7803,7 +7803,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; @@ -7836,7 +7836,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 426; + CURRENT_PROJECT_VERSION = 427; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7874,7 +7874,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 2.4.2; + MARKETING_VERSION = 2.4.3; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; PRODUCT_NAME = Session; diff --git a/Session/Settings/BlockedContactsViewModel.swift b/Session/Settings/BlockedContactsViewModel.swift index 0a612d0b0..ffbe5b70b 100644 --- a/Session/Settings/BlockedContactsViewModel.swift +++ b/Session/Settings/BlockedContactsViewModel.swift @@ -8,7 +8,7 @@ import SessionUIKit import SignalUtilitiesKit import SessionUtilitiesKit -class BlockedContactsViewModel: SessionTableViewModel { +class BlockedContactsViewModel: SessionTableViewModel { // MARK: - Section public enum Section: SessionTableSection { @@ -39,10 +39,14 @@ class BlockedContactsViewModel: SessionTableViewModel = TypedTableAlias() let contact: TypedTableAlias = TypedTableAlias() + let profile: TypedTableAlias = TypedTableAlias() - return SQL("JOIN \(Contact.self) ON \(contact[.id]) = \(profile[.id])") + return SQL("JOIN \(Profile.self) ON \(profile[.id]) = \(contact[.id])") }() ) ], @@ -101,7 +101,7 @@ class BlockedContactsViewModel: SessionTableViewModel), Never> = CurrentValueSubject(([], StagedChangeset())) private let selectedContactIdsSubject: CurrentValueSubject, Never> = CurrentValueSubject([]) - private var _pagedDataObserver: PagedDatabaseObserver? + private var _pagedDataObserver: PagedDatabaseObserver? public override var pagedDataObserver: TransactionObserver? { _pagedDataObserver } public override var observableTableData: ObservableData { _observableTableData } @@ -138,26 +138,32 @@ class BlockedContactsViewModel: SessionTableViewModel Bool in - lhs.profile.displayName() < rhs.profile.displayName() + let lhsValue: String = (lhs.profile?.displayName() ?? lhs.id) + let rhsValue: String = (rhs.profile?.displayName() ?? rhs.id) + + return (lhsValue < rhsValue) } - .map { [weak self] model -> SessionCell.Info in + .map { [weak self] model -> SessionCell.Info in SessionCell.Info( - id: model.profile, - leftAccessory: .profile(id: model.profile.id, profile: model.profile), - title: model.profile.displayName(), + id: model, + leftAccessory: .profile(id: model.id, profile: model.profile), + title: ( + model.profile?.displayName() ?? + Profile.truncated(id: model.id, truncating: .middle) + ), rightAccessory: .radio( isSelected: { - self?.selectedContactIdsSubject.value.contains(model.profile.id) == true + self?.selectedContactIdsSubject.value.contains(model.id) == true } ), onTap: { var updatedSelectedIds: Set = (self?.selectedContactIdsSubject.value ?? []) - if !updatedSelectedIds.contains(model.profile.id) { - updatedSelectedIds.insert(model.profile.id) + if !updatedSelectedIds.contains(model.id) { + updatedSelectedIds.insert(model.id) } else { - updatedSelectedIds.remove(model.profile.id) + updatedSelectedIds.remove(model.id) } self?.selectedContactIdsSubject.send(updatedSelectedIds) @@ -182,7 +188,7 @@ class BlockedContactsViewModel: SessionTableViewModel = section.elements + let info: SessionCell.Info = section.elements .first(where: { info in info.id.id == contactId }) else { return contactId } @@ -262,20 +268,22 @@ class BlockedContactsViewModel: SessionTableViewModel (([Int64]) -> any FetchRequest) { return { rowIds -> any FetchRequest in + let contact: TypedTableAlias = TypedTableAlias() let profile: TypedTableAlias = TypedTableAlias() /// **Note:** The `numColumnsBeforeProfile` value **MUST** match the number of fields before @@ -283,15 +291,17 @@ class BlockedContactsViewModel: SessionTableViewModel = """ SELECT - \(profile[.rowId]) AS \(DataModel.Columns.rowId), + \(contact[.rowId]) AS \(DataModel.Columns.rowId), + \(contact[.id]), \(profile.allColumns) - FROM \(Profile.self) - WHERE \(profile[.rowId]) IN \(rowIds) + FROM \(Contact.self) + LEFT JOIN \(Profile.self) ON \(profile[.id]) = \(contact[.id]) + WHERE \(contact[.rowId]) IN \(rowIds) ORDER BY \(orderSQL) """ @@ -309,10 +319,10 @@ class BlockedContactsViewModel: SessionTableViewModel = TypedTableAlias() let contact: TypedTableAlias = TypedTableAlias() + let profile: TypedTableAlias = TypedTableAlias() - return SQL("JOIN \(Contact.self) ON \(contact[.id]) = \(profile[.id])") + return SQL("LEFT JOIN \(Profile.self) ON \(profile[.id]) = \(contact[.id])") }() static var filterSQL: SQL = { @@ -322,9 +332,10 @@ class BlockedContactsViewModel: SessionTableViewModel = TypedTableAlias() let profile: TypedTableAlias = TypedTableAlias() - return SQL("IFNULL(IFNULL(\(profile[.nickname]), \(profile[.name])), \(profile[.id])) ASC") + return SQL("IFNULL(IFNULL(\(profile[.nickname]), \(profile[.name])), \(contact[.id])) ASC") }() } diff --git a/Session/Settings/Views/BlockedContactCell.swift b/Session/Settings/Views/BlockedContactCell.swift index 1525895df..92035fc7f 100644 --- a/Session/Settings/Views/BlockedContactCell.swift +++ b/Session/Settings/Views/BlockedContactCell.swift @@ -77,13 +77,16 @@ class BlockedContactCell: UITableViewCell { public func update(with cellViewModel: BlockedContactsViewModel.DataModel, isSelected: Bool) { profilePictureView.update( - publicKey: cellViewModel.profile.id, + publicKey: cellViewModel.id, threadVariant: .contact, customImageData: nil, profile: cellViewModel.profile, additionalProfile: nil ) - selectionView.text = cellViewModel.profile.displayName() + selectionView.text = ( + cellViewModel.profile?.displayName() ?? + Profile.truncated(id: cellViewModel.id, truncating: .middle) + ) selectionView.update(isSelected: isSelected) } } diff --git a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift index 6848bce11..5d59af0c4 100644 --- a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift +++ b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift @@ -11,7 +11,7 @@ import DifferenceKit /// **Note:** We **MUST** have accurate `filterSQL` and `orderSQL` values otherwise the indexing won't work public class PagedDatabaseObserver: TransactionObserver where ObservedTable: TableRecord & ColumnExpressible & Identifiable, T: FetchableRecordWithRowId & Identifiable { private let commitProcessingQueue: DispatchQueue = DispatchQueue( - label: "PagedDatabaseObserver.commitProcessingQueue", + label: "PagedDatabaseObserver.commitProcessingQueue", // stringlint:disable qos: .userInitiated, attributes: [] // Must be serial in order to avoid updates getting processed in the wrong order ) diff --git a/_SharedTestUtilities/SynchronousStorage.swift b/_SharedTestUtilities/SynchronousStorage.swift index 66680cd2e..dd956df08 100644 --- a/_SharedTestUtilities/SynchronousStorage.swift +++ b/_SharedTestUtilities/SynchronousStorage.swift @@ -43,8 +43,11 @@ class SynchronousStorage: Storage { } @discardableResult override func read( + fileName: String = #file, + functionName: String = #function, + lineNumber: Int = #line, using dependencies: Dependencies = Dependencies(), - _ value: (Database) throws -> T? + _ value: @escaping (Database) throws -> T? ) -> T? { guard isValid, let dbWriter: DatabaseWriter = testDbWriter else { return nil } @@ -56,16 +59,25 @@ class SynchronousStorage: Storage { return try? dbWriter.unsafeReentrantRead(value) } - return super.read(using: dependencies, value) + return super.read( + fileName: fileName, + functionName: functionName, + lineNumber: lineNumber, + using: dependencies, + value + ) } // MARK: - Async Methods override func readPublisher( + fileName: String = #file, + functionName: String = #function, + lineNumber: Int = #line, using dependencies: Dependencies = Dependencies(), value: @escaping (Database) throws -> T ) -> AnyPublisher { - guard let result: T = self.read(using: dependencies, value) else { + guard let result: T = self.read(fileName: fileName, functionName: functionName, lineNumber: lineNumber, using: dependencies, value) else { return Fail(error: StorageError.generic) .eraseToAnyPublisher() }