Unverified Commit f5c8aa45 authored by Rafael Kellermann Streit's avatar Rafael Kellermann Streit Committed by GitHub

Merge branch 'develop' into nullfix

parents 73235eb1 04c07f98
...@@ -16,7 +16,7 @@ android { ...@@ -16,7 +16,7 @@ android {
applicationId "chat.rocket.android" applicationId "chat.rocket.android"
minSdkVersion versions.minSdk minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk targetSdkVersion versions.targetSdk
versionCode 2053 versionCode 2054
versionName "3.2.0" versionName "3.2.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
......
...@@ -169,8 +169,8 @@ ...@@ -169,8 +169,8 @@
<string name="msg_send_email">Отправить e-mail</string> <string name="msg_send_email">Отправить e-mail</string>
<string name="msg_android_app_support">Поддержка Android-приложения</string> <string name="msg_android_app_support">Поддержка Android-приложения</string>
<string name="msg_muted_on_this_channel">Вы лишены дара речи на этом канале</string> <string name="msg_muted_on_this_channel">Вы лишены дара речи на этом канале</string>
<string name="msg_unable_to_update_password">Unable to update password. Error message: %1$s</string> <!-- TODO - Add proper translation --> <string name="msg_unable_to_update_password">Невозможно обновить пароль. Ошибка: %1$s</string>
<string name="msg_password_updated_successfully">Password updated successfully</string> <!-- TODO - Add proper translation --> <string name="msg_password_updated_successfully">Пароль успешно обновлен</string>
<plurals name="msg_reacted_with_"> <plurals name="msg_reacted_with_">
<item quantity="one">%1$s реагирует с %2$s</item> <item quantity="one">%1$s реагирует с %2$s</item>
<item quantity="few">%1$s реагируют с %2$s</item> <item quantity="few">%1$s реагируют с %2$s</item>
......
...@@ -29,6 +29,9 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>( ...@@ -29,6 +29,9 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(
notifyDataSetChanged() notifyDataSetChanged()
} }
private var currentCount = 0;
private var currentItems = listOf<SuggestionModel>()
init { init {
setHasStableIds(true) setHasStableIds(true)
} }
...@@ -41,10 +44,10 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>( ...@@ -41,10 +44,10 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(
holder.bind(getItem(position), itemClickListener) holder.bind(getItem(position), itemClickListener)
} }
override fun getItemCount() = strategy.autocompleteItems(currentTerm).size override fun getItemCount() = currentCount
private fun getItem(position: Int): SuggestionModel { private fun getItem(position: Int): SuggestionModel {
return strategy.autocompleteItems(currentTerm)[position] return currentItems[position]
} }
/** /**
...@@ -58,12 +61,15 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>( ...@@ -58,12 +61,15 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(
fun autocomplete(newTerm: String) { fun autocomplete(newTerm: String) {
this.currentTerm = newTerm.toLowerCase().trim() this.currentTerm = newTerm.toLowerCase().trim()
currentItems = strategy.autocompleteItems(currentTerm)
currentCount = currentItems.size
} }
fun addItems(list: List<SuggestionModel>) { fun addItems(list: List<SuggestionModel>) {
strategy.addAll(list) strategy.addAll(list)
// Since we've just added new items we should check for possible new completion suggestions. // Since we've just added new items we should check for possible new completion suggestions.
strategy.autocompleteItems(currentTerm) //strategy.autocompleteItems(currentTerm)
autocomplete(currentTerm)
notifyDataSetChanged() notifyDataSetChanged()
} }
......
...@@ -10,6 +10,7 @@ import android.text.TextWatcher ...@@ -10,6 +10,7 @@ import android.text.TextWatcher
import android.transition.Slide import android.transition.Slide
import android.transition.TransitionManager import android.transition.TransitionManager
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.widget.EditText import android.widget.EditText
...@@ -24,6 +25,7 @@ import chat.rocket.android.suggestions.model.SuggestionModel ...@@ -24,6 +25,7 @@ import chat.rocket.android.suggestions.model.SuggestionModel
import chat.rocket.android.suggestions.ui.SuggestionsAdapter.Companion.CONSTRAINT_BOUND_TO_START import chat.rocket.android.suggestions.ui.SuggestionsAdapter.Companion.CONSTRAINT_BOUND_TO_START
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import kotlin.system.measureTimeMillis
// This is a special index that means we're not at an autocompleting state. // This is a special index that means we're not at an autocompleting state.
private const val NO_STATE_INDEX = 0 private const val NO_STATE_INDEX = 0
...@@ -101,22 +103,32 @@ class SuggestionsView : FrameLayout, TextWatcher { ...@@ -101,22 +103,32 @@ class SuggestionsView : FrameLayout, TextWatcher {
return return
} }
val prefixEndIndex = this.editor?.get()?.selectionStart ?: NO_STATE_INDEX if (completionOffset.get() == NO_STATE_INDEX) {
if (prefixEndIndex == NO_STATE_INDEX || prefixEndIndex < completionOffset.get()) return return
val prefix = s.subSequence(completionOffset.get(), this.editor?.get()?.selectionStart
?: completionOffset.get()).toString()
recyclerView.adapter?.let {
it as SuggestionsAdapter
// we need to look up only after the '@'
it.autocomplete(prefix)
val cacheMap = localProvidersByToken[it.token]
if (cacheMap != null && cacheMap[prefix] != null) {
it.addItems(cacheMap[prefix]!!)
} else {
// fetch more suggestions from an external source if any
externalProvidersByToken[it.token]?.invoke(prefix)
}
} }
measureTimeMillis {
val prefixEndIndex = this.editor?.get()?.selectionStart ?: NO_STATE_INDEX
if (prefixEndIndex == NO_STATE_INDEX || prefixEndIndex < completionOffset.get()) return
val prefix = s.subSequence(completionOffset.get(), this.editor?.get()?.selectionStart
?: completionOffset.get()).toString()
recyclerView.adapter?.also {
it as SuggestionsAdapter
// we need to look up only after the '@'
measureTimeMillis { it.autocomplete(prefix) }.let { time ->
Log.d("SuggestionsView", "autocomplete($prefix) in $time ms")
}
val cacheMap = localProvidersByToken[it.token]
if (cacheMap != null && cacheMap[prefix] != null) {
if (it.itemCount == 0) {
it.addItems(cacheMap[prefix]!!)
}
} else {
// fetch more suggestions from an external source if any
externalProvidersByToken[it.token]?.invoke(prefix)
}
}
}.let { Log.d("SuggestionsView", "whole prefix in $it ms") }
} }
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment