Merge branch 'commentImprovements' into 'master'
Comment improvements See merge request pixeldroid/PixelDroid!460
This commit is contained in:
commit
5cc5d0d9d7
|
@ -45,6 +45,10 @@ android {
|
||||||
testBuildType "staging"
|
testBuildType "staging"
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix '.debug'
|
||||||
|
versionNameSuffix "-debug"
|
||||||
|
}
|
||||||
staging {
|
staging {
|
||||||
initWith debug
|
initWith debug
|
||||||
testCoverageEnabled true
|
testCoverageEnabled true
|
||||||
|
@ -67,10 +71,6 @@ android {
|
||||||
buildConfigField "String", "CLIENT_ID", System.getenv("CLIENT_ID") ?: localProperties['CLIENT_ID'] ?: '""'
|
buildConfigField "String", "CLIENT_ID", System.getenv("CLIENT_ID") ?: localProperties['CLIENT_ID'] ?: '""'
|
||||||
buildConfigField "String", "CLIENT_SECRET", System.getenv("CLIENT_SECRET") ?: localProperties['CLIENT_SECRET'] ?: '""'
|
buildConfigField "String", "CLIENT_SECRET", System.getenv("CLIENT_SECRET") ?: localProperties['CLIENT_SECRET'] ?: '""'
|
||||||
}
|
}
|
||||||
debug {
|
|
||||||
applicationIdSuffix '.debug'
|
|
||||||
versionNameSuffix "-debug"
|
|
||||||
}
|
|
||||||
release {
|
release {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
|
|
|
@ -136,7 +136,7 @@ class LoginActivity : BaseThemedWithoutBarActivity() {
|
||||||
val credentialsDeferred: Deferred<Application?> = async {
|
val credentialsDeferred: Deferred<Application?> = async {
|
||||||
try {
|
try {
|
||||||
pixelfedAPI.registerApplication(
|
pixelfedAPI.registerApplication(
|
||||||
appName, "$oauthScheme://$PACKAGE_ID", SCOPE
|
appName, "$oauthScheme://$PACKAGE_ID", SCOPE, "https://pixeldroid.org"
|
||||||
)
|
)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
return@async null
|
return@async null
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
package org.pixeldroid.app.posts
|
package org.pixeldroid.app.posts
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
|
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import org.pixeldroid.app.R
|
import org.pixeldroid.app.R
|
||||||
import org.pixeldroid.app.databinding.ActivityPostBinding
|
import org.pixeldroid.app.databinding.ActivityPostBinding
|
||||||
import org.pixeldroid.app.databinding.CommentBinding
|
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.BaseThemedWithBarActivity
|
||||||
import org.pixeldroid.app.utils.api.PixelfedAPI
|
import org.pixeldroid.app.utils.api.PixelfedAPI
|
||||||
import org.pixeldroid.app.utils.api.objects.Mention
|
|
||||||
import org.pixeldroid.app.utils.api.objects.Status
|
import org.pixeldroid.app.utils.api.objects.Status
|
||||||
import org.pixeldroid.app.utils.api.objects.Status.Companion.POST_COMMENT_TAG
|
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.POST_TAG
|
||||||
|
@ -24,10 +22,10 @@ import retrofit2.HttpException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
class PostActivity : BaseThemedWithBarActivity() {
|
class PostActivity : BaseThemedWithBarActivity() {
|
||||||
lateinit var domain : String
|
|
||||||
|
|
||||||
private lateinit var binding: ActivityPostBinding
|
private lateinit var binding: ActivityPostBinding
|
||||||
|
|
||||||
|
private var commentFragment = CommentFragment()
|
||||||
|
|
||||||
private lateinit var status: Status
|
private lateinit var status: Status
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -43,9 +41,6 @@ class PostActivity : BaseThemedWithBarActivity() {
|
||||||
|
|
||||||
val user = db.userDao().getActiveUser()
|
val user = db.userDao().getActiveUser()
|
||||||
|
|
||||||
domain = user?.instance_uri.orEmpty()
|
|
||||||
|
|
||||||
|
|
||||||
supportActionBar?.title = getString(R.string.post_title).format(status.account?.getDisplayName())
|
supportActionBar?.title = getString(R.string.post_title).format(status.account?.getDisplayName())
|
||||||
|
|
||||||
val holder = StatusViewHolder(binding.postFragmentSingle)
|
val holder = StatusViewHolder(binding.postFragmentSingle)
|
||||||
|
@ -53,6 +48,7 @@ class PostActivity : BaseThemedWithBarActivity() {
|
||||||
holder.bind(status, apiHolder, db, lifecycleScope, displayDimensionsInPx(), isActivity = true)
|
holder.bind(status, apiHolder, db, lifecycleScope, displayDimensionsInPx(), isActivity = true)
|
||||||
|
|
||||||
activateCommenter()
|
activateCommenter()
|
||||||
|
initCommentsFragment(domain = user?.instance_uri.orEmpty())
|
||||||
|
|
||||||
if(viewComments || postComment){
|
if(viewComments || postComment){
|
||||||
//Scroll already down as much as possible (since comments are not loaded yet)
|
//Scroll already down as much as possible (since comments are not loaded yet)
|
||||||
|
@ -63,12 +59,6 @@ class PostActivity : BaseThemedWithBarActivity() {
|
||||||
window.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE)
|
window.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE)
|
||||||
binding.editComment.requestFocus()
|
binding.editComment.requestFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
// also retrieve comments if we're not posting the comment
|
|
||||||
if(!postComment) retrieveComments(apiHolder.api!!)
|
|
||||||
}
|
|
||||||
binding.postFragmentSingle.viewComments.setOnClickListener {
|
|
||||||
retrieveComments(apiHolder.api!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,53 +82,15 @@ class PostActivity : BaseThemedWithBarActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addComment(context: Context, commentContainer: LinearLayout,
|
private fun initCommentsFragment(domain: String) {
|
||||||
commentUsername: String, commentContent: String, mentions: List<Mention>) {
|
|
||||||
|
|
||||||
|
val arguments = Bundle()
|
||||||
|
arguments.putSerializable(COMMENT_STATUS_ID, status.id)
|
||||||
|
arguments.putSerializable(COMMENT_DOMAIN, domain)
|
||||||
|
commentFragment.arguments = arguments
|
||||||
|
|
||||||
val itemBinding = CommentBinding.inflate(
|
supportFragmentManager.beginTransaction()
|
||||||
LayoutInflater.from(context), commentContainer, true
|
.add(R.id.commentFragment, commentFragment).commit()
|
||||||
)
|
|
||||||
|
|
||||||
itemBinding.user.text = commentUsername
|
|
||||||
itemBinding.commentText.text = parseHTMLText(
|
|
||||||
commentContent,
|
|
||||||
mentions,
|
|
||||||
apiHolder,
|
|
||||||
context,
|
|
||||||
lifecycleScope
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun retrieveComments(api: PixelfedAPI) {
|
|
||||||
lifecycleScope.launchWhenCreated {
|
|
||||||
status.id.let {
|
|
||||||
try {
|
|
||||||
val statuses = api.statusComments(it).descendants
|
|
||||||
|
|
||||||
binding.commentContainer.removeAllViews()
|
|
||||||
|
|
||||||
//Create the new views for each comment
|
|
||||||
for (status in statuses) {
|
|
||||||
addComment(
|
|
||||||
binding.root.context,
|
|
||||||
binding.commentContainer,
|
|
||||||
status.account!!.username!!,
|
|
||||||
status.content!!,
|
|
||||||
status.mentions.orEmpty()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
binding.commentContainer.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
//Focus the comments
|
|
||||||
binding.scrollview.requestChildFocus(binding.commentContainer, binding.commentContainer)
|
|
||||||
} catch (exception: IOException) {
|
|
||||||
Log.e("COMMENT FETCH ERROR", exception.toString())
|
|
||||||
} catch (exception: HttpException) {
|
|
||||||
Log.e("COMMENT ERROR", "${exception.code()} with body ${exception.response()?.errorBody()}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun postComment(
|
private suspend fun postComment(
|
||||||
|
@ -151,11 +103,8 @@ class PostActivity : BaseThemedWithBarActivity() {
|
||||||
val response = api.postStatus(nonNullText, it)
|
val response = api.postStatus(nonNullText, it)
|
||||||
binding.commentIn.visibility = View.GONE
|
binding.commentIn.visibility = View.GONE
|
||||||
|
|
||||||
//Add the comment to the comment section
|
//Reload to add the comment to the comment section
|
||||||
addComment(
|
commentFragment.adapter.refresh()
|
||||||
binding.root.context, binding.commentContainer, response.account!!.username!!,
|
|
||||||
response.content!!, response.mentions.orEmpty()
|
|
||||||
)
|
|
||||||
|
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
binding.root.context,
|
binding.root.context,
|
||||||
|
@ -177,5 +126,4 @@ class PostActivity : BaseThemedWithBarActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,10 @@ internal fun <T: Any> initAdapter(
|
||||||
footer = ReposLoadStateAdapter { adapter.retry() }
|
footer = ReposLoadStateAdapter { adapter.retry() }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
swipeRefreshLayout.setOnRefreshListener {
|
||||||
|
adapter.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
adapter.addLoadStateListener { loadState ->
|
adapter.addLoadStateListener { loadState ->
|
||||||
|
|
||||||
if(!progressBar.isVisible && swipeRefreshLayout.isRefreshing) {
|
if(!progressBar.isVisible && swipeRefreshLayout.isRefreshing) {
|
||||||
|
|
|
@ -75,10 +75,6 @@ open class CachedFeedFragment<T: FeedContentDatabase> : BaseFragment() {
|
||||||
initAdapter(binding.progressBar, binding.swipeRefreshLayout,
|
initAdapter(binding.progressBar, binding.swipeRefreshLayout,
|
||||||
binding.list, binding.motionLayout, binding.errorLayout, adapter)
|
binding.list, binding.motionLayout, binding.errorLayout, adapter)
|
||||||
|
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
|
||||||
adapter.refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,6 @@ open class UncachedFeedFragment<T: FeedContent> : BaseFragment() {
|
||||||
initAdapter(binding.progressBar, binding.swipeRefreshLayout, binding.list,
|
initAdapter(binding.progressBar, binding.swipeRefreshLayout, binding.list,
|
||||||
binding.motionLayout, binding.errorLayout, adapter)
|
binding.motionLayout, binding.errorLayout, adapter)
|
||||||
|
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
|
||||||
adapter.refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.pixeldroid.app.posts.feeds.uncachedFeeds.comments
|
||||||
|
|
||||||
|
import androidx.paging.ExperimentalPagingApi
|
||||||
|
import androidx.paging.Pager
|
||||||
|
import androidx.paging.PagingConfig
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import org.pixeldroid.app.posts.feeds.uncachedFeeds.UncachedContentRepository
|
||||||
|
import org.pixeldroid.app.posts.feeds.uncachedFeeds.profile.ProfilePagingSource
|
||||||
|
import org.pixeldroid.app.utils.api.PixelfedAPI
|
||||||
|
import org.pixeldroid.app.utils.api.objects.Status
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class CommentContentRepository @ExperimentalPagingApi
|
||||||
|
@Inject constructor(
|
||||||
|
private val api: PixelfedAPI,
|
||||||
|
private val statusId: String
|
||||||
|
) : UncachedContentRepository<Status> {
|
||||||
|
override fun getStream(): Flow<PagingData<Status>> {
|
||||||
|
return Pager(
|
||||||
|
config = PagingConfig(
|
||||||
|
initialLoadSize = NETWORK_PAGE_SIZE,
|
||||||
|
pageSize = NETWORK_PAGE_SIZE),
|
||||||
|
pagingSourceFactory = {
|
||||||
|
CommentPagingSource(api, statusId)
|
||||||
|
}
|
||||||
|
).flow
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val NETWORK_PAGE_SIZE = 20
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.pixeldroid.app.posts.feeds.uncachedFeeds.comments
|
||||||
|
|
||||||
|
import androidx.paging.PagingSource
|
||||||
|
import androidx.paging.PagingState
|
||||||
|
import org.pixeldroid.app.utils.api.PixelfedAPI
|
||||||
|
import org.pixeldroid.app.utils.api.objects.Status
|
||||||
|
import retrofit2.HttpException
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class CommentPagingSource(
|
||||||
|
private val api: PixelfedAPI,
|
||||||
|
private val statusId: String
|
||||||
|
) : PagingSource<String, Status>() {
|
||||||
|
override suspend fun load(params: LoadParams<String>): LoadResult<String, Status> {
|
||||||
|
//val position = params.key
|
||||||
|
return try {
|
||||||
|
val comments = api.statusComments(statusId).descendants
|
||||||
|
|
||||||
|
// TODO use pagination to have many comments also work
|
||||||
|
// For now, don't paginate (nextKey and prevKey null)
|
||||||
|
LoadResult.Page(
|
||||||
|
data = comments,
|
||||||
|
prevKey = null,
|
||||||
|
nextKey = null
|
||||||
|
)
|
||||||
|
} catch (exception: HttpException) {
|
||||||
|
LoadResult.Error(exception)
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
LoadResult.Error(exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRefreshKey(state: PagingState<String, Status>): String? = null
|
||||||
|
}
|
|
@ -1,59 +1,79 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
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/scrollview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".posts.PostActivity"
|
tools:context=".posts.PostActivity">
|
||||||
android:id="@+id/scrollview">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/app_bar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
|
android:id="@+id/collapsing_toolbar_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_scrollFlags="scroll|exitUntilCollapsed">
|
||||||
|
|
||||||
<include layout="@layout/post_fragment"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/postFragmentSingle"/>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<LinearLayout
|
<include
|
||||||
|
android:id="@+id/postFragmentSingle"
|
||||||
|
layout="@layout/post_fragment" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/commentIn"
|
android:id="@+id/commentIn"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/postFragmentSingle"
|
app:layout_constraintTop_toBottomOf="@+id/postFragmentSingle"
|
||||||
tools:layout_editor_absoluteX="10dp">
|
tools:layout_editor_absoluteX="10dp">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/textInputLayout2"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/submitComment"
|
||||||
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/editComment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="3">
|
android:hint="@string/comment"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="text" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<EditText
|
<Button
|
||||||
android:id="@+id/editComment"
|
android:id="@+id/submitComment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/comment"
|
android:layout_margin="8dp"
|
||||||
android:inputType="text"
|
android:contentDescription="@string/submit_comment"
|
||||||
android:importantForAutofill="no" />
|
android:text="@string/comment"
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
app:layout_constraintBottom_toBottomOf="@+id/textInputLayout2"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/textInputLayout2"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/textInputLayout2" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<ImageButton
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
android:id="@+id/submitComment"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:contentDescription="@string/submit_comment"
|
|
||||||
android:src="@drawable/ic_send_blue" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
android:id="@+id/commentContainer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/commentIn">
|
|
||||||
|
|
||||||
</LinearLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
android:id="@+id/commentFragment"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -1,39 +1,70 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
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/comment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="20dp">
|
android:layout_margin="4dp">
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/comment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profilePic"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:contentDescription="@string/profile_picture"
|
||||||
|
tools:src="@drawable/ic_default_user"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/user"
|
android:id="@+id/user"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="8"
|
android:layout_marginStart="10dp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/profilePic"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="username" />
|
tools:text="username" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/commentText"
|
android:id="@+id/postDomain"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="2"
|
android:layout_marginStart="8dp"
|
||||||
tools:text="This is a comment on this awesome post" />
|
android:textColor="@color/domainGray"
|
||||||
</LinearLayout>
|
app:layout_constraintBottom_toBottomOf="@+id/user"
|
||||||
</androidx.cardview.widget.CardView>
|
app:layout_constraintStart_toEndOf="@+id/user"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/user"
|
||||||
|
tools:text="from domain.tld" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
<TextView
|
||||||
|
android:id="@+id/commentText"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="1.0"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/user"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/user"
|
||||||
|
tools:text="This is a comment on this awesome post. Very long comment! \nMaybe with multiple lines" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/replies"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textStyle="italic"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/commentText"
|
||||||
|
app:layout_constraintHorizontal_bias="0.8"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/commentText"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/commentText"
|
||||||
|
tools:text="3 replies" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
|
@ -47,8 +47,9 @@
|
||||||
android:id="@+id/list"
|
android:id="@+id/list"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/errorLayout"
|
app:layout_constraintTop_toBottomOf="@id/errorLayout"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layoutManager="LinearLayoutManager"
|
app:layoutManager="LinearLayoutManager"
|
||||||
tools:listitem="@layout/post_fragment"/>
|
tools:listitem="@layout/post_fragment"/>
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
<color name="white">#FFFFFF</color>
|
<color name="white">#FFFFFF</color>
|
||||||
|
|
||||||
|
<color name="domainGray">#b3b3b3</color>
|
||||||
|
|
||||||
<!-- > Following are theme color values </-->
|
<!-- > Following are theme color values </-->
|
||||||
<color name="seed">#f4a261</color>
|
<color name="seed">#f4a261</color>
|
||||||
<color name="md_theme_light_primary">#924C00</color>
|
<color name="md_theme_light_primary">#924C00</color>
|
||||||
|
|
|
@ -291,4 +291,8 @@ For more info about Pixelfed, you can check here: https://pixelfed.org"</string>
|
||||||
<string name="add_images_error">Error while adding images</string>
|
<string name="add_images_error">Error while adding images</string>
|
||||||
<string name="notification_thumbnail">"Thumbnail of image in this notification's post"</string>
|
<string name="notification_thumbnail">"Thumbnail of image in this notification's post"</string>
|
||||||
<string name="post_preview">Preview of a post</string>
|
<string name="post_preview">Preview of a post</string>
|
||||||
|
<plurals name="replies_count">
|
||||||
|
<item quantity="one">%d reply</item>
|
||||||
|
<item quantity="other">%d replies</item>
|
||||||
|
</plurals>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue