mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 06:10:31 +05:30
Merge pull request #2509 from Bnyro/master
Fix crash during startup caused by the comments sheet
This commit is contained in:
commit
3b4fdc8e7d
@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
data class CommentsPage(
|
||||
val comments: MutableList<Comment> = arrayListOf(),
|
||||
var comments: MutableList<Comment> = arrayListOf(),
|
||||
val disabled: Boolean? = null,
|
||||
val nextpage: String? = null
|
||||
)
|
||||
|
@ -36,7 +36,6 @@ import com.github.libretube.R
|
||||
import com.github.libretube.api.CronetHelper
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.obj.ChapterSegment
|
||||
import com.github.libretube.api.obj.Comment
|
||||
import com.github.libretube.api.obj.PipedStream
|
||||
import com.github.libretube.api.obj.Segment
|
||||
import com.github.libretube.api.obj.SegmentData
|
||||
@ -76,6 +75,7 @@ import com.github.libretube.ui.extensions.setFormattedHtml
|
||||
import com.github.libretube.ui.extensions.setInvisible
|
||||
import com.github.libretube.ui.extensions.setupSubscriptionButton
|
||||
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
|
||||
import com.github.libretube.ui.models.CommentsViewModel
|
||||
import com.github.libretube.ui.models.PlayerViewModel
|
||||
import com.github.libretube.ui.sheets.BaseBottomSheet
|
||||
import com.github.libretube.ui.sheets.CommentsSheet
|
||||
@ -124,6 +124,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
private lateinit var doubleTapOverlayBinding: DoubleTapOverlayBinding
|
||||
private lateinit var playerGestureControlsViewBinding: PlayerGestureControlsViewBinding
|
||||
private val viewModel: PlayerViewModel by activityViewModels()
|
||||
private val commentsViewModel: CommentsViewModel by activityViewModels()
|
||||
|
||||
/**
|
||||
* video information
|
||||
@ -152,8 +153,6 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
* Chapters and comments
|
||||
*/
|
||||
private lateinit var chapters: List<ChapterSegment>
|
||||
private val comments: MutableList<Comment> = mutableListOf()
|
||||
private var commentsNextPage: String? = null
|
||||
|
||||
/**
|
||||
* for the player view
|
||||
@ -330,15 +329,11 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
}
|
||||
|
||||
binding.commentsToggle.setOnClickListener {
|
||||
CommentsSheet(
|
||||
videoId!!,
|
||||
comments,
|
||||
commentsNextPage,
|
||||
binding.root.height - binding.player.height
|
||||
) { comments, nextPage ->
|
||||
this.comments.addAll(comments)
|
||||
this.commentsNextPage = nextPage
|
||||
}.show(childFragmentManager)
|
||||
videoId ?: return@setOnClickListener
|
||||
// set the max height to not cover the currently playing video
|
||||
commentsViewModel.maxHeight = binding.root.height - binding.player.height
|
||||
commentsViewModel.videoId = videoId
|
||||
CommentsSheet().show(childFragmentManager)
|
||||
}
|
||||
|
||||
playerBinding.queueToggle.visibility = View.VISIBLE
|
||||
@ -604,6 +599,9 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
playerBinding.exoProgress.clearSegments()
|
||||
playerBinding.sbToggle.visibility = View.GONE
|
||||
|
||||
// reset the comments to become reloaded later
|
||||
commentsViewModel.reset()
|
||||
|
||||
lifecycleScope.launchWhenCreated {
|
||||
streams = try {
|
||||
RetrofitInstance.api.getStreams(videoId!!)
|
||||
@ -754,10 +752,6 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
if (nextVideoId != null) {
|
||||
videoId = nextVideoId
|
||||
|
||||
// reset the comments to be reloaded later
|
||||
comments.clear()
|
||||
commentsNextPage = null
|
||||
|
||||
// play the next video
|
||||
playVideo()
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
package com.github.libretube.ui.models
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.obj.CommentsPage
|
||||
import com.github.libretube.extensions.TAG
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class CommentsViewModel : ViewModel() {
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
private var isLoading = false
|
||||
|
||||
val commentsPage = MutableLiveData<CommentsPage?>()
|
||||
|
||||
private var nextPage: String? = null
|
||||
|
||||
var videoId: String? = null
|
||||
var maxHeight: Int = 0
|
||||
|
||||
fun fetchComments() {
|
||||
videoId ?: return
|
||||
scope.launch {
|
||||
isLoading = true
|
||||
val response = try {
|
||||
RetrofitInstance.api.getComments(videoId!!)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), e.toString())
|
||||
return@launch
|
||||
}
|
||||
nextPage = response.nextpage
|
||||
commentsPage.postValue(response)
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchNextComments() {
|
||||
if (isLoading || nextPage == null || videoId == null) return
|
||||
scope.launch {
|
||||
isLoading = true
|
||||
val response = try {
|
||||
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), e.toString())
|
||||
return@launch
|
||||
}
|
||||
val updatedPage = commentsPage.value?.apply {
|
||||
comments = comments.plus(response.comments).toMutableList()
|
||||
}
|
||||
nextPage = response.nextpage
|
||||
commentsPage.postValue(updatedPage)
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
isLoading = false
|
||||
nextPage = null
|
||||
commentsPage.value = null
|
||||
videoId = null
|
||||
}
|
||||
}
|
@ -1,32 +1,22 @@
|
||||
package com.github.libretube.ui.sheets
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.obj.Comment
|
||||
import com.github.libretube.databinding.CommentsSheetBinding
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.ui.adapters.CommentsAdapter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.github.libretube.ui.models.CommentsViewModel
|
||||
|
||||
class CommentsSheet(
|
||||
private val videoId: String,
|
||||
private val comments: List<Comment>,
|
||||
private var nextPage: String?,
|
||||
private val maxHeight: Int,
|
||||
private val onMoreComments: (comments: List<Comment>, nextPage: String?) -> Unit
|
||||
) : ExpandedBottomSheet() {
|
||||
class CommentsSheet : ExpandedBottomSheet() {
|
||||
private lateinit var binding: CommentsSheetBinding
|
||||
|
||||
private lateinit var commentsAdapter: CommentsAdapter
|
||||
private var isLoading = false
|
||||
|
||||
private val viewModel: CommentsViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@ -35,7 +25,7 @@ class CommentsSheet(
|
||||
): View {
|
||||
binding = CommentsSheetBinding.inflate(layoutInflater)
|
||||
// set a fixed maximum height
|
||||
binding.root.maxHeight = maxHeight
|
||||
binding.root.maxHeight = viewModel.maxHeight
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@ -48,62 +38,40 @@ class CommentsSheet(
|
||||
binding.commentsRV.viewTreeObserver
|
||||
.addOnScrollChangedListener {
|
||||
if (!binding.commentsRV.canScrollVertically(1)) {
|
||||
fetchNextComments()
|
||||
viewModel.fetchNextComments()
|
||||
}
|
||||
}
|
||||
|
||||
commentsAdapter = CommentsAdapter(videoId, comments.toMutableList()) {
|
||||
commentsAdapter = CommentsAdapter(
|
||||
viewModel.videoId!!,
|
||||
viewModel.commentsPage.value?.comments.orEmpty().toMutableList()
|
||||
) {
|
||||
dialog?.dismiss()
|
||||
}
|
||||
binding.commentsRV.adapter = commentsAdapter
|
||||
|
||||
if (comments.isEmpty()) fetchComments()
|
||||
}
|
||||
|
||||
private fun fetchComments() {
|
||||
binding.progress.visibility = View.VISIBLE
|
||||
lifecycleScope.launchWhenCreated {
|
||||
isLoading = true
|
||||
val response = try {
|
||||
RetrofitInstance.api.getComments(videoId)
|
||||
} catch (e: Exception) {
|
||||
return@launchWhenCreated
|
||||
}
|
||||
binding.progress.visibility = View.GONE
|
||||
if (response.disabled == true) {
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
}
|
||||
return@launchWhenCreated
|
||||
}
|
||||
if (response.comments.isEmpty()) {
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.errorTV.text = getString(R.string.no_comments_available)
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
}
|
||||
return@launchWhenCreated
|
||||
}
|
||||
commentsAdapter.updateItems(response.comments)
|
||||
nextPage = response.nextpage
|
||||
onMoreComments.invoke(response.comments, response.nextpage)
|
||||
isLoading = false
|
||||
if (viewModel.commentsPage.value?.comments.orEmpty().isEmpty()) {
|
||||
binding.progress.visibility = View.VISIBLE
|
||||
viewModel.fetchComments()
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchNextComments() {
|
||||
if (isLoading || nextPage == null) return
|
||||
lifecycleScope.launchWhenCreated {
|
||||
isLoading = true
|
||||
val response = try {
|
||||
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage!!)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), e.toString())
|
||||
return@launchWhenCreated
|
||||
// listen for new comments to be loaded
|
||||
viewModel.commentsPage.observe(viewLifecycleOwner) {
|
||||
it ?: return@observe
|
||||
binding.progress.visibility = View.GONE
|
||||
if (it.disabled == true) {
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
return@observe
|
||||
}
|
||||
nextPage = response.nextpage
|
||||
commentsAdapter.updateItems(response.comments)
|
||||
onMoreComments.invoke(response.comments, response.nextpage)
|
||||
isLoading = false
|
||||
if (it.comments.isEmpty()) {
|
||||
binding.errorTV.text = getString(R.string.no_comments_available)
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
return@observe
|
||||
}
|
||||
commentsAdapter.updateItems(
|
||||
// only add the new comments to the recycler view
|
||||
it.comments.subList(commentsAdapter.itemCount, it.comments.size)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user