fix: don't block ui thread while filtering watched videos

This commit is contained in:
Bnyro 2025-04-23 19:37:41 +02:00
parent 4445df6ede
commit c255d1b1c2
No known key found for this signature in database
4 changed files with 20 additions and 21 deletions

View File

@ -1,7 +1,5 @@
package com.github.libretube.api
import android.content.Context
import com.github.libretube.R
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.obj.SubscriptionsFeedItem
import com.github.libretube.helpers.PreferenceHelper
@ -14,8 +12,6 @@ import com.github.libretube.repo.PipedAccountFeedRepository
import com.github.libretube.repo.PipedLocalSubscriptionsRepository
import com.github.libretube.repo.PipedNoAccountFeedRepository
import com.github.libretube.repo.SubscriptionsRepository
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.runBlocking
object SubscriptionHelper {
/**

View File

@ -102,7 +102,7 @@ object DatabaseHelper {
return unfinished xor isVideoWatched(watchHistoryItem.videoId, watchHistoryItem.duration ?: 0)
}
fun filterByStatusAndWatchPosition(
suspend fun filterByStatusAndWatchPosition(
streams: List<StreamItem>,
hideWatched: Boolean
): List<StreamItem> {
@ -116,13 +116,8 @@ object DatabaseHelper {
else -> true
}
}
if (!hideWatched) return streamItems
return if (hideWatched) {
runBlocking {
filterUnwatched(streamItems)
}
} else {
streamItems
}
return filterUnwatched(streamItems)
}
}

View File

@ -28,6 +28,7 @@ import com.github.libretube.ui.extensions.setupFragmentAnimation
import com.github.libretube.ui.models.HomeViewModel
import com.github.libretube.ui.models.SubscriptionsViewModel
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.runBlocking
class HomeFragment : Fragment(R.layout.fragment_home) {
@ -150,7 +151,7 @@ class HomeFragment : Fragment(R.layout.fragment_home) {
makeVisible(binding.featuredRV, binding.featuredTV)
val hideWatched = PreferenceHelper.getBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, false)
val feedVideos = streamItems
.let { DatabaseHelper.filterByStatusAndWatchPosition(it, hideWatched) }
.let { runBlocking { DatabaseHelper.filterByStatusAndWatchPosition(it, hideWatched) } }
.take(20)
feedAdapter.submitList(feedVideos)

View File

@ -142,7 +142,9 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
var alreadyShowedFeedOnce = false
viewModel.videoFeed.observe(viewLifecycleOwner) {
if (!viewModel.isCurrentTabSubChannels && it != null) {
lifecycleScope.launch {
showFeed(!alreadyShowedFeedOnce)
}
alreadyShowedFeedOnce = true
}
}
@ -179,7 +181,9 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
binding.subRefresh.isRefreshing = true
viewModel.isCurrentTabSubChannels = !viewModel.isCurrentTabSubChannels
lifecycleScope.launch {
if (viewModel.isCurrentTabSubChannels) showSubscriptions() else showFeed()
}
binding.subChannels.isVisible = viewModel.isCurrentTabSubChannels
binding.subFeed.isGone = viewModel.isCurrentTabSubChannels
@ -204,8 +208,11 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
binding.channelGroups.setOnCheckedStateChangeListener { group, _ ->
selectedFilterGroup = group.children.indexOfFirst { it.id == group.checkedChipId }
lifecycleScope.launch {
if (viewModel.isCurrentTabSubChannels) showSubscriptions() else showFeed()
}
}
channelGroupsModel.groups.observe(viewLifecycleOwner) {
lifecycleScope.launch { initChannelGroups() }
@ -256,7 +263,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
selectedSortOrder = resultBundle.getInt(IntentData.sortOptions)
hideWatched = resultBundle.getBoolean(IntentData.hideWatched)
showUpcoming = resultBundle.getBoolean(IntentData.showUpcoming)
showFeed()
lifecycleScope.launch { showFeed() }
}
FilterSortBottomSheet()
@ -283,7 +290,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
_binding = null
}
private fun playByGroup(groupIndex: Int) {
private suspend fun playByGroup(groupIndex: Int) {
val streams = viewModel.videoFeed.value.orEmpty()
.filterByGroup(groupIndex)
.let { DatabaseHelper.filterByStatusAndWatchPosition(it, hideWatched) }
@ -306,7 +313,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
binding.chipAll.isChecked = selectedFilterGroup == 0
binding.chipAll.setOnLongClickListener {
playByGroup(0)
lifecycleScope.launch { playByGroup(0) }
true
}
@ -321,7 +328,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
text = group.name
setOnLongClickListener {
// the index must be increased by one to skip the "all channels" group button
playByGroup(index + 1)
lifecycleScope.launch { playByGroup(index + 1) }
true
}
}
@ -360,7 +367,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
else -> this
}
private fun showFeed(restoreScrollState: Boolean = true) {
private suspend fun showFeed(restoreScrollState: Boolean = true) {
val binding = _binding ?: return
val videoFeed = viewModel.videoFeed.value ?: return