Make ExtensionFilterViewModel collect languages only while subscribed (#3718)
Assisted-by: Claude:claude-opus-5
This commit is contained in:
@@ -2,9 +2,9 @@ package eu.kanade.tachiyomi.ui.browse.extension
|
|||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
@@ -22,7 +22,7 @@ class ExtensionFilterScreen : Screen() {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val viewModel = viewModel<ExtensionFilterViewModel>()
|
val viewModel = viewModel<ExtensionFilterViewModel>()
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
if (state is ExtensionFilterState.Loading) {
|
if (state is ExtensionFilterState.Loading) {
|
||||||
LoadingScreen()
|
LoadingScreen()
|
||||||
|
|||||||
+13
-17
@@ -1,53 +1,49 @@
|
|||||||
package eu.kanade.tachiyomi.ui.browse.extension
|
package eu.kanade.tachiyomi.ui.browse.extension
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
|
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
|
||||||
import eu.kanade.domain.source.interactor.ToggleLanguage
|
import eu.kanade.domain.source.interactor.ToggleLanguage
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
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.catch
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import mihon.core.viewmodel.StateViewModel
|
|
||||||
import tachiyomi.core.common.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
class ExtensionFilterViewModel(
|
class ExtensionFilterViewModel(
|
||||||
private val preferences: SourcePreferences = Injekt.get(),
|
private val preferences: SourcePreferences = Injekt.get(),
|
||||||
private val getExtensionLanguages: GetExtensionLanguages = Injekt.get(),
|
private val getExtensionLanguages: GetExtensionLanguages = Injekt.get(),
|
||||||
private val toggleLanguage: ToggleLanguage = Injekt.get(),
|
private val toggleLanguage: ToggleLanguage = Injekt.get(),
|
||||||
) : StateViewModel<ExtensionFilterState>(ExtensionFilterState.Loading) {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _events: Channel<ExtensionFilterEvent> = Channel()
|
private val _events: Channel<ExtensionFilterEvent> = Channel()
|
||||||
val events: Flow<ExtensionFilterEvent> = _events.receiveAsFlow()
|
val events: Flow<ExtensionFilterEvent> = _events.receiveAsFlow()
|
||||||
|
|
||||||
init {
|
val state: StateFlow<ExtensionFilterState> = combine(
|
||||||
viewModelScope.launch {
|
|
||||||
combine(
|
|
||||||
getExtensionLanguages.subscribe(),
|
getExtensionLanguages.subscribe(),
|
||||||
preferences.enabledLanguages.changes(),
|
preferences.enabledLanguages.changes(),
|
||||||
) { a, b -> a to b }
|
) { extensionLanguages, enabledLanguages ->
|
||||||
.catch { throwable ->
|
|
||||||
logcat(LogPriority.ERROR, throwable)
|
|
||||||
_events.send(ExtensionFilterEvent.FailedFetchingLanguages)
|
|
||||||
}
|
|
||||||
.collectLatest { (extensionLanguages, enabledLanguages) ->
|
|
||||||
mutableState.update {
|
|
||||||
ExtensionFilterState.Success(
|
ExtensionFilterState.Success(
|
||||||
languages = extensionLanguages,
|
languages = extensionLanguages,
|
||||||
enabledLanguages = enabledLanguages,
|
enabledLanguages = enabledLanguages,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.catch { throwable ->
|
||||||
|
logcat(LogPriority.ERROR, throwable)
|
||||||
|
_events.send(ExtensionFilterEvent.FailedFetchingLanguages)
|
||||||
}
|
}
|
||||||
}
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), ExtensionFilterState.Loading)
|
||||||
}
|
|
||||||
|
|
||||||
fun toggle(language: String) {
|
fun toggle(language: String) {
|
||||||
toggleLanguage.await(language)
|
toggleLanguage.await(language)
|
||||||
|
|||||||
Reference in New Issue
Block a user