Make MigrateMangaViewModel collect favorites only while subscribed (#3722)

Assisted-by: Claude:claude-opus-5
This commit is contained in:
AntsyLich
2026-08-08 11:59:04 +06:00
committed by GitHub
parent 6c0058d230
commit fab4cbd279
2 changed files with 35 additions and 30 deletions
@@ -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()
@@ -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<MigrateMangaViewModel.State>(State()) {
) : ViewModel() {
companion object {
val SOURCE_ID_KEY = CreationExtras.Key<Long>()
@@ -45,41 +52,39 @@ class MigrateMangaViewModel(
private val _events: Channel<MigrationMangaEvent> = Channel()
val events: Flow<MigrationMangaEvent> = _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<Long>())
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<State> = 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