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
This commit is contained in:
parent
4a95b4c921
commit
2cff251e8d
|
@ -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;
|
||||
|
|
|
@ -8,7 +8,7 @@ import SessionUIKit
|
|||
import SignalUtilitiesKit
|
||||
import SessionUtilitiesKit
|
||||
|
||||
class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsViewModel.Section, Profile> {
|
||||
class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsViewModel.Section, BlockedContactsViewModel.DataModel> {
|
||||
// MARK: - Section
|
||||
|
||||
public enum Section: SessionTableSection {
|
||||
|
@ -39,10 +39,14 @@ class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsView
|
|||
// doesn't stutter (it should load basically immediately but without this there is a
|
||||
// distinct stutter)
|
||||
_pagedDataObserver = PagedDatabaseObserver(
|
||||
pagedTable: Profile.self,
|
||||
pagedTable: Contact.self,
|
||||
pageSize: BlockedContactsViewModel.pageSize,
|
||||
idColumn: .id,
|
||||
observedChanges: [
|
||||
PagedData.ObservedChanges(
|
||||
table: Contact.self,
|
||||
columns: [.id, .isBlocked]
|
||||
),
|
||||
PagedData.ObservedChanges(
|
||||
table: Profile.self,
|
||||
columns: [
|
||||
|
@ -50,16 +54,12 @@ class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsView
|
|||
.name,
|
||||
.nickname,
|
||||
.profilePictureFileName
|
||||
]
|
||||
),
|
||||
PagedData.ObservedChanges(
|
||||
table: Contact.self,
|
||||
columns: [.isBlocked],
|
||||
],
|
||||
joinToPagedType: {
|
||||
let profile: TypedTableAlias<Profile> = TypedTableAlias()
|
||||
let contact: TypedTableAlias<Contact> = TypedTableAlias()
|
||||
let profile: TypedTableAlias<Profile> = 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<NoNav, BlockedContactsView
|
|||
|
||||
private let contactDataSubject: CurrentValueSubject<([SectionModel], StagedChangeset<[SectionModel]>), Never> = CurrentValueSubject(([], StagedChangeset()))
|
||||
private let selectedContactIdsSubject: CurrentValueSubject<Set<String>, Never> = CurrentValueSubject([])
|
||||
private var _pagedDataObserver: PagedDatabaseObserver<Profile, DataModel>?
|
||||
private var _pagedDataObserver: PagedDatabaseObserver<Contact, DataModel>?
|
||||
public override var pagedDataObserver: TransactionObserver? { _pagedDataObserver }
|
||||
|
||||
public override var observableTableData: ObservableData { _observableTableData }
|
||||
|
@ -138,26 +138,32 @@ class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsView
|
|||
section: .contacts,
|
||||
elements: data
|
||||
.sorted { lhs, rhs -> 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<Profile> in
|
||||
.map { [weak self] model -> SessionCell.Info<DataModel> 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<String> = (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<NoNav, BlockedContactsView
|
|||
guard
|
||||
let section: BlockedContactsViewModel.SectionModel = self.tableData
|
||||
.first(where: { section in section.model == .contacts }),
|
||||
let info: SessionCell.Info<Profile> = section.elements
|
||||
let info: SessionCell.Info<DataModel> = section.elements
|
||||
.first(where: { info in info.id.id == contactId })
|
||||
else { return contactId }
|
||||
|
||||
|
@ -262,20 +268,22 @@ class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsView
|
|||
public typealias Columns = CodingKeys
|
||||
public enum CodingKeys: String, CodingKey, ColumnExpression, CaseIterable {
|
||||
case rowId
|
||||
case id
|
||||
case profile
|
||||
}
|
||||
|
||||
public var differenceIdentifier: String { profile.id }
|
||||
public var id: String { profile.id }
|
||||
public var differenceIdentifier: String { id }
|
||||
|
||||
public let rowId: Int64
|
||||
public let profile: Profile
|
||||
public let id: String
|
||||
public let profile: Profile?
|
||||
|
||||
static func query(
|
||||
filterSQL: SQL,
|
||||
orderSQL: SQL
|
||||
) -> (([Int64]) -> any FetchRequest<DataModel>) {
|
||||
return { rowIds -> any FetchRequest<DataModel> in
|
||||
let contact: TypedTableAlias<Contact> = TypedTableAlias()
|
||||
let profile: TypedTableAlias<Profile> = TypedTableAlias()
|
||||
|
||||
/// **Note:** The `numColumnsBeforeProfile` value **MUST** match the number of fields before
|
||||
|
@ -283,15 +291,17 @@ class BlockedContactsViewModel: SessionTableViewModel<NoNav, BlockedContactsView
|
|||
/// parse and might throw
|
||||
///
|
||||
/// Explicitly set default values for the fields ignored for search results
|
||||
let numColumnsBeforeProfile: Int = 1
|
||||
let numColumnsBeforeProfile: Int = 2
|
||||
|
||||
let request: SQLRequest<DataModel> = """
|
||||
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<NoNav, BlockedContactsView
|
|||
}
|
||||
|
||||
static var optimisedJoinSQL: SQL = {
|
||||
let profile: TypedTableAlias<Profile> = TypedTableAlias()
|
||||
let contact: TypedTableAlias<Contact> = TypedTableAlias()
|
||||
let profile: TypedTableAlias<Profile> = 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<NoNav, BlockedContactsView
|
|||
}()
|
||||
|
||||
static let orderSQL: SQL = {
|
||||
let contact: TypedTableAlias<Contact> = TypedTableAlias()
|
||||
let profile: TypedTableAlias<Profile> = TypedTableAlias()
|
||||
|
||||
return SQL("IFNULL(IFNULL(\(profile[.nickname]), \(profile[.name])), \(profile[.id])) ASC")
|
||||
return SQL("IFNULL(IFNULL(\(profile[.nickname]), \(profile[.name])), \(contact[.id])) ASC")
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import DifferenceKit
|
|||
/// **Note:** We **MUST** have accurate `filterSQL` and `orderSQL` values otherwise the indexing won't work
|
||||
public class PagedDatabaseObserver<ObservedTable, T>: 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
|
||||
)
|
||||
|
|
|
@ -43,8 +43,11 @@ class SynchronousStorage: Storage {
|
|||
}
|
||||
|
||||
@discardableResult override func read<T>(
|
||||
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<T>(
|
||||
fileName: String = #file,
|
||||
functionName: String = #function,
|
||||
lineNumber: Int = #line,
|
||||
using dependencies: Dependencies = Dependencies(),
|
||||
value: @escaping (Database) throws -> T
|
||||
) -> AnyPublisher<T, Error> {
|
||||
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()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue