Make ExtensionFilterViewModel collect languages only while subscribed (#3718)

Assisted-by: Claude:claude-opus-5
This commit is contained in:
AntsyLich
2026-08-08 11:58:18 +06:00
committed by GitHub
parent f6aad7497e
commit 864281af7d
2 changed files with 22 additions and 26 deletions
@@ -2,9 +2,9 @@ package eu.kanade.tachiyomi.ui.browse.extension
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.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
@@ -22,7 +22,7 @@ class ExtensionFilterScreen : Screen() {
val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow
val viewModel = viewModel<ExtensionFilterViewModel>()
val state by viewModel.state.collectAsState()
val state by viewModel.state.collectAsStateWithLifecycle()
if (state is ExtensionFilterState.Loading) {
LoadingScreen()
@@ -1,53 +1,49 @@
package eu.kanade.tachiyomi.ui.browse.extension
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
import eu.kanade.domain.source.interactor.ToggleLanguage
import eu.kanade.domain.source.service.SourcePreferences
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.stateIn
import logcat.LogPriority
import mihon.core.viewmodel.StateViewModel
import tachiyomi.core.common.util.system.logcat
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.time.Duration.Companion.seconds
class ExtensionFilterViewModel(
private val preferences: SourcePreferences = Injekt.get(),
private val getExtensionLanguages: GetExtensionLanguages = Injekt.get(),
private val toggleLanguage: ToggleLanguage = Injekt.get(),
) : StateViewModel<ExtensionFilterState>(ExtensionFilterState.Loading) {
) : ViewModel() {
private val _events: Channel<ExtensionFilterEvent> = Channel()
val events: Flow<ExtensionFilterEvent> = _events.receiveAsFlow()
init {
viewModelScope.launch {
combine(
getExtensionLanguages.subscribe(),
preferences.enabledLanguages.changes(),
) { a, b -> a to b }
.catch { throwable ->
logcat(LogPriority.ERROR, throwable)
_events.send(ExtensionFilterEvent.FailedFetchingLanguages)
}
.collectLatest { (extensionLanguages, enabledLanguages) ->
mutableState.update {
ExtensionFilterState.Success(
languages = extensionLanguages,
enabledLanguages = enabledLanguages,
)
}
}
}
val state: StateFlow<ExtensionFilterState> = combine(
getExtensionLanguages.subscribe(),
preferences.enabledLanguages.changes(),
) { extensionLanguages, enabledLanguages ->
ExtensionFilterState.Success(
languages = extensionLanguages,
enabledLanguages = enabledLanguages,
)
}
.catch { throwable ->
logcat(LogPriority.ERROR, throwable)
_events.send(ExtensionFilterEvent.FailedFetchingLanguages)
}
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), ExtensionFilterState.Loading)
fun toggle(language: String) {
toggleLanguage.await(language)