커뮤니티 전체보기 페이지 추가
This commit is contained in:
parent
116dde1b7e
commit
62ecf3dd51
|
@ -95,8 +95,8 @@
|
|||
<activity android:name=".explorer.profile.UserProfileActivity" />
|
||||
<activity android:name=".explorer.profile.donation.UserProfileDonationAllViewActivity" />
|
||||
<activity android:name=".explorer.profile.fantalk.UserProfileFantalkAllViewActivity" />
|
||||
<activity android:name=".explorer.profile.CreatorNoticeWriteActivity" />
|
||||
<activity android:name=".explorer.profile.follow.UserFollowerListActivity" />
|
||||
<activity android:name=".explorer.profile.creator_community.all.CreatorCommunityAllActivity" />
|
||||
<activity android:name=".message.text.TextMessageWriteActivity" />
|
||||
<activity android:name=".message.text.TextMessageDetailActivity" />
|
||||
<activity android:name=".message.SelectMessageRecipientActivity" />
|
||||
|
|
|
@ -57,4 +57,8 @@ object Constants {
|
|||
const val LIVE_SERVICE_NOTIFICATION_ID: Int = 2
|
||||
const val ACTION_AUDIO_CONTENT_RECEIVER = "soda_live_action_content_receiver"
|
||||
const val ACTION_MAIN_AUDIO_CONTENT_RECEIVER = "soda_live_action_main_content_receiver"
|
||||
|
||||
const val EXTRA_COMMUNITY_POST_ID = "community_post_id"
|
||||
const val EXTRA_COMMUNITY_CREATOR_ID = "community_creator_id"
|
||||
const val EXTRA_COMMUNITY_POST_COMMENT = "community_post_comment_id"
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import kr.co.vividnext.sodalive.explorer.ExplorerViewModel
|
|||
import kr.co.vividnext.sodalive.explorer.profile.UserProfileViewModel
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityApi
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllViewModel
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreatorCommunityCommentListViewModel
|
||||
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewModel
|
||||
import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewModel
|
||||
import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListViewModel
|
||||
|
@ -215,6 +217,8 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||
viewModel { AudioContentNewAllViewModel(get()) }
|
||||
viewModel { AudioContentRankingAllViewModel(get()) }
|
||||
viewModel { RouletteSettingsViewModel(get()) }
|
||||
viewModel { CreatorCommunityAllViewModel(get()) }
|
||||
viewModel { CreatorCommunityCommentListViewModel(get()) }
|
||||
}
|
||||
|
||||
private val repositoryModule = module {
|
||||
|
|
|
@ -36,6 +36,7 @@ import kr.co.vividnext.sodalive.databinding.ActivityUserProfileBinding
|
|||
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityBinding
|
||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.UserProfileCheersAdapter
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAdapter
|
||||
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewActivity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewActivity
|
||||
|
@ -474,7 +475,13 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
|||
|
||||
private fun setupCreatorCommunityView() {
|
||||
binding.layoutCreatorCommunityPost.ivWrite.setOnClickListener { }
|
||||
binding.layoutCreatorCommunityPost.llAll.setOnClickListener { }
|
||||
binding.layoutCreatorCommunityPost.llAll.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(applicationContext, CreatorCommunityAllActivity::class.java).apply {
|
||||
putExtra(Constants.EXTRA_USER_ID, userId)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindData() {
|
||||
|
@ -734,7 +741,13 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
|||
layout.tvLikeCount.text = "${item.likeCount}"
|
||||
layout.tvCommentCount.text = "${item.commentCount}"
|
||||
|
||||
layout.root.setOnClickListener { }
|
||||
layout.root.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(applicationContext, CreatorCommunityAllActivity::class.java).apply {
|
||||
putExtra(Constants.EXTRA_USER_ID, userId)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (index > 0) {
|
||||
val lp = layout.root.layoutParams as LinearLayout.LayoutParams
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
||||
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.PostCommunityPostLikeRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreateCommunityPostCommentRequest
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.PUT
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface CreatorCommunityApi {
|
||||
|
@ -21,4 +28,40 @@ interface CreatorCommunityApi {
|
|||
@Query("timezone") timezone: String,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<List<GetCommunityPostListResponse>>>
|
||||
|
||||
@POST("/creator-community/like")
|
||||
fun communityPostLike(
|
||||
@Body request: PostCommunityPostLikeRequest,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<Any>>
|
||||
|
||||
@GET("/creator-community/{id}/comment")
|
||||
fun getCommunityPostCommentList(
|
||||
@Path("id") postId: Long,
|
||||
@Query("page") page: Int,
|
||||
@Query("size") size: Int,
|
||||
@Query("timezone") timezone: String,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<GetCommunityPostCommentListResponse>>
|
||||
|
||||
@POST("/creator-community/comment")
|
||||
fun createCommunityPostComment(
|
||||
@Body request: CreateCommunityPostCommentRequest,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<Any>>
|
||||
|
||||
@PUT("/creator-community/comment")
|
||||
fun modifyComment(
|
||||
@Body request: ModifyCommentRequest,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<Any>>
|
||||
|
||||
@GET("/creator-community/comment/{id}")
|
||||
fun getCommentReplyList(
|
||||
@Path("id") commentId: Long,
|
||||
@Query("page") page: Int,
|
||||
@Query("size") size: Int,
|
||||
@Query("timezone") timezone: String,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<GetCommunityPostCommentListResponse>>
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
||||
|
||||
import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.PostCommunityPostLikeRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreateCommunityPostCommentRequest
|
||||
import java.util.TimeZone
|
||||
|
||||
class CreatorCommunityRepository(private val api: CreatorCommunityApi) {
|
||||
|
@ -22,4 +25,49 @@ class CreatorCommunityRepository(private val api: CreatorCommunityApi) {
|
|||
timezone = TimeZone.getDefault().id,
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun communityPostLike(postId: Long, token: String) = api.communityPostLike(
|
||||
request = PostCommunityPostLikeRequest(postId = postId),
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun getCommunityPostCommentList(
|
||||
postId: Long,
|
||||
page: Int,
|
||||
size: Int,
|
||||
token: String
|
||||
) = api.getCommunityPostCommentList(
|
||||
postId = postId,
|
||||
page = page,
|
||||
size = size,
|
||||
timezone = TimeZone.getDefault().id,
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun registerComment(
|
||||
postId: Long,
|
||||
comment: String,
|
||||
parentId: Long? = null,
|
||||
token: String
|
||||
) = api.createCommunityPostComment(
|
||||
request = CreateCommunityPostCommentRequest(
|
||||
comment = comment,
|
||||
postId = postId,
|
||||
parentId = parentId
|
||||
),
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun modifyComment(request: ModifyCommentRequest, token: String) = api.modifyComment(
|
||||
request = request,
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun getCommentReplyList(commentId: Long, page: Int, size: Int, token: String) = api.getCommentReplyList(
|
||||
commentId = commentId,
|
||||
page = page,
|
||||
size = size,
|
||||
timezone = TimeZone.getDefault().id,
|
||||
authHeader = token
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
data class GetCommunityPostCommentListResponse(
|
||||
@SerializedName("totalCount") val totalCount: Int,
|
||||
@SerializedName("items") val items: List<GetCommunityPostCommentListItem>
|
||||
)
|
||||
|
||||
@Parcelize
|
||||
data class GetCommunityPostCommentListItem(
|
||||
@SerializedName("id") val id: Long,
|
||||
@SerializedName("writerId") val writerId: Long,
|
||||
|
@ -15,4 +18,4 @@ data class GetCommunityPostCommentListItem(
|
|||
@SerializedName("comment") val comment: String,
|
||||
@SerializedName("date") val date: String,
|
||||
@SerializedName("replyCount") val replyCount: Int,
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
|
@ -12,7 +12,7 @@ data class GetCommunityPostListResponse(
|
|||
@SerializedName("date") val date: String,
|
||||
@SerializedName("isCommentAvailable") val isCommentAvailable: Boolean,
|
||||
@SerializedName("isAdult") val isAdult: Boolean,
|
||||
@SerializedName("isLike") val isLike: Boolean,
|
||||
@SerializedName("isLike") var isLike: Boolean,
|
||||
@SerializedName("likeCount") val likeCount: Int,
|
||||
@SerializedName("commentCount") val commentCount: Int,
|
||||
@SerializedName("firstComment") val firstComment: GetCommunityPostCommentListItem?
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||
import kr.co.vividnext.sodalive.common.Constants
|
||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||
import kr.co.vividnext.sodalive.databinding.ActivityCreatorCommunityAllBinding
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreatorCommunityCommentFragment
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class CreatorCommunityAllActivity : BaseActivity<ActivityCreatorCommunityAllBinding>(
|
||||
ActivityCreatorCommunityAllBinding::inflate
|
||||
) {
|
||||
|
||||
private val viewModel: CreatorCommunityAllViewModel by inject()
|
||||
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
private lateinit var adapter: CreatorCommunityAllAdapter
|
||||
|
||||
private var creatorId: Long = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
creatorId = intent.getLongExtra(Constants.EXTRA_USER_ID, 0)
|
||||
if (creatorId <= 0) {
|
||||
Toast.makeText(applicationContext, "잘못된 요청입니다.", Toast.LENGTH_LONG).show()
|
||||
finish()
|
||||
}
|
||||
|
||||
bindData()
|
||||
viewModel.creatorId = creatorId
|
||||
viewModel.getCommunityPostList()
|
||||
}
|
||||
|
||||
override fun setupView() {
|
||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||
binding.toolbar.tvBack.text = "커뮤니티"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
adapter = CreatorCommunityAllAdapter(
|
||||
onClickLike = { viewModel.communityPostLike(it) },
|
||||
writeComment = { postId, parentId, comment ->
|
||||
viewModel.registerComment(
|
||||
comment,
|
||||
postId,
|
||||
parentId
|
||||
)
|
||||
},
|
||||
showCommentBottomSheetDialog = {
|
||||
val dialog = CreatorCommunityCommentFragment(
|
||||
creatorId = creatorId,
|
||||
postId = it
|
||||
)
|
||||
dialog.show(
|
||||
supportFragmentManager,
|
||||
dialog.tag
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
val recyclerView = binding.rvCreatorCommunity
|
||||
recyclerView.layoutManager = LinearLayoutManager(
|
||||
applicationContext,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false
|
||||
)
|
||||
|
||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
|
||||
outRect.left = 6.7f.dpToPx().toInt()
|
||||
outRect.right = 6.7f.dpToPx().toInt()
|
||||
|
||||
when (parent.getChildAdapterPosition(view)) {
|
||||
0 -> {
|
||||
outRect.top = 13.3f.dpToPx().toInt()
|
||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
adapter.itemCount - 1 -> {
|
||||
outRect.top = 6.7f.dpToPx().toInt()
|
||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.top = 6.7f.dpToPx().toInt()
|
||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
recyclerView.adapter = adapter
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun bindData() {
|
||||
viewModel.toastLiveData.observe(this) {
|
||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
viewModel.isLoading.observe(this) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth, "")
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.communityPostListLiveData.observe(this) {
|
||||
if (viewModel.page == 2) {
|
||||
adapter.items.clear()
|
||||
}
|
||||
|
||||
adapter.items.addAll(it)
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import coil.transform.CircleCropTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityAllBinding
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
||||
|
||||
class CreatorCommunityAllAdapter(
|
||||
private val onClickLike: (Long) -> Unit,
|
||||
private val writeComment: (Long, Long?, String) -> Unit,
|
||||
private val showCommentBottomSheetDialog: (Long) -> Unit
|
||||
) : RecyclerView.Adapter<CreatorCommunityAllAdapter.ViewHolder>() {
|
||||
|
||||
val items = mutableListOf<GetCommunityPostListResponse>()
|
||||
|
||||
inner class ViewHolder(
|
||||
private val binding: ItemCreatorCommunityAllBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun bind(item: GetCommunityPostListResponse, index: Int) {
|
||||
binding.tvNickname.text = item.creatorNickname
|
||||
binding.ivCreatorProfile.loadUrl(item.creatorProfileUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
|
||||
binding.tvContent.text = item.content
|
||||
|
||||
binding.ivLike.setImageResource(
|
||||
if (item.isLike) {
|
||||
R.drawable.ic_audio_content_heart_pressed
|
||||
} else {
|
||||
R.drawable.ic_audio_content_heart_normal
|
||||
}
|
||||
)
|
||||
|
||||
binding.tvLike.text = "${item.likeCount}"
|
||||
binding.llLike.setOnClickListener {
|
||||
val isLike = !item.isLike
|
||||
|
||||
items[index] = items[index].copy(
|
||||
isLike = !item.isLike,
|
||||
likeCount = if (isLike) item.likeCount + 1 else item.likeCount - 1
|
||||
)
|
||||
notifyDataSetChanged()
|
||||
|
||||
onClickLike(item.postId)
|
||||
}
|
||||
|
||||
if (item.imageUrl != null) {
|
||||
binding.ivContent.visibility = View.VISIBLE
|
||||
binding.ivContent.loadUrl(item.imageUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
}
|
||||
} else {
|
||||
binding.ivContent.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (item.isCommentAvailable) {
|
||||
binding.llComment.visibility = View.VISIBLE
|
||||
binding.tvCommentCount.text = "${item.commentCount}"
|
||||
} else {
|
||||
binding.llComment.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (item.commentCount > 0) {
|
||||
binding.ivCommentProfile.load(item.firstComment!!.profileUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
binding.tvCommentText.text = item.firstComment.comment
|
||||
binding.tvCommentText.visibility = View.VISIBLE
|
||||
binding.rlInputComment.visibility = View.GONE
|
||||
|
||||
binding.llComment.setOnClickListener { showCommentBottomSheetDialog(item.postId) }
|
||||
} else {
|
||||
binding.tvCommentText.visibility = View.GONE
|
||||
binding.rlInputComment.visibility = View.VISIBLE
|
||||
binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
|
||||
binding.ivCommentSend.setOnClickListener {
|
||||
val comment = binding.etComment.text.toString()
|
||||
binding.etComment.setText("")
|
||||
writeComment(item.postId, null, comment)
|
||||
}
|
||||
|
||||
binding.llComment.setOnClickListener {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||
ItemCreatorCommunityAllBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(items[position], position)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.orhanobut.logger.Logger
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
||||
|
||||
class CreatorCommunityAllViewModel(
|
||||
private val repository: CreatorCommunityRepository
|
||||
) : BaseViewModel() {
|
||||
private val _toastLiveData = MutableLiveData<String?>()
|
||||
val toastLiveData: LiveData<String?>
|
||||
get() = _toastLiveData
|
||||
|
||||
private var _isLoading = MutableLiveData(false)
|
||||
val isLoading: LiveData<Boolean>
|
||||
get() = _isLoading
|
||||
|
||||
private var _communityPostListLiveData = MutableLiveData<List<GetCommunityPostListResponse>>()
|
||||
val communityPostListLiveData: LiveData<List<GetCommunityPostListResponse>>
|
||||
get() = _communityPostListLiveData
|
||||
|
||||
var page = 1
|
||||
var isLast = false
|
||||
private val pageSize = 10
|
||||
|
||||
var creatorId = 0L
|
||||
|
||||
fun getCommunityPostList() {
|
||||
if (!_isLoading.value!! && !isLast) {
|
||||
_isLoading.value = true
|
||||
compositeDisposable.add(
|
||||
repository
|
||||
.getCommunityPostList(
|
||||
creatorId = creatorId,
|
||||
page = page,
|
||||
size = pageSize,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
if (it.data.isNotEmpty()) {
|
||||
page += 1
|
||||
_communityPostListLiveData.postValue(it.data!!)
|
||||
} else {
|
||||
isLast = true
|
||||
}
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_isLoading.value = false
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun communityPostLike(postId: Long) {
|
||||
compositeDisposable.add(
|
||||
repository.communityPostLike(
|
||||
postId = postId,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({}, {})
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
fun registerComment(comment: String, postId: Long, parentId: Long? = null) {
|
||||
if (!_isLoading.value!!) {
|
||||
_isLoading.value = true
|
||||
}
|
||||
|
||||
compositeDisposable.add(
|
||||
repository.registerComment(
|
||||
postId = postId,
|
||||
comment = comment,
|
||||
parentId = parentId,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
_isLoading.value = false
|
||||
|
||||
if (it.success) {
|
||||
page = 1
|
||||
isLast = false
|
||||
getCommunityPostList()
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class PostCommunityPostLikeRequest(
|
||||
@SerializedName("postId") val postId: Long
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class CreateCommunityPostCommentRequest(
|
||||
@SerializedName("comment") val comment: String,
|
||||
@SerializedName("postId") val postId: Long,
|
||||
@SerializedName("parentId") val parentId: Long?
|
||||
)
|
|
@ -0,0 +1,128 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import coil.transform.CircleCropTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.ItemCommunityPostCommentBinding
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
||||
|
||||
class CreatorCommunityCommentAdapter(
|
||||
private val creatorId: Long,
|
||||
private val modifyComment: (Long, String) -> Unit,
|
||||
private val onClickDelete: (Long) -> Unit,
|
||||
private val onItemClick: (GetCommunityPostCommentListItem) -> Unit
|
||||
) : RecyclerView.Adapter<CreatorCommunityCommentAdapter.ViewHolder>() {
|
||||
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
||||
|
||||
inner class ViewHolder(
|
||||
private val context: Context,
|
||||
private val binding: ItemCommunityPostCommentBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(item: GetCommunityPostCommentListItem) {
|
||||
binding.ivCommentProfile.load(item.profileUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
|
||||
binding.tvComment.text = item.comment
|
||||
binding.tvCommentDate.text = item.date
|
||||
binding.tvCommentNickname.text = item.nickname
|
||||
|
||||
binding.tvWriteReply.text = if (item.replyCount > 0) {
|
||||
"답글 ${item.replyCount}개"
|
||||
} else {
|
||||
"답글 쓰기"
|
||||
}
|
||||
|
||||
if (
|
||||
item.writerId == SharedPreferenceManager.userId ||
|
||||
creatorId == SharedPreferenceManager.userId
|
||||
) {
|
||||
binding.etCommentModify.setText(item.comment)
|
||||
binding.ivMenu.visibility = View.VISIBLE
|
||||
binding.ivMenu.setOnClickListener {
|
||||
showOptionMenu(
|
||||
context,
|
||||
binding.ivMenu,
|
||||
commentId = item.id,
|
||||
writerId = item.writerId,
|
||||
creatorId = creatorId,
|
||||
onClickModify = {
|
||||
binding.rlCommentModify.visibility = View.VISIBLE
|
||||
binding.tvComment.visibility = View.GONE
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
binding.tvModify.setOnClickListener {
|
||||
binding.rlCommentModify.visibility = View.GONE
|
||||
binding.tvComment.visibility = View.VISIBLE
|
||||
modifyComment(item.id, binding.etCommentModify.text.toString())
|
||||
}
|
||||
} else {
|
||||
binding.ivMenu.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.tvWriteReply.setOnClickListener { onItemClick(item) }
|
||||
binding.root.setOnClickListener { onItemClick(item) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||
parent.context,
|
||||
ItemCommunityPostCommentBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(items.toList()[position])
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
private fun showOptionMenu(
|
||||
context: Context,
|
||||
v: View,
|
||||
commentId: Long,
|
||||
writerId: Long,
|
||||
creatorId: Long,
|
||||
onClickModify: () -> Unit
|
||||
) {
|
||||
val popup = PopupMenu(context, v)
|
||||
val inflater = popup.menuInflater
|
||||
|
||||
if (writerId == SharedPreferenceManager.userId) {
|
||||
inflater.inflate(R.menu.content_comment_option_menu, popup.menu)
|
||||
} else if (creatorId == SharedPreferenceManager.userId) {
|
||||
inflater.inflate(R.menu.content_comment_option_menu2, popup.menu)
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_review_modify -> {
|
||||
onClickModify()
|
||||
}
|
||||
|
||||
R.id.menu_review_delete -> {
|
||||
onClickDelete(commentId)
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
popup.show()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.databinding.DialogAudioContentCommentBinding
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
||||
|
||||
class CreatorCommunityCommentFragment(
|
||||
private val creatorId: Long,
|
||||
private val postId: Long
|
||||
) : BottomSheetDialogFragment() {
|
||||
|
||||
private lateinit var binding: DialogAudioContentCommentBinding
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val dialog = super.onCreateDialog(savedInstanceState)
|
||||
|
||||
dialog.setOnShowListener {
|
||||
val d = it as BottomSheetDialog
|
||||
val bottomSheet = d.findViewById<FrameLayout>(
|
||||
com.google.android.material.R.id.design_bottom_sheet
|
||||
)
|
||||
if (bottomSheet != null) {
|
||||
BottomSheetBehavior.from(bottomSheet).state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = DialogAudioContentCommentBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val commentListFragmentTag = "COMMENT_LIST_FRAGMENT"
|
||||
val commentListFragment = CreatorCommunityCommentListFragment.newInstance(
|
||||
creatorId = creatorId,
|
||||
postId = postId
|
||||
)
|
||||
val fragmentTransaction = childFragmentManager.beginTransaction()
|
||||
fragmentTransaction.add(R.id.fl_container, commentListFragment, commentListFragmentTag)
|
||||
fragmentTransaction.addToBackStack(commentListFragmentTag)
|
||||
fragmentTransaction.commit()
|
||||
}
|
||||
|
||||
fun hideCommentDialog() {
|
||||
dialog?.dismiss()
|
||||
}
|
||||
|
||||
fun onClickComment(comment: GetCommunityPostCommentListItem) {
|
||||
val commentReplyFragmentTag = "COMMENT_REPLY_FRAGMENT"
|
||||
val commentReplyFragment = CreatorCommunityCommentReplyFragment.newInstance(
|
||||
creatorId = creatorId,
|
||||
postId = postId,
|
||||
comment = comment
|
||||
)
|
||||
val fragmentTransaction = childFragmentManager.beginTransaction()
|
||||
fragmentTransaction.add(R.id.fl_container, commentReplyFragment, commentReplyFragmentTag)
|
||||
fragmentTransaction.addToBackStack(commentReplyFragmentTag)
|
||||
fragmentTransaction.commit()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Service
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import coil.transform.CircleCropTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.audio_content.comment.AudioContentCommentFragment
|
||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||
import kr.co.vividnext.sodalive.base.SodaDialog
|
||||
import kr.co.vividnext.sodalive.common.Constants
|
||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentListBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class CreatorCommunityCommentListFragment : BaseFragment<FragmentAudioContentCommentListBinding>(
|
||||
FragmentAudioContentCommentListBinding::inflate
|
||||
) {
|
||||
private val viewModel: CreatorCommunityCommentListViewModel by inject()
|
||||
|
||||
private lateinit var imm: InputMethodManager
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
private lateinit var adapter: CreatorCommunityCommentAdapter
|
||||
|
||||
private var creatorId: Long = 0
|
||||
private var postId: Long = 0
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
creatorId = arguments?.getLong(Constants.EXTRA_COMMUNITY_CREATOR_ID) ?: 0
|
||||
postId = arguments?.getLong(Constants.EXTRA_COMMUNITY_POST_ID) ?: 0
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
||||
imm = requireContext().getSystemService(
|
||||
Service.INPUT_METHOD_SERVICE
|
||||
) as InputMethodManager
|
||||
|
||||
setupView()
|
||||
bindData()
|
||||
viewModel.getCommentList(postId) { hideDialog() }
|
||||
}
|
||||
|
||||
private fun hideDialog() {
|
||||
(parentFragment as CreatorCommunityCommentFragment).hideCommentDialog()
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
binding.ivClose.setOnClickListener { hideDialog() }
|
||||
|
||||
binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.ic_place_holder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
|
||||
binding.ivCommentSend.setOnClickListener {
|
||||
hideKeyboard()
|
||||
val comment = binding.etComment.text.toString()
|
||||
binding.etComment.setText("")
|
||||
viewModel.registerComment(postId, comment)
|
||||
}
|
||||
|
||||
adapter = CreatorCommunityCommentAdapter(
|
||||
creatorId = creatorId,
|
||||
modifyComment = { commentId, comment ->
|
||||
hideKeyboard()
|
||||
viewModel.modifyComment(
|
||||
commentId = commentId,
|
||||
postId = postId,
|
||||
comment = comment
|
||||
)
|
||||
},
|
||||
onClickDelete = {
|
||||
SodaDialog(
|
||||
activity = requireActivity(),
|
||||
layoutInflater = layoutInflater,
|
||||
title = "댓글 삭제",
|
||||
desc = "삭제하시겠습니까?",
|
||||
confirmButtonTitle = "삭제",
|
||||
confirmButtonClick = {
|
||||
viewModel.modifyComment(
|
||||
commentId = it,
|
||||
postId = postId,
|
||||
isActive = false
|
||||
)
|
||||
},
|
||||
cancelButtonTitle = "취소",
|
||||
cancelButtonClick = {}
|
||||
).show(screenWidth)
|
||||
},
|
||||
onItemClick = {
|
||||
(parentFragment as CreatorCommunityCommentFragment).onClickComment(it)
|
||||
}
|
||||
)
|
||||
|
||||
val recyclerView = binding.rvComment
|
||||
recyclerView.setHasFixedSize(true)
|
||||
recyclerView.layoutManager = LinearLayoutManager(
|
||||
activity,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false
|
||||
)
|
||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
|
||||
outRect.left = 13.3f.dpToPx().toInt()
|
||||
outRect.right = 13.3f.dpToPx().toInt()
|
||||
|
||||
when (parent.getChildAdapterPosition(view)) {
|
||||
0 -> {
|
||||
outRect.top = 13.3f.dpToPx().toInt()
|
||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
adapter.itemCount - 1 -> {
|
||||
outRect.top = 6.7f.dpToPx().toInt()
|
||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.top = 6.7f.dpToPx().toInt()
|
||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
|
||||
val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
|
||||
.findLastCompletelyVisibleItemPosition()
|
||||
val itemTotalCount = recyclerView.adapter!!.itemCount - 1
|
||||
|
||||
// 스크롤이 끝에 도달했는지 확인
|
||||
if (!recyclerView.canScrollVertically(1) &&
|
||||
lastVisibleItemPosition == itemTotalCount
|
||||
) {
|
||||
viewModel.getCommentList(postId = postId)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
recyclerView.adapter = adapter
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun bindData() {
|
||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth)
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
viewModel.totalCommentCount.observe(viewLifecycleOwner) {
|
||||
binding.tvCommentCount.text = "$it"
|
||||
}
|
||||
|
||||
viewModel.commentList.observe(viewLifecycleOwner) {
|
||||
if (viewModel.page - 1 == 1) {
|
||||
adapter.items.clear()
|
||||
binding.rvComment.scrollToPosition(0)
|
||||
}
|
||||
|
||||
adapter.items.addAll(it)
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideKeyboard() {
|
||||
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(creatorId: Long, postId: Long): CreatorCommunityCommentListFragment {
|
||||
val args = Bundle()
|
||||
args.putLong(Constants.EXTRA_COMMUNITY_CREATOR_ID, creatorId)
|
||||
args.putLong(Constants.EXTRA_COMMUNITY_POST_ID, postId)
|
||||
|
||||
val fragment = CreatorCommunityCommentListFragment()
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,248 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.orhanobut.logger.Logger
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest
|
||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
||||
|
||||
class CreatorCommunityCommentListViewModel(
|
||||
private val repository: CreatorCommunityRepository
|
||||
) : BaseViewModel() {
|
||||
private val _toastLiveData = MutableLiveData<String?>()
|
||||
val toastLiveData: LiveData<String?>
|
||||
get() = _toastLiveData
|
||||
|
||||
private var _isLoading = MutableLiveData(false)
|
||||
val isLoading: LiveData<Boolean>
|
||||
get() = _isLoading
|
||||
|
||||
private var _commentList = MutableLiveData<List<GetCommunityPostCommentListItem>>()
|
||||
val commentList: LiveData<List<GetCommunityPostCommentListItem>>
|
||||
get() = _commentList
|
||||
|
||||
private var _totalCommentCount = MutableLiveData(0)
|
||||
val totalCommentCount: LiveData<Int>
|
||||
get() = _totalCommentCount
|
||||
|
||||
var page = 1
|
||||
private var isLast = false
|
||||
private val size = 10
|
||||
|
||||
fun getCommentList(postId: Long, onFailure: (() -> Unit)? = null) {
|
||||
if (!_isLoading.value!! && !isLast) {
|
||||
_isLoading.value = true
|
||||
compositeDisposable.add(
|
||||
repository.getCommunityPostCommentList(
|
||||
postId = postId,
|
||||
page = page - 1,
|
||||
size = size,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
_totalCommentCount.postValue(it.data.totalCount)
|
||||
|
||||
page += 1
|
||||
if (it.data.items.isNotEmpty()) {
|
||||
_commentList.postValue(it.data.items)
|
||||
} else {
|
||||
isLast = true
|
||||
_commentList.postValue(listOf())
|
||||
}
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
|
||||
if (onFailure != null) {
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
|
||||
_isLoading.value = false
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
if (onFailure != null) {
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun registerComment(postId: Long, comment: String, commentId: Long? = null) {
|
||||
if (!_isLoading.value!!) {
|
||||
_isLoading.value = true
|
||||
}
|
||||
|
||||
compositeDisposable.add(
|
||||
repository.registerComment(
|
||||
postId = postId,
|
||||
comment = comment,
|
||||
parentId = commentId,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
_isLoading.value = false
|
||||
|
||||
if (it.success) {
|
||||
page = 1
|
||||
isLast = false
|
||||
if (commentId != null) {
|
||||
getCommentReplyList(commentId = commentId)
|
||||
} else {
|
||||
getCommentList(postId)
|
||||
}
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun modifyComment(
|
||||
commentId: Long,
|
||||
postId: Long,
|
||||
parentCommentId: Long? = null,
|
||||
comment: String? = null,
|
||||
isActive: Boolean? = null
|
||||
) {
|
||||
if (comment == null && isActive == null) {
|
||||
_toastLiveData.postValue("변경사항이 없습니다.")
|
||||
return
|
||||
}
|
||||
|
||||
if (comment != null && comment.isBlank()) {
|
||||
_toastLiveData.postValue("내용을 입력하세요")
|
||||
return
|
||||
}
|
||||
|
||||
_isLoading.value = true
|
||||
|
||||
val request = ModifyCommentRequest(commentId = commentId)
|
||||
|
||||
if (comment != null) {
|
||||
request.comment = comment
|
||||
}
|
||||
|
||||
if (isActive != null) {
|
||||
request.isActive = isActive
|
||||
}
|
||||
|
||||
compositeDisposable.add(
|
||||
repository.modifyComment(
|
||||
request = request,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
_isLoading.value = false
|
||||
|
||||
if (it.success) {
|
||||
page = 1
|
||||
isLast = false
|
||||
|
||||
if (parentCommentId != null) {
|
||||
getCommentReplyList(parentCommentId)
|
||||
} else {
|
||||
getCommentList(postId)
|
||||
}
|
||||
} else {
|
||||
val message = it.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
_toastLiveData.postValue(message)
|
||||
}
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun getCommentReplyList(commentId: Long, onFailure: (() -> Unit)? = null) {
|
||||
if (!_isLoading.value!! && !isLast) {
|
||||
_isLoading.value = true
|
||||
compositeDisposable.add(
|
||||
repository.getCommentReplyList(
|
||||
commentId = commentId,
|
||||
page = page - 1,
|
||||
size = size,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
page += 1
|
||||
if (it.data.items.isNotEmpty()) {
|
||||
_commentList.postValue(it.data.items)
|
||||
} else {
|
||||
isLast = true
|
||||
_commentList.postValue(listOf())
|
||||
}
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
|
||||
if (onFailure != null) {
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
|
||||
_isLoading.value = false
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
if (onFailure != null) {
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import coil.load
|
||||
import coil.transform.CircleCropTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.ItemCommunityPostCommentBinding
|
||||
import kr.co.vividnext.sodalive.databinding.ItemCommunityPostCommentReplyBinding
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
||||
|
||||
class CreatorCommunityCommentReplyAdapter(
|
||||
private val creatorId: Long,
|
||||
private val modifyComment: (Long, String) -> Unit,
|
||||
private val onClickDelete: (Long) -> Unit
|
||||
) : RecyclerView.Adapter<CreatorCommunityCommentReplyViewHolder>() {
|
||||
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): CreatorCommunityCommentReplyViewHolder {
|
||||
return if (viewType == 0) {
|
||||
CreatorCommunityCommentReplyHeaderViewHolder(
|
||||
binding = ItemCommunityPostCommentBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
} else {
|
||||
CreatorCommunityCommentReplyItemViewHolder(
|
||||
context = parent.context,
|
||||
creatorId = creatorId,
|
||||
binding = ItemCommunityPostCommentReplyBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
),
|
||||
showOptionMenu = { context, view, commentId, writerId, creatorId, onClickModify ->
|
||||
showOptionMenu(context, view, commentId, writerId, creatorId, onClickModify)
|
||||
},
|
||||
modifyComment = modifyComment
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CreatorCommunityCommentReplyViewHolder, position: Int) {
|
||||
holder.bind(items.toList()[position])
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return position
|
||||
}
|
||||
|
||||
private fun showOptionMenu(
|
||||
context: Context,
|
||||
v: View,
|
||||
commentId: Long,
|
||||
writerId: Long,
|
||||
creatorId: Long,
|
||||
onClickModify: () -> Unit
|
||||
) {
|
||||
val popup = PopupMenu(context, v)
|
||||
val inflater = popup.menuInflater
|
||||
|
||||
if (writerId == SharedPreferenceManager.userId) {
|
||||
inflater.inflate(R.menu.content_comment_option_menu, popup.menu)
|
||||
} else if (creatorId == SharedPreferenceManager.userId) {
|
||||
inflater.inflate(R.menu.content_comment_option_menu2, popup.menu)
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_review_modify -> {
|
||||
onClickModify()
|
||||
}
|
||||
|
||||
R.id.menu_review_delete -> {
|
||||
onClickDelete(commentId)
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
popup.show()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class CreatorCommunityCommentReplyViewHolder(
|
||||
binding: ViewBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
abstract fun bind(item: GetCommunityPostCommentListItem)
|
||||
}
|
||||
|
||||
class CreatorCommunityCommentReplyHeaderViewHolder(
|
||||
private val binding: ItemCommunityPostCommentBinding
|
||||
) : CreatorCommunityCommentReplyViewHolder(binding) {
|
||||
override fun bind(item: GetCommunityPostCommentListItem) {
|
||||
binding.ivCommentProfile.loadUrl(item.profileUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.ic_place_holder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
|
||||
binding.tvComment.text = item.comment
|
||||
binding.tvCommentDate.text = item.date
|
||||
binding.tvCommentNickname.text = item.nickname
|
||||
|
||||
binding.tvWriteReply.visibility = View.GONE
|
||||
binding.ivMenu.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
class CreatorCommunityCommentReplyItemViewHolder(
|
||||
private val context: Context,
|
||||
private val creatorId: Long,
|
||||
private val binding: ItemCommunityPostCommentReplyBinding,
|
||||
private val showOptionMenu: (
|
||||
Context, View, Long, Long, Long, onClickModify: () -> Unit
|
||||
) -> Unit,
|
||||
private val modifyComment: (Long, String) -> Unit
|
||||
) : CreatorCommunityCommentReplyViewHolder(binding) {
|
||||
override fun bind(item: GetCommunityPostCommentListItem) {
|
||||
binding.ivCommentProfile.load(item.profileUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.ic_place_holder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
|
||||
binding.tvComment.text = item.comment
|
||||
binding.tvCommentDate.text = item.date
|
||||
binding.tvCommentNickname.text = item.nickname
|
||||
|
||||
if (
|
||||
item.writerId == SharedPreferenceManager.userId ||
|
||||
creatorId == SharedPreferenceManager.userId
|
||||
) {
|
||||
binding.etCommentModify.setText(item.comment)
|
||||
binding.ivMenu.visibility = View.VISIBLE
|
||||
binding.ivMenu.setOnClickListener {
|
||||
showOptionMenu(
|
||||
context,
|
||||
binding.ivMenu,
|
||||
item.id,
|
||||
item.writerId,
|
||||
creatorId
|
||||
) {
|
||||
binding.rlCommentModify.visibility = View.VISIBLE
|
||||
binding.tvComment.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
binding.tvModify.setOnClickListener {
|
||||
binding.rlCommentModify.visibility = View.GONE
|
||||
binding.tvComment.visibility = View.VISIBLE
|
||||
modifyComment(item.id, binding.etCommentModify.text.toString())
|
||||
}
|
||||
} else {
|
||||
binding.ivMenu.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Service
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import androidx.core.os.BundleCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import coil.transform.CircleCropTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||
import kr.co.vividnext.sodalive.base.SodaDialog
|
||||
import kr.co.vividnext.sodalive.common.Constants
|
||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentReplyBinding
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class CreatorCommunityCommentReplyFragment : BaseFragment<FragmentAudioContentCommentReplyBinding>(
|
||||
FragmentAudioContentCommentReplyBinding::inflate
|
||||
) {
|
||||
private val viewModel: CreatorCommunityCommentListViewModel by inject()
|
||||
|
||||
private lateinit var imm: InputMethodManager
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
private lateinit var adapter: CreatorCommunityCommentReplyAdapter
|
||||
|
||||
private var originalComment: GetCommunityPostCommentListItem? = null
|
||||
private var creatorId: Long = 0
|
||||
private var postId: Long = 0
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
creatorId = arguments?.getLong(Constants.EXTRA_COMMUNITY_CREATOR_ID) ?: 0
|
||||
postId = arguments?.getLong(Constants.EXTRA_COMMUNITY_POST_ID) ?: 0
|
||||
originalComment = BundleCompat.getParcelable(
|
||||
requireArguments(),
|
||||
Constants.EXTRA_COMMUNITY_POST_COMMENT,
|
||||
GetCommunityPostCommentListItem::class.java
|
||||
)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
if (originalComment == null) {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
|
||||
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
||||
imm = requireContext().getSystemService(
|
||||
Service.INPUT_METHOD_SERVICE
|
||||
) as InputMethodManager
|
||||
|
||||
setupView()
|
||||
bindData()
|
||||
viewModel.getCommentReplyList(commentId = originalComment!!.id) {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideDialog() {
|
||||
(parentFragment as CreatorCommunityCommentFragment).hideCommentDialog()
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
binding.root.setOnClickListener { }
|
||||
|
||||
binding.tvBack.setOnClickListener {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
|
||||
binding.ivClose.setOnClickListener { hideDialog() }
|
||||
|
||||
binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.ic_place_holder)
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
|
||||
binding.ivCommentSend.setOnClickListener {
|
||||
hideKeyboard()
|
||||
val comment = binding.etComment.text.toString()
|
||||
binding.etComment.setText("")
|
||||
viewModel.registerComment(postId, comment, originalComment!!.id)
|
||||
}
|
||||
|
||||
adapter = CreatorCommunityCommentReplyAdapter(
|
||||
creatorId = creatorId,
|
||||
modifyComment = { commentId, comment ->
|
||||
hideKeyboard()
|
||||
viewModel.modifyComment(
|
||||
commentId = commentId,
|
||||
postId = postId,
|
||||
parentCommentId = originalComment!!.id,
|
||||
comment = comment
|
||||
)
|
||||
},
|
||||
onClickDelete = {
|
||||
SodaDialog(
|
||||
activity = requireActivity(),
|
||||
layoutInflater = layoutInflater,
|
||||
title = "댓글 삭제",
|
||||
desc = "삭제하시겠습니까?",
|
||||
confirmButtonTitle = "삭제",
|
||||
confirmButtonClick = {
|
||||
viewModel.modifyComment(
|
||||
commentId = it,
|
||||
postId = postId,
|
||||
parentCommentId = originalComment!!.id,
|
||||
isActive = false
|
||||
)
|
||||
},
|
||||
cancelButtonTitle = "취소",
|
||||
cancelButtonClick = {}
|
||||
).show(screenWidth)
|
||||
},
|
||||
).apply {
|
||||
items.add(originalComment!!)
|
||||
}
|
||||
|
||||
val recyclerView = binding.rvCommentReply
|
||||
recyclerView.setHasFixedSize(true)
|
||||
recyclerView.layoutManager = LinearLayoutManager(
|
||||
activity,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false
|
||||
)
|
||||
|
||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
|
||||
outRect.left = 13.3f.dpToPx().toInt()
|
||||
outRect.right = 13.3f.dpToPx().toInt()
|
||||
|
||||
when (parent.getChildAdapterPosition(view)) {
|
||||
0 -> {
|
||||
outRect.top = 13.3f.dpToPx().toInt()
|
||||
outRect.bottom = 12f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
adapter.itemCount - 1 -> {
|
||||
outRect.top = 12f.dpToPx().toInt()
|
||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.top = 12f.dpToPx().toInt()
|
||||
outRect.bottom = 12f.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
|
||||
val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
|
||||
.findLastCompletelyVisibleItemPosition()
|
||||
val itemTotalCount = recyclerView.adapter!!.itemCount - 1
|
||||
|
||||
// 스크롤이 끝에 도달했는지 확인
|
||||
if (!recyclerView.canScrollVertically(1) &&
|
||||
lastVisibleItemPosition == itemTotalCount
|
||||
) {
|
||||
viewModel.getCommentReplyList(originalComment!!.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
recyclerView.adapter = adapter
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun bindData() {
|
||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth)
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
viewModel.commentList.observe(viewLifecycleOwner) {
|
||||
if (viewModel.page - 1 == 1) {
|
||||
adapter.items.clear()
|
||||
binding.rvCommentReply.scrollToPosition(0)
|
||||
adapter.items.add(originalComment!!)
|
||||
}
|
||||
|
||||
adapter.items.addAll(it)
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideKeyboard() {
|
||||
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(
|
||||
creatorId: Long,
|
||||
postId: Long,
|
||||
comment: GetCommunityPostCommentListItem
|
||||
): CreatorCommunityCommentReplyFragment {
|
||||
val args = Bundle()
|
||||
args.putLong(Constants.EXTRA_COMMUNITY_POST_ID, postId)
|
||||
args.putLong(Constants.EXTRA_COMMUNITY_CREATOR_ID, creatorId)
|
||||
args.putParcelable(Constants.EXTRA_COMMUNITY_POST_COMMENT, comment)
|
||||
|
||||
val fragment = CreatorCommunityCommentReplyFragment()
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/color_222222" />
|
||||
<corners android:radius="5.3dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/color_222222" />
|
||||
</shape>
|
|
@ -0,0 +1,15 @@
|
|||
<?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="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_creator_community"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_comment_profile"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment_nickname"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6.7dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_menu"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_comment_profile"
|
||||
app:layout_constraintTop_toTopOf="@+id/iv_comment_profile"
|
||||
tools:text="alkfje203" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_seemore_vertical"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/iv_comment_profile" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment_date"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_525252"
|
||||
android:textSize="10.3sp"
|
||||
app:layout_constraintEnd_toEndOf="@+id/tv_comment_nickname"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_comment_nickname"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_comment_nickname"
|
||||
tools:ignore="SmallSp"
|
||||
tools:text="2시간전" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_comment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="@+id/tv_comment_date"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_comment_date"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_comment_date">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_777777"
|
||||
android:textSize="12sp"
|
||||
tools:text="내용내용내용내용내용내용내용내용내용내용내용내용내용 내용내용내용내용내용내용내용내용내용내용 내용내용내용내용" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_comment_modify"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_comment_modify"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginEnd="13.3dp"
|
||||
android:layout_toStartOf="@+id/tv_modify"
|
||||
android:background="@drawable/bg_round_corner_10_339970ff_9970ff"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
android:paddingHorizontal="13.3dp"
|
||||
android:paddingVertical="13dp"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textColorHint="@color/color_eeeeee"
|
||||
android:textCursorDrawable="@drawable/edit_text_cursor"
|
||||
android:textSize="13.3sp"
|
||||
android:theme="@style/EditTextStyle"
|
||||
tools:ignore="LabelFor" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_modify"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:background="@drawable/bg_round_corner_6_7_9970ff"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:padding="13dp"
|
||||
android:text="수정"
|
||||
android:textColor="@color/white" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_write_reply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="답글 쓰기"
|
||||
android:textColor="@color/color_9970ff"
|
||||
android:textSize="13.3sp"
|
||||
app:layout_constraintStart_toStartOf="@+id/ll_comment"
|
||||
app:layout_constraintTop_toBottomOf="@+id/ll_comment" />
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginTop="16.7dp"
|
||||
android:background="@color/color_595959"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_write_reply" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_comment_profile"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment_nickname"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6.7dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_menu"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_comment_profile"
|
||||
app:layout_constraintTop_toTopOf="@+id/iv_comment_profile"
|
||||
tools:text="alkfje203" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_seemore_vertical"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/iv_comment_profile" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment_date"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_525252"
|
||||
android:textSize="10.3sp"
|
||||
app:layout_constraintEnd_toEndOf="@+id/tv_comment_nickname"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_comment_nickname"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_comment_nickname"
|
||||
tools:ignore="SmallSp"
|
||||
tools:text="2시간전" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_comment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="@+id/tv_comment_date"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_comment_date"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_comment_date">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_777777"
|
||||
android:textSize="12sp"
|
||||
tools:text="내용내용내용내용내용내용내용내용내용내용내용내용내용 내용내용내용내용내용내용내용내용내용내용 내용내용내용내용" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_comment_modify"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_comment_modify"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginEnd="13.3dp"
|
||||
android:layout_toStartOf="@+id/tv_modify"
|
||||
android:background="@drawable/bg_round_corner_10_339970ff_9970ff"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
android:paddingHorizontal="13.3dp"
|
||||
android:paddingVertical="13dp"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textColorHint="@color/color_eeeeee"
|
||||
android:textCursorDrawable="@drawable/edit_text_cursor"
|
||||
android:textSize="13.3sp"
|
||||
android:theme="@style/EditTextStyle"
|
||||
tools:ignore="LabelFor" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_modify"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:background="@drawable/bg_round_corner_6_7_9970ff"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:padding="13dp"
|
||||
android:text="수정"
|
||||
android:textColor="@color/white" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,209 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_round_corner_5_3_222222"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:paddingVertical="11dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_creator_profile"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:contentDescription="@null"
|
||||
tools:src="@drawable/ic_logo" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginHorizontal="11dp"
|
||||
android:layout_toStartOf="@+id/iv_see_more"
|
||||
android:layout_toEndOf="@+id/iv_creator_profile"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_nickname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
tools:text="민하나" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:fontFamily="@font/gmarket_sans_light"
|
||||
android:textColor="@color/color_777777"
|
||||
android:textSize="13.3sp"
|
||||
tools:text="3시간전" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_see_more"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="8.3dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_seemore_vertical" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:maxLines="3"
|
||||
android:textColor="@color/color_bbbbbb"
|
||||
android:textSize="13.3sp"
|
||||
tools:text="너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_like"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_round_corner_26_7_19ffffff"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="13.3dp"
|
||||
android:paddingVertical="5.3dp"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_like"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_audio_content_heart_normal" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_like"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_d2d2d2"
|
||||
android:textSize="13.3sp"
|
||||
tools:text="1234" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_comment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:background="@drawable/bg_round_corner_5_3_19ffffff"
|
||||
android:orientation="vertical"
|
||||
android:padding="10.3dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="댓글"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_909090"
|
||||
android:textSize="12sp"
|
||||
tools:text="1,204" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10.3dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_comment_profile"
|
||||
android:layout_width="33.3dp"
|
||||
android:layout_height="33.3dp"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_input_comment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_comment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_round_corner_10_232323_9970ff"
|
||||
android:hint="댓글을 입력해 보세요"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
android:paddingVertical="13.3dp"
|
||||
android:paddingStart="13.3dp"
|
||||
android:paddingEnd="50.7dp"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textColorHint="@color/color_777777"
|
||||
android:textCursorDrawable="@drawable/edit_text_cursor"
|
||||
android:textSize="13.3sp"
|
||||
tools:ignore="LabelFor" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_comment_send"
|
||||
android:layout_width="33.3dp"
|
||||
android:layout_height="33.3dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/btn_message_send" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="11dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_bbbbbb"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
tools:text="너무 좋아요!!! 너무 좋아요!!! 너무 좋아요!!! 너무 좋아요!!! 너무 좋아요!!! 너무 좋아요!!!" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
Loading…
Reference in New Issue