Skip to content

Commit

Permalink
Merge pull request #6965 from Bnyro/master
Browse files Browse the repository at this point in the history
fix: only show/hide scroll to top button at end of scrolling
  • Loading branch information
Bnyro authored Jan 16, 2025
2 parents f519168 + 5e53df0 commit b2e0701
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
Expand All @@ -15,6 +14,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.paging.LoadState
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.constants.IntentData
import com.github.libretube.databinding.FragmentCommentsBinding
Expand All @@ -31,8 +31,6 @@ class CommentsMainFragment : Fragment() {
private val binding get() = _binding!!
private val viewModel: CommentsViewModel by activityViewModels()

private var scrollListener: ViewTreeObserver.OnScrollChangedListener? = null

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand All @@ -57,20 +55,19 @@ class CommentsMainFragment : Fragment() {
viewModel.setCommentsPosition(POSITION_START)
}

var restoredScrollPosition = viewModel.currentCommentsPosition.value == 0
binding.commentsRV.viewTreeObserver.addOnScrollChangedListener {
// hide or show the scroll to top button
commentsSheet?.binding?.btnScrollToTop?.isVisible =
viewModel.currentCommentsPosition.value != 0
binding.commentsRV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState != RecyclerView.SCROLL_STATE_IDLE) return

val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
if (!restoredScrollPosition) {
restoredScrollPosition = firstVisiblePosition >= (viewModel.currentCommentsPosition.value ?: 0)
return@addOnScrollChangedListener
}
val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()

viewModel.setCommentsPosition(firstVisiblePosition)
}
// hide or show the scroll to top button
commentsSheet?.binding?.btnScrollToTop?.isVisible = firstVisiblePosition != 0
viewModel.setCommentsPosition(firstVisiblePosition)

super.onScrollStateChanged(recyclerView, newState)
}
})

commentsSheet?.updateFragmentInfo(false, getString(R.string.comments))

Expand All @@ -89,14 +86,17 @@ class CommentsMainFragment : Fragment() {
}
binding.commentsRV.adapter = commentPagingAdapter

var scrollPositionRestoreRequired = viewModel.currentCommentsPosition.value == 0
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
commentPagingAdapter.loadStateFlow.collect {
binding.progress.isVisible = it.refresh is LoadState.Loading

if (!restoredScrollPosition && it.refresh is LoadState.NotLoading) {
if (!scrollPositionRestoreRequired && it.refresh is LoadState.NotLoading) {
viewModel.currentCommentsPosition.value?.let { position ->
scrollPositionRestoreRequired = false

withContext(Dispatchers.Main) {
binding.commentsRV.scrollToPosition(position)
}
Expand Down Expand Up @@ -129,12 +129,6 @@ class CommentsMainFragment : Fragment() {
}
}

override fun onPause() {
super.onPause()
binding.commentsRV.viewTreeObserver.removeOnScrollChangedListener(scrollListener)
scrollListener = null
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.os.bundleOf
import androidx.core.view.isGone
import androidx.core.view.isVisible
Expand All @@ -19,6 +18,7 @@ import androidx.paging.LoadState
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.api.obj.Comment
import com.github.libretube.constants.IntentData
Expand All @@ -37,8 +37,6 @@ class CommentsRepliesFragment : Fragment() {

private val viewModel: CommentsViewModel by activityViewModels()

private var scrollListener: ViewTreeObserver.OnScrollChangedListener? = null

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand Down Expand Up @@ -97,15 +95,19 @@ class CommentsRepliesFragment : Fragment() {
viewModel.setRepliesPosition(POSITION_START)
}

scrollListener = ViewTreeObserver.OnScrollChangedListener {
// save the last scroll position to become used next time when the sheet is opened
viewModel.setRepliesPosition(layoutManager.findFirstVisibleItemPosition())
// hide or show the scroll to top button
commentsSheet?.binding?.btnScrollToTop?.isVisible =
viewModel.currentRepliesPosition.value != 0
}
binding.commentsRV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState != RecyclerView.SCROLL_STATE_IDLE) return

binding.commentsRV.viewTreeObserver.addOnScrollChangedListener(scrollListener)
val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()

// hide or show the scroll to top button
commentsSheet?.binding?.btnScrollToTop?.isVisible = firstVisiblePosition != 0
viewModel.setRepliesPosition(firstVisiblePosition)

super.onScrollStateChanged(recyclerView, newState)
}
})

val commentRepliesFlow = Pager(PagingConfig(20, enablePlaceholders = false)) {
CommentRepliesPagingSource(videoId, comment)
Expand All @@ -128,12 +130,6 @@ class CommentsRepliesFragment : Fragment() {
}
}

override fun onPause() {
super.onPause()
binding.commentsRV.viewTreeObserver.removeOnScrollChangedListener(scrollListener)
scrollListener = null
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
Expand Down

0 comments on commit b2e0701

Please sign in to comment.