refactor: simplify logic of loading comments and replies

This commit is contained in:
Bnyro 2023-11-17 15:10:02 +01:00
parent 73d12036f4
commit 155682bccc
4 changed files with 52 additions and 39 deletions

View File

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@ -72,23 +71,26 @@ class CommentsMainFragment : Fragment() {
}
binding.commentsRV.adapter = commentsAdapter
if (viewModel.commentsPage.value?.comments.orEmpty().isEmpty()) {
binding.progress.isVisible = true
if (viewModel.commentsPage.value?.comments.isNullOrEmpty()) {
viewModel.fetchComments()
} else {
binding.commentsRV.scrollToPosition(viewModel.currentCommentsPosition)
}
viewModel.isLoading.observe(viewLifecycleOwner) {
_binding?.progress?.isVisible = it == true
}
// listen for new comments to be loaded
viewModel.commentsPage.observe(viewLifecycleOwner) {
if (it == null) return@observe
val viewBinding = _binding ?: return@observe
if (it == null) return@observe
viewBinding.progress.isGone = true
if (it.disabled) {
viewBinding.errorTV.isVisible = true
return@observe
}
commentsSheet?.updateFragmentInfo(
false,
"${getString(R.string.comments)} (${it.commentCount.formatShort()})"

View File

@ -82,13 +82,11 @@ class CommentsRepliesFragment : Fragment() {
::repliesPage.isInitialized &&
repliesPage.nextpage != null
) {
fetchReplies(videoId, repliesPage.nextpage!!) {
repliesAdapter.updateItems(repliesPage.comments)
}
fetchReplies(videoId, repliesPage.nextpage!!)
}
}
loadInitialReplies(videoId, comment.repliesPage.orEmpty(), repliesAdapter)
loadInitialReplies(videoId, comment.repliesPage.orEmpty())
}
override fun onDestroyView() {
@ -98,34 +96,32 @@ class CommentsRepliesFragment : Fragment() {
private fun loadInitialReplies(
videoId: String,
nextPage: String,
repliesAdapter: CommentsAdapter
nextPage: String
) {
_binding?.progress?.isVisible = true
fetchReplies(videoId, nextPage) {
repliesAdapter.updateItems(it.comments)
_binding?.progress?.isGone = true
}
fetchReplies(videoId, nextPage)
}
private fun fetchReplies(
videoId: String,
nextPage: String,
onFinished: (CommentsPage) -> Unit
) {
lifecycleScope.launch(Dispatchers.IO) {
private fun fetchReplies(videoId: String, nextPage: String) {
_binding?.progress?.isVisible = true
lifecycleScope.launch {
if (isLoading) return@launch
isLoading = true
repliesPage = try {
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage)
withContext(Dispatchers.IO) {
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage)
}
} catch (e: Exception) {
Log.e(TAG(), "IOException, you might not have internet connection")
return@launch
} finally {
_binding?.progress?.isGone = true
}
repliesPage.comments = repliesPage.comments.filterNonEmptyComments()
withContext(Dispatchers.Main) {
onFinished.invoke(repliesPage)
repliesAdapter.updateItems(repliesPage.comments)
}
isLoading = false
}

View File

@ -10,6 +10,7 @@ import com.github.libretube.extensions.TAG
import com.github.libretube.ui.extensions.filterNonEmptyComments
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class CommentsViewModel : ViewModel() {
val commentsPage = MutableLiveData<CommentsPage?>()
@ -17,11 +18,12 @@ class CommentsViewModel : ViewModel() {
var videoId: String? = null
var channelAvatar: String? = null
var handleLink: ((url: String) -> Unit)? = null
private var nextPage: String? = null
private var isLoading = false
var isLoading = MutableLiveData<Boolean>()
var currentCommentsPosition = 0
var commentsSheetDismiss: (() -> Unit)? = null
var handleLink: ((url: String) -> Unit)? = null
fun setCommentSheetExpand(value: Boolean?) {
if (commentSheetExpand.value != value) {
@ -30,31 +32,43 @@ class CommentsViewModel : ViewModel() {
}
fun fetchComments() {
videoId ?: return
viewModelScope.launch(Dispatchers.IO) {
isLoading = true
val videoId = videoId ?: return
isLoading.value = true
viewModelScope.launch {
val response = try {
RetrofitInstance.api.getComments(videoId!!)
withContext(Dispatchers.IO) {
RetrofitInstance.api.getComments(videoId)
}
} catch (e: Exception) {
Log.e(TAG(), e.toString())
return@launch
} finally {
isLoading.value = false
}
nextPage = response.nextpage
response.comments = response.comments.filterNonEmptyComments()
commentsPage.postValue(response)
isLoading = false
}
}
fun fetchNextComments() {
if (isLoading || nextPage == null || videoId == null) return
viewModelScope.launch(Dispatchers.IO) {
isLoading = true
if (isLoading.value == true || nextPage == null || videoId == null) return
isLoading.value = true
viewModelScope.launch {
val response = try {
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
withContext(Dispatchers.IO) {
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
}
} catch (e: Exception) {
Log.e(TAG(), e.toString())
return@launch
} finally {
isLoading.value = false
}
val updatedPage = commentsPage.value?.apply {
@ -65,12 +79,11 @@ class CommentsViewModel : ViewModel() {
nextPage = response.nextpage
commentsPage.postValue(updatedPage)
isLoading = false
}
}
fun reset() {
isLoading = false
isLoading.value = false
nextPage = null
commentsPage.value = null
videoId = null

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/commentsRV"
@ -15,6 +16,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:visibility="gone" />
<TextView
@ -26,4 +28,4 @@
android:text="@string/comments_disabled"
android:visibility="gone" />
</FrameLayout>
</LinearLayout>