Commit 530a49e9 authored by Leonardo Aramaki's avatar Leonardo Aramaki

Set command list completion restrained to the line start offset

parent f3224435
......@@ -11,7 +11,8 @@ import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.android.widget.autocompletion.ui.BaseSuggestionViewHolder
import chat.rocket.android.widget.autocompletion.ui.SuggestionsAdapter
class CommandSuggestionsAdapter : SuggestionsAdapter<CommandSuggestionsViewHolder>("/", UNLIMITED_RESULT_COUNT) {
class CommandSuggestionsAdapter : SuggestionsAdapter<CommandSuggestionsViewHolder>(token = "/",
constraint = CONSTRAINT_BOUND_TO_START, threshold = UNLIMITED_RESULT_COUNT) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommandSuggestionsViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.suggestion_command_item, parent,
......
......@@ -6,10 +6,10 @@ import chat.rocket.android.chatroom.adapter.AutoCompleteType
import chat.rocket.android.chatroom.adapter.PEOPLE
import chat.rocket.android.chatroom.adapter.ROOMS
import chat.rocket.android.chatroom.domain.UriInteractor
import chat.rocket.android.chatroom.viewmodel.suggestion.ChatRoomSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import chat.rocket.android.chatroom.viewmodel.suggestion.ChatRoomSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.helper.UrlHelper
import chat.rocket.android.infrastructure.LocalRepository
......@@ -203,25 +203,25 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
val roomType = roomTypeOf(chatRoomType!!)
messagesRepository.getByRoomId(chatRoomId!!)
.sortedByDescending { it.timestamp }.firstOrNull()?.let { lastMessage ->
val instant = Instant.ofEpochMilli(lastMessage.timestamp)
val messages = client.history(chatRoomId!!, roomType, count = 50,
oldest = instant.toString())
Timber.d("History: $messages")
if (messages.result.isNotEmpty()) {
val models = mapper.map(messages.result)
messagesRepository.saveAll(messages.result)
launchUI(strategy) {
view.showNewMessage(models)
}
if (messages.result.size == 50) {
// we loade at least count messages, try one more to fetch more messages
loadMissingMessages()
}
}
val instant = Instant.ofEpochMilli(lastMessage.timestamp)
val messages = client.history(chatRoomId!!, roomType, count = 50,
oldest = instant.toString())
Timber.d("History: $messages")
if (messages.result.isNotEmpty()) {
val models = mapper.map(messages.result)
messagesRepository.saveAll(messages.result)
launchUI(strategy) {
view.showNewMessage(models)
}
if (messages.result.size == 50) {
// we loade at least count messages, try one more to fetch more messages
loadMissingMessages()
}
}
}
}
}
}
......@@ -489,16 +489,12 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
view.showReactionsPopup(messageId)
}
/**
* Loads the list of available commands.
*/
fun loadCommands(query: String = "") {
fun loadCommands() {
launchUI(strategy) {
try {
//TODO: cache the commands
val commands = client.commands(0, 100).result
view.populateCommandSuggestions(commands.map {
println(it)
CommandSuggestionViewModel(it.command, it.description ?: "", listOf(it.command))
})
} catch (ex: RocketChatException) {
......
......@@ -494,10 +494,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
private fun setupSuggestionsView() {
suggestions_view.anchor(text_message)
.registerTokenAdapter(PeopleSuggestionsAdapter())
.registerTokenAdapter(CommandSuggestionsAdapter())
.registerTokenAdapter(RoomSuggestionsAdapter())
suggestions_view.anchorTo(text_message)
.addTokenAdapter(PeopleSuggestionsAdapter())
.addTokenAdapter(CommandSuggestionsAdapter())
.addTokenAdapter(RoomSuggestionsAdapter())
.addSuggestionProviderAction("@") { query ->
if (query.isNotEmpty()) {
presenter.spotlight(query, PEOPLE, true)
......@@ -508,8 +508,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.loadChatRooms()
}
}
.addSuggestionProviderAction("/") { query ->
presenter.loadCommands(query)
.addSuggestionProviderAction("/") { _ ->
presenter.loadCommands()
}
presenter.loadCommands()
......
......@@ -7,9 +7,18 @@ import chat.rocket.android.widget.autocompletion.strategy.regex.StringMatchingCo
import java.lang.reflect.Type
import kotlin.properties.Delegates
abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(val token: String, threshold: Int = MAX_RESULT_COUNT) : RecyclerView.Adapter<VH>() {
abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(
val token: String,
val constraint: Int = CONSTRAINT_UNBOUND,
threshold: Int = MAX_RESULT_COUNT) : RecyclerView.Adapter<VH>() {
companion object {
// Any number of results.
const val UNLIMITED_RESULT_COUNT = -1
// Trigger suggestions only if on the line start.
const val CONSTRAINT_BOUND_TO_START = 0
// Trigger suggestions from anywhere.
const val CONSTRAINT_UNBOUND = 1
// Maximum number of results to display by default.
private const val MAX_RESULT_COUNT = 5
}
private var itemType: Type? = null
......
......@@ -21,6 +21,7 @@ import android.widget.EditText
import android.widget.FrameLayout
import chat.rocket.android.R
import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.android.widget.autocompletion.ui.SuggestionsAdapter.Companion.CONSTRAINT_BOUND_TO_START
import java.lang.ref.WeakReference
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicInteger
......@@ -77,6 +78,10 @@ class SuggestionsView : FrameLayout, TextWatcher {
val new = s.subSequence(start, start + count).toString()
if (adaptersByToken.containsKey(new)) {
val constraint = adapter(new).constraint
if (constraint == CONSTRAINT_BOUND_TO_START && start != 0) {
return
}
swapAdapter(getAdapterForToken(new)!!)
completionStartIndex.compareAndSet(NO_STATE_INDEX, start + 1)
editor?.let {
......@@ -125,14 +130,14 @@ class SuggestionsView : FrameLayout, TextWatcher {
private fun getAdapterForToken(token: String): SuggestionsAdapter<*>? = adaptersByToken.get(token)
fun anchor(editText: EditText): SuggestionsView {
fun anchorTo(editText: EditText): SuggestionsView {
editText.removeTextChangedListener(this)
editText.addTextChangedListener(this)
editor = WeakReference(editText)
return this
}
fun registerTokenAdapter(adapter: SuggestionsAdapter<*>): SuggestionsView {
fun addTokenAdapter(adapter: SuggestionsAdapter<*>): SuggestionsView {
adaptersByToken.getOrPut(adapter.token, { adapter })
return this
}
......
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