Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 748fc05c authored by moezbhatti's avatar moezbhatti
Browse files

Fix unicode stripping for search

Fixes #1420
parent 8b8da9c5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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}"), "")
+7 −5
Original line number Diff line number Diff line
@@ -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<SearchResult> {
    override fun searchConversations(query: CharSequence): List<SearchResult> {
        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)
    }

+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ interface ConversationRepository {

    fun setConversationName(id: Long, name: String)

    fun searchConversations(query: String): List<SearchResult>
    fun searchConversations(query: CharSequence): List<SearchResult>

    fun getBlockedConversations(): RealmResults<Conversation>

+1 −4
Original line number Diff line number Diff line
@@ -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)) } }

+2 −1
Original line number Diff line number Diff line
@@ -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)