Browse Source

refactored contact search

nayooti 5 years ago
parent
commit
6cce4adb7e

+ 17 - 1
deltachat-ios/Extensions/String+Extension.swift

@@ -13,7 +13,7 @@ extension String {
         return !trimmingCharacters(in: [" "]).isEmpty
     }
 
-    // O(n) - returns indexes of subsequences -> can be used to highlight subsequence within string
+    // O(n) - incremental search - returns indexes of subsequences -> can be used to highlight subsequence within string
     func contains(subSequence: String) -> [Int] {
         if subSequence.count > count {
             return []
@@ -39,6 +39,22 @@ extension String {
         return foundIndexes.count == sub.count ? foundIndexes : []
     }
 
+    func containsExact(subSequence: String) -> [Int] {
+        if subSequence.count > count {
+            return []
+        }
+
+        if let range = range(of: subSequence, options: .caseInsensitive) {
+            let index: Int = distance(from: startIndex, to: range.lowerBound)
+            var indexes: [Int] = []
+            for i in index..<(index + subSequence.count) {
+                indexes.append(i)
+            }
+            return indexes
+        }
+        return []
+    }
+
     func subScript(_ i: Int) -> Character {
         return self[index(startIndex, offsetBy: i)]
     }

+ 16 - 32
deltachat-ios/ViewModel/ChatListViewModel.swift

@@ -294,39 +294,23 @@ extension ChatListViewModel: UISearchResultsUpdating {
         var filteredContactCellViewModels: [ContactCellViewModel] = []
         let contactIds: [Int] = dcContext.getContacts(flags: DC_GCL_ADD_SELF)
 
-        // contactWithSearchResults.indexesToHightLight empty by default
-        var contacts: [ContactWithSearchResults] {
-            return contactIds.map { ContactWithSearchResults(contact: DcContact(id: $0), indexesToHighlight: []) }
-        }
-
-        let contactsWithHighlights: [ContactWithSearchResults] = contacts.map { contact in
-            let indexes = contact.contact.containsExact(searchText: searchText)
-            return ContactWithSearchResults(contact: contact.contact, indexesToHighlight: indexes)
-        }
-
-        let contactResults = contactsWithHighlights.filter { !$0.indexesToHighlight.isEmpty }
-
-        for contact in contactResults {
-            var nameIndexes: [Int] = []
-            var emailIndexes: [Int] = []
-
-            for indexes in contact.indexesToHighlight {
-                switch indexes.contactDetail {
-                case .NAME:
-                    nameIndexes = indexes.indexes
-                case .EMAIL:
-                    emailIndexes = indexes.indexes
-                }
+        let contacts = contactIds.map { return DcContact(id: $0) }
+
+        for contact in contacts {
+            let nameIndexes = contact.displayName.containsExact(subSequence: searchText)
+            let emailIndexes = contact.email.containsExact(subSequence: searchText)
+
+            if !nameIndexes.isEmpty || !emailIndexes.isEmpty {
+                // contact contains searchText
+                let viewModel = ContactCellViewModel(
+                    contactData: ContactCellData(
+                        contactId: contact.id
+                    ),
+                    titleHighlightIndexes: nameIndexes,
+                    subtitleHighlightIndexes: emailIndexes
+                )
+                filteredContactCellViewModels.append(viewModel)
             }
-            
-            let viewModel = ContactCellViewModel(
-                contactData: ContactCellData(
-                    contactId: contact.contact.id
-                ),
-                titleHighlightIndexes: nameIndexes,
-                subtitleHighlightIndexes: emailIndexes
-            )
-            filteredContactCellViewModels.append(viewModel)
         }
         filteredContacts.cellData = filteredContactCellViewModels