Merge pull request #2845 from Bnyro/master

Fix unresponsiveness when opening watch history
This commit is contained in:
Bnyro 2023-01-23 18:22:24 +01:00 committed by GitHub
commit dbd6516b62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 26 deletions

View File

@ -26,7 +26,7 @@ object DatabaseHelper {
query { query {
Database.watchHistoryDao().insertAll(watchHistoryItem) Database.watchHistoryDao().insertAll(watchHistoryItem)
val maxHistorySize = val maxHistorySize =
PreferenceHelper.getString(PreferenceKeys.WATCH_HISTORY_SIZE, "unlimited") PreferenceHelper.getString(PreferenceKeys.WATCH_HISTORY_SIZE, "100")
if (maxHistorySize == "unlimited") return@query if (maxHistorySize == "unlimited") return@query
// delete the first watch history entry if the limit is reached // delete the first watch history entry if the limit is reached

View File

@ -21,6 +21,10 @@ class WatchHistoryAdapter(
) : ) :
RecyclerView.Adapter<WatchHistoryViewHolder>() { RecyclerView.Adapter<WatchHistoryViewHolder>() {
var visibleCount = minOf(10, watchHistory.size)
override fun getItemCount(): Int = visibleCount
fun removeFromWatchHistory(position: Int) { fun removeFromWatchHistory(position: Int) {
val history = watchHistory[position] val history = watchHistory[position]
query { query {
@ -31,6 +35,13 @@ class WatchHistoryAdapter(
notifyItemRangeChanged(position, itemCount) notifyItemRangeChanged(position, itemCount)
} }
fun showMoreItems() {
val oldSize = visibleCount
visibleCount += minOf(10, watchHistory.size - oldSize)
if (visibleCount == oldSize) return
notifyItemRangeInserted(oldSize, visibleCount)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WatchHistoryViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WatchHistoryViewHolder {
val layoutInflater = LayoutInflater.from(parent.context) val layoutInflater = LayoutInflater.from(parent.context)
val binding = VideoRowBinding.inflate(layoutInflater, parent, false) val binding = VideoRowBinding.inflate(layoutInflater, parent, false)
@ -71,8 +82,4 @@ class WatchHistoryAdapter(
watchProgress.setWatchProgressLength(video.videoId, video.duration) watchProgress.setWatchProgressLength(video.videoId, video.duration)
} }
} }
override fun getItemCount(): Int {
return watchHistory.size
}
} }

View File

@ -91,9 +91,7 @@ class ChannelFragment : BaseFragment() {
binding.channelScrollView.viewTreeObserver binding.channelScrollView.viewTreeObserver
.addOnScrollChangedListener { .addOnScrollChangedListener {
if (binding.channelScrollView.getChildAt(0).bottom if (!binding.channelScrollView.canScrollVertically(1)) {
== (binding.channelScrollView.height + binding.channelScrollView.scrollY)
) {
try { try {
onScrollEnd.invoke() onScrollEnd.invoke()
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -212,9 +212,7 @@ class PlaylistFragment : BaseFragment() {
binding.playlistRecView.adapter = playlistAdapter binding.playlistRecView.adapter = playlistAdapter
binding.playlistScrollview.viewTreeObserver binding.playlistScrollview.viewTreeObserver
.addOnScrollChangedListener { .addOnScrollChangedListener {
if (binding.playlistScrollview.getChildAt(0).bottom if (!binding.playlistScrollview.canScrollVertically(1)) {
== (binding.playlistScrollview.height + binding.playlistScrollview.scrollY)
) {
if (isLoading) return@addOnScrollChangedListener if (isLoading) return@addOnScrollChangedListener
// append more playlists to the recycler view // append more playlists to the recycler view

View File

@ -137,9 +137,7 @@ class SubscriptionsFragment : BaseFragment() {
binding.scrollviewSub.viewTreeObserver binding.scrollviewSub.viewTreeObserver
.addOnScrollChangedListener { .addOnScrollChangedListener {
if (binding.scrollviewSub.getChildAt(0).bottom if (!binding.scrollviewSub.canScrollVertically(1)) {
== (binding.scrollviewSub.height + binding.scrollviewSub.scrollY)
) {
// scroll view is at bottom // scroll view is at bottom
if (viewModel.videoFeed.value == null) return@addOnScrollChangedListener if (viewModel.videoFeed.value == null) return@addOnScrollChangedListener
binding.subRefresh.isRefreshing = true binding.subRefresh.isRefreshing = true

View File

@ -1,6 +1,8 @@
package com.github.libretube.ui.fragments package com.github.libretube.ui.fragments
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -28,6 +30,7 @@ class WatchHistoryFragment : BaseFragment() {
private lateinit var binding: FragmentWatchHistoryBinding private lateinit var binding: FragmentWatchHistoryBinding
private val playerViewModel: PlayerViewModel by activityViewModels() private val playerViewModel: PlayerViewModel by activityViewModels()
private var isLoading = false
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -49,7 +52,7 @@ class WatchHistoryFragment : BaseFragment() {
val watchHistory = awaitQuery { val watchHistory = awaitQuery {
Database.watchHistoryDao().getAll() Database.watchHistoryDao().getAll()
} }.reversed()
if (watchHistory.isEmpty()) return if (watchHistory.isEmpty()) return
@ -96,16 +99,15 @@ class WatchHistoryFragment : BaseFragment() {
) )
} }
// reversed order
binding.watchHistoryRecView.layoutManager = LinearLayoutManager(requireContext()).apply {
reverseLayout = true
stackFromEnd = true
}
val watchHistoryAdapter = WatchHistoryAdapter( val watchHistoryAdapter = WatchHistoryAdapter(
watchHistory.toMutableList() watchHistory.toMutableList()
) )
binding.watchHistoryRecView.layoutManager = LinearLayoutManager(context)
binding.watchHistoryRecView.adapter = watchHistoryAdapter
binding.historyEmpty.visibility = View.GONE
binding.historyScrollView.visibility = View.VISIBLE
val itemTouchCallback = object : ItemTouchHelper.SimpleCallback( val itemTouchCallback = object : ItemTouchHelper.SimpleCallback(
0, 0,
ItemTouchHelper.LEFT ItemTouchHelper.LEFT
@ -130,7 +132,7 @@ class WatchHistoryFragment : BaseFragment() {
val itemTouchHelper = ItemTouchHelper(itemTouchCallback) val itemTouchHelper = ItemTouchHelper(itemTouchCallback)
itemTouchHelper.attachToRecyclerView(binding.watchHistoryRecView) itemTouchHelper.attachToRecyclerView(binding.watchHistoryRecView)
// observe changes // observe changes to indicate if the history is empty
watchHistoryAdapter.registerAdapterDataObserver(object : watchHistoryAdapter.registerAdapterDataObserver(object :
RecyclerView.AdapterDataObserver() { RecyclerView.AdapterDataObserver() {
override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) { override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
@ -141,8 +143,15 @@ class WatchHistoryFragment : BaseFragment() {
} }
}) })
binding.watchHistoryRecView.adapter = watchHistoryAdapter // add a listener for scroll end, delay needed to prevent loading new ones the first time
binding.historyEmpty.visibility = View.GONE Handler(Looper.getMainLooper()).postDelayed({
binding.historyScrollView.visibility = View.VISIBLE binding.historyScrollView.viewTreeObserver.addOnScrollChangedListener {
if (!binding.historyScrollView.canScrollVertically(1) && !isLoading) {
isLoading = true
watchHistoryAdapter.showMoreItems()
isLoading = false
}
}
}, 200)
} }
} }

View File

@ -28,7 +28,7 @@
app:title="@string/watch_history" /> app:title="@string/watch_history" />
<ListPreference <ListPreference
android:defaultValue="unlimited" android:defaultValue="100"
android:entries="@array/historySize" android:entries="@array/historySize"
android:entryValues="@array/historySizeValues" android:entryValues="@array/historySizeValues"
android:icon="@drawable/ic_list" android:icon="@drawable/ic_list"