Make DownloadQueueViewModel collect downloads only while subscribed (#3727)

Assisted-by: Claude:claude-opus-5
This commit is contained in:
AntsyLich
2026-08-08 20:04:29 +06:00
committed by GitHub
parent ae37c1651a
commit c68efd0e86
2 changed files with 18 additions and 25 deletions
@@ -19,7 +19,6 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.animateFloatingActionButton
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -41,6 +40,7 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.ViewCompat
import androidx.core.view.updatePadding
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.recyclerview.widget.LinearLayoutManager
import cafe.adriel.voyager.navigator.LocalNavigator
@@ -66,7 +66,7 @@ object DownloadQueueScreen : Screen() {
val navigator = LocalNavigator.currentOrThrow
val scope = rememberCoroutineScope()
val viewModel = viewModel<DownloadQueueViewModel>()
val downloadList by viewModel.state.collectAsState()
val downloadList by viewModel.state.collectAsStateWithLifecycle()
val downloadCount by remember {
derivedStateOf { downloadList.sumOf { it.subItems.size } }
}
@@ -198,7 +198,7 @@ object DownloadQueueScreen : Screen() {
)
},
floatingActionButton = {
val isRunning by viewModel.isDownloaderRunning.collectAsState()
val isRunning by viewModel.isDownloaderRunning.collectAsStateWithLifecycle()
SmallExtendedFloatingActionButton(
text = {
val id = if (isRunning) {
@@ -10,27 +10,36 @@ import eu.kanade.tachiyomi.databinding.DownloadListBinding
import eu.kanade.tachiyomi.source.model.Page
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
class DownloadQueueViewModel(
private val downloadManager: DownloadManager = Injekt.get(),
) : ViewModel() {
private val _state = MutableStateFlow(emptyList<DownloadHeaderItem>())
val state = _state.asStateFlow()
val state: StateFlow<List<DownloadHeaderItem>> = downloadManager.queueState
.map { downloads ->
downloads
.groupBy { it.source }
.map { entry ->
DownloadHeaderItem(entry.key.id, entry.key.name, entry.value.size).apply {
addSubItems(0, entry.value.map { DownloadItem(it, this) })
}
}
}
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), emptyList())
lateinit var controllerBinding: DownloadListBinding
@@ -116,22 +125,6 @@ class DownloadQueueViewModel(
}
}
init {
viewModelScope.launch {
downloadManager.queueState
.map { downloads ->
downloads
.groupBy { it.source }
.map { entry ->
DownloadHeaderItem(entry.key.id, entry.key.name, entry.value.size).apply {
addSubItems(0, entry.value.map { DownloadItem(it, this) })
}
}
}
.collect { newList -> _state.update { newList } }
}
}
override fun onCleared() {
for (job in progressJobs.values) {
job.cancel()
@@ -141,7 +134,7 @@ class DownloadQueueViewModel(
}
val isDownloaderRunning = downloadManager.isDownloaderRunning
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false)
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), false)
fun getDownloadStatusFlow() = downloadManager.statusFlow()
fun getDownloadProgressFlow() = downloadManager.progressFlow()