|
|
|
|
@ -6,6 +6,7 @@ import kotlinx.coroutines.*
|
|
|
|
|
import org.koitharu.kotatsu.R
|
|
|
|
|
import org.koitharu.kotatsu.base.domain.MangaDataRepository
|
|
|
|
|
import org.koitharu.kotatsu.base.ui.BaseViewModel
|
|
|
|
|
import org.koitharu.kotatsu.core.model.MangaTag
|
|
|
|
|
import org.koitharu.kotatsu.core.model.SortOrder
|
|
|
|
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
|
|
|
|
import java.util.*
|
|
|
|
|
@ -21,12 +22,10 @@ class FilterViewModel(
|
|
|
|
|
private var job: Job? = null
|
|
|
|
|
private var selectedSortOrder: SortOrder? = state.sortOrder
|
|
|
|
|
private val selectedTags = HashSet(state.tags)
|
|
|
|
|
private val availableTagsDeferred = viewModelScope.async(Dispatchers.Default + createErrorHandler()) {
|
|
|
|
|
repository.getTags()
|
|
|
|
|
}
|
|
|
|
|
private val localTagsDeferred = viewModelScope.async(Dispatchers.Default + createErrorHandler()) {
|
|
|
|
|
private val localTagsDeferred = viewModelScope.async(Dispatchers.Default) {
|
|
|
|
|
dataRepository.findTags(repository.source)
|
|
|
|
|
}
|
|
|
|
|
private var availableTagsDeferred = loadTagsAsync()
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
|
showFilter()
|
|
|
|
|
@ -52,21 +51,24 @@ class FilterViewModel(
|
|
|
|
|
val previousJob = job
|
|
|
|
|
job = launchJob(Dispatchers.Default) {
|
|
|
|
|
previousJob?.cancelAndJoin()
|
|
|
|
|
val tags = availableTagsDeferred.await()
|
|
|
|
|
val tags = tryLoadTags()
|
|
|
|
|
val localTags = localTagsDeferred.await()
|
|
|
|
|
val sortOrders = repository.sortOrders
|
|
|
|
|
val list = ArrayList<FilterItem>(sortOrders.size + tags.size + 2)
|
|
|
|
|
val list = ArrayList<FilterItem>(sortOrders.size + (tags?.size ?: 1) + 2)
|
|
|
|
|
list.add(FilterItem.Header(R.string.sort_order))
|
|
|
|
|
sortOrders.sortedBy { it.ordinal }.mapTo(list) {
|
|
|
|
|
FilterItem.Sort(it, isSelected = it == selectedSortOrder)
|
|
|
|
|
}
|
|
|
|
|
if (tags.isNotEmpty() || selectedTags.isNotEmpty()) {
|
|
|
|
|
if (tags == null || tags.isNotEmpty() || selectedTags.isNotEmpty()) {
|
|
|
|
|
list.add(FilterItem.Header(R.string.genres))
|
|
|
|
|
val mappedTags = TreeSet<FilterItem.Tag>(compareBy({ !it.isChecked }, { it.tag.title }))
|
|
|
|
|
localTags.mapTo(mappedTags) { FilterItem.Tag(it, isChecked = it in selectedTags) }
|
|
|
|
|
tags.mapTo(mappedTags) { FilterItem.Tag(it, isChecked = it in selectedTags) }
|
|
|
|
|
tags?.mapTo(mappedTags) { FilterItem.Tag(it, isChecked = it in selectedTags) }
|
|
|
|
|
selectedTags.mapTo(mappedTags) { FilterItem.Tag(it, isChecked = true) }
|
|
|
|
|
list.addAll(mappedTags)
|
|
|
|
|
if (tags == null) {
|
|
|
|
|
list.add(FilterItem.Error(R.string.filter_load_error))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ensureActive()
|
|
|
|
|
filter.postValue(list)
|
|
|
|
|
@ -93,4 +95,20 @@ class FilterViewModel(
|
|
|
|
|
updateFilters()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private suspend fun tryLoadTags(): Set<MangaTag>? {
|
|
|
|
|
val shouldRetryOnError = availableTagsDeferred.isCompleted
|
|
|
|
|
val result = availableTagsDeferred.await()
|
|
|
|
|
if (result == null && shouldRetryOnError) {
|
|
|
|
|
availableTagsDeferred = loadTagsAsync()
|
|
|
|
|
return availableTagsDeferred.await()
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun loadTagsAsync() = viewModelScope.async(Dispatchers.Default) {
|
|
|
|
|
kotlin.runCatching {
|
|
|
|
|
repository.getTags()
|
|
|
|
|
}.getOrNull()
|
|
|
|
|
}
|
|
|
|
|
}
|