Always suggest available tags in manga list header

This commit is contained in:
Koitharu
2022-07-09 09:13:18 +03:00
parent f6c6111459
commit 53f127987c
4 changed files with 58 additions and 16 deletions

View File

@@ -29,7 +29,7 @@ fun listHeader2AD(
binding.scrollView.smoothScrollTo(0, 0)
}
ignoreChecking = true
binding.chipsTags.setChips(item.chips)
binding.chipsTags.setChips(item.chips) // TODO use recyclerview
ignoreChecking = false
binding.textViewFilter.setTextAndVisible(item.sortOrder?.titleRes ?: 0)
}

View File

@@ -30,7 +30,7 @@ class FilterCoordinator(
private var availableTagsDeferred = loadTagsAsync()
val items: LiveData<List<FilterItem>> = getItemsFlow()
.asLiveDataDistinct(coroutineScope.coroutineContext + Dispatchers.Default)
.asLiveDataDistinct(coroutineScope.coroutineContext + Dispatchers.Default, listOf(FilterItem.Loading))
init {
observeState()
@@ -54,6 +54,13 @@ class FilterCoordinator(
}
}
fun observeAvailableTags(): Flow<Set<MangaTag>?> = flow {
if (!availableTagsDeferred.isCompleted) {
emit(emptySet())
}
emit(availableTagsDeferred.await())
}
fun observeState() = currentState.asStateFlow()
fun setTags(tags: Set<MangaTag>) {

View File

@@ -3,7 +3,28 @@ package org.koitharu.kotatsu.list.ui.model
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
import org.koitharu.kotatsu.parsers.model.SortOrder
data class ListHeader2(
class ListHeader2(
val chips: Collection<ChipsView.ChipModel>,
val sortOrder: SortOrder?,
) : ListModel
val hasSelectedTags: Boolean,
) : ListModel {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ListHeader2
if (chips != other.chips) return false
if (sortOrder != other.sortOrder) return false
// Not need to check hasSelectedTags
return true
}
override fun hashCode(): Int {
var result = chips.hashCode()
result = 31 * result + (sortOrder?.hashCode() ?: 0)
return result
}
}

View File

@@ -45,16 +45,16 @@ class RemoteListViewModel(
override val content = combine(
mangaList,
createListModeFlow(),
filter.observeState(),
createHeaderFlow(),
listError,
hasNextPage,
) { list, mode, filterState, error, hasNext ->
) { list, mode, header, error, hasNext ->
buildList(list?.size?.plus(2) ?: 2) {
add(ListHeader2(createChipsList(filterState), filterState.sortOrder))
add(header)
when {
list.isNullOrEmpty() && error != null -> add(error.toErrorState(canRetry = true))
list == null -> add(LoadingState)
list.isEmpty() -> add(createEmptyState(filterState))
list.isEmpty() -> add(createEmptyState(header.hasSelectedTags))
else -> {
list.toUi(this, mode)
when {
@@ -64,10 +64,7 @@ class RemoteListViewModel(
}
}
}
}.asLiveDataDistinct(
viewModelScope.coroutineContext + Dispatchers.Default,
listOf(ListHeader(repository.source.title, 0, null), LoadingState),
)
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, listOf(LoadingState))
init {
filter.observeState()
@@ -144,16 +141,33 @@ class RemoteListViewModel(
}
}
private fun createEmptyState(filterState: FilterState) = EmptyState(
private fun createEmptyState(canResetFilter: Boolean) = EmptyState(
icon = R.drawable.ic_empty_search,
textPrimary = R.string.nothing_found,
textSecondary = 0,
actionStringRes = if (filterState.tags.isEmpty()) 0 else R.string.reset_filter,
actionStringRes = if (canResetFilter) R.string.reset_filter else 0,
)
private suspend fun createChipsList(filterState: FilterState): List<ChipsView.ChipModel> {
private fun createHeaderFlow() = combine(
filter.observeState(),
filter.observeAvailableTags(),
) { state, available ->
val chips = createChipsList(state, available.orEmpty())
ListHeader2(chips, state.sortOrder, state.tags.isNotEmpty())
}
private suspend fun createChipsList(
filterState: FilterState,
availableTags: Set<MangaTag>
): List<ChipsView.ChipModel> {
val selectedTags = filterState.tags.toMutableSet()
val tags = searchRepository.getTagsSuggestion("", 6, repository.source)
var tags = searchRepository.getTagsSuggestion("", 6, repository.source)
if (tags.isEmpty()) {
tags = availableTags.take(6)
}
if (tags.isEmpty() && selectedTags.isEmpty()) {
return emptyList()
}
val result = LinkedList<ChipsView.ChipModel>()
for (tag in tags) {
val model = ChipsView.ChipModel(