Make MigrateMangaViewModel collect favorites only while subscribed (#3722)
Assisted-by: Claude:claude-opus-5
This commit is contained in:
+2
-2
@@ -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()
|
||||
|
||||
+33
-28
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user