feat: comment placement | tagging

This commit is contained in:
rebelonion 2024-02-26 03:01:11 -06:00
parent 8a922bd083
commit 7f943d34ac
20 changed files with 548 additions and 293 deletions

View file

@ -108,9 +108,6 @@
<activity <activity
android:name=".others.imagesearch.ImageSearchActivity" android:name=".others.imagesearch.ImageSearchActivity"
android:parentActivityName=".MainActivity" /> android:parentActivityName=".MainActivity" />
<activity
android:name=".media.comments.CommentsActivity"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity <activity
android:name=".media.SearchActivity" android:name=".media.SearchActivity"
android:parentActivityName=".MainActivity" /> android:parentActivityName=".MainActivity" />
@ -130,7 +127,8 @@
<activity <activity
android:name=".media.MediaDetailsActivity" android:name=".media.MediaDetailsActivity"
android:parentActivityName=".MainActivity" android:parentActivityName=".MainActivity"
android:theme="@style/Theme.Dantotsu.NeverCutout" /> android:theme="@style/Theme.Dantotsu.NeverCutout"
android:windowSoftInputMode="adjustPan|stateHidden"/>
<activity android:name=".media.CharacterDetailsActivity" /> <activity android:name=".media.CharacterDetailsActivity" />
<activity android:name=".home.NoInternet" /> <activity android:name=".home.NoInternet" />
<activity <activity

View file

@ -30,9 +30,12 @@ object CommentsAPI {
var isMod: Boolean = false var isMod: Boolean = false
var totalVotes: Int = 0 var totalVotes: Int = 0
suspend fun getCommentsForId(id: Int, page: Int = 1): CommentResponse? { suspend fun getCommentsForId(id: Int, page: Int = 1, tag: Int?): CommentResponse? {
val url = "$address/comments/$id/$page" var url = "$address/comments/$id/$page"
val request = requestBuilder() val request = requestBuilder()
tag?.let {
url += "?tag=$it"
}
val json = try { val json = try {
request.get(url) request.get(url)
} catch (e: IOException) { } catch (e: IOException) {
@ -90,12 +93,15 @@ object CommentsAPI {
return res return res
} }
suspend fun comment(mediaId: Int, parentCommentId: Int?, content: String): Comment? { suspend fun comment(mediaId: Int, parentCommentId: Int?, content: String, tag: Int?): Comment? {
val url = "$address/comments" val url = "$address/comments"
val body = FormBody.Builder() val body = FormBody.Builder()
.add("user_id", userId ?: return null) .add("user_id", userId ?: return null)
.add("media_id", mediaId.toString()) .add("media_id", mediaId.toString())
.add("content", content) .add("content", content)
if (tag != null) {
body.add("tag", tag.toString())
}
parentCommentId?.let { parentCommentId?.let {
body.add("parent_comment_id", it.toString()) body.add("parent_comment_id", it.toString())
} }
@ -125,6 +131,7 @@ object CommentsAPI {
parsed.content, parsed.content,
parsed.timestamp, parsed.timestamp,
parsed.deleted, parsed.deleted,
parsed.tag,
0, 0,
0, 0,
null, null,
@ -224,7 +231,7 @@ object CommentsAPI {
} }
val url = "$address/authenticate" val url = "$address/authenticate"
val token = PrefManager.getVal(PrefName.AnilistToken, null as String?) ?: return val token = PrefManager.getVal(PrefName.AnilistToken, null as String?) ?: return
repeat(MAX_RETRIES) { // Define MAX_RETRIES as a constant repeat(MAX_RETRIES) {
try { try {
val json = authRequest(token, url) val json = authRequest(token, url)
if (json.code == 200) { if (json.code == 200) {
@ -252,7 +259,6 @@ object CommentsAPI {
snackString("Failed to login to comments API") snackString("Failed to login to comments API")
return return
} }
// Wait for 1 minute before retrying
kotlinx.coroutines.delay(60000) kotlinx.coroutines.delay(60000)
} }
snackString("Failed to login after multiple attempts") snackString("Failed to login after multiple attempts")
@ -367,6 +373,8 @@ data class Comment(
@SerialName("deleted") @SerialName("deleted")
@Serializable(with = NumericBooleanSerializer::class) @Serializable(with = NumericBooleanSerializer::class)
val deleted: Boolean?, val deleted: Boolean?,
@SerialName("tag")
val tag: Int?,
@SerialName("upvotes") @SerialName("upvotes")
var upvotes: Int, var upvotes: Int,
@SerialName("downvotes") @SerialName("downvotes")
@ -408,6 +416,8 @@ data class ReturnedComment(
@SerialName("deleted") @SerialName("deleted")
@Serializable(with = NumericBooleanSerializer::class) @Serializable(with = NumericBooleanSerializer::class)
val deleted: Boolean?, val deleted: Boolean?,
@SerialName("tag")
val tag: Int?,
) )
object NumericBooleanSerializer : KSerializer<Boolean> { object NumericBooleanSerializer : KSerializer<Boolean> {

View file

@ -36,6 +36,7 @@ import ani.dantotsu.databinding.ActivityMediaBinding
import ani.dantotsu.initActivity import ani.dantotsu.initActivity
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.media.anime.AnimeWatchFragment import ani.dantotsu.media.anime.AnimeWatchFragment
import ani.dantotsu.media.comments.CommentsFragment
import ani.dantotsu.media.manga.MangaReadFragment import ani.dantotsu.media.manga.MangaReadFragment
import ani.dantotsu.media.novel.NovelReadFragment import ani.dantotsu.media.novel.NovelReadFragment
import ani.dantotsu.navBarHeight import ani.dantotsu.navBarHeight
@ -318,13 +319,14 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
tabLayout.menu.clear() tabLayout.menu.clear()
if (media.anime != null) { if (media.anime != null) {
viewPager.adapter = viewPager.adapter =
ViewPagerAdapter(supportFragmentManager, lifecycle, SupportedMedia.ANIME) ViewPagerAdapter(supportFragmentManager, lifecycle, SupportedMedia.ANIME, media)
tabLayout.inflateMenu(R.menu.anime_menu_detail) tabLayout.inflateMenu(R.menu.anime_menu_detail)
} else if (media.manga != null) { } else if (media.manga != null) {
viewPager.adapter = ViewPagerAdapter( viewPager.adapter = ViewPagerAdapter(
supportFragmentManager, supportFragmentManager,
lifecycle, lifecycle,
if (media.format == "NOVEL") SupportedMedia.NOVEL else SupportedMedia.MANGA if (media.format == "NOVEL") SupportedMedia.NOVEL else SupportedMedia.MANGA,
media
) )
if (media.format == "NOVEL") { if (media.format == "NOVEL") {
tabLayout.inflateMenu(R.menu.novel_menu_detail) tabLayout.inflateMenu(R.menu.novel_menu_detail)
@ -378,6 +380,10 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
R.id.watch, R.id.read -> { R.id.watch, R.id.read -> {
selected = 1 selected = 1
} }
R.id.comment -> {
selected = 2
}
} }
} }
@ -385,10 +391,12 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
if (anime) when (selected) { if (anime) when (selected) {
0 -> return R.id.info 0 -> return R.id.info
1 -> return R.id.watch 1 -> return R.id.watch
2 -> return R.id.comment
} }
else when (selected) { else when (selected) {
0 -> return R.id.info 0 -> return R.id.info
1 -> return R.id.read 1 -> return R.id.read
2 -> return R.id.comment
} }
return R.id.info return R.id.info
} }
@ -408,19 +416,28 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
private class ViewPagerAdapter( private class ViewPagerAdapter(
fragmentManager: FragmentManager, fragmentManager: FragmentManager,
lifecycle: Lifecycle, lifecycle: Lifecycle,
private val media: SupportedMedia private val mediaType: SupportedMedia,
private val media: Media
) : ) :
FragmentStateAdapter(fragmentManager, lifecycle) { FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int = 2 override fun getItemCount(): Int = 3
override fun createFragment(position: Int): Fragment = when (position) { override fun createFragment(position: Int): Fragment = when (position) {
0 -> MediaInfoFragment() 0 -> MediaInfoFragment()
1 -> when (media) { 1 -> when (mediaType) {
SupportedMedia.ANIME -> AnimeWatchFragment() SupportedMedia.ANIME -> AnimeWatchFragment()
SupportedMedia.MANGA -> MangaReadFragment() SupportedMedia.MANGA -> MangaReadFragment()
SupportedMedia.NOVEL -> NovelReadFragment() SupportedMedia.NOVEL -> NovelReadFragment()
} }
2 -> {
val fragment = CommentsFragment()
val bundle = Bundle()
bundle.putInt("mediaId", media.id)
bundle.putString("mediaName", media.mainName())
fragment.arguments = bundle
fragment
}
else -> MediaInfoFragment() else -> MediaInfoFragment()
} }

View file

@ -19,7 +19,6 @@ import ani.dantotsu.connections.comments.CommentsAPI
import ani.dantotsu.databinding.DialogLayoutBinding import ani.dantotsu.databinding.DialogLayoutBinding
import ani.dantotsu.databinding.ItemAnimeWatchBinding import ani.dantotsu.databinding.ItemAnimeWatchBinding
import ani.dantotsu.databinding.ItemChipBinding import ani.dantotsu.databinding.ItemChipBinding
import ani.dantotsu.media.comments.CommentsActivity
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.SourceSearchDialogFragment import ani.dantotsu.media.SourceSearchDialogFragment
@ -60,17 +59,6 @@ class AnimeWatchAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val binding = holder.binding val binding = holder.binding
_binding = binding _binding = binding
//CommentsAPI
binding.animeComments.visibility = if (CommentsAPI.userId == null) View.GONE else View.VISIBLE
binding.animeComments.setOnClickListener {
startActivity(
fragment.requireContext(),
Intent(fragment.requireContext(), CommentsActivity::class.java)
.putExtra("mediaId", media.id)
.putExtra("mediaName", media.mainName()),
null
)
}
binding.faqbutton.setOnClickListener { binding.faqbutton.setOnClickListener {
startActivity( startActivity(

View file

@ -12,8 +12,6 @@ import ani.dantotsu.currActivity
import ani.dantotsu.databinding.ItemCommentsBinding import ani.dantotsu.databinding.ItemCommentsBinding
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.openLinkInBrowser import ani.dantotsu.openLinkInBrowser
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.GroupieAdapter
import com.xwray.groupie.Section import com.xwray.groupie.Section
@ -33,7 +31,7 @@ import kotlin.math.sqrt
class CommentItem(val comment: Comment, class CommentItem(val comment: Comment,
private val markwon: Markwon, private val markwon: Markwon,
val parentSection: Section, val parentSection: Section,
private val commentsActivity: CommentsActivity, private val commentsFragment: CommentsFragment,
private val backgroundColor: Int, private val backgroundColor: Int,
val commentDepth: Int val commentDepth: Int
) : BindableItem<ItemCommentsBinding>() { ) : BindableItem<ItemCommentsBinding>() {
@ -62,6 +60,12 @@ 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
if (comment.tag == null) {
viewBinding.commentUserTagLayout.visibility = View.GONE
} else {
viewBinding.commentUserTagLayout.visibility = View.VISIBLE
viewBinding.commentUserTag.text = comment.tag.toString()
}
replying(isReplying) //sets default text replying(isReplying) //sets default text
editing(isEditing) editing(isEditing)
if ((comment.replyCount ?: 0) > 0) { if ((comment.replyCount ?: 0) > 0) {
@ -83,7 +87,7 @@ class CommentItem(val comment: Comment,
} else { } else {
viewBinding.commentTotalReplies.text = "Hide Replies" viewBinding.commentTotalReplies.text = "Hide Replies"
repliesSection.clear() repliesSection.clear()
commentsActivity.viewReplyCallback(this) commentsFragment.viewReplyCallback(this)
repliesVisible = true repliesVisible = true
} }
} }
@ -98,12 +102,12 @@ class CommentItem(val comment: Comment,
viewBinding.commentEdit.setOnClickListener { viewBinding.commentEdit.setOnClickListener {
editing(!isEditing) editing(!isEditing)
commentsActivity.editCallback(this) commentsFragment.editCallback(this)
} }
viewBinding.commentReply.setOnClickListener { viewBinding.commentReply.setOnClickListener {
replying(!isReplying) replying(!isReplying)
commentsActivity.replyTo(this, comment.username) commentsFragment.replyTo(this, comment.username)
commentsActivity.replyCallback(this) commentsFragment.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
@ -134,7 +138,7 @@ class CommentItem(val comment: Comment,
dialogBuilder("Report Comment", "Only report comments that violate the rules. Are you sure you want to report this comment?") { dialogBuilder("Report Comment", "Only report comments that violate the rules. Are you sure you want to report this comment?") {
val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
scope.launch { scope.launch {
val success = CommentsAPI.reportComment(comment.commentId, comment.username, commentsActivity.mediaName) val success = CommentsAPI.reportComment(comment.commentId, comment.username, commentsFragment.mediaName)
if (success) { if (success) {
snackString("Comment Reported") snackString("Comment Reported")
} }
@ -347,7 +351,7 @@ class CommentItem(val comment: Comment,
* @param callback the callback to call when the user clicks yes * @param callback the callback to call when the user clicks yes
*/ */
private fun dialogBuilder(title: String, message: String, callback: () -> Unit) { private fun dialogBuilder(title: String, message: String, callback: () -> Unit) {
val alertDialog = android.app.AlertDialog.Builder(commentsActivity, R.style.MyPopup) val alertDialog = android.app.AlertDialog.Builder(commentsFragment.activity, R.style.MyPopup)
.setTitle(title) .setTitle(title)
.setMessage(message) .setMessage(message)
.setPositiveButton("Yes") { dialog, _ -> .setPositiveButton("Yes") { dialog, _ ->

View file

@ -1,14 +1,23 @@
package ani.dantotsu.media.comments package ani.dantotsu.media.comments
import android.graphics.drawable.ColorDrawable import android.animation.ValueAnimator
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context.INPUT_METHOD_SERVICE
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.text.TextWatcher import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.animation.doOnEnd
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R import ani.dantotsu.R
@ -16,13 +25,11 @@ import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.comments.Comment import ani.dantotsu.connections.comments.Comment
import ani.dantotsu.connections.comments.CommentResponse import ani.dantotsu.connections.comments.CommentResponse
import ani.dantotsu.connections.comments.CommentsAPI import ani.dantotsu.connections.comments.CommentsAPI
import ani.dantotsu.databinding.ActivityCommentsBinding import ani.dantotsu.databinding.FragmentCommentsBinding
import ani.dantotsu.initActivity
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.themes.ThemeManager
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.RequestManager import com.bumptech.glide.RequestManager
@ -51,30 +58,39 @@ import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.TimeZone import java.util.TimeZone
class CommentsActivity : AppCompatActivity() { class CommentsFragment : Fragment() {
lateinit var binding: ActivityCommentsBinding lateinit var binding: FragmentCommentsBinding
lateinit var activity: AppCompatActivity
private var interactionState = InteractionState.NONE private var interactionState = InteractionState.NONE
private var commentWithInteraction: CommentItem? = null private var commentWithInteraction: CommentItem? = null
private val section = Section() private val section = Section()
private val adapter = GroupieAdapter() private val adapter = GroupieAdapter()
private var tag: Int? = null
private var filterTag: Int? = null
private var mediaId: Int = -1 private var mediaId: Int = -1
var mediaName: String = "" var mediaName: String = ""
private var backgroundColor: Int = 0 private var backgroundColor: Int = 0
var pagesLoaded = 1 var pagesLoaded = 1
var totalPages = 1 var totalPages = 1
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreateView(
super.onCreate(savedInstanceState) inflater: LayoutInflater,
ThemeManager(this).applyTheme() container: ViewGroup?,
binding = ActivityCommentsBinding.inflate(layoutInflater) savedInstanceState: Bundle?
setContentView(binding.root) ): View {
initActivity(this) binding = FragmentCommentsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity = requireActivity() as AppCompatActivity
//get the media id from the intent //get the media id from the intent
val mediaId = intent.getIntExtra("mediaId", -1) val mediaId = arguments?.getInt("mediaId") ?: -1
mediaName = intent.getStringExtra("mediaName")?:"unknown" mediaName = arguments?.getString("mediaName") ?: "unknown"
if (mediaId == -1) { if (mediaId == -1) {
snackString("Invalid Media ID") snackString("Invalid Media ID")
finish() return
} }
this.mediaId = mediaId this.mediaId = mediaId
backgroundColor = (binding.root.background as? ColorDrawable)?.color ?: 0 backgroundColor = (binding.root.background as? ColorDrawable)?.color ?: 0
@ -82,7 +98,6 @@ class CommentsActivity : AppCompatActivity() {
val markwon = buildMarkwon() val markwon = buildMarkwon()
binding.commentUserAvatar.loadImage(Anilist.avatar) binding.commentUserAvatar.loadImage(Anilist.avatar)
binding.commentTitle.text = getText(R.string.comments)
val markwonEditor = MarkwonEditor.create(markwon) val markwonEditor = MarkwonEditor.create(markwon)
binding.commentInput.addTextChangedListener( binding.commentInput.addTextChangedListener(
MarkwonEditorTextWatcher.withProcess( MarkwonEditorTextWatcher.withProcess(
@ -99,7 +114,7 @@ class CommentsActivity : AppCompatActivity() {
} }
binding.commentsList.adapter = adapter binding.commentsList.adapter = adapter
binding.commentsList.layoutManager = LinearLayoutManager(this) binding.commentsList.layoutManager = LinearLayoutManager(activity)
lifecycleScope.launch { lifecycleScope.launch {
loadAndDisplayComments() loadAndDisplayComments()
@ -117,7 +132,7 @@ class CommentsActivity : AppCompatActivity() {
section.update(groups) section.update(groups)
} }
val popup = PopupMenu(this, view) val popup = PopupMenu(activity, view)
popup.setOnMenuItemClickListener { item -> popup.setOnMenuItemClickListener { item ->
val sortOrder = when (item.itemId) { val sortOrder = when (item.itemId) {
R.id.comment_sort_newest -> "newest" R.id.comment_sort_newest -> "newest"
@ -136,6 +151,36 @@ class CommentsActivity : AppCompatActivity() {
popup.show() popup.show()
} }
binding.commentFilter.setOnClickListener {
val alertDialog = android.app.AlertDialog.Builder(activity, R.style.MyPopup)
.setTitle("Enter a chapter/episode number tag")
.setView(R.layout.dialog_edittext)
.setPositiveButton("OK") { dialog, _ ->
val editText =
(dialog as AlertDialog).findViewById<EditText>(R.id.dialogEditText)
val text = editText?.text.toString()
filterTag = text.toIntOrNull()
lifecycleScope.launch {
loadAndDisplayComments()
}
dialog.dismiss()
}
.setNeutralButton("Clear") { dialog, _ ->
filterTag = null
lifecycleScope.launch {
loadAndDisplayComments()
}
dialog.dismiss()
}
.setNegativeButton("Cancel") { dialog, _ ->
filterTag = null
dialog.dismiss()
}
val dialog = alertDialog.show()
dialog?.window?.setDimAmount(0.8f)
}
var isFetching = false var isFetching = false
//if we have scrolled to the bottom of the list, load more comments //if we have scrolled to the bottom of the list, load more comments
binding.commentsList.addOnScrollListener(object : binding.commentsList.addOnScrollListener(object :
@ -170,7 +215,7 @@ class CommentsActivity : AppCompatActivity() {
private suspend fun fetchComments(): CommentResponse? { private suspend fun fetchComments(): CommentResponse? {
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
CommentsAPI.getCommentsForId(mediaId, pagesLoaded + 1) CommentsAPI.getCommentsForId(mediaId, pagesLoaded + 1, filterTag)
} }
} }
@ -182,7 +227,7 @@ class CommentsActivity : AppCompatActivity() {
comment, comment,
buildMarkwon(), buildMarkwon(),
section, section,
this@CommentsActivity, this@CommentsFragment,
backgroundColor, backgroundColor,
0 0
) )
@ -206,6 +251,79 @@ class CommentsActivity : AppCompatActivity() {
} }
} }
}) })
binding.commentInput.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
val targetWidth = binding.commentInputLayout.width -
binding.commentLabel.width -
binding.commentSend.width -
binding.commentUserAvatar.width - 12 + 16
val anim = ValueAnimator.ofInt(binding.commentInput.width, targetWidth)
anim.addUpdateListener { valueAnimator ->
val layoutParams = binding.commentInput.layoutParams
layoutParams.width = valueAnimator.animatedValue as Int
binding.commentInput.layoutParams = layoutParams
}
anim.duration = 300
anim.start()
anim.doOnEnd {
binding.commentLabel.visibility = View.VISIBLE
binding.commentSend.visibility = View.VISIBLE
binding.commentLabel.animate().translationX(0f).setDuration(300).start()
binding.commentSend.animate().translationX(0f).setDuration(300).start()
}
}
binding.commentLabel.setOnClickListener {
//alert dialog to enter a number, with a cancel and ok button
val alertDialog = android.app.AlertDialog.Builder(activity, R.style.MyPopup)
.setTitle("Enter a chapter/episode number tag")
.setView(R.layout.dialog_edittext)
.setPositiveButton("OK") { dialog, _ ->
val editText =
(dialog as AlertDialog).findViewById<EditText>(R.id.dialogEditText)
val text = editText?.text.toString()
tag = text.toIntOrNull()
if (tag == null) {
binding.commentLabel.background = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_label_off_24,
null
)
} else {
binding.commentLabel.background = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_label_24,
null
)
}
dialog.dismiss()
}
.setNeutralButton("Clear") { dialog, _ ->
tag = null
binding.commentLabel.background = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_label_off_24,
null
)
dialog.dismiss()
}
.setNegativeButton("Cancel") { dialog, _ ->
tag = null
binding.commentLabel.background = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_label_off_24,
null
)
dialog.dismiss()
}
val dialog = alertDialog.show()
dialog?.window?.setDimAmount(0.8f)
}
}
binding.commentSend.setOnClickListener { binding.commentSend.setOnClickListener {
if (CommentsAPI.isBanned) { if (CommentsAPI.isBanned) {
snackString("You are banned from commenting :(") snackString("You are banned from commenting :(")
@ -220,6 +338,19 @@ class CommentsActivity : AppCompatActivity() {
} }
} }
@SuppressLint("NotifyDataSetChanged")
override fun onStart() {
super.onStart()
adapter.notifyDataSetChanged()
}
@SuppressLint("NotifyDataSetChanged")
override fun onResume() {
super.onResume()
tag = null
adapter.notifyDataSetChanged()
}
enum class InteractionState { enum class InteractionState {
NONE, EDIT, REPLY NONE, EDIT, REPLY
} }
@ -229,7 +360,6 @@ class CommentsActivity : AppCompatActivity() {
* Called when the activity is created * Called when the activity is created
* Or when the user refreshes the comments * Or when the user refreshes the comments
*/ */
private suspend fun loadAndDisplayComments() { private suspend fun loadAndDisplayComments() {
binding.commentsProgressBar.visibility = View.VISIBLE binding.commentsProgressBar.visibility = View.VISIBLE
binding.commentsList.visibility = View.GONE binding.commentsList.visibility = View.GONE
@ -237,7 +367,7 @@ class CommentsActivity : AppCompatActivity() {
section.clear() section.clear()
val comments = withContext(Dispatchers.IO) { val comments = withContext(Dispatchers.IO) {
CommentsAPI.getCommentsForId(mediaId) CommentsAPI.getCommentsForId(mediaId, tag = filterTag)
} }
val sortedComments = sortComments(comments?.comments) val sortedComments = sortComments(comments?.comments)
@ -248,7 +378,7 @@ class CommentsActivity : AppCompatActivity() {
it, it,
buildMarkwon(), buildMarkwon(),
section, section,
this@CommentsActivity, this@CommentsFragment,
backgroundColor, backgroundColor,
0 0
) )
@ -264,8 +394,7 @@ class CommentsActivity : AppCompatActivity() {
private fun sortComments(comments: List<Comment>?): List<Comment> { private fun sortComments(comments: List<Comment>?): List<Comment> {
if (comments == null) return emptyList() if (comments == null) return emptyList()
val sortOrder = PrefManager.getVal(PrefName.CommentSortOrder, "newest") return when (PrefManager.getVal(PrefName.CommentSortOrder, "newest")) {
return when (sortOrder) {
"newest" -> comments.sortedByDescending { CommentItem.timestampToMillis(it.timestamp) } "newest" -> comments.sortedByDescending { CommentItem.timestampToMillis(it.timestamp) }
"oldest" -> comments.sortedBy { CommentItem.timestampToMillis(it.timestamp) } "oldest" -> comments.sortedBy { CommentItem.timestampToMillis(it.timestamp) }
"highest_rated" -> comments.sortedByDescending { it.upvotes - it.downvotes } "highest_rated" -> comments.sortedByDescending { it.upvotes - it.downvotes }
@ -285,7 +414,7 @@ class CommentsActivity : AppCompatActivity() {
InteractionState.EDIT -> { InteractionState.EDIT -> {
binding.commentReplyToContainer.visibility = View.GONE binding.commentReplyToContainer.visibility = View.GONE
binding.commentInput.setText("") binding.commentInput.setText("")
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager val imm = activity.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.commentInput.windowToken, 0) imm.hideSoftInputFromWindow(binding.commentInput.windowToken, 0)
commentWithInteraction?.editing(false) commentWithInteraction?.editing(false)
InteractionState.EDIT InteractionState.EDIT
@ -293,7 +422,7 @@ class CommentsActivity : AppCompatActivity() {
InteractionState.REPLY -> { InteractionState.REPLY -> {
binding.commentInput.setText("") binding.commentInput.setText("")
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager val imm = activity.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.commentInput.windowToken, 0) imm.hideSoftInputFromWindow(binding.commentInput.windowToken, 0)
commentWithInteraction?.replying(false) commentWithInteraction?.replying(false)
InteractionState.REPLY InteractionState.REPLY
@ -316,7 +445,7 @@ class CommentsActivity : AppCompatActivity() {
binding.commentInput.setText(comment.comment.content) binding.commentInput.setText(comment.comment.content)
binding.commentInput.requestFocus() binding.commentInput.requestFocus()
binding.commentInput.setSelection(binding.commentInput.text.length) binding.commentInput.setSelection(binding.commentInput.text.length)
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager val imm = activity.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(binding.commentInput, InputMethodManager.SHOW_IMPLICIT) imm.showSoftInput(binding.commentInput, InputMethodManager.SHOW_IMPLICIT)
interactionState = InteractionState.EDIT interactionState = InteractionState.EDIT
} }
@ -332,11 +461,12 @@ class CommentsActivity : AppCompatActivity() {
binding.commentReplyToContainer.visibility = View.VISIBLE binding.commentReplyToContainer.visibility = View.VISIBLE
binding.commentInput.requestFocus() binding.commentInput.requestFocus()
binding.commentInput.setSelection(binding.commentInput.text.length) binding.commentInput.setSelection(binding.commentInput.text.length)
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager val imm = activity.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(binding.commentInput, InputMethodManager.SHOW_IMPLICIT) imm.showSoftInput(binding.commentInput, InputMethodManager.SHOW_IMPLICIT)
interactionState = InteractionState.REPLY interactionState = InteractionState.REPLY
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun replyTo(comment: CommentItem, username: String) { fun replyTo(comment: CommentItem, username: String) {
if (comment.isReplying) { if (comment.isReplying) {
@ -363,14 +493,16 @@ class CommentsActivity : AppCompatActivity() {
} }
replies?.comments?.forEach { replies?.comments?.forEach {
val depth = if (comment.commentDepth + 1 > comment.MAX_DEPTH) comment.commentDepth else comment.commentDepth + 1 val depth =
val section = if (comment.commentDepth + 1 > comment.MAX_DEPTH) comment.parentSection else comment.repliesSection if (comment.commentDepth + 1 > comment.MAX_DEPTH) comment.commentDepth else comment.commentDepth + 1
val section =
if (comment.commentDepth + 1 > comment.MAX_DEPTH) comment.parentSection else comment.repliesSection
if (depth >= comment.MAX_DEPTH) comment.registerSubComment(it.commentId) if (depth >= comment.MAX_DEPTH) comment.registerSubComment(it.commentId)
val newCommentItem = CommentItem( val newCommentItem = CommentItem(
it, it,
buildMarkwon(), buildMarkwon(),
section, section,
this@CommentsActivity, this@CommentsFragment,
backgroundColor, backgroundColor,
depth depth
) )
@ -386,7 +518,7 @@ class CommentsActivity : AppCompatActivity() {
* Called when the user tries to comment for the first time * Called when the user tries to comment for the first time
*/ */
private fun showCommentRulesDialog() { private fun showCommentRulesDialog() {
val alertDialog = android.app.AlertDialog.Builder(this, R.style.MyPopup) val alertDialog = android.app.AlertDialog.Builder(activity, R.style.MyPopup)
.setTitle("Commenting Rules") .setTitle("Commenting Rules")
.setMessage( .setMessage(
"I WILL BAN YOU WITHOUT HESITATION\n" + "I WILL BAN YOU WITHOUT HESITATION\n" +
@ -426,6 +558,12 @@ class CommentsActivity : AppCompatActivity() {
handleEditComment(commentText) handleEditComment(commentText)
} else { } else {
handleNewComment(commentText) handleNewComment(commentText)
tag = null
binding.commentLabel.background = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_label_off_24,
null
)
} }
} }
} }
@ -469,22 +607,27 @@ class CommentsActivity : AppCompatActivity() {
CommentsAPI.comment( CommentsAPI.comment(
mediaId, mediaId,
if (interactionState == InteractionState.REPLY) commentWithInteraction?.comment?.commentId else null, if (interactionState == InteractionState.REPLY) commentWithInteraction?.comment?.commentId else null,
commentText commentText,
tag
) )
} }
success?.let { success?.let {
if (interactionState == InteractionState.REPLY) { if (interactionState == InteractionState.REPLY) {
if (commentWithInteraction == null) return@let if (commentWithInteraction == null) return@let
val section = if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) commentWithInteraction?.parentSection else commentWithInteraction?.repliesSection val section =
val depth = if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) commentWithInteraction!!.commentDepth else commentWithInteraction!!.commentDepth + 1 if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) commentWithInteraction?.parentSection else commentWithInteraction?.repliesSection
if (depth >= commentWithInteraction!!.MAX_DEPTH) commentWithInteraction!!.registerSubComment(it.commentId) val depth =
if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) commentWithInteraction!!.commentDepth else commentWithInteraction!!.commentDepth + 1
if (depth >= commentWithInteraction!!.MAX_DEPTH) commentWithInteraction!!.registerSubComment(
it.commentId
)
section?.add( section?.add(
if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) 0 else section.itemCount, if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) 0 else section.itemCount,
CommentItem( CommentItem(
it, it,
buildMarkwon(), buildMarkwon(),
section, section,
this@CommentsActivity, this@CommentsFragment,
backgroundColor, backgroundColor,
depth depth
) )
@ -492,7 +635,14 @@ class CommentsActivity : AppCompatActivity() {
} else { } else {
section.add( section.add(
0, 0,
CommentItem(it, buildMarkwon(), section, this@CommentsActivity, backgroundColor, 0) CommentItem(
it,
buildMarkwon(),
section,
this@CommentsFragment,
backgroundColor,
0
)
) )
} }
} }
@ -503,11 +653,11 @@ class CommentsActivity : AppCompatActivity() {
* @return the markwon instance * @return the markwon instance
*/ */
private fun buildMarkwon(): Markwon { private fun buildMarkwon(): Markwon {
val markwon = Markwon.builder(this) val markwon = Markwon.builder(activity)
.usePlugin(SoftBreakAddsNewLinePlugin.create()) .usePlugin(SoftBreakAddsNewLinePlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(TablePlugin.create(this)) .usePlugin(TablePlugin.create(activity))
.usePlugin(TaskListPlugin.create(this)) .usePlugin(TaskListPlugin.create(activity))
.usePlugin(HtmlPlugin.create { plugin -> .usePlugin(HtmlPlugin.create { plugin ->
plugin.addHandler( plugin.addHandler(
TagHandlerNoOp.create("h1", "h2", "h3", "h4", "h5", "h6", "hr", "pre") TagHandlerNoOp.create("h1", "h2", "h3", "h4", "h5", "h6", "hr", "pre")
@ -516,7 +666,7 @@ class CommentsActivity : AppCompatActivity() {
.usePlugin(GlideImagesPlugin.create(object : GlideImagesPlugin.GlideStore { .usePlugin(GlideImagesPlugin.create(object : GlideImagesPlugin.GlideStore {
private val requestManager: RequestManager = private val requestManager: RequestManager =
Glide.with(this@CommentsActivity).apply { Glide.with(this@CommentsFragment).apply {
addDefaultRequestListener(object : RequestListener<Any> { addDefaultRequestListener(object : RequestListener<Any> {
override fun onResourceReady( override fun onResourceReady(
resource: Any, resource: Any,

View file

@ -24,7 +24,6 @@ import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.SourceSearchDialogFragment import ani.dantotsu.media.SourceSearchDialogFragment
import ani.dantotsu.media.anime.handleProgress import ani.dantotsu.media.anime.handleProgress
import ani.dantotsu.media.comments.CommentsActivity
import ani.dantotsu.others.LanguageMapper import ani.dantotsu.others.LanguageMapper
import ani.dantotsu.others.webview.CookieCatcher import ani.dantotsu.others.webview.CookieCatcher
import ani.dantotsu.parsers.DynamicMangaParser import ani.dantotsu.parsers.DynamicMangaParser
@ -67,17 +66,6 @@ class MangaReadAdapter(
_binding = binding _binding = binding
binding.sourceTitle.setText(R.string.chaps) binding.sourceTitle.setText(R.string.chaps)
binding.animeComments.visibility = if (CommentsAPI.userId == null) View.GONE else View.VISIBLE
binding.animeComments.setOnClickListener {
startActivity(
fragment.requireContext(),
Intent(fragment.requireContext(), CommentsActivity::class.java)
.putExtra("mediaId", media.id)
.putExtra("mediaName", media.mainName()),
null
)
}
//Fuck u launch //Fuck u launch
binding.faqbutton.setOnClickListener { binding.faqbutton.setOnClickListener {
val intent = Intent(fragment.requireContext(), FAQActivity::class.java) val intent = Intent(fragment.requireContext(), FAQActivity::class.java)

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FFF"
android:pathData="M840,480 L666,726q-11,16 -28.5,25t-37.5,9L200,760q-33,0 -56.5,-23.5T120,680v-400q0,-33 23.5,-56.5T200,200h400q20,0 37.5,9t28.5,25l174,246ZM742,480L600,280L200,280v400h400l142,-200ZM200,480v200,-400 200Z"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FFF"
android:pathData="m738,624 l-58,-58 62,-86 -142,-200L394,280l-80,-80h286q20,0 37,8.5t29,25.5l174,246 -102,144ZM792,904L638,750q-9,5 -18,7.5t-20,2.5L200,760q-33,0 -56.5,-23.5T120,680v-400q0,-11 2.5,-20t7.5,-18l-74,-74 56,-56 736,736 -56,56ZM383,496ZM537,423ZM568,680L200,312v368h368Z"/>
</vector>

View file

@ -1,10 +1,10 @@
<vector android:alpha="0.9" android:height="24dp" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportHeight="960"
android:viewportWidth="960"
android:tint="?attr/colorControlNormal"
android:width="24dp" android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android"> android:height="24dp"
<path android:tint="?attr/colorControlNormal"
android:fillColor="@android:color/white" android:viewportWidth="960"
android:pathData="M240,560h320v-80L240,480v80ZM240,440h480v-80L240,360v80ZM240,320h480v-80L240,240v80ZM80,880v-720q0,-33 23.5,-56.5T160,80h640q33,0 56.5,23.5T880,160v480q0,33 -23.5,56.5T800,720L240,720L80,880ZM206,640h594v-480L160,160v525l46,-45ZM160,640v-480,480Z"/> android:viewportHeight="960">
<path
android:fillColor="#FFF"
android:pathData="M280,720q-17,0 -28.5,-11.5T240,680v-80h520v-360h80q17,0 28.5,11.5T880,280v600L720,720L280,720ZM80,680v-560q0,-17 11.5,-28.5T120,80h520q17,0 28.5,11.5T680,120v360q0,17 -11.5,28.5T640,520L240,520L80,680ZM600,440v-280L160,160v280h440ZM160,440v-280,280Z"/>
</vector> </vector>

View file

@ -1,11 +1,10 @@
<vector android:alpha="0.9" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp" android:width="48dp"
android:viewportHeight="25" android:height="48dp"
android:viewportWidth="25"
android:tint="?attr/colorControlNormal" android:tint="?attr/colorControlNormal"
android:width="24dp" android:viewportWidth="960"
xmlns:android="http://schemas.android.com/apk/res/android"> android:viewportHeight="960">
<path <path
android:fillColor="@android:color/white" android:fillColor="#FFF"
android:pathData="M19.117,12.648C19.474,12.858 19.934,12.738 20.143,12.381C20.353,12.024 20.233,11.564 19.876,11.355L19.117,12.648ZM6.943,4.637L6.556,5.279L6.564,5.283L6.943,4.637ZM5.924,4.66L5.508,4.036L5.508,4.036L5.924,4.66ZM5.51,5.592L4.768,5.702C4.776,5.751 4.788,5.8 4.805,5.847L5.51,5.592ZM7.124,12.257C7.265,12.646 7.695,12.848 8.084,12.707C8.474,12.566 8.675,12.136 8.535,11.746L7.124,12.257ZM19.876,12.648C20.233,12.439 20.353,11.979 20.143,11.622C19.934,11.265 19.474,11.145 19.117,11.355L19.876,12.648ZM6.943,19.367L6.564,18.72L6.556,18.724L6.943,19.367ZM5.924,19.343L5.508,19.967L5.508,19.967L5.924,19.343ZM5.51,18.412L4.805,18.156C4.788,18.204 4.776,18.252 4.768,18.302L5.51,18.412ZM8.535,12.257C8.675,11.867 8.474,11.437 8.084,11.296C7.695,11.155 7.265,11.357 7.124,11.746L8.535,12.257ZM19.496,12.752C19.91,12.752 20.246,12.416 20.246,12.002C20.246,11.587 19.91,11.252 19.496,11.252L19.496,12.752ZM7.829,11.252C7.415,11.252 7.079,11.587 7.079,12.002C7.079,12.416 7.415,12.752 7.829,12.752L7.829,11.252ZM19.876,11.355L7.323,3.99L6.564,5.283L19.117,12.648L19.876,11.355ZM7.33,3.994C6.766,3.654 6.056,3.67 5.508,4.036L6.34,5.284C6.405,5.241 6.489,5.239 6.556,5.279L7.33,3.994ZM5.508,4.036C4.96,4.401 4.672,5.05 4.768,5.702L6.252,5.482C6.241,5.404 6.275,5.327 6.34,5.284L5.508,4.036ZM4.805,5.847L7.124,12.257L8.535,11.746L6.216,5.336L4.805,5.847ZM19.117,11.355L6.564,18.72L7.323,20.013L19.876,12.648L19.117,11.355ZM6.556,18.724C6.489,18.764 6.405,18.763 6.34,18.719L5.508,19.967C6.056,20.333 6.766,20.349 7.33,20.009L6.556,18.724ZM6.34,18.719C6.275,18.676 6.241,18.599 6.252,18.521L4.768,18.302C4.672,18.953 4.96,19.602 5.508,19.967L6.34,18.719ZM6.216,18.667L8.535,12.257L7.124,11.746L4.805,18.156L6.216,18.667ZM19.496,11.252L7.829,11.252L7.829,12.752L19.496,12.752L19.496,11.252Z"/> android:pathData="M792,517 L176,777q-20,8 -38,-3.5T120,740v-520q0,-22 18,-33.5t38,-3.5l616,260q25,11 25,37t-25,37ZM200,680l474,-200 -474,-200v140l240,60 -240,60v140ZM200,680v-400,400Z" />
</vector> </vector>

View file

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

View file

@ -234,7 +234,7 @@
android:id="@+id/mediaViewPager" android:id="@+id/mediaViewPager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:nestedScrollingEnabled="false" android:nestedScrollingEnabled="true"
tools:ignore="SpeakableTextPresentCheck" /> tools:ignore="SpeakableTextPresentCheck" />
</LinearLayout> </LinearLayout>
@ -248,7 +248,7 @@
android:translationZ="1dp" android:translationZ="1dp"
app:itemActiveIndicatorStyle="@style/BottomNavBar" app:itemActiveIndicatorStyle="@style/BottomNavBar"
app:itemIconTint="@color/tab_layout_icon" app:itemIconTint="@color/tab_layout_icon"
app:itemRippleColor="?attr/colorPrimary" app:itemRippleColor="#00000000"
app:itemTextAppearanceActive="@style/NavBarText" app:itemTextAppearanceActive="@style/NavBarText"
app:itemTextAppearanceInactive="@style/NavBarText" app:itemTextAppearanceInactive="@style/NavBarText"
app:itemTextColor="@color/tab_layout_icon" app:itemTextColor="@color/tab_layout_icon"

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/dialogEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLines="1"
android:maxLength="4"
android:autofillHints="e.g. 1" />
</LinearLayout>

View file

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="@+id/commentsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:colorBackground"
android:fitsSystemWindows="true">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/commentsRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/commentInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:windowSoftInputMode="adjustResize">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/commentUserAvatar"
style="@style/CircularImageView"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="12dp"
android:scaleType="center"
app:srcCompat="@drawable/ic_round_add_circle_24"
tools:ignore="ContentDescription,ImageContrastCheck" />
<EditText
android:id="@+id/commentInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:layout_gravity="start|center_vertical"
android:autofillHints="The One Piece is real"
android:background="@drawable/card_outline"
android:fontFamily="@font/poppins_semi_bold"
android:hint="Add a comment..."
android:inputType="textMultiLine"
android:maxLength="300"
android:maxLines="8"
android:padding="8dp"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<ImageButton
android:id="@+id/commentLabel"
android:layout_width="42dp"
android:layout_height="42dp"
android:scaleType="center"
android:scaleX="0.6"
android:scaleY="0.6"
android:translationX="100dp"
android:background="@drawable/ic_label_off_24"
android:visibility="gone"/>
<ImageButton
android:id="@+id/commentSend"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginEnd="12dp"
android:translationX="100dp"
android:scaleType="center"
android:scaleX="0.85"
android:scaleY="0.85"
android:background="@drawable/ic_round_send_24"
tools:ignore="ContentDescription"
android:visibility="gone"/>
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/commentFilter"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/sort_by"
app:srcCompat="@drawable/ic_round_filter_alt_24"
app:tint="?attr/colorOnBackground" />
<ImageView
android:id="@+id/commentSort"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/sort_by"
app:srcCompat="@drawable/ic_round_sort_24"
app:tint="?attr/colorOnBackground" />
</LinearLayout>
<ProgressBar
android:id="@+id/commentsProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginTop="64dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/commentsList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
android:visibility="gone"
tools:listitem="@layout/item_comments"
tools:visibility="visible" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:background="@color/nav_bg"
android:orientation="vertical"
android:windowSoftInputMode="adjustResize">
<LinearLayout
android:id="@+id/commentReplyToContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<TextView
android:id="@+id/commentReplyTo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:ellipsize="end"
android:fontFamily="@font/poppins_semi_bold"
android:singleLine="true"
android:text="Replying to "
android:textColor="?attr/colorOnBackground"
android:textSize="14sp"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/commentReplyToCancel"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="16dp"
android:background="?android:attr/selectableItemBackground"
app:srcCompat="@drawable/ic_round_close_24"
app:tint="?attr/colorOnBackground"
tools:ignore="ContentDescription" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -19,22 +19,6 @@
android:orientation="vertical" android:orientation="vertical"
android:padding="32dp"> android:padding="32dp">
<Button
android:id="@+id/animeComments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:backgroundTint="?attr/colorSurfaceVariant"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:text="@string/comments"
android:textAlignment="center"
android:textColor="@color/bg_white"
android:visibility="gone"
tools:ignore="TextContrastCheck"
tools:visibility="visible"/>
<TextView <TextView
android:id="@+id/animeSourceTitle" android:id="@+id/animeSourceTitle"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -27,6 +27,7 @@
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:scaleType="center" android:scaleType="center"
android:layout_gravity="center_horizontal"
style="@style/CircularImageView" style="@style/CircularImageView"
app:srcCompat="@drawable/ic_round_add_circle_24" app:srcCompat="@drawable/ic_round_add_circle_24"
tools:ignore="ContentDescription,ImageContrastCheck" /> tools:ignore="ContentDescription,ImageContrastCheck" />
@ -42,8 +43,37 @@
android:alpha="0.6" android:alpha="0.6"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<LinearLayout
android:id="@+id/commentUserTagLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/commentTag"
android:layout_width="16dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_label_24" />
<TextView
android:id="@+id/commentUserTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins_semi_bold"
android:paddingTop="2dp"
android:text="9999"
android:maxLines="1"
android:textSize="12sp"
android:alpha="0.6"
android:layout_marginEnd="12dp"
android:layout_gravity="center_vertical"
tools:ignore="HardcodedText" />
</LinearLayout> </LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -116,7 +146,7 @@
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="4" android:maxLines="8"
android:scrollHorizontally="false" android:scrollHorizontally="false"
android:ellipsize="end" android:ellipsize="end"
android:text="@string/slogan" android:text="@string/slogan"
@ -132,6 +162,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:alpha="0.6" android:alpha="0.6"
android:paddingTop="1dp"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="Reply" android:text="Reply"
android:textSize="12sp" android:textSize="12sp"
@ -143,6 +174,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:alpha="0.6" android:alpha="0.6"
android:paddingTop="1dp"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="Edit" android:text="Edit"
android:textSize="12sp" android:textSize="12sp"
@ -154,6 +186,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:alpha="0.6" android:alpha="0.6"
android:paddingTop="1dp"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="Delete" android:text="Delete"
android:textSize="12sp" android:textSize="12sp"
@ -165,6 +198,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:alpha="0.6" android:alpha="0.6"
android:paddingTop="1dp"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="Report" android:text="Report"
android:textSize="12sp" android:textSize="12sp"
@ -175,6 +209,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:alpha="0.6" android:alpha="0.6"
android:paddingTop="1dp"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="Ban User" android:text="Ban User"
android:textSize="12sp" android:textSize="12sp"

View file

@ -11,4 +11,10 @@
android:enabled="true" android:enabled="true"
android:icon="@drawable/ic_round_movie_filter_24" android:icon="@drawable/ic_round_movie_filter_24"
android:title="@string/watch" /> android:title="@string/watch" />
<item
android:id="@+id/comment"
android:enabled="true"
android:icon="@drawable/ic_round_comment_24"
android:title="@string/comments" />
</menu> </menu>

View file

@ -11,4 +11,10 @@
android:enabled="true" android:enabled="true"
android:icon="@drawable/ic_round_import_contacts_24" android:icon="@drawable/ic_round_import_contacts_24"
android:title="@string/read" /> android:title="@string/read" />
<item
android:id="@+id/comment"
android:enabled="true"
android:icon="@drawable/ic_round_comment_24"
android:title="@string/comments" />
</menu> </menu>

View file

@ -12,4 +12,10 @@
android:icon="@drawable/ic_round_book_24" android:icon="@drawable/ic_round_book_24"
android:title="@string/read" /> android:title="@string/read" />
<item
android:id="@+id/comment"
android:enabled="true"
android:icon="@drawable/ic_round_comment_24"
android:title="@string/comments" />
</menu> </menu>