mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 08:20:32 +05:30
refactor: simplify logic of loading comments and replies
This commit is contained in:
parent
73d12036f4
commit
155682bccc
@ -4,7 +4,6 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isGone
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
@ -72,23 +71,26 @@ class CommentsMainFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
binding.commentsRV.adapter = commentsAdapter
|
binding.commentsRV.adapter = commentsAdapter
|
||||||
|
|
||||||
if (viewModel.commentsPage.value?.comments.orEmpty().isEmpty()) {
|
if (viewModel.commentsPage.value?.comments.isNullOrEmpty()) {
|
||||||
binding.progress.isVisible = true
|
|
||||||
viewModel.fetchComments()
|
viewModel.fetchComments()
|
||||||
} else {
|
} else {
|
||||||
binding.commentsRV.scrollToPosition(viewModel.currentCommentsPosition)
|
binding.commentsRV.scrollToPosition(viewModel.currentCommentsPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||||
|
_binding?.progress?.isVisible = it == true
|
||||||
|
}
|
||||||
|
|
||||||
// listen for new comments to be loaded
|
// listen for new comments to be loaded
|
||||||
viewModel.commentsPage.observe(viewLifecycleOwner) {
|
viewModel.commentsPage.observe(viewLifecycleOwner) {
|
||||||
|
if (it == null) return@observe
|
||||||
val viewBinding = _binding ?: return@observe
|
val viewBinding = _binding ?: return@observe
|
||||||
|
|
||||||
if (it == null) return@observe
|
|
||||||
viewBinding.progress.isGone = true
|
|
||||||
if (it.disabled) {
|
if (it.disabled) {
|
||||||
viewBinding.errorTV.isVisible = true
|
viewBinding.errorTV.isVisible = true
|
||||||
return@observe
|
return@observe
|
||||||
}
|
}
|
||||||
|
|
||||||
commentsSheet?.updateFragmentInfo(
|
commentsSheet?.updateFragmentInfo(
|
||||||
false,
|
false,
|
||||||
"${getString(R.string.comments)} (${it.commentCount.formatShort()})"
|
"${getString(R.string.comments)} (${it.commentCount.formatShort()})"
|
||||||
|
@ -82,13 +82,11 @@ class CommentsRepliesFragment : Fragment() {
|
|||||||
::repliesPage.isInitialized &&
|
::repliesPage.isInitialized &&
|
||||||
repliesPage.nextpage != null
|
repliesPage.nextpage != null
|
||||||
) {
|
) {
|
||||||
fetchReplies(videoId, repliesPage.nextpage!!) {
|
fetchReplies(videoId, repliesPage.nextpage!!)
|
||||||
repliesAdapter.updateItems(repliesPage.comments)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadInitialReplies(videoId, comment.repliesPage.orEmpty(), repliesAdapter)
|
loadInitialReplies(videoId, comment.repliesPage.orEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
@ -98,34 +96,32 @@ class CommentsRepliesFragment : Fragment() {
|
|||||||
|
|
||||||
private fun loadInitialReplies(
|
private fun loadInitialReplies(
|
||||||
videoId: String,
|
videoId: String,
|
||||||
nextPage: String,
|
nextPage: String
|
||||||
repliesAdapter: CommentsAdapter
|
|
||||||
) {
|
) {
|
||||||
_binding?.progress?.isVisible = true
|
_binding?.progress?.isVisible = true
|
||||||
fetchReplies(videoId, nextPage) {
|
fetchReplies(videoId, nextPage)
|
||||||
repliesAdapter.updateItems(it.comments)
|
|
||||||
_binding?.progress?.isGone = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchReplies(
|
private fun fetchReplies(videoId: String, nextPage: String) {
|
||||||
videoId: String,
|
_binding?.progress?.isVisible = true
|
||||||
nextPage: String,
|
|
||||||
onFinished: (CommentsPage) -> Unit
|
lifecycleScope.launch {
|
||||||
) {
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
if (isLoading) return@launch
|
if (isLoading) return@launch
|
||||||
isLoading = true
|
isLoading = true
|
||||||
|
|
||||||
repliesPage = try {
|
repliesPage = try {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage)
|
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage)
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG(), "IOException, you might not have internet connection")
|
Log.e(TAG(), "IOException, you might not have internet connection")
|
||||||
return@launch
|
return@launch
|
||||||
|
} finally {
|
||||||
|
_binding?.progress?.isGone = true
|
||||||
}
|
}
|
||||||
repliesPage.comments = repliesPage.comments.filterNonEmptyComments()
|
repliesPage.comments = repliesPage.comments.filterNonEmptyComments()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
onFinished.invoke(repliesPage)
|
repliesAdapter.updateItems(repliesPage.comments)
|
||||||
}
|
}
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import com.github.libretube.extensions.TAG
|
|||||||
import com.github.libretube.ui.extensions.filterNonEmptyComments
|
import com.github.libretube.ui.extensions.filterNonEmptyComments
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class CommentsViewModel : ViewModel() {
|
class CommentsViewModel : ViewModel() {
|
||||||
val commentsPage = MutableLiveData<CommentsPage?>()
|
val commentsPage = MutableLiveData<CommentsPage?>()
|
||||||
@ -17,11 +18,12 @@ class CommentsViewModel : ViewModel() {
|
|||||||
|
|
||||||
var videoId: String? = null
|
var videoId: String? = null
|
||||||
var channelAvatar: String? = null
|
var channelAvatar: String? = null
|
||||||
|
var handleLink: ((url: String) -> Unit)? = null
|
||||||
|
|
||||||
private var nextPage: String? = null
|
private var nextPage: String? = null
|
||||||
private var isLoading = false
|
var isLoading = MutableLiveData<Boolean>()
|
||||||
var currentCommentsPosition = 0
|
var currentCommentsPosition = 0
|
||||||
var commentsSheetDismiss: (() -> Unit)? = null
|
var commentsSheetDismiss: (() -> Unit)? = null
|
||||||
var handleLink: ((url: String) -> Unit)? = null
|
|
||||||
|
|
||||||
fun setCommentSheetExpand(value: Boolean?) {
|
fun setCommentSheetExpand(value: Boolean?) {
|
||||||
if (commentSheetExpand.value != value) {
|
if (commentSheetExpand.value != value) {
|
||||||
@ -30,31 +32,43 @@ class CommentsViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun fetchComments() {
|
fun fetchComments() {
|
||||||
videoId ?: return
|
val videoId = videoId ?: return
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
|
||||||
isLoading = true
|
isLoading.value = true
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getComments(videoId!!)
|
withContext(Dispatchers.IO) {
|
||||||
|
RetrofitInstance.api.getComments(videoId)
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG(), e.toString())
|
Log.e(TAG(), e.toString())
|
||||||
return@launch
|
return@launch
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
nextPage = response.nextpage
|
nextPage = response.nextpage
|
||||||
response.comments = response.comments.filterNonEmptyComments()
|
response.comments = response.comments.filterNonEmptyComments()
|
||||||
commentsPage.postValue(response)
|
commentsPage.postValue(response)
|
||||||
isLoading = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchNextComments() {
|
fun fetchNextComments() {
|
||||||
if (isLoading || nextPage == null || videoId == null) return
|
if (isLoading.value == true || nextPage == null || videoId == null) return
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
|
||||||
isLoading = true
|
isLoading.value = true
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
val response = try {
|
val response = try {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
|
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG(), e.toString())
|
Log.e(TAG(), e.toString())
|
||||||
return@launch
|
return@launch
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
val updatedPage = commentsPage.value?.apply {
|
val updatedPage = commentsPage.value?.apply {
|
||||||
@ -65,12 +79,11 @@ class CommentsViewModel : ViewModel() {
|
|||||||
|
|
||||||
nextPage = response.nextpage
|
nextPage = response.nextpage
|
||||||
commentsPage.postValue(updatedPage)
|
commentsPage.postValue(updatedPage)
|
||||||
isLoading = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
isLoading = false
|
isLoading.value = false
|
||||||
nextPage = null
|
nextPage = null
|
||||||
commentsPage.value = null
|
commentsPage.value = null
|
||||||
videoId = null
|
videoId = null
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-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_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/commentsRV"
|
android:id="@+id/commentsRV"
|
||||||
@ -15,6 +16,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -26,4 +28,4 @@
|
|||||||
android:text="@string/comments_disabled"
|
android:text="@string/comments_disabled"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
</FrameLayout>
|
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user