Make MigrateSourceViewModel collect sources only while subscribed (#3723)
Assisted-by: Claude:claude-opus-5
This commit is contained in:
+2
-2
@@ -3,9 +3,9 @@ package eu.kanade.tachiyomi.ui.browse.migration.sources
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
@@ -22,7 +22,7 @@ fun Screen.migrateSourceTab(): TabContent {
|
|||||||
val uriHandler = LocalUriHandler.current
|
val uriHandler = LocalUriHandler.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val viewModel = viewModel<MigrateSourceViewModel>()
|
val viewModel = viewModel<MigrateSourceViewModel>()
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
return TabContent(
|
return TabContent(
|
||||||
titleRes = MR.strings.label_migration,
|
titleRes = MR.strings.label_migration,
|
||||||
|
|||||||
+26
-34
@@ -1,79 +1,71 @@
|
|||||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||||
|
|
||||||
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.source.interactor.GetSourcesWithFavoriteCount
|
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
|
||||||
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.channels.Channel
|
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.catch
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import mihon.core.viewmodel.StateViewModel
|
import tachiyomi.core.common.preference.getAndSet
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.core.common.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
import tachiyomi.domain.source.model.Source
|
import tachiyomi.domain.source.model.Source
|
||||||
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 MigrateSourceViewModel(
|
class MigrateSourceViewModel(
|
||||||
preferences: SourcePreferences = Injekt.get(),
|
private val preferences: SourcePreferences = Injekt.get(),
|
||||||
private val getSourcesWithFavoriteCount: GetSourcesWithFavoriteCount = Injekt.get(),
|
private val getSourcesWithFavoriteCount: GetSourcesWithFavoriteCount = Injekt.get(),
|
||||||
private val setMigrateSorting: SetMigrateSorting = Injekt.get(),
|
) : ViewModel() {
|
||||||
) : StateViewModel<MigrateSourceViewModel.State>(State()) {
|
|
||||||
|
|
||||||
private val _channel = Channel<Event>(Int.MAX_VALUE)
|
private val _channel = Channel<Event>(Int.MAX_VALUE)
|
||||||
val channel = _channel.receiveAsFlow()
|
val channel = _channel.receiveAsFlow()
|
||||||
|
|
||||||
init {
|
val state: StateFlow<State> = combine(
|
||||||
viewModelScope.launchIO {
|
|
||||||
getSourcesWithFavoriteCount.subscribe()
|
getSourcesWithFavoriteCount.subscribe()
|
||||||
.catch {
|
.catch {
|
||||||
logcat(LogPriority.ERROR, it)
|
logcat(LogPriority.ERROR, it)
|
||||||
_channel.send(Event.FailedFetchingSourcesWithCount)
|
_channel.send(Event.FailedFetchingSourcesWithCount)
|
||||||
}
|
},
|
||||||
.collectLatest { sources ->
|
preferences.migrationSortingMode.changes(),
|
||||||
mutableState.update {
|
preferences.migrationSortingDirection.changes(),
|
||||||
it.copy(
|
) { sources, sortingMode, sortingDirection ->
|
||||||
|
State(
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
items = sources,
|
items = sources,
|
||||||
|
sortingMode = sortingMode,
|
||||||
|
sortingDirection = sortingDirection,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
.flowOn(Dispatchers.IO)
|
||||||
}
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), State())
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toggleSortingMode() {
|
fun toggleSortingMode() {
|
||||||
with(state.value) {
|
preferences.migrationSortingMode.getAndSet { mode ->
|
||||||
val newMode = when (sortingMode) {
|
when (mode) {
|
||||||
SetMigrateSorting.Mode.ALPHABETICAL -> SetMigrateSorting.Mode.TOTAL
|
SetMigrateSorting.Mode.ALPHABETICAL -> SetMigrateSorting.Mode.TOTAL
|
||||||
SetMigrateSorting.Mode.TOTAL -> SetMigrateSorting.Mode.ALPHABETICAL
|
SetMigrateSorting.Mode.TOTAL -> SetMigrateSorting.Mode.ALPHABETICAL
|
||||||
}
|
}
|
||||||
|
|
||||||
setMigrateSorting.await(newMode, sortingDirection)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleSortingDirection() {
|
fun toggleSortingDirection() {
|
||||||
with(state.value) {
|
preferences.migrationSortingDirection.getAndSet { direction ->
|
||||||
val newDirection = when (sortingDirection) {
|
when (direction) {
|
||||||
SetMigrateSorting.Direction.ASCENDING -> SetMigrateSorting.Direction.DESCENDING
|
SetMigrateSorting.Direction.ASCENDING -> SetMigrateSorting.Direction.DESCENDING
|
||||||
SetMigrateSorting.Direction.DESCENDING -> SetMigrateSorting.Direction.ASCENDING
|
SetMigrateSorting.Direction.DESCENDING -> SetMigrateSorting.Direction.ASCENDING
|
||||||
}
|
}
|
||||||
|
|
||||||
setMigrateSorting.await(sortingMode, newDirection)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user