diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceTab.kt index b4f8d2fd8..cda1422ad 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceTab.kt @@ -3,9 +3,9 @@ package eu.kanade.tachiyomi.ui.browse.migration.sources import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.HelpOutline import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.platform.LocalUriHandler +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator @@ -22,7 +22,7 @@ fun Screen.migrateSourceTab(): TabContent { val uriHandler = LocalUriHandler.current val navigator = LocalNavigator.currentOrThrow val viewModel = viewModel() - val state by viewModel.state.collectAsState() + val state by viewModel.state.collectAsStateWithLifecycle() return TabContent( titleRes = MR.strings.label_migration, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceViewModel.kt index 94a67213c..4f99f5b69 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceViewModel.kt @@ -1,79 +1,71 @@ package eu.kanade.tachiyomi.ui.browse.migration.sources import androidx.compose.runtime.Immutable +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount import eu.kanade.domain.source.interactor.SetMigrateSorting import eu.kanade.domain.source.service.SourcePreferences +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel +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.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.stateIn import logcat.LogPriority -import mihon.core.viewmodel.StateViewModel -import tachiyomi.core.common.util.lang.launchIO +import tachiyomi.core.common.preference.getAndSet import tachiyomi.core.common.util.system.logcat import tachiyomi.domain.source.model.Source import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import kotlin.time.Duration.Companion.seconds class MigrateSourceViewModel( - preferences: SourcePreferences = Injekt.get(), + private val preferences: SourcePreferences = Injekt.get(), private val getSourcesWithFavoriteCount: GetSourcesWithFavoriteCount = Injekt.get(), - private val setMigrateSorting: SetMigrateSorting = Injekt.get(), -) : StateViewModel(State()) { +) : ViewModel() { private val _channel = Channel(Int.MAX_VALUE) val channel = _channel.receiveAsFlow() - init { - viewModelScope.launchIO { - getSourcesWithFavoriteCount.subscribe() - .catch { - logcat(LogPriority.ERROR, it) - _channel.send(Event.FailedFetchingSourcesWithCount) - } - .collectLatest { sources -> - mutableState.update { - it.copy( - isLoading = false, - items = sources, - ) - } - } - } - - preferences.migrationSortingDirection.changes() - .onEach { mutableState.update { state -> state.copy(sortingDirection = it) } } - .launchIn(viewModelScope) - - preferences.migrationSortingMode.changes() - .onEach { mutableState.update { state -> state.copy(sortingMode = it) } } - .launchIn(viewModelScope) + val state: StateFlow = combine( + getSourcesWithFavoriteCount.subscribe() + .catch { + logcat(LogPriority.ERROR, it) + _channel.send(Event.FailedFetchingSourcesWithCount) + }, + preferences.migrationSortingMode.changes(), + preferences.migrationSortingDirection.changes(), + ) { sources, sortingMode, sortingDirection -> + State( + isLoading = false, + items = sources, + sortingMode = sortingMode, + sortingDirection = sortingDirection, + ) } + .flowOn(Dispatchers.IO) + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), State()) fun toggleSortingMode() { - with(state.value) { - val newMode = when (sortingMode) { + preferences.migrationSortingMode.getAndSet { mode -> + when (mode) { SetMigrateSorting.Mode.ALPHABETICAL -> SetMigrateSorting.Mode.TOTAL SetMigrateSorting.Mode.TOTAL -> SetMigrateSorting.Mode.ALPHABETICAL } - - setMigrateSorting.await(newMode, sortingDirection) } } fun toggleSortingDirection() { - with(state.value) { - val newDirection = when (sortingDirection) { + preferences.migrationSortingDirection.getAndSet { direction -> + when (direction) { SetMigrateSorting.Direction.ASCENDING -> SetMigrateSorting.Direction.DESCENDING SetMigrateSorting.Direction.DESCENDING -> SetMigrateSorting.Direction.ASCENDING } - - setMigrateSorting.await(sortingMode, newDirection) } }