Merge branch 'charlesmchen/searchImprovements'
This commit is contained in:
commit
b2063352d5
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@ -257,7 +257,8 @@ public class FullTextSearcher: NSObject {
|
||||
maxResults: UInt = kDefaultMaxResults,
|
||||
transaction: SDSAnyReadTransaction) -> ComposeScreenSearchResultSet {
|
||||
|
||||
var signalContacts: [ContactSearchResult] = []
|
||||
var signalContactMap = [SignalServiceAddress: ContactSearchResult]()
|
||||
var signalRecipentResults: [ContactSearchResult] = []
|
||||
var groups: [GroupSearchResult] = []
|
||||
|
||||
var count: UInt = 0
|
||||
@ -272,7 +273,16 @@ public class FullTextSearcher: NSObject {
|
||||
switch match {
|
||||
case let signalAccount as SignalAccount:
|
||||
let searchResult = ContactSearchResult(signalAccount: signalAccount, transaction: transaction)
|
||||
signalContacts.append(searchResult)
|
||||
assert(signalContactMap[signalAccount.recipientAddress] == nil)
|
||||
signalContactMap[signalAccount.recipientAddress] = searchResult
|
||||
case let signalRecipient as SignalRecipient:
|
||||
guard signalRecipient.devices.count > 0 else {
|
||||
// Ignore unregistered recipients.
|
||||
return
|
||||
}
|
||||
let signalAccount = SignalAccount(signalRecipient: signalRecipient, contact: nil, multipleAccountLabelText: nil)
|
||||
let searchResult = ContactSearchResult(signalAccount: signalAccount, transaction: transaction)
|
||||
signalRecipentResults.append(searchResult)
|
||||
case let groupThread as TSGroupThread:
|
||||
let sortKey = ConversationSortKey(isContactThread: false,
|
||||
creationDate: groupThread.creationDate,
|
||||
@ -291,19 +301,28 @@ public class FullTextSearcher: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
if matchesNoteToSelf(searchText: searchText, transaction: transaction) {
|
||||
if !signalContacts.contains(where: { $0.signalAccount.recipientAddress.isLocalAddress }) {
|
||||
if let localAddress = TSAccountManager.localAddress {
|
||||
let localAccount = SignalAccount(address: localAddress)
|
||||
let localResult = ContactSearchResult(signalAccount: localAccount, transaction: transaction)
|
||||
signalContacts.append(localResult)
|
||||
} else {
|
||||
owsFailDebug("localAddress was unexpectedly nil")
|
||||
}
|
||||
// Fill in user matches from SignalRecipients, but only if
|
||||
// we don't already have a SignalAccount for the same user.
|
||||
for signalRecipentResult in signalRecipentResults {
|
||||
if signalContactMap[signalRecipentResult.recipientAddress] == nil {
|
||||
signalContactMap[signalRecipentResult.recipientAddress] = signalRecipentResult
|
||||
}
|
||||
}
|
||||
|
||||
if let localAddress = TSAccountManager.localAddress {
|
||||
if matchesNoteToSelf(searchText: searchText, transaction: transaction) {
|
||||
if signalContactMap[localAddress] == nil {
|
||||
let localAccount = SignalAccount(address: localAddress)
|
||||
let localResult = ContactSearchResult(signalAccount: localAccount, transaction: transaction)
|
||||
signalContactMap[localAddress] = localResult
|
||||
}
|
||||
}
|
||||
} else {
|
||||
owsFailDebug("localAddress was unexpectedly nil")
|
||||
}
|
||||
|
||||
// Order contact results by display name.
|
||||
var signalContacts: [ContactSearchResult] = Array(signalContactMap.values)
|
||||
signalContacts.sort()
|
||||
|
||||
// Order the conversation and message results in reverse chronological order.
|
||||
|
||||
@ -486,6 +486,11 @@ const NSUInteger SignalRecipientSchemaVersion = 1;
|
||||
[self.signalRecipientReadCache didRemoveSignalRecipient:self transaction:transaction];
|
||||
}
|
||||
|
||||
+ (BOOL)shouldBeIndexedForFTS
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -79,6 +79,7 @@ public class GRDBSchemaMigrator: NSObject {
|
||||
case addMarkedUnreadIndexToThread
|
||||
case fixIncorrectIndexes
|
||||
case resetThreadVisibility
|
||||
case indexSignalRecipients
|
||||
|
||||
// NOTE: Every time we add a migration id, consider
|
||||
// incrementing grdbSchemaVersionLatest.
|
||||
@ -302,8 +303,9 @@ public class GRDBSchemaMigrator: NSObject {
|
||||
do {
|
||||
try autoreleasepool {
|
||||
let transaction = GRDBWriteTransaction(database: db)
|
||||
defer { transaction.finalizeTransaction() }
|
||||
|
||||
try dedupeSignalRecipients(transaction: transaction.asAnyWrite)
|
||||
transaction.finalizeTransaction()
|
||||
}
|
||||
|
||||
try db.drop(index: "index_signal_recipients_on_recipientPhoneNumber")
|
||||
@ -600,9 +602,10 @@ public class GRDBSchemaMigrator: NSObject {
|
||||
try db.drop(table: "model_OWSLinkedDeviceReadReceipt")
|
||||
|
||||
let transaction = GRDBWriteTransaction(database: db)
|
||||
defer { transaction.finalizeTransaction() }
|
||||
|
||||
let viewOnceStore = SDSKeyValueStore(collection: "viewOnceMessages")
|
||||
viewOnceStore.removeAll(transaction: transaction.asAnyWrite)
|
||||
transaction.finalizeTransaction()
|
||||
} catch {
|
||||
owsFail("Error: \(error)")
|
||||
}
|
||||
@ -715,6 +718,16 @@ public class GRDBSchemaMigrator: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
migrator.registerMigration(MigrationId.indexSignalRecipients.rawValue) { db in
|
||||
let transaction = GRDBWriteTransaction(database: db)
|
||||
defer { transaction.finalizeTransaction() }
|
||||
|
||||
SignalRecipient.anyEnumerate(transaction: transaction.asAnyWrite) { (signalRecipient: SignalRecipient,
|
||||
_: UnsafeMutablePointer<ObjCBool>) in
|
||||
GRDBFullTextSearchFinder.modelWasInserted(model: signalRecipient, transaction: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Schema Migration Insertion Point
|
||||
}
|
||||
|
||||
@ -726,8 +739,9 @@ public class GRDBSchemaMigrator: NSObject {
|
||||
migrator.registerMigration(MigrationId.dataMigration_populateGalleryItems.rawValue) { db in
|
||||
do {
|
||||
let transaction = GRDBWriteTransaction(database: db)
|
||||
defer { transaction.finalizeTransaction() }
|
||||
|
||||
try createInitialGalleryRecords(transaction: transaction)
|
||||
transaction.finalizeTransaction()
|
||||
} catch {
|
||||
owsFail("Error: \(error)")
|
||||
}
|
||||
@ -735,11 +749,12 @@ public class GRDBSchemaMigrator: NSObject {
|
||||
|
||||
migrator.registerMigration(MigrationId.dataMigration_markOnboardedUsers_v2.rawValue) { db in
|
||||
let transaction = GRDBWriteTransaction(database: db)
|
||||
defer { transaction.finalizeTransaction() }
|
||||
|
||||
if TSAccountManager.sharedInstance().isRegistered(transaction: transaction.asAnyWrite) {
|
||||
Logger.info("marking existing user as onboarded")
|
||||
TSAccountManager.sharedInstance().setIsOnboarded(true, transaction: transaction.asAnyWrite)
|
||||
}
|
||||
transaction.finalizeTransaction()
|
||||
}
|
||||
|
||||
migrator.registerMigration(MigrationId.dataMigration_clearLaunchScreenCache.rawValue) { _ in
|
||||
@ -748,19 +763,20 @@ public class GRDBSchemaMigrator: NSObject {
|
||||
|
||||
migrator.registerMigration(MigrationId.dataMigration_enableV2RegistrationLockIfNecessary.rawValue) { db in
|
||||
let transaction = GRDBWriteTransaction(database: db)
|
||||
defer { transaction.finalizeTransaction() }
|
||||
|
||||
guard KeyBackupService.hasMasterKey(transaction: transaction.asAnyWrite) else {
|
||||
transaction.finalizeTransaction()
|
||||
return
|
||||
|
||||
}
|
||||
OWS2FAManager.keyValueStore().setBool(true, key: OWS2FAManager.isRegistrationLockV2EnabledKey, transaction: transaction.asAnyWrite)
|
||||
transaction.finalizeTransaction()
|
||||
}
|
||||
|
||||
migrator.registerMigration(MigrationId.dataMigration_resetStorageServiceData.rawValue) { db in
|
||||
let transaction = GRDBWriteTransaction(database: db)
|
||||
defer { transaction.finalizeTransaction() }
|
||||
|
||||
SSKEnvironment.shared.storageServiceManager.resetLocalData(transaction: transaction.asAnyWrite)
|
||||
transaction.finalizeTransaction()
|
||||
}
|
||||
|
||||
migrator.registerMigration(MigrationId.dataMigration_markAllInteractionsAsNotDeleted.rawValue) { db in
|
||||
|
||||
@ -28,6 +28,15 @@ public class FullTextSearchFinder: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func modelWasUpdatedObjc(model: TSYapDatabaseObject, transaction: SDSAnyWriteTransaction) {
|
||||
guard let model = model as? SDSModel else {
|
||||
owsFailDebug("Invalid model.")
|
||||
return
|
||||
}
|
||||
modelWasUpdated(model: model, transaction: transaction)
|
||||
}
|
||||
|
||||
public func modelWasUpdated(model: SDSModel, transaction: SDSAnyWriteTransaction) {
|
||||
assert(type(of: model).shouldBeIndexedForFTS)
|
||||
|
||||
@ -342,6 +351,13 @@ class GRDBFullTextSearchFinder: NSObject {
|
||||
return nil
|
||||
}
|
||||
return model
|
||||
case SignalRecipient.collection():
|
||||
guard let model = SignalRecipient.anyFetch(uniqueId: uniqueId,
|
||||
transaction: transaction.asAnyRead) else {
|
||||
owsFailDebug("Couldn't load record: \(collection)")
|
||||
return nil
|
||||
}
|
||||
return model
|
||||
default:
|
||||
owsFailDebug("Unexpected record type: \(collection)")
|
||||
return nil
|
||||
@ -515,6 +531,8 @@ class AnySearchIndexer {
|
||||
return self.messageIndexer.index(message, transaction: transaction)
|
||||
} else if let signalAccount = object as? SignalAccount {
|
||||
return self.recipientIndexer.index(signalAccount.recipientAddress, transaction: transaction)
|
||||
} else if let signalRecipient = object as? SignalRecipient {
|
||||
return self.recipientIndexer.index(signalRecipient.address, transaction: transaction)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -771,6 +771,8 @@ NSUInteger const kUserProfileSchemaVersion = 1;
|
||||
{
|
||||
[super anyDidInsertWithTransaction:transaction];
|
||||
|
||||
[self reindexAssociatedModels:transaction];
|
||||
|
||||
[self.userProfileReadCache didInsertOrUpdateUserProfile:self transaction:transaction];
|
||||
}
|
||||
|
||||
@ -778,6 +780,8 @@ NSUInteger const kUserProfileSchemaVersion = 1;
|
||||
{
|
||||
[super anyDidUpdateWithTransaction:transaction];
|
||||
|
||||
[self reindexAssociatedModels:transaction];
|
||||
|
||||
[self.userProfileReadCache didInsertOrUpdateUserProfile:self transaction:transaction];
|
||||
}
|
||||
|
||||
@ -788,6 +792,33 @@ NSUInteger const kUserProfileSchemaVersion = 1;
|
||||
[self.userProfileReadCache didRemoveUserProfile:self transaction:transaction];
|
||||
}
|
||||
|
||||
- (void)reindexAssociatedModels:(SDSAnyWriteTransaction *)transaction
|
||||
{
|
||||
// The profile can affect how accounts, recipients and contact threads are indexed, so we
|
||||
// need to re-index them whenever the profile changes.
|
||||
FullTextSearchFinder *fullTextSearchFinder = [FullTextSearchFinder new];
|
||||
|
||||
AnySignalAccountFinder *accountFinder = [AnySignalAccountFinder new];
|
||||
SignalAccount *_Nullable signalAccount = [accountFinder signalAccountForAddress:self.address
|
||||
transaction:transaction];
|
||||
if (signalAccount != nil) {
|
||||
[fullTextSearchFinder modelWasUpdatedObjcWithModel:signalAccount transaction:transaction];
|
||||
}
|
||||
|
||||
AnySignalRecipientFinder *signalRecipientFinder = [AnySignalRecipientFinder new];
|
||||
SignalRecipient *_Nullable signalRecipient = [signalRecipientFinder signalRecipientForAddress:self.address
|
||||
transaction:transaction];
|
||||
if (signalRecipient != nil) {
|
||||
[fullTextSearchFinder modelWasUpdatedObjcWithModel:signalRecipient transaction:transaction];
|
||||
}
|
||||
|
||||
TSContactThread *_Nullable contactThread = [TSContactThread getThreadWithContactAddress:self.address
|
||||
transaction:transaction];
|
||||
if (contactThread != nil) {
|
||||
[fullTextSearchFinder modelWasUpdatedObjcWithModel:contactThread transaction:transaction];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)mergeUserProfilesIfNecessaryForAddress:(SignalServiceAddress *)address
|
||||
transaction:(SDSAnyWriteTransaction *)transaction
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user