Make CategoryViewModel collect categories only while subscribed (#3720)

Assisted-by: Claude:claude-opus-5
This commit is contained in:
AntsyLich
2026-08-08 11:58:41 +06:00
committed by GitHub
parent bb9767c9df
commit 2aec7d19c0
2 changed files with 24 additions and 29 deletions
@@ -2,10 +2,10 @@ package eu.kanade.tachiyomi.ui.category
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.util.fastMap
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
@@ -26,7 +26,7 @@ class CategoryScreen : Screen() {
val navigator = LocalNavigator.currentOrThrow
val viewModel = viewModel<CategoryViewModel>()
val state by viewModel.state.collectAsState()
val state by viewModel.state.collectAsStateWithLifecycle()
if (state is CategoryScreenState.Loading) {
LoadingScreen()
@@ -1,14 +1,19 @@
package eu.kanade.tachiyomi.ui.category
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import mihon.core.viewmodel.StateViewModel
import tachiyomi.domain.category.interactor.CreateCategoryWithName
import tachiyomi.domain.category.interactor.DeleteCategory
import tachiyomi.domain.category.interactor.GetCategories
@@ -18,6 +23,7 @@ import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.time.Duration.Companion.seconds
class CategoryViewModel(
private val getCategories: GetCategories = Injekt.get(),
@@ -25,24 +31,23 @@ class CategoryViewModel(
private val deleteCategory: DeleteCategory = Injekt.get(),
private val reorderCategory: ReorderCategory = Injekt.get(),
private val renameCategory: RenameCategory = Injekt.get(),
) : StateViewModel<CategoryScreenState>(CategoryScreenState.Loading) {
) : ViewModel() {
private val _events: Channel<CategoryEvent> = Channel()
val events = _events.receiveAsFlow()
init {
viewModelScope.launch {
getCategories.subscribe()
.collectLatest { categories ->
mutableState.update {
CategoryScreenState.Success(
categories = categories
.filterNot(Category::isSystemCategory),
)
}
}
}
private val dialog = MutableStateFlow<CategoryDialog?>(null)
val state: StateFlow<CategoryScreenState> = combine(
getCategories.subscribe(),
dialog,
) { categories, dialog ->
CategoryScreenState.Success(
categories = categories.filterNot(Category::isSystemCategory),
dialog = dialog,
)
}
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), CategoryScreenState.Loading)
fun createCategory(name: String) {
viewModelScope.launch {
@@ -81,21 +86,11 @@ class CategoryViewModel(
}
fun showDialog(dialog: CategoryDialog) {
mutableState.update {
when (it) {
CategoryScreenState.Loading -> it
is CategoryScreenState.Success -> it.copy(dialog = dialog)
}
}
this.dialog.update { dialog }
}
fun dismissDialog() {
mutableState.update {
when (it) {
CategoryScreenState.Loading -> it
is CategoryScreenState.Success -> it.copy(dialog = null)
}
}
dialog.update { null }
}
}