MessageSearchHelper.kt 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * Nextcloud Talk - Android Client
  3. *
  4. * SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
  5. * SPDX-FileCopyrightText: 2022 Nextcloud GmbH
  6. * SPDX-License-Identifier: GPL-3.0-or-later
  7. */
  8. package com.nextcloud.talk.messagesearch
  9. import android.util.Log
  10. import com.nextcloud.talk.models.domain.SearchMessageEntry
  11. import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
  12. import io.reactivex.Observable
  13. import io.reactivex.disposables.Disposable
  14. class MessageSearchHelper @JvmOverloads constructor(
  15. private val unifiedSearchRepository: UnifiedSearchRepository,
  16. private val fromRoom: String? = null
  17. ) {
  18. data class MessageSearchResults(val messages: List<SearchMessageEntry>, val hasMore: Boolean)
  19. private var unifiedSearchDisposable: Disposable? = null
  20. private var previousSearch: String? = null
  21. private var previousCursor: Int = 0
  22. private var previousResults: List<SearchMessageEntry> = emptyList()
  23. fun startMessageSearch(search: String): Observable<MessageSearchResults> {
  24. resetCachedData()
  25. return doSearch(search)
  26. }
  27. fun loadMore(): Observable<MessageSearchResults>? {
  28. previousSearch?.let {
  29. return doSearch(it, previousCursor)
  30. }
  31. return null
  32. }
  33. fun cancelSearch() {
  34. disposeIfPossible()
  35. }
  36. private fun doSearch(search: String, cursor: Int = 0): Observable<MessageSearchResults> {
  37. disposeIfPossible()
  38. return searchCall(search, cursor)
  39. .map { results ->
  40. previousSearch = search
  41. previousCursor = results.cursor
  42. previousResults = previousResults + results.entries
  43. MessageSearchResults(previousResults, results.hasMore)
  44. }
  45. .doOnSubscribe {
  46. unifiedSearchDisposable = it
  47. }
  48. .doOnError { throwable ->
  49. Log.e(TAG, "message search - ERROR", throwable)
  50. resetCachedData()
  51. disposeIfPossible()
  52. }
  53. .doOnComplete(this::disposeIfPossible)
  54. }
  55. private fun searchCall(
  56. search: String,
  57. cursor: Int
  58. ): Observable<UnifiedSearchRepository.UnifiedSearchResults<SearchMessageEntry>> {
  59. return when {
  60. fromRoom != null -> {
  61. unifiedSearchRepository.searchInRoom(
  62. roomToken = fromRoom,
  63. searchTerm = search,
  64. cursor = cursor
  65. )
  66. }
  67. else -> {
  68. unifiedSearchRepository.searchMessages(
  69. searchTerm = search,
  70. cursor = cursor
  71. )
  72. }
  73. }
  74. }
  75. private fun resetCachedData() {
  76. previousSearch = null
  77. previousCursor = 0
  78. previousResults = emptyList()
  79. }
  80. private fun disposeIfPossible() {
  81. unifiedSearchDisposable?.dispose()
  82. unifiedSearchDisposable = null
  83. }
  84. companion object {
  85. private val TAG = MessageSearchHelper::class.simpleName
  86. }
  87. }