Merge pull request #2102 from Bnyro/improve-comments-sheet

Improve the comments sheet
This commit is contained in:
Bnyro 2022-11-27 14:24:45 +01:00 committed by GitHub
commit 35ed8e22d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 22 deletions

View File

@ -7,11 +7,14 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.Comment import com.github.libretube.api.obj.Comment
import com.github.libretube.databinding.BottomSheetBinding import com.github.libretube.databinding.CommentsSheetBinding
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.ui.adapters.CommentsAdapter import com.github.libretube.ui.adapters.CommentsAdapter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class CommentsSheet( class CommentsSheet(
private val videoId: String, private val videoId: String,
@ -19,61 +22,71 @@ class CommentsSheet(
private var nextPage: String?, private var nextPage: String?,
private val onMoreComments: (comments: List<Comment>, nextPage: String?) -> Unit private val onMoreComments: (comments: List<Comment>, nextPage: String?) -> Unit
) : ExpandedBottomSheet() { ) : ExpandedBottomSheet() {
private lateinit var binding: BottomSheetBinding private lateinit var binding: CommentsSheetBinding
private var commentsAdapter: CommentsAdapter? = null private lateinit var commentsAdapter: CommentsAdapter
private var isLoading = true private var isLoading = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = BottomSheetBinding.inflate(layoutInflater) binding = CommentsSheetBinding.inflate(layoutInflater)
return binding.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding.optionsRecycler.layoutManager = LinearLayoutManager(requireContext()) binding.commentsRV.layoutManager = LinearLayoutManager(requireContext())
binding.optionsRecycler.setItemViewCacheSize(20) binding.commentsRV.setItemViewCacheSize(20)
binding.optionsRecycler.viewTreeObserver binding.commentsRV.viewTreeObserver
.addOnScrollChangedListener { .addOnScrollChangedListener {
if (!binding.optionsRecycler.canScrollVertically(1)) { if (!binding.commentsRV.canScrollVertically(1)) {
fetchNextComments() fetchNextComments()
} }
} }
if (comments.isNotEmpty()) {
setCommentsAdapter(comments)
} else {
fetchComments()
}
}
private fun setCommentsAdapter(comments: MutableList<Comment>) {
commentsAdapter = CommentsAdapter(videoId, comments) { commentsAdapter = CommentsAdapter(videoId, comments) {
dialog?.dismiss() dialog?.dismiss()
} }
binding.optionsRecycler.adapter = commentsAdapter binding.commentsRV.adapter = commentsAdapter
isLoading = false
if (comments.isEmpty()) fetchComments()
} }
private fun fetchComments() { private fun fetchComments() {
binding.progress.visibility = View.VISIBLE
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
isLoading = true
val response = try { val response = try {
RetrofitInstance.api.getComments(videoId) RetrofitInstance.api.getComments(videoId)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG(), e.toString()) Log.e(TAG(), e.toString())
return@launchWhenCreated return@launchWhenCreated
} }
setCommentsAdapter(response.comments) 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
}
binding.progress.visibility = View.GONE
commentsAdapter.updateItems(response.comments)
nextPage = response.nextpage nextPage = response.nextpage
onMoreComments.invoke(response.comments, response.nextpage) onMoreComments.invoke(response.comments, response.nextpage)
isLoading = false
} }
} }
private fun fetchNextComments() { private fun fetchNextComments() {
if (isLoading || nextPage == null) return
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
if (isLoading || nextPage == null) return@launchWhenCreated
isLoading = true isLoading = true
val response = try { val response = try {
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage!!) RetrofitInstance.api.getCommentsNextPage(videoId, nextPage!!)
@ -82,7 +95,7 @@ class CommentsSheet(
return@launchWhenCreated return@launchWhenCreated
} }
nextPage = response.nextpage nextPage = response.nextpage
commentsAdapter?.updateItems(response.comments) commentsAdapter.updateItems(response.comments)
onMoreComments.invoke(response.comments, response.nextpage) onMoreComments.invoke(response.comments, response.nextpage)
isLoading = false isLoading = false
} }

View File

@ -247,6 +247,8 @@ internal class CustomExoPlayerView(
binding.exoCenterControls.visibility = visibility binding.exoCenterControls.visibility = visibility
binding.exoBottomBar.visibility = visibility binding.exoBottomBar.visibility = visibility
binding.closeImageButton.visibility = visibility binding.closeImageButton.visibility = visibility
binding.exoTitle.visibility = visibility
binding.exoPlayPause.visibility = visibility
// disable tap and swipe gesture if the player is locked // disable tap and swipe gesture if the player is locked
playerGestureController.isEnabled = isLocked playerGestureController.isEnabled = isLocked

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/standard_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="20dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Drag handle for accessibility -->
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/drag_handle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/commentsRV"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
<TextView
android:id="@+id/errorTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginVertical="5dp"
android:text="@string/comments_disabled"
android:visibility="gone" />
</FrameLayout>
</LinearLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -396,6 +396,8 @@
<string name="swipe_controls_summary">Use swipe gesture to adjust the brightness and volume.</string> <string name="swipe_controls_summary">Use swipe gesture to adjust the brightness and volume.</string>
<string name="defaults">Defaults</string> <string name="defaults">Defaults</string>
<string name="pop_up">Pop-Up</string> <string name="pop_up">Pop-Up</string>
<string name="comments_disabled">Comments are disabled by the author.</string>
<string name="no_comments_available">This video has no comments available.</string>
<!-- Notification channel strings --> <!-- Notification channel strings -->
<string name="download_channel_name">Download Service</string> <string name="download_channel_name">Download Service</string>