improve on comments

This commit is contained in:
Matthieu 2022-08-03 20:19:29 +02:00
parent 88ac02150c
commit 62dc91413d
4 changed files with 171 additions and 157 deletions

View File

@ -1,28 +1,16 @@
package org.pixeldroid.app.posts
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.ExperimentalPagingApi
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Job
import org.pixeldroid.app.R
import org.pixeldroid.app.databinding.ActivityPostBinding
import org.pixeldroid.app.databinding.CommentBinding
import org.pixeldroid.app.posts.feeds.initAdapter
import org.pixeldroid.app.posts.feeds.launch
import org.pixeldroid.app.posts.feeds.uncachedFeeds.FeedViewModel
import org.pixeldroid.app.posts.feeds.uncachedFeeds.comments.CommentContentRepository
import org.pixeldroid.app.profile.ProfileViewModelFactory
import org.pixeldroid.app.posts.feeds.uncachedFeeds.comments.CommentFragment
import org.pixeldroid.app.posts.feeds.uncachedFeeds.comments.CommentFragment.Companion.COMMENT_DOMAIN
import org.pixeldroid.app.posts.feeds.uncachedFeeds.comments.CommentFragment.Companion.COMMENT_STATUS_ID
import org.pixeldroid.app.utils.BaseThemedWithBarActivity
import org.pixeldroid.app.utils.api.PixelfedAPI
import org.pixeldroid.app.utils.api.objects.Status
@ -30,18 +18,13 @@ import org.pixeldroid.app.utils.api.objects.Status.Companion.POST_COMMENT_TAG
import org.pixeldroid.app.utils.api.objects.Status.Companion.POST_TAG
import org.pixeldroid.app.utils.api.objects.Status.Companion.VIEW_COMMENTS_TAG
import org.pixeldroid.app.utils.displayDimensionsInPx
import org.pixeldroid.app.utils.setProfileImageFromURL
import retrofit2.HttpException
import java.io.IOException
class PostActivity : BaseThemedWithBarActivity() {
lateinit var domain : String
private lateinit var binding: ActivityPostBinding
private lateinit var profileAdapter: PagingDataAdapter<Status, RecyclerView.ViewHolder>
private lateinit var commentViewModel: FeedViewModel<Status>
private var job: Job? = null
private var commentFragment = CommentFragment()
private lateinit var status: Status
@ -58,8 +41,6 @@ class PostActivity : BaseThemedWithBarActivity() {
val user = db.userDao().getActiveUser()
domain = user?.instance_uri.orEmpty()
supportActionBar?.title = getString(R.string.post_title).format(status.account?.getDisplayName())
val holder = StatusViewHolder(binding.postFragmentSingle)
@ -67,7 +48,7 @@ class PostActivity : BaseThemedWithBarActivity() {
holder.bind(status, apiHolder, db, lifecycleScope, displayDimensionsInPx(), isActivity = true)
activateCommenter()
retrieveComments()
initCommentsFragment(domain = user?.instance_uri.orEmpty())
if(viewComments || postComment){
//Scroll already down as much as possible (since comments are not loaded yet)
@ -101,24 +82,15 @@ class PostActivity : BaseThemedWithBarActivity() {
}
}
@OptIn(ExperimentalPagingApi::class)
private fun retrieveComments() {
// get the view model
@Suppress("UNCHECKED_CAST")
commentViewModel = ViewModelProvider(this@PostActivity, ProfileViewModelFactory(
CommentContentRepository(
apiHolder.setToCurrentUser(),
status.id
)
)
)[FeedViewModel::class.java] as FeedViewModel<Status>
private fun initCommentsFragment(domain: String) {
profileAdapter = CommentAdapter()
initAdapter(binding.postCommentsProgressBar, binding.postRefreshLayout,
binding.commentRecyclerView, binding.motionLayout, binding.errorLayout,
profileAdapter)
val arguments = Bundle()
arguments.putSerializable(COMMENT_STATUS_ID, status.id)
arguments.putSerializable(COMMENT_DOMAIN, domain)
commentFragment.arguments = arguments
job = launch(job, lifecycleScope, commentViewModel, profileAdapter)
supportFragmentManager.beginTransaction()
.add(R.id.commentFragment, commentFragment).commit()
}
private suspend fun postComment(
@ -131,8 +103,8 @@ class PostActivity : BaseThemedWithBarActivity() {
val response = api.postStatus(nonNullText, it)
binding.commentIn.visibility = View.GONE
//Add the comment to the comment section
profileAdapter.refresh()
//Reload to add the comment to the comment section
commentFragment.adapter.refresh()
Toast.makeText(
binding.root.context,
@ -154,82 +126,4 @@ class PostActivity : BaseThemedWithBarActivity() {
}
}
}
inner class CommentViewHolder(val binding: CommentBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(comment: Status) {
setProfileImageFromURL(binding.profilePic,
comment.account!!.anyAvatar(),
binding.profilePic
)
binding.user.text = comment.account.username
binding.commentText.text = parseHTMLText(
comment.content!!,
comment.mentions.orEmpty(),
apiHolder,
this@PostActivity,
lifecycleScope
)
binding.postDomain.text = comment.getStatusDomain(domain, binding.postDomain.context)
if(comment.replies_count == 0 || comment.replies_count == null){
binding.replies.visibility = View.GONE
} else {
binding.replies.visibility = View.VISIBLE
binding.replies.text = resources.getQuantityString(
R.plurals.replies_count,
comment.replies_count,
comment.replies_count
)
}
binding.comment.setOnClickListener{ openComment(comment) }
binding.profilePic.setOnClickListener{ comment.account.openProfile(itemView.context) }
binding.user.setOnClickListener { comment.account.openProfile(itemView.context) }
}
private fun openComment(comment: Status) {
val intent = Intent(itemView.context, PostActivity::class.java).apply {
putExtra(POST_TAG, comment)
}
itemView.context.startActivity(intent)
}
}
inner class CommentAdapter : PagingDataAdapter<Status, RecyclerView.ViewHolder>(
UIMODEL_COMPARATOR
) {
fun create(parent: ViewGroup): CommentViewHolder {
val itemBinding = CommentBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return CommentViewHolder(itemBinding)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return create(parent)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val post = getItem(position)
post?.let {
(holder as CommentViewHolder).bind(it)
}
}
}
private val UIMODEL_COMPARATOR = object : DiffUtil.ItemCallback<Status>() {
override fun areItemsTheSame(oldItem: Status, newItem: Status): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Status, newItem: Status): Boolean =
oldItem.content == newItem.content
}
}

View File

@ -0,0 +1,151 @@
package org.pixeldroid.app.posts.feeds.uncachedFeeds.comments
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.ExperimentalPagingApi
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import org.pixeldroid.app.R
import org.pixeldroid.app.databinding.CommentBinding
import org.pixeldroid.app.posts.PostActivity
import org.pixeldroid.app.posts.feeds.uncachedFeeds.FeedViewModel
import org.pixeldroid.app.posts.feeds.uncachedFeeds.UncachedFeedFragment
import org.pixeldroid.app.posts.feeds.uncachedFeeds.ViewModelFactory
import org.pixeldroid.app.posts.parseHTMLText
import org.pixeldroid.app.utils.api.objects.Status
import org.pixeldroid.app.utils.setProfileImageFromURL
/**
* Fragment to show a list of [Status]s, in form of comments
*/
class CommentFragment : UncachedFeedFragment<Status>() {
private lateinit var id: String
private lateinit var domain: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
id = arguments?.getSerializable(COMMENT_STATUS_ID) as String
domain = arguments?.getSerializable(COMMENT_DOMAIN) as String
adapter = CommentAdapter()
}
@OptIn(ExperimentalPagingApi::class)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = super.onCreateView(inflater, container, savedInstanceState)
// get the view model
@Suppress("UNCHECKED_CAST")
viewModel = ViewModelProvider(
requireActivity(), ViewModelFactory(
CommentContentRepository(
apiHolder.setToCurrentUser(),
id
)
)
)["commentFragment", FeedViewModel::class.java] as FeedViewModel<Status>
launch()
initSearch()
return view
}
companion object {
const val COMMENT_STATUS_ID = "PostActivityCommentsId"
const val COMMENT_DOMAIN = "PostActivityCommentsDomain"
}
private val UIMODEL_COMPARATOR = object : DiffUtil.ItemCallback<Status>() {
override fun areItemsTheSame(oldItem: Status, newItem: Status): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Status, newItem: Status): Boolean =
oldItem.content == newItem.content
}
inner class CommentAdapter : PagingDataAdapter<Status, RecyclerView.ViewHolder>(
UIMODEL_COMPARATOR
) {
fun create(parent: ViewGroup): CommentViewHolder {
val itemBinding = CommentBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return CommentViewHolder(itemBinding)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return create(parent)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val post = getItem(position)
post?.let {
(holder as CommentViewHolder).bind(it)
}
}
}
inner class CommentViewHolder(val binding: CommentBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(comment: Status) {
setProfileImageFromURL(
binding.profilePic,
comment.account!!.anyAvatar(),
binding.profilePic
)
binding.user.text = comment.account.username
binding.commentText.text = parseHTMLText(
comment.content!!,
comment.mentions.orEmpty(),
apiHolder,
itemView.context,
lifecycleScope
)
binding.postDomain.text =
comment.getStatusDomain(domain, binding.postDomain.context)
if (comment.replies_count == 0 || comment.replies_count == null) {
binding.replies.visibility = View.GONE
} else {
binding.replies.visibility = View.VISIBLE
binding.replies.text = itemView.context.resources.getQuantityString(
R.plurals.replies_count,
comment.replies_count,
comment.replies_count
)
}
binding.comment.setOnClickListener { openComment(comment) }
binding.profilePic.setOnClickListener { comment.account.openProfile(itemView.context) }
binding.user.setOnClickListener { comment.account.openProfile(itemView.context) }
}
private fun openComment(comment: Status) {
val intent = Intent(itemView.context, PostActivity::class.java).apply {
putExtra(Status.POST_TAG, comment)
}
itemView.context.startActivity(intent)
}
}
}

View File

@ -69,43 +69,11 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/motionLayout"
<androidx.fragment.app.FragmentContainerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:visibility="visible"
app:layoutDescription="@xml/error_layout_xml_error_scene"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/commentFragment"
/>
<include
android:id="@+id/errorLayout"
layout="@layout/error_layout"
tools:layout_editor_absoluteX="50dp" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/postRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@id/errorLayout">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/commentRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/comment" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
<ProgressBar
android:id="@+id/postCommentsProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
app:layout_anchor="@id/motionLayout" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -47,8 +47,9 @@
android:id="@+id/list"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/errorLayout"
app:layout_constraintBottom_toBottomOf="parent"
app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/post_fragment"/>