123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- /*
- * Nextcloud Talk - Android Client
- *
- * SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
- * SPDX-FileCopyrightText: 2022 Nextcloud GmbH
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
- package com.nextcloud.talk.messagesearch
- import android.annotation.SuppressLint
- import android.util.Log
- import androidx.lifecycle.LiveData
- import androidx.lifecycle.MutableLiveData
- import androidx.lifecycle.ViewModel
- import com.nextcloud.talk.models.domain.SearchMessageEntry
- import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
- import io.reactivex.android.schedulers.AndroidSchedulers
- import io.reactivex.schedulers.Schedulers
- import javax.inject.Inject
- /**
- * Install PlantUML plugin to render this state diagram
- * @startuml
- * hide empty description
- * [*] --> InitialState
- * InitialState --> LoadingState
- * LoadingState --> EmptyState
- * LoadingState --> LoadedState
- * LoadingState --> LoadingState
- * LoadedState --> LoadingState
- * EmptyState --> LoadingState
- * LoadingState --> ErrorState
- * ErrorState --> LoadingState
- * @enduml
- */
- class MessageSearchViewModel @Inject constructor(private val unifiedSearchRepository: UnifiedSearchRepository) :
- ViewModel() {
- sealed class ViewState
- object InitialState : ViewState()
- object LoadingState : ViewState()
- object EmptyState : ViewState()
- object ErrorState : ViewState()
- class LoadedState(val results: List<SearchMessageEntry>, val hasMore: Boolean) : ViewState()
- class FinishedState(val selectedMessageId: String) : ViewState()
- private lateinit var messageSearchHelper: MessageSearchHelper
- private val _state: MutableLiveData<ViewState> = MutableLiveData(InitialState)
- val state: LiveData<ViewState>
- get() = _state
- fun initialize(roomToken: String) {
- messageSearchHelper = MessageSearchHelper(unifiedSearchRepository, roomToken)
- }
- @SuppressLint("CheckResult") // handled by helper
- fun onQueryTextChange(newText: String) {
- if (newText.length >= MIN_CHARS_FOR_SEARCH) {
- _state.value = LoadingState
- messageSearchHelper.cancelSearch()
- messageSearchHelper.startMessageSearch(newText)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(this::onReceiveResults, this::onError)
- }
- }
- @SuppressLint("CheckResult") // handled by helper
- fun loadMore() {
- _state.value = LoadingState
- messageSearchHelper.cancelSearch()
- messageSearchHelper.loadMore()
- ?.subscribeOn(Schedulers.io())
- ?.observeOn(AndroidSchedulers.mainThread())
- ?.subscribe(this::onReceiveResults)
- }
- private fun onReceiveResults(results: MessageSearchHelper.MessageSearchResults) {
- if (results.messages.isEmpty()) {
- _state.value = EmptyState
- } else {
- _state.value = LoadedState(results.messages, results.hasMore)
- }
- }
- private fun onError(throwable: Throwable) {
- Log.e(TAG, "onError:", throwable)
- messageSearchHelper.cancelSearch()
- _state.value = ErrorState
- }
- fun refresh(query: String?) {
- query?.let { onQueryTextChange(it) }
- }
- fun selectMessage(messageEntry: SearchMessageEntry) {
- _state.value = FinishedState(messageEntry.messageId!!)
- }
- companion object {
- private val TAG = MessageSearchViewModel::class.simpleName
- private const val MIN_CHARS_FOR_SEARCH = 2
- }
- }
|