From 748fc05cc0361b7adcb93090a765ffb9aaa7ea74 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Sun, 29 Sep 2019 18:43:23 -0400 Subject: [PATCH] Fix unicode stripping for search Fixes #1420 --- .../com/moez/QKSMS/extensions/StringExtensions.kt | 2 +- .../QKSMS/repository/ConversationRepositoryImpl.kt | 12 +++++++----- .../moez/QKSMS/repository/ConversationRepository.kt | 2 +- .../com/moez/QKSMS/feature/main/MainViewModel.kt | 5 +---- .../com/moez/QKSMS/feature/main/SearchAdapter.kt | 3 ++- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/data/src/main/java/com/moez/QKSMS/extensions/StringExtensions.kt b/data/src/main/java/com/moez/QKSMS/extensions/StringExtensions.kt index 3312c78f..1ef0a6ed 100644 --- a/data/src/main/java/com/moez/QKSMS/extensions/StringExtensions.kt +++ b/data/src/main/java/com/moez/QKSMS/extensions/StringExtensions.kt @@ -23,4 +23,4 @@ import java.text.Normalizer /** * Strip the accents from a string */ -fun CharSequence.removeAccents() = Normalizer.normalize(this, Normalizer.Form.NFD) +fun CharSequence.removeAccents(): String = Normalizer.normalize(this, Normalizer.Form.NFKD).replace(Regex("\\p{M}"), "") diff --git a/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt b/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt index 15fe0442..494dd91f 100644 --- a/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt @@ -25,6 +25,7 @@ import android.telephony.PhoneNumberUtils import com.moez.QKSMS.compat.TelephonyCompat import com.moez.QKSMS.extensions.anyOf import com.moez.QKSMS.extensions.map +import com.moez.QKSMS.extensions.removeAccents import com.moez.QKSMS.filter.ConversationFilter import com.moez.QKSMS.mapper.CursorToConversation import com.moez.QKSMS.mapper.CursorToRecipient @@ -100,22 +101,23 @@ class ConversationRepositoryImpl @Inject constructor( } } - override fun searchConversations(query: String): List { + override fun searchConversations(query: CharSequence): List { + val normalizedQuery = query.removeAccents() val conversations = getConversationsSnapshot() val messagesByConversation = Realm.getDefaultInstance() .where(Message::class.java) - .contains("body", query, Case.INSENSITIVE) + .contains("body", normalizedQuery, Case.INSENSITIVE) .findAll() .groupBy { message -> message.threadId } .filter { (threadId, _) -> conversations.firstOrNull { it.id == threadId } != null } .map { (threadId, messages) -> Pair(conversations.first { it.id == threadId }, messages.size) } - .map { (conversation, messages) -> SearchResult(query, conversation, messages) } + .map { (conversation, messages) -> SearchResult(normalizedQuery, conversation, messages) } .sortedByDescending { result -> result.messages } return conversations - .filter { conversation -> conversationFilter.filter(conversation, query) } - .map { conversation -> SearchResult(query, conversation, 0) } + .filter { conversation -> conversationFilter.filter(conversation, normalizedQuery) } + .map { conversation -> SearchResult(normalizedQuery, conversation, 0) } .plus(messagesByConversation) } diff --git a/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt b/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt index dd20f119..56785a57 100644 --- a/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt +++ b/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt @@ -36,7 +36,7 @@ interface ConversationRepository { fun setConversationName(id: Long, name: String) - fun searchConversations(query: String): List + fun searchConversations(query: CharSequence): List fun getBlockedConversations(): RealmResults diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt index 1c033d9e..07e9ae7e 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt @@ -24,7 +24,6 @@ import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.BillingManager import com.moez.QKSMS.extensions.mapNotNull -import com.moez.QKSMS.extensions.removeAccents import com.moez.QKSMS.interactor.DeleteConversations import com.moez.QKSMS.interactor.MarkAllSeen import com.moez.QKSMS.interactor.MarkArchived @@ -45,7 +44,6 @@ import com.moez.QKSMS.repository.SyncRepository import com.moez.QKSMS.util.Preferences import com.uber.autodispose.android.lifecycle.scope import com.uber.autodispose.autoDisposable -import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.withLatestFrom @@ -175,7 +173,6 @@ class MainViewModel @Inject constructor( view.queryChangedIntent .debounce(200, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) - .map { query -> query.removeAccents() } .withLatestFrom(state) { query, state -> if (query.isEmpty() && state.page is Searching) { newState { copy(page = Inbox(data = conversationRepo.getConversations())) } @@ -190,7 +187,7 @@ class MainViewModel @Inject constructor( } } .observeOn(Schedulers.io()) - .switchMap { query -> Observable.just(query).map { conversationRepo.searchConversations(it) } } + .map(conversationRepo::searchConversations) .autoDisposable(view.scope()) .subscribe { data -> newState { copy(page = Searching(loading = false, data = data)) } } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/SearchAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/SearchAdapter.kt index 7f32e691..6e429aa5 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/SearchAdapter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/SearchAdapter.kt @@ -31,6 +31,7 @@ import com.moez.QKSMS.common.base.QkViewHolder import com.moez.QKSMS.common.util.Colors import com.moez.QKSMS.common.util.DateFormatter import com.moez.QKSMS.common.util.extensions.setVisible +import com.moez.QKSMS.extensions.removeAccents import com.moez.QKSMS.model.SearchResult import kotlinx.android.synthetic.main.search_list_item.view.* import javax.inject.Inject @@ -64,7 +65,7 @@ class SearchAdapter @Inject constructor( val query = result.query val title = SpannableString(result.conversation.getTitle()) - var index = title.indexOf(query, ignoreCase = true) + var index = title.removeAccents().indexOf(query, ignoreCase = true) while (index >= 0) { title.setSpan(BackgroundColorSpan(highlightColor), index, index + query.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)