Fix search
parent
cef5d91eec
commit
a215d9ebfc
@ -1,29 +1,64 @@
|
||||
package org.koitharu.kotatsu.search.ui
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||
import org.koitharu.kotatsu.list.ui.model.IndeterminateProgress
|
||||
import org.koitharu.kotatsu.list.ui.model.toGridModel
|
||||
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
|
||||
import org.koitharu.kotatsu.list.ui.model.toListModel
|
||||
|
||||
class SearchViewModel(
|
||||
private val repository: MangaRepository,
|
||||
private val query: String,
|
||||
settings: AppSettings
|
||||
) : MangaListViewModel(settings) {
|
||||
|
||||
override val content = MutableLiveData<List<Any>>()
|
||||
private val mangaList = MutableStateFlow<List<Manga>>(emptyList())
|
||||
private val hasNextPage = MutableStateFlow(false)
|
||||
private var loadingJob: Job? = null
|
||||
|
||||
fun loadList(query: String, append: Boolean) {
|
||||
launchLoadingJob {
|
||||
val list = withContext(Dispatchers.Default) {
|
||||
repository.getList(TODO(), query = query)
|
||||
}
|
||||
override val content = combine(mangaList.drop(1), createListModeFlow()) { list, mode ->
|
||||
when (mode) {
|
||||
ListMode.LIST -> list.map { it.toListModel() }
|
||||
ListMode.DETAILED_LIST -> list.map { it.toListDetailedModel() }
|
||||
ListMode.GRID -> list.map { it.toGridModel() }
|
||||
}
|
||||
}.onEach {
|
||||
isEmptyState.postValue(it.isEmpty())
|
||||
}.combine(hasNextPage) { list, isHasNextPage ->
|
||||
if (isHasNextPage && list.isNotEmpty()) list + IndeterminateProgress else list
|
||||
}.asLiveData(viewModelScope.coroutineContext + Dispatchers.Default)
|
||||
|
||||
init {
|
||||
loadList(append = false)
|
||||
}
|
||||
|
||||
fun loadList(append: Boolean) {
|
||||
if (loadingJob?.isActive == true) {
|
||||
return
|
||||
}
|
||||
loadingJob = launchLoadingJob(Dispatchers.Default) {
|
||||
val list = repository.getList(
|
||||
offset = if (append) mangaList.value.size else 0,
|
||||
query = query
|
||||
)
|
||||
if (!append) {
|
||||
content.value = list
|
||||
} else {
|
||||
content.value = content.value.orEmpty() + list
|
||||
mangaList.value = list
|
||||
} else if (list.isNotEmpty()) {
|
||||
mangaList.value += list
|
||||
}
|
||||
hasNextPage.value = list.isNotEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,43 +1,70 @@
|
||||
package org.koitharu.kotatsu.search.ui.global
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.plus
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||
import org.koitharu.kotatsu.list.ui.model.IndeterminateProgress
|
||||
import org.koitharu.kotatsu.list.ui.model.toGridModel
|
||||
import org.koitharu.kotatsu.list.ui.model.toListDetailedModel
|
||||
import org.koitharu.kotatsu.list.ui.model.toListModel
|
||||
import org.koitharu.kotatsu.search.domain.MangaSearchRepository
|
||||
import org.koitharu.kotatsu.utils.ext.onFirst
|
||||
import java.io.IOException
|
||||
|
||||
class GlobalSearchViewModel(
|
||||
private val query: String,
|
||||
private val repository: MangaSearchRepository,
|
||||
settings: AppSettings
|
||||
) : MangaListViewModel(settings) {
|
||||
|
||||
override val content = MutableLiveData<List<Any>>()
|
||||
private val mangaList = MutableStateFlow<List<Manga>>(emptyList())
|
||||
private val hasNextPage = MutableStateFlow(false)
|
||||
private var searchJob: Job? = null
|
||||
|
||||
fun startSearch(query: String) {
|
||||
isLoading.value = true
|
||||
override val content = combine(mangaList.drop(1), createListModeFlow()) { list, mode ->
|
||||
when (mode) {
|
||||
ListMode.LIST -> list.map { it.toListModel() }
|
||||
ListMode.DETAILED_LIST -> list.map { it.toListDetailedModel() }
|
||||
ListMode.GRID -> list.map { it.toGridModel() }
|
||||
}
|
||||
}.combine(hasNextPage) { list, isHasNextPage ->
|
||||
if (isHasNextPage && list.isNotEmpty()) list + IndeterminateProgress else list
|
||||
}.asLiveData(viewModelScope.coroutineContext + Dispatchers.Default)
|
||||
|
||||
init {
|
||||
onRefresh()
|
||||
}
|
||||
|
||||
fun onRefresh() {
|
||||
searchJob?.cancel()
|
||||
searchJob = repository.globalSearch(query)
|
||||
.flowOn(Dispatchers.Default)
|
||||
.catch { e ->
|
||||
if (e is IOException) {
|
||||
onError.call(e)
|
||||
}
|
||||
onError.postCall(e)
|
||||
isLoading.postValue(false)
|
||||
hasNextPage.value = false
|
||||
}.filterNot { x -> x.isEmpty() }
|
||||
.onEmpty {
|
||||
content.value = emptyList()
|
||||
isLoading.value = false
|
||||
.onStart {
|
||||
isLoading.postValue(true)
|
||||
}.onEmpty {
|
||||
mangaList.value = emptyList()
|
||||
isEmptyState.postValue(true)
|
||||
isLoading.postValue(false)
|
||||
}.onCompletion {
|
||||
// TODO
|
||||
isLoading.postValue(false)
|
||||
hasNextPage.value = false
|
||||
}.onFirst {
|
||||
isEmptyState.postValue(false)
|
||||
hasNextPage.value = true
|
||||
isLoading.value = false
|
||||
}.onEach {
|
||||
content.value = content.value.orEmpty() + it
|
||||
}.launchIn(viewModelScope)
|
||||
mangaList.value += it
|
||||
}.launchIn(viewModelScope + Dispatchers.Default)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue