feat: basic replying

This commit is contained in:
rebelonion 2024-02-19 01:28:11 -06:00
parent 98b227876b
commit 0c2e2db1dc
6 changed files with 245 additions and 115 deletions

View file

@ -25,8 +25,6 @@ android {
versionName "2.2.0" versionName "2.2.0"
versionCode 220000000 versionCode 220000000
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
buildConfigField("String", "APP_SECRET", apikeyProperties['APP_SECRET'])
buildConfigField("String", "USER_ID_ENCRYPT_KEY", apikeyProperties['USER_ID_ENCRYPT_KEY'])
} }
flavorDimensions "store" flavorDimensions "store"

View file

@ -46,6 +46,24 @@ object CommentsAPI {
return parsed return parsed
} }
suspend fun getRepliesFromId(id: Int, page: Int = 1): CommentResponse? {
val url = "$address/comments/parent/$id/$page"
val request = requestBuilder()
val json = request.get(url)
if (!json.text.startsWith("{")) return null
val res = json.code == 200
if (!res && json.code != 404) {
errorReason(json.code, json.text)
}
val parsed = try {
Json.decodeFromString<CommentResponse>(json.text)
} catch (e: Exception) {
println("comments: $e")
return null
}
return parsed
}
suspend fun vote(commentId: Int, voteType: Int): Boolean { suspend fun vote(commentId: Int, voteType: Int): Boolean {
val url = "$address/comments/vote/$commentId/$voteType" val url = "$address/comments/vote/$commentId/$voteType"
val request = requestBuilder() val request = requestBuilder()
@ -155,16 +173,13 @@ object CommentsAPI {
} }
private fun headerBuilder(): Map<String, String> { private fun headerBuilder(): Map<String, String> {
return if (authToken != null) { val map = mutableMapOf(
mapOf( "appauth" to "6*45Qp%W2RS@t38jkXoSKY588Ynj%n"
"appauth" to BuildConfig.APP_SECRET, )
"Authorization" to authToken!! if (authToken != null) {
) map["Authorization"] = authToken!!
} else {
mapOf(
"appauth" to BuildConfig.APP_SECRET,
)
} }
return map
} }
private fun requestBuilder(): Requests { private fun requestBuilder(): Requests {
@ -250,7 +265,9 @@ data class Comment(
val isMod: Boolean? = null, val isMod: Boolean? = null,
@SerialName("is_admin") @SerialName("is_admin")
@Serializable(with = NumericBooleanSerializer::class) @Serializable(with = NumericBooleanSerializer::class)
val isAdmin: Boolean? = null val isAdmin: Boolean? = null,
@SerialName("reply_count")
val replyCount: Int? = null
) )
@Serializable @Serializable

View file

@ -2,6 +2,7 @@ package ani.dantotsu.media.comments
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.view.View import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.comments.Comment import ani.dantotsu.connections.comments.Comment
import ani.dantotsu.connections.comments.CommentsAPI import ani.dantotsu.connections.comments.CommentsAPI
@ -25,11 +26,23 @@ import java.util.TimeZone
class CommentItem(val comment: Comment, class CommentItem(val comment: Comment,
private val markwon: Markwon, private val markwon: Markwon,
private val section: Section, private val section: Section,
private val editCallback: (CommentItem) -> Unit private val editCallback: (CommentItem) -> Unit,
private val viewReplyCallback: (CommentItem) -> Unit,
private val replyCallback: (CommentItem) -> Unit
) : BindableItem<ItemCommentsBinding>() { ) : BindableItem<ItemCommentsBinding>() {
var binding: ItemCommentsBinding? = null
val adapter = GroupieAdapter()
val repliesSection = Section()
init {
adapter.add(repliesSection)
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun bind(viewBinding: ItemCommentsBinding, position: Int) { override fun bind(viewBinding: ItemCommentsBinding, position: Int) {
binding = viewBinding
viewBinding.commentRepliesList.layoutManager = LinearLayoutManager(currActivity())
viewBinding.commentRepliesList.adapter = adapter
val isUserComment = CommentsAPI.userId == comment.userId val isUserComment = CommentsAPI.userId == comment.userId
val node = markwon.parse(comment.content) val node = markwon.parse(comment.content)
val spanned = markwon.render(node) val spanned = markwon.render(node)
@ -37,16 +50,25 @@ class CommentItem(val comment: Comment,
viewBinding.commentDelete.visibility = if (isUserComment || CommentsAPI.isAdmin || CommentsAPI.isMod) View.VISIBLE else View.GONE viewBinding.commentDelete.visibility = if (isUserComment || CommentsAPI.isAdmin || CommentsAPI.isMod) View.VISIBLE else View.GONE
viewBinding.commentBanUser.visibility = if ((CommentsAPI.isAdmin || CommentsAPI.isMod) && !isUserComment) View.VISIBLE else View.GONE viewBinding.commentBanUser.visibility = if ((CommentsAPI.isAdmin || CommentsAPI.isMod) && !isUserComment) View.VISIBLE else View.GONE
viewBinding.commentEdit.visibility = if (isUserComment) View.VISIBLE else View.GONE viewBinding.commentEdit.visibility = if (isUserComment) View.VISIBLE else View.GONE
viewBinding.commentReply.visibility = View.GONE //TODO: implement reply if ((comment.replyCount ?: 0) > 0) {
viewBinding.commentTotalReplies.visibility = View.GONE //TODO: implement reply viewBinding.commentTotalReplies.visibility = View.VISIBLE
viewBinding.commentReply.setOnClickListener { viewBinding.commentTotalReplies.text = "View ${comment.replyCount} repl${if (comment.replyCount == 1) "y" else "ies"}"
} else {
viewBinding.commentTotalReplies.visibility = View.GONE
}
viewBinding.commentReply.visibility = View.VISIBLE
viewBinding.commentTotalReplies.setOnClickListener {
viewBinding.commentTotalReplies.visibility = View.GONE
viewReplyCallback(this)
} }
var isEditing = false var isEditing = false
var isReplying = false
viewBinding.commentEdit.setOnClickListener { viewBinding.commentEdit.setOnClickListener {
if (!isEditing) { if (!isEditing) {
viewBinding.commentEdit.text = currActivity()!!.getString(R.string.cancel) viewBinding.commentEdit.text = currActivity()!!.getString(R.string.cancel)
isEditing = true isEditing = true
isReplying = false
viewBinding.commentReply.text = "Reply"
editCallback(this) editCallback(this)
} else { } else {
viewBinding.commentEdit.text = currActivity()!!.getString(R.string.edit) viewBinding.commentEdit.text = currActivity()!!.getString(R.string.edit)
@ -55,6 +77,19 @@ class CommentItem(val comment: Comment,
} }
} }
viewBinding.commentReply.setOnClickListener {
if (!isReplying) {
viewBinding.commentReply.text = currActivity()!!.getString(R.string.cancel)
isReplying = true
isEditing = false
viewBinding.commentEdit.text = currActivity()!!.getString(R.string.edit)
replyCallback(this)
} else {
viewBinding.commentReply.text = "Reply"
isReplying = false
replyCallback(this)
}
}
viewBinding.modBadge.visibility = if (comment.isMod == true) View.VISIBLE else View.GONE viewBinding.modBadge.visibility = if (comment.isMod == true) View.VISIBLE else View.GONE
viewBinding.adminBadge.visibility = if (comment.isAdmin == true) View.VISIBLE else View.GONE viewBinding.adminBadge.visibility = if (comment.isAdmin == true) View.VISIBLE else View.GONE
viewBinding.commentDelete.setOnClickListener { viewBinding.commentDelete.setOnClickListener {

View file

@ -76,7 +76,11 @@ class CommentsActivity : AppCompatActivity() {
binding.commentReplyToContainer.visibility = View.GONE //TODO: implement reply binding.commentReplyToContainer.visibility = View.GONE //TODO: implement reply
var editing = false var editing = false
var editingCommentId = -1 var editingCommentId = -1
var replying = false
var replyingComment: CommentItem? = null
fun editCallback(comment: CommentItem) { fun editCallback(comment: CommentItem) {
replying = false
replyingComment = null
if (editingCommentId == comment.comment.commentId) { if (editingCommentId == comment.comment.commentId) {
editing = false editing = false
editingCommentId = -1 editingCommentId = -1
@ -95,6 +99,42 @@ class CommentsActivity : AppCompatActivity() {
} }
fun replyCallback(comment: CommentItem) {
editing = false
editingCommentId = -1
if (replyingComment?.comment?.commentId == comment.comment.commentId) {
replying = false
replyingComment = null
binding.commentInput.setText("")
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.commentInput.windowToken, 0)
} else {
replying = true
replyingComment = comment
binding.commentInput.requestFocus()
binding.commentInput.setSelection(binding.commentInput.text.length)
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(binding.commentInput, InputMethodManager.SHOW_IMPLICIT)
}
}
fun viewReplyCallback(comment: CommentItem) {
lifecycleScope.launch {
val replies = withContext(Dispatchers.IO) {
CommentsAPI.getRepliesFromId(comment.comment.commentId)
}
replies?.comments?.forEach {
comment.repliesSection.add(CommentItem(it, buildMarkwon(), comment.repliesSection, { comment ->
editCallback(comment)
}, { comment ->
viewReplyCallback(comment)
}, { comment ->
replyCallback(comment)
}))
}
}
}
binding.commentsRefresh.setOnRefreshListener { binding.commentsRefresh.setOnRefreshListener {
lifecycleScope.launch { lifecycleScope.launch {
binding.commentsList.visibility = View.GONE binding.commentsList.visibility = View.GONE
@ -123,9 +163,13 @@ class CommentsActivity : AppCompatActivity() {
} }
sorted?.forEach { sorted?.forEach {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
section.add(CommentItem(it, buildMarkwon(), section) { comment -> section.add(CommentItem(it, buildMarkwon(), section, { comment ->
editCallback(comment) editCallback(comment)
}) }, { comment ->
viewReplyCallback(comment)
}, { comment ->
replyCallback(comment)
}))
} }
} }
} }
@ -165,9 +209,13 @@ class CommentsActivity : AppCompatActivity() {
} }
sorted?.forEach { sorted?.forEach {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
section.add(CommentItem(it, buildMarkwon(), section) { comment -> section.add(CommentItem(it, buildMarkwon(), section, { comment ->
editCallback(comment) editCallback(comment)
}) }, { comment ->
viewReplyCallback(comment)
}, { comment ->
replyCallback(comment)
}))
} }
} }
totalPages = comments?.totalPages ?: 1 totalPages = comments?.totalPages ?: 1
@ -254,10 +302,14 @@ class CommentsActivity : AppCompatActivity() {
CommentItem( CommentItem(
it, it,
buildMarkwon(), buildMarkwon(),
section section, { comment ->
) { comment -> editCallback(comment)
editCallback(comment) }, { comment ->
}) viewReplyCallback(comment)
}, { comment ->
replyCallback(comment)
})
)
} }
} }
totalPages = comments?.totalPages ?: 1 totalPages = comments?.totalPages ?: 1
@ -290,6 +342,76 @@ class CommentsActivity : AppCompatActivity() {
snackString("You are banned from commenting :(") snackString("You are banned from commenting :(")
return@setOnClickListener return@setOnClickListener
} }
fun onSuccess() {
binding.commentInput.text.toString().let {
if (it.isNotEmpty()) {
binding.commentInput.text.clear()
lifecycleScope.launch {
if (editing) {
val success = withContext(Dispatchers.IO) {
CommentsAPI.editComment(editingCommentId, it)
}
if (success) {
val groups = section.groups
groups.forEach { item ->
if (item is CommentItem) {
if (item.comment.commentId == editingCommentId) {
item.comment.content = it
val dateFormat =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
dateFormat.timeZone =
TimeZone.getTimeZone("UTC")
item.comment.timestamp =
dateFormat.format(System.currentTimeMillis())
item.notifyChanged()
snackString("Comment edited")
}
}
}
}
} else {
val success = withContext(Dispatchers.IO) {
CommentsAPI.comment(mediaId, if (replying) replyingComment!!.comment.commentId else null, it)
}
if (success != null)
if (replying) {
replyingComment?.repliesSection?.add(
0,
CommentItem(
success,
buildMarkwon(),
replyingComment?.repliesSection!!, { comment ->
editCallback(comment)
}, { comment ->
viewReplyCallback(comment)
}, { comment ->
replyCallback(comment)
})
)
} else {
section.add(
0,
CommentItem(
success,
buildMarkwon(),
section, { comment ->
editCallback(comment)
}, { comment ->
viewReplyCallback(comment)
}, { comment ->
replyCallback(comment)
})
)
}
}
}
} else {
snackString("Comment cannot be empty")
}
}
}
val firstComment = PrefManager.getVal<Boolean>(PrefName.FirstComment) val firstComment = PrefManager.getVal<Boolean>(PrefName.FirstComment)
if (firstComment) { if (firstComment) {
//show a dialog explaining the rules //show a dialog explaining the rules
@ -311,53 +433,7 @@ class CommentsActivity : AppCompatActivity() {
.setPositiveButton("I Understand") { dialog, _ -> .setPositiveButton("I Understand") { dialog, _ ->
dialog.dismiss() dialog.dismiss()
PrefManager.setVal(PrefName.FirstComment, false) PrefManager.setVal(PrefName.FirstComment, false)
binding.commentInput.text.toString().let { onSuccess()
if (it.isNotEmpty()) {
binding.commentInput.text.clear()
lifecycleScope.launch {
if (editing) {
val success = withContext(Dispatchers.IO) {
CommentsAPI.editComment(editingCommentId, it)
}
if (success) {
val groups = section.groups
groups.forEach { item ->
if (item is CommentItem) {
if (item.comment.commentId == editingCommentId) {
item.comment.content = it
val dateFormat =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
dateFormat.timeZone =
TimeZone.getTimeZone("UTC")
item.comment.timestamp =
dateFormat.format(System.currentTimeMillis())
item.notifyChanged()
snackString("Comment edited")
}
}
}
}
} else {
val success = withContext(Dispatchers.IO) {
CommentsAPI.comment(mediaId, null, it)
}
if (success != null)
section.add(
0,
CommentItem(
success,
buildMarkwon(),
section
) { comment ->
editCallback(comment)
})
}
}
} else {
snackString("Comment cannot be empty")
}
}
} }
.setNegativeButton("Cancel") { dialog, _ -> .setNegativeButton("Cancel") { dialog, _ ->
dialog.dismiss() dialog.dismiss()
@ -365,6 +441,8 @@ class CommentsActivity : AppCompatActivity() {
val dialog = alertDialog.show() val dialog = alertDialog.show()
dialog?.window?.setDimAmount(0.8f) dialog?.window?.setDimAmount(0.8f)
} else {
onSuccess()
} }
} }
} }

View file

@ -1,29 +1,31 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout 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" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/commentsLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto" android:fitsSystemWindows="true">
android:fitsSystemWindows="true"
android:id="@+id/commentsLayout">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
tools:ignore="UseCompoundDrawables"> tools:ignore="UseCompoundDrawables">
<TextView <TextView
android:id="@+id/commentTitle" android:id="@+id/commentTitle"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_weight="1"
android:layout_gravity="" android:layout_gravity=""
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_weight="1"
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
android:gravity="center|start" android:gravity="center|start"
android:text="@string/comments" android:text="@string/comments"
@ -34,8 +36,8 @@
android:id="@+id/commentSort" android:id="@+id/commentSort"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:layout_marginEnd="16dp"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginEnd="16dp"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/sort_by" android:contentDescription="@string/sort_by"
app:srcCompat="@drawable/ic_round_sort_24" app:srcCompat="@drawable/ic_round_sort_24"
@ -59,42 +61,44 @@
android:clipChildren="false" android:clipChildren="false"
android:clipToPadding="false"> android:clipToPadding="false">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/commentsList" android:id="@+id/commentsList"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" tools:listitem="@layout/item_comments"
tools:listitem="@layout/item_comments" /> tools:visibility="visible" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:windowSoftInputMode="adjustResize" android:background="@color/nav_bg"
android:background="@color/nav_bg"> android:orientation="vertical"
android:windowSoftInputMode="adjustResize">
<LinearLayout <LinearLayout
android:id="@+id/commentReplyToContainer" android:id="@+id/commentReplyToContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables"> tools:ignore="UseCompoundDrawables">
<TextView <TextView
android:id="@+id/commentReplyTo" android:id="@+id/commentReplyTo"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:singleLine="true" android:layout_weight="1"
android:ellipsize="end" android:ellipsize="end"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:singleLine="true"
android:text="Replying to " android:text="Replying to "
android:textColor="?attr/colorOnBackground" android:textColor="?attr/colorOnBackground"
android:textSize="14sp" android:textSize="14sp"
@ -112,22 +116,23 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/commentInputLayout" android:id="@+id/commentInputLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingBottom="8dp"
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingBottom="8dp"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/commentUserAvatar" android:id="@+id/commentUserAvatar"
style="@style/CircularImageView"
android:layout_width="42dp" android:layout_width="42dp"
android:layout_height="42dp" android:layout_height="42dp"
android:scaleType="center"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
style="@style/CircularImageView" android:scaleType="center"
app:srcCompat="@drawable/ic_round_add_circle_24" app:srcCompat="@drawable/ic_round_add_circle_24"
tools:ignore="ContentDescription,ImageContrastCheck" /> tools:ignore="ContentDescription,ImageContrastCheck" />
@ -135,19 +140,19 @@
android:id="@+id/commentInput" android:id="@+id/commentInput"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_weight="1" android:layout_weight="1"
android:textSize="12sp" android:autofillHints="The One Piece is real"
android:background="@drawable/card_outline"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:hint="Add a comment..." android:hint="Add a comment..."
android:inputType="textMultiLine" android:inputType="textMultiLine"
android:padding="8dp"
android:background="@drawable/card_outline"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:maxLength="300" android:maxLength="300"
android:maxLines="15" android:maxLines="15"
tools:ignore="HardcodedText" android:padding="8dp"
android:autofillHints="The One Piece is real" /> android:textSize="12sp"
tools:ignore="HardcodedText" />
<ImageButton <ImageButton
android:id="@+id/commentSend" android:id="@+id/commentSend"

View file

@ -99,7 +99,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:maxLines="3" android:maxLines="4"
android:scrollHorizontally="false"
android:ellipsize="end" android:ellipsize="end"
android:text="@string/slogan" android:text="@string/slogan"
android:textSize="12sp" /> android:textSize="12sp" />
@ -185,19 +186,6 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/commentTotalRepliesContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<View
android:layout_width="32dp"
android:layout_height="3dp"
android:layout_gravity="center"
android:layout_marginStart="44dp"
android:background="@color/nav_tab" />
<TextView <TextView
android:id="@+id/commentTotalReplies" android:id="@+id/commentTotalReplies"
@ -210,5 +198,14 @@
android:textSize="12sp" android:textSize="12sp"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
</LinearLayout> <androidx.recyclerview.widget.RecyclerView
android:id="@+id/commentRepliesList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:visibility="visible"
tools:visibility="visible"
tools:listitem="@layout/item_comments"
tools:ignore="RtlSymmetry" />
</LinearLayout> </LinearLayout>