Loading data/src/main/java/com/moez/QKSMS/extensions/StringExtensions.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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}"), "") data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt +7 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) } Loading domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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> Loading presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +1 −4 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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())) } Loading @@ -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)) } } Loading presentation/src/main/java/com/moez/QKSMS/feature/main/SearchAdapter.kt +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading Loading
data/src/main/java/com/moez/QKSMS/extensions/StringExtensions.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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}"), "")
data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt +7 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) } Loading
domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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> Loading
presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +1 −4 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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())) } Loading @@ -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)) } } Loading
presentation/src/main/java/com/moez/QKSMS/feature/main/SearchAdapter.kt +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading