Merge pull request #5751 from Bnyro/fix-comment-replies

fix: false message about no comments and scroll to top button
This commit is contained in:
Bnyro 2024-03-17 13:00:58 +01:00 committed by GitHub
commit ae51baaf2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 84 additions and 10 deletions

View File

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@ -25,6 +26,8 @@ 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?,
@ -45,17 +48,19 @@ class CommentsMainFragment : Fragment() {
val commentsSheet = parentFragment as? CommentsSheet
commentsSheet?.binding?.btnScrollToTop?.setOnClickListener {
// scroll back to the top / first comment
_binding?.commentsRV?.smoothScrollToPosition(0)
viewModel.currentCommentsPosition = 0
_binding?.commentsRV?.smoothScrollToPosition(POSITION_START)
viewModel.setCommentsPosition(POSITION_START)
}
binding.commentsRV.viewTreeObserver.addOnScrollChangedListener {
scrollListener = ViewTreeObserver.OnScrollChangedListener {
// save the last scroll position to become used next time when the sheet is opened
viewModel.currentCommentsPosition = layoutManager.findFirstVisibleItemPosition()
viewModel.setCommentsPosition(layoutManager.findFirstVisibleItemPosition())
// hide or show the scroll to top button
commentsSheet?.binding?.btnScrollToTop?.isVisible = viewModel.currentCommentsPosition != 0
commentsSheet?.binding?.btnScrollToTop?.isVisible =
viewModel.currentCommentsPosition.value != 0
}
binding.commentsRV.viewTreeObserver.addOnScrollChangedListener(scrollListener)
commentsSheet?.updateFragmentInfo(false, getString(R.string.comments))
val commentPagingAdapter = CommentPagingAdapter(
@ -74,7 +79,7 @@ class CommentsMainFragment : Fragment() {
commentPagingAdapter.loadStateFlow.collect {
binding.progress.isVisible = it.refresh is LoadState.Loading
if (it.append is LoadState.NotLoading && it.append.endOfPaginationReached) {
if (it.append is LoadState.NotLoading && it.append.endOfPaginationReached && commentPagingAdapter.itemCount == 0) {
binding.errorTV.text = getString(R.string.no_comments_available)
binding.errorTV.isVisible = true
return@collect
@ -97,8 +102,18 @@ class CommentsMainFragment : Fragment() {
}
}
override fun onPause() {
super.onPause()
binding.commentsRV.viewTreeObserver.removeOnScrollChangedListener(scrollListener)
scrollListener = null
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
private const val POSITION_START = 0
}
}

View File

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
@ -31,6 +32,8 @@ class CommentsRepliesFragment : Fragment() {
private val viewModel: CommentsViewModel by activityViewModels()
private var scrollListener: ViewTreeObserver.OnScrollChangedListener? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -66,9 +69,37 @@ class CommentsRepliesFragment : Fragment() {
)
binding.commentsRV.updatePadding(top = 0)
binding.commentsRV.layoutManager = LinearLayoutManager(context)
val layoutManager = LinearLayoutManager(context)
binding.commentsRV.layoutManager = layoutManager
binding.commentsRV.adapter = repliesAdapter
// init scroll position
if (viewModel.currentRepliesPosition.value != null) {
if (viewModel.currentRepliesPosition.value!! > POSITION_START) {
layoutManager.scrollToPosition(viewModel.currentRepliesPosition.value!!)
} else {
layoutManager.scrollToPosition(POSITION_START)
}
}
commentsSheet?.binding?.btnScrollToTop?.setOnClickListener {
// scroll back to the top / first comment
layoutManager.scrollToPosition(POSITION_START)
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.viewTreeObserver.addOnScrollChangedListener(scrollListener)
viewModel.selectedCommentLiveData.postValue(comment.repliesPage)
viewLifecycleOwner.lifecycleScope.launch {
@ -88,8 +119,18 @@ class CommentsRepliesFragment : Fragment() {
}
}
override fun onPause() {
super.onPause()
binding.commentsRV.viewTreeObserver.removeOnScrollChangedListener(scrollListener)
scrollListener = null
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
const val POSITION_START = 0
}
}

View File

@ -1,5 +1,6 @@
package com.github.libretube.ui.models
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asFlow
@ -41,7 +42,12 @@ class CommentsViewModel : ViewModel() {
var channelAvatar: String? = null
var handleLink: ((url: String) -> Unit)? = null
var currentCommentsPosition = 0
private val _currentCommentsPosition = MutableLiveData(0)
val currentCommentsPosition: LiveData<Int> = _currentCommentsPosition
private val _currentRepliesPosition = MutableLiveData(0)
val currentRepliesPosition: LiveData<Int> = _currentRepliesPosition
var commentsSheetDismiss: (() -> Unit)? = null
fun setCommentSheetExpand(value: Boolean?) {
@ -52,6 +58,18 @@ class CommentsViewModel : ViewModel() {
fun reset() {
setCommentSheetExpand(null)
currentCommentsPosition = 0
_currentCommentsPosition.value = 0
}
fun setCommentsPosition(position: Int) {
if (position != currentCommentsPosition.value) {
_currentCommentsPosition.postValue(position)
}
}
fun setRepliesPosition(position: Int) {
if (position != currentRepliesPosition.value) {
_currentRepliesPosition.postValue(position)
}
}
}