mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-27 23:40:33 +05:30
fix: multiple recyclerview adapter regressions in SubscriptionsFragment (#7085)
* Fix IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder * Fix new videos not being added to feed * Remove obsolete sortedFeed variable * Display items from start
This commit is contained in:
parent
18dd76093c
commit
481828c0f4
@ -18,9 +18,6 @@ import com.github.libretube.ui.viewholders.SubscriptionChannelViewHolder
|
||||
|
||||
class SubscriptionChannelAdapter :
|
||||
ListAdapter<Subscription, SubscriptionChannelViewHolder>(DiffUtilItemCallback()) {
|
||||
private var visibleCount = 20
|
||||
|
||||
override fun getItemCount() = minOf(visibleCount, currentList.size)
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
@ -31,13 +28,6 @@ class SubscriptionChannelAdapter :
|
||||
return SubscriptionChannelViewHolder(binding)
|
||||
}
|
||||
|
||||
fun updateItems() {
|
||||
val oldSize = visibleCount
|
||||
visibleCount += minOf(10, currentList.size - oldSize)
|
||||
if (visibleCount == oldSize) return
|
||||
notifyItemRangeInserted(oldSize, visibleCount)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: SubscriptionChannelViewHolder, position: Int) {
|
||||
val subscription = getItem(holder.bindingAdapterPosition)
|
||||
|
||||
|
@ -65,8 +65,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
private var isAppBarFullyExpanded = true
|
||||
|
||||
private var feedAdapter = VideosAdapter()
|
||||
private val sortedFeed: MutableList<StreamItem> = mutableListOf()
|
||||
|
||||
private var selectedSortOrder = PreferenceHelper.getInt(PreferenceKeys.FEED_SORT_ORDER, 0)
|
||||
set(value) {
|
||||
PreferenceHelper.putInt(PreferenceKeys.FEED_SORT_ORDER, value)
|
||||
@ -175,15 +173,10 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
|
||||
if (viewModel.subscriptions.value != null && isCurrentTabSubChannels) {
|
||||
binding.subRefresh.isRefreshing = true
|
||||
channelsAdapter.updateItems()
|
||||
binding.subRefresh.isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
binding.subFeed.addOnBottomReachedListener {
|
||||
loadNextFeedItems()
|
||||
}
|
||||
|
||||
// add some extra margin to the subscribed channels while the mini player is visible
|
||||
// otherwise the last channel would be invisible
|
||||
playerModel.isMiniPlayerVisible.observe(viewLifecycleOwner) {
|
||||
@ -192,8 +185,8 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
}
|
||||
}
|
||||
|
||||
binding.channelGroups.setOnCheckedStateChangeListener { group, checkedIds ->
|
||||
selectedFilterGroup = group.children.indexOfFirst { it.id == checkedIds.first() }
|
||||
binding.channelGroups.setOnCheckedStateChangeListener { group, _ ->
|
||||
selectedFilterGroup = group.children.indexOfFirst { it.id == group.checkedChipId }
|
||||
if (isCurrentTabSubChannels) showSubscriptions() else showFeed()
|
||||
}
|
||||
|
||||
@ -231,25 +224,22 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadNextFeedItems() {
|
||||
private fun loadFeedItems(sortedFeed: List<StreamItem>) {
|
||||
val binding = _binding ?: return
|
||||
|
||||
val hasMore = sortedFeed.size > feedAdapter.itemCount
|
||||
if (viewModel.videoFeed.value != null && !isCurrentTabSubChannels && !binding.subRefresh.isRefreshing && hasMore) {
|
||||
if (viewModel.videoFeed.value != null && !isCurrentTabSubChannels && !binding.subRefresh.isRefreshing) {
|
||||
binding.subRefresh.isRefreshing = true
|
||||
|
||||
lifecycleScope.launch {
|
||||
val toIndex = minOf(feedAdapter.itemCount + 10, sortedFeed.size)
|
||||
|
||||
var streamItemsToInsert = sortedFeed
|
||||
.subList(feedAdapter.itemCount, toIndex)
|
||||
.toList()
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching { streamItemsToInsert = streamItemsToInsert.deArrow() }
|
||||
val streamItemsToInsert = sortedFeed.let {
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching { it.deArrow() }.getOrDefault(it)
|
||||
}
|
||||
}
|
||||
|
||||
feedAdapter.insertItems(streamItemsToInsert)
|
||||
feedAdapter.submitList(streamItemsToInsert) {
|
||||
binding.subFeed.scrollToPosition(0)
|
||||
}
|
||||
binding.subRefresh.isRefreshing = false
|
||||
}
|
||||
}
|
||||
@ -383,15 +373,13 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
val sorted = feed
|
||||
.sortedBySelectedOrder()
|
||||
.toMutableList()
|
||||
sortedFeed.clear()
|
||||
sortedFeed.addAll(sorted)
|
||||
|
||||
// add an "all caught up item"
|
||||
if (selectedSortOrder == 0) {
|
||||
val lastCheckedFeedTime = PreferenceHelper.getLastCheckedFeedTime()
|
||||
val caughtUpIndex = feed.indexOfFirst { it.uploaded <= lastCheckedFeedTime && !it.isUpcoming }
|
||||
if (caughtUpIndex > 0) {
|
||||
sortedFeed.add(
|
||||
sorted.add(
|
||||
caughtUpIndex,
|
||||
StreamItem(type = VideosAdapter.CAUGHT_UP_STREAM_TYPE)
|
||||
)
|
||||
@ -404,13 +392,13 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
val notLoaded = viewModel.videoFeed.value.isNullOrEmpty()
|
||||
binding.subFeed.isGone = notLoaded
|
||||
binding.emptyFeed.isVisible = notLoaded
|
||||
loadNextFeedItems()
|
||||
loadFeedItems(sorted)
|
||||
|
||||
binding.toggleSubs.text = getString(R.string.subscriptions)
|
||||
|
||||
feed.firstOrNull { !it.isUpcoming }?.uploaded?.let {
|
||||
PreferenceHelper.setLastFeedWatchedTime(it)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@ -423,9 +411,13 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
)
|
||||
|
||||
if (legacySubscriptions) {
|
||||
legacySubscriptionsAdapter.submitList(subscriptions)
|
||||
legacySubscriptionsAdapter.submitList(subscriptions) {
|
||||
binding.subFeed.scrollToPosition(0)
|
||||
}
|
||||
} else {
|
||||
channelsAdapter.submitList(subscriptions)
|
||||
channelsAdapter.submitList(subscriptions) {
|
||||
binding.subFeed.scrollToPosition(0)
|
||||
}
|
||||
}
|
||||
|
||||
binding.subRefresh.isRefreshing = false
|
||||
@ -442,7 +434,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
|
||||
|
||||
fun removeItem(videoId: String) {
|
||||
feedAdapter.removeItemById(videoId)
|
||||
sortedFeed.removeAll { it.url?.toID() != videoId }
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user