Merge pull request #1543 from Bnyro/master

Copy comments by long pressing them
This commit is contained in:
Bnyro 2022-10-12 20:08:37 +02:00 committed by GitHub
commit 5472cee8c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 213 deletions

View File

@ -10,11 +10,13 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R 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.CommentsPage import com.github.libretube.api.obj.CommentsPage
import com.github.libretube.databinding.CommentsRowBinding import com.github.libretube.databinding.CommentsRowBinding
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.formatShort import com.github.libretube.extensions.formatShort
import com.github.libretube.ui.viewholders.CommentsViewHolder import com.github.libretube.ui.viewholders.CommentsViewHolder
import com.github.libretube.util.ClipboardHelper
import com.github.libretube.util.ImageHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -25,14 +27,21 @@ import java.io.IOException
class CommentsAdapter( class CommentsAdapter(
private val videoId: String, private val videoId: String,
private val comments: MutableList<com.github.libretube.api.obj.Comment> private val comments: MutableList<Comment>,
private val isRepliesAdapter: Boolean = false
) : RecyclerView.Adapter<CommentsViewHolder>() { ) : RecyclerView.Adapter<CommentsViewHolder>() {
private var isLoading = false private var isLoading = false
private var nextpage = "" private var nextpage = ""
private var repliesPage = com.github.libretube.api.obj.CommentsPage() private var repliesPage = CommentsPage()
fun updateItems(newItems: List<com.github.libretube.api.obj.Comment>) { fun clear() {
val size: Int = comments.size
comments.clear()
notifyItemRangeRemoved(0, size)
}
fun updateItems(newItems: List<Comment>) {
val commentsSize = comments.size val commentsSize = comments.size
comments.addAll(newItems) comments.addAll(newItems)
notifyItemRangeInserted(commentsSize, newItems.size) notifyItemRangeInserted(commentsSize, newItems.size)
@ -48,6 +57,11 @@ class CommentsAdapter(
override fun onBindViewHolder(holder: CommentsViewHolder, position: Int) { override fun onBindViewHolder(holder: CommentsViewHolder, position: Int) {
val comment = comments[position] val comment = comments[position]
holder.binding.apply { holder.binding.apply {
if (isRepliesAdapter) {
root.scaleX = 0.9f
root.scaleY = 0.9f
}
commentInfos.text = comment.author.toString() + "" + comment.commentedTime.toString() commentInfos.text = comment.author.toString() + "" + comment.commentedTime.toString()
commentText.text = comment.commentText.toString() commentText.text = comment.commentText.toString()
@ -73,31 +87,35 @@ class CommentsAdapter(
} }
repliesRecView.layoutManager = LinearLayoutManager(root.context) repliesRecView.layoutManager = LinearLayoutManager(root.context)
val repliesAdapter = RepliesAdapter(CommentsPage().comments) val repliesAdapter = CommentsAdapter(videoId, CommentsPage().comments, true)
repliesRecView.adapter = repliesAdapter repliesRecView.adapter = repliesAdapter
if (!isRepliesAdapter && comment.repliesPage != null) {
root.setOnClickListener { root.setOnClickListener {
when { when {
repliesAdapter.itemCount.equals(0) && comment.repliesPage != null -> { repliesAdapter.itemCount.equals(0) -> {
nextpage = comment.repliesPage nextpage = comment.repliesPage
fetchReplies(nextpage, repliesAdapter) fetchReplies(nextpage, repliesAdapter)
} }
repliesAdapter.itemCount.equals(0) -> {
Toast.makeText(root.context, R.string.no_replies, Toast.LENGTH_SHORT)
.show()
}
else -> repliesAdapter.clear() else -> repliesAdapter.clear()
} }
} }
} }
root.setOnLongClickListener {
ClipboardHelper(root.context).save(comment.commentText.toString())
Toast.makeText(root.context, R.string.copied, Toast.LENGTH_SHORT).show()
true
}
}
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return comments.size return comments.size
} }
private fun fetchReplies(nextPage: String, repliesAdapter: RepliesAdapter) { private fun fetchReplies(nextPage: String, repliesAdapter: CommentsAdapter) {
CoroutineScope(Dispatchers.Main).launch { CoroutineScope(Dispatchers.Main).launch {
if (!isLoading) { if (isLoading) return@launch
isLoading = true isLoading = true
try { try {
repliesPage = RetrofitInstance.api.getCommentsNextPage(videoId, nextPage) repliesPage = RetrofitInstance.api.getCommentsNextPage(videoId, nextPage)
@ -111,5 +129,4 @@ class CommentsAdapter(
isLoading = false isLoading = false
} }
} }
}
} }

View File

@ -1,66 +0,0 @@
package com.github.libretube.ui.adapters
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.RepliesRowBinding
import com.github.libretube.extensions.formatShort
import com.github.libretube.ui.viewholders.RepliesViewHolder
import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper
class RepliesAdapter(
private val replies: MutableList<com.github.libretube.api.obj.Comment>
) : RecyclerView.Adapter<RepliesViewHolder>() {
fun clear() {
val size: Int = replies.size
replies.clear()
notifyItemRangeRemoved(0, size)
}
fun updateItems(newItems: List<com.github.libretube.api.obj.Comment>) {
var repliesSize = replies.size
replies.addAll(newItems)
notifyItemRangeInserted(repliesSize, newItems.size)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RepliesViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = RepliesRowBinding.inflate(layoutInflater, parent, false)
return RepliesViewHolder(binding)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: RepliesViewHolder, position: Int) {
holder.binding.apply {
val reply = replies[position]
commentInfos.text =
reply.author.toString() +
"" + reply.commentedTime.toString()
commentText.text =
reply.commentText.toString()
ImageHelper.loadImage(reply.thumbnail, commentorImage)
likesTextView.text =
reply.likeCount?.toLong().formatShort()
if (reply.verified == true) {
verifiedImageView.visibility = View.VISIBLE
}
if (reply.pinned == true) {
pinnedImageView.visibility = View.VISIBLE
}
if (reply.hearted == true) {
heartedImageView.visibility = View.VISIBLE
}
commentorImage.setOnClickListener {
NavigationHelper.navigateVideo(root.context, reply.commentorUrl)
}
}
}
override fun getItemCount(): Int {
return replies.size
}
}

View File

@ -1,17 +1,17 @@
package com.github.libretube.ui.dialogs package com.github.libretube.ui.dialogs
import android.annotation.SuppressLint
import android.app.Dialog import android.app.Dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.util.ClipboardHelper
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
class ErrorDialog : DialogFragment() { class ErrorDialog : DialogFragment() {
@SuppressLint("PrivateResource")
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val errorLog = PreferenceHelper.getErrorLog() val errorLog = PreferenceHelper.getErrorLog()
// reset the error log // reset the error log
@ -22,13 +22,7 @@ class ErrorDialog : DialogFragment() {
.setMessage(errorLog) .setMessage(errorLog)
.setNegativeButton(R.string.okay, null) .setNegativeButton(R.string.okay, null)
.setPositiveButton(R.string.copy) { _, _ -> .setPositiveButton(R.string.copy) { _, _ ->
/** ClipboardHelper(requireContext()).save(errorLog)
* copy the error log to the clipboard
*/
val clipboard: ClipboardManager =
context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(context?.getString(R.string.copied), errorLog)
clipboard.setPrimaryClip(clip)
Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show()
} }
.show() .show()

View File

@ -1,8 +0,0 @@
package com.github.libretube.ui.viewholders
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.RepliesRowBinding
class RepliesViewHolder(
val binding: RepliesRowBinding
) : RecyclerView.ViewHolder(binding.root)

View File

@ -0,0 +1,17 @@
package com.github.libretube.util
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import com.github.libretube.R
class ClipboardHelper(
private val context: Context
) {
fun save(text: String) {
val clipboard: ClipboardManager =
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(context.getString(R.string.copied), text)
clipboard.setPrimaryClip(clip)
}
}

View File

@ -124,7 +124,6 @@
android:id="@+id/replies_recView" android:id="@+id/replies_recView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:background="@null" android:background="@null"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />

View File

@ -1,101 +0,0 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/commentor_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="16dp"
app:srcCompat="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/comment_infos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textSize="15sp"
android:textStyle="bold"
tools:text="Author and Time" />
<ImageView
android:id="@+id/verified_imageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:visibility="gone"
app:srcCompat="@drawable/ic_verified" />
<ImageView
android:id="@+id/pinned_imageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:visibility="gone"
app:srcCompat="@drawable/ic_pinned" />
</LinearLayout>
<TextView
android:id="@+id/comment_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:autoLink="web"
tools:text="Comment Text" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/likes_imageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="6dp"
app:srcCompat="@drawable/ic_thumb_up" />
<TextView
android:id="@+id/likes_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="LikeCount" />
<ImageView
android:id="@+id/hearted_imageView"
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:visibility="gone"
app:srcCompat="@drawable/ic_hearted" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>