diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt index dbd1148a2..f4879f7c6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt @@ -14,11 +14,11 @@ import androidx.compose.material3.Text import androidx.compose.material3.animateFloatingActionButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.CreationExtras import androidx.lifecycle.viewmodel.compose.viewModel import cafe.adriel.voyager.navigator.LocalNavigator @@ -55,7 +55,7 @@ data class MigrateMangaScreen( }, ) - val state by viewModel.state.collectAsState() + val state by viewModel.state.collectAsStateWithLifecycle() if (state.isLoading) { LoadingScreen() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaViewModel.kt index 1fd3d8633..104440a7c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaViewModel.kt @@ -1,34 +1,41 @@ package eu.kanade.tachiyomi.ui.browse.migration.manga import androidx.compose.runtime.Immutable +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.CreationExtras import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory import eu.kanade.tachiyomi.source.Source +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +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.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch import logcat.LogPriority import mihon.core.common.utils.mutate -import mihon.core.viewmodel.StateViewModel import tachiyomi.core.common.util.system.logcat import tachiyomi.domain.manga.interactor.GetFavorites import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.source.service.SourceManager import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import kotlin.time.Duration.Companion.seconds class MigrateMangaViewModel( private val sourceId: Long, private val sourceManager: SourceManager = Injekt.get(), private val getFavorites: GetFavorites = Injekt.get(), -) : StateViewModel(State()) { +) : ViewModel() { companion object { val SOURCE_ID_KEY = CreationExtras.Key() @@ -45,41 +52,39 @@ class MigrateMangaViewModel( private val _events: Channel = Channel() val events: Flow = _events.receiveAsFlow() - init { - viewModelScope.launch { - mutableState.update { state -> - state.copy(source = sourceManager.getOrStub(sourceId)) - } + private val source by lazy { sourceManager.getOrStub(sourceId) } - getFavorites.subscribe(sourceId) - .catch { - logcat(LogPriority.ERROR, it) - _events.send(MigrationMangaEvent.FailedFetchingFavorites) - mutableState.update { state -> - state.copy(titleList = listOf()) - } - } - .map { manga -> - manga - .sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.title }) - } - .collectLatest { list -> - mutableState.update { it.copy(titleList = list) } - } + private val selection = MutableStateFlow(emptySet()) + + private val favorites = getFavorites.subscribe(sourceId) + .catch { + logcat(LogPriority.ERROR, it) + _events.send(MigrationMangaEvent.FailedFetchingFavorites) + emit(listOf()) } + .map { manga -> + manga.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.title }) + } + + val state: StateFlow = combine( + favorites, + selection, + ) { titleList, selection -> + State(source = source, selection = selection, titleList = titleList) } + .flowOn(Dispatchers.IO) + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), State()) fun toggleSelection(item: Manga) { - mutableState.update { state -> - val selection = state.selection.mutate { list -> + selection.update { selection -> + selection.mutate { list -> if (!list.remove(item.id)) list.add(item.id) } - state.copy(selection = selection) } } fun clearSelection() { - mutableState.update { it.copy(selection = emptySet()) } + selection.update { emptySet() } } @Immutable