parent
1b8d65c3ea
commit
1f36d8ef25
|
@ -35,8 +35,8 @@ android {
|
||||||
applicationId "kr.co.vividnext.sodalive"
|
applicationId "kr.co.vividnext.sodalive"
|
||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 34
|
targetSdk 34
|
||||||
versionCode 102
|
versionCode 104
|
||||||
versionName "1.16.2"
|
versionName "1.17.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
|
import com.orhanobut.logger.Logger
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemAudioContentCommentBinding
|
import kr.co.vividnext.sodalive.databinding.ItemAudioContentCommentBinding
|
||||||
|
@ -19,7 +20,8 @@ class AudioContentCommentAdapter(
|
||||||
private val creatorId: Long,
|
private val creatorId: Long,
|
||||||
private val modifyComment: (Long, String) -> Unit,
|
private val modifyComment: (Long, String) -> Unit,
|
||||||
private val onClickDelete: (Long) -> Unit,
|
private val onClickDelete: (Long) -> Unit,
|
||||||
private val onItemClick: (GetAudioContentCommentListItem) -> Unit
|
private val onItemClick: (GetAudioContentCommentListItem) -> Unit,
|
||||||
|
private val onClickProfile: (Long) -> Unit
|
||||||
) : RecyclerView.Adapter<AudioContentCommentAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<AudioContentCommentAdapter.ViewHolder>() {
|
||||||
|
|
||||||
var items = mutableSetOf<GetAudioContentCommentListItem>()
|
var items = mutableSetOf<GetAudioContentCommentListItem>()
|
||||||
|
@ -42,6 +44,12 @@ class AudioContentCommentAdapter(
|
||||||
transformations(CircleCropTransformation())
|
transformations(CircleCropTransformation())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.ivCommentProfile.setOnClickListener {
|
||||||
|
if (SharedPreferenceManager.userId != item.writerId) {
|
||||||
|
onClickProfile(item.writerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val tvCommentLayoutParams = binding.tvComment.layoutParams as LinearLayout.LayoutParams
|
val tvCommentLayoutParams = binding.tvComment.layoutParams as LinearLayout.LayoutParams
|
||||||
val can = item.donationCan
|
val can = item.donationCan
|
||||||
if (can > 0) {
|
if (can > 0) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentListBinding
|
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentListBinding
|
||||||
|
import kr.co.vividnext.sodalive.dialog.MemberProfileDialog
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
@ -121,6 +122,14 @@ class AudioContentCommentListFragment : BaseFragment<FragmentAudioContentComment
|
||||||
},
|
},
|
||||||
onItemClick = {
|
onItemClick = {
|
||||||
(parentFragment as AudioContentCommentFragment).onClickComment(it)
|
(parentFragment as AudioContentCommentFragment).onClickComment(it)
|
||||||
|
},
|
||||||
|
onClickProfile = {
|
||||||
|
MemberProfileDialog(
|
||||||
|
activity = requireActivity(),
|
||||||
|
layoutInflater = layoutInflater,
|
||||||
|
memberId = it,
|
||||||
|
screenWidth = screenWidth
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,7 @@ import kr.co.vividnext.sodalive.settings.terms.TermsRepository
|
||||||
import kr.co.vividnext.sodalive.settings.terms.TermsViewModel
|
import kr.co.vividnext.sodalive.settings.terms.TermsViewModel
|
||||||
import kr.co.vividnext.sodalive.user.UserApi
|
import kr.co.vividnext.sodalive.user.UserApi
|
||||||
import kr.co.vividnext.sodalive.user.UserRepository
|
import kr.co.vividnext.sodalive.user.UserRepository
|
||||||
|
import kr.co.vividnext.sodalive.user.UserViewModel
|
||||||
import kr.co.vividnext.sodalive.user.find_password.FindPasswordViewModel
|
import kr.co.vividnext.sodalive.user.find_password.FindPasswordViewModel
|
||||||
import kr.co.vividnext.sodalive.user.login.LoginViewModel
|
import kr.co.vividnext.sodalive.user.login.LoginViewModel
|
||||||
import kr.co.vividnext.sodalive.user.signup.SignUpViewModel
|
import kr.co.vividnext.sodalive.user.signup.SignUpViewModel
|
||||||
|
@ -258,6 +259,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
viewModel { CanChargeIapViewModel(get()) }
|
viewModel { CanChargeIapViewModel(get()) }
|
||||||
viewModel { AlarmListViewModel(get()) }
|
viewModel { AlarmListViewModel(get()) }
|
||||||
viewModel { BlockMemberViewModel(get()) }
|
viewModel { BlockMemberViewModel(get()) }
|
||||||
|
viewModel { UserViewModel(get(), get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repositoryModule = module {
|
private val repositoryModule = module {
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
package kr.co.vividnext.sodalive.dialog
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.Window
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import coil.load
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
|
import kr.co.vividnext.sodalive.databinding.DialogMemberProfileBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
import kr.co.vividnext.sodalive.report.ProfileReportDialog
|
||||||
|
import kr.co.vividnext.sodalive.report.ReportType
|
||||||
|
import kr.co.vividnext.sodalive.report.UserReportDialog
|
||||||
|
import kr.co.vividnext.sodalive.settings.notification.MemberRole
|
||||||
|
import kr.co.vividnext.sodalive.user.UserViewModel
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
|
||||||
|
class MemberProfileDialog(
|
||||||
|
private val activity: FragmentActivity,
|
||||||
|
private val layoutInflater: LayoutInflater,
|
||||||
|
private val memberId: Long,
|
||||||
|
private val screenWidth: Int
|
||||||
|
) : KoinComponent {
|
||||||
|
|
||||||
|
private val viewModel: UserViewModel by inject()
|
||||||
|
private val alertDialog: AlertDialog
|
||||||
|
|
||||||
|
val dialogView = DialogMemberProfileBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
|
||||||
|
init {
|
||||||
|
val dialogBuilder = AlertDialog.Builder(activity)
|
||||||
|
dialogBuilder.setView(dialogView.root)
|
||||||
|
|
||||||
|
alertDialog = dialogBuilder.create()
|
||||||
|
alertDialog.setCancelable(false)
|
||||||
|
alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||||
|
alertDialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||||
|
|
||||||
|
setupView()
|
||||||
|
bindData()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dismiss() {
|
||||||
|
alertDialog.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun show() {
|
||||||
|
viewModel.getMemberProfile(memberId) {
|
||||||
|
alertDialog.show()
|
||||||
|
|
||||||
|
val lp = WindowManager.LayoutParams()
|
||||||
|
lp.copyFrom(alertDialog.window?.attributes)
|
||||||
|
lp.width = screenWidth - (40.dpToPx()).toInt()
|
||||||
|
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
|
|
||||||
|
alertDialog.window?.attributes = lp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupView() {
|
||||||
|
loadingDialog = LoadingDialog(activity, layoutInflater)
|
||||||
|
|
||||||
|
val profileLP = dialogView.ivProfile.layoutParams
|
||||||
|
profileLP.width = activity.resources.displayMetrics.widthPixels - (66.7f.dpToPx()).toInt()
|
||||||
|
profileLP.height = activity.resources.displayMetrics.widthPixels - (66.7f.dpToPx()).toInt()
|
||||||
|
dialogView.ivProfile.layoutParams = profileLP
|
||||||
|
dialogView.ivClose.setOnClickListener { dismiss() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindData() {
|
||||||
|
viewModel.isLoading.observe(activity) {
|
||||||
|
if (it) {
|
||||||
|
loadingDialog.show(screenWidth)
|
||||||
|
} else {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.toastLiveData.observe(activity) {
|
||||||
|
Toast.makeText(activity, it, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.memberProfile.observe(activity) {
|
||||||
|
dialogView.ivProfile.load(it.profileImageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
transformations(RoundedCornersTransformation(8.dpToPx()))
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogView.tvNickname.text = it.nickname
|
||||||
|
dialogView.tvBlockMember.text = if (it.isBlocked) {
|
||||||
|
"차단 해제"
|
||||||
|
} else {
|
||||||
|
"차단"
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogView.tvBlockMember.setOnClickListener { _ ->
|
||||||
|
if (it.isBlocked) {
|
||||||
|
viewModel.memberUnBlock(it.memberId) { dismiss() }
|
||||||
|
} else {
|
||||||
|
showMemberBlockDialog(it.memberId, it.nickname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogView.tvReportMember.setOnClickListener { _ ->
|
||||||
|
showMemberReportDialog(it.memberId)
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogView.tvReportMemberProfile.setOnClickListener { _ ->
|
||||||
|
showProfileReportDialog(it.memberId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showMemberBlockDialog(memberId: Long, nickname: String) {
|
||||||
|
val message = if (SharedPreferenceManager.role == MemberRole.CREATOR.name) {
|
||||||
|
"""
|
||||||
|
${nickname}님을 차단하시겠습니까?
|
||||||
|
|
||||||
|
사용자를 차단하면 사용자는 아래 기능이 제한됩니다.
|
||||||
|
- 내가 개설한 라이브 입장 불가
|
||||||
|
- 나에게 메시지 보내기 불가
|
||||||
|
- 내 채널의 팬Talk 작성불가
|
||||||
|
""".trimIndent()
|
||||||
|
} else {
|
||||||
|
"""
|
||||||
|
${nickname}님을 차단하시겠습니까?
|
||||||
|
|
||||||
|
- 사용자를 차단하면 '차단한 사용자의 라이브 중 채팅'이 보이지 않습니다.
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
val dialog = android.app.AlertDialog.Builder(activity)
|
||||||
|
dialog.setTitle("사용자 차단")
|
||||||
|
dialog.setMessage(message)
|
||||||
|
dialog.setPositiveButton("차단") { _, _ ->
|
||||||
|
viewModel.memberBlock(memberId) { dismiss() }
|
||||||
|
}
|
||||||
|
dialog.setNegativeButton("취소") { _, _ -> }
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showMemberReportDialog(memberId: Long) {
|
||||||
|
val dialog = UserReportDialog(activity, layoutInflater) {
|
||||||
|
viewModel.report(
|
||||||
|
type = ReportType.USER,
|
||||||
|
userId = memberId,
|
||||||
|
reason = it
|
||||||
|
) { dismiss() }
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show(screenWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showProfileReportDialog(memberId: Long) {
|
||||||
|
val dialog = ProfileReportDialog(activity, layoutInflater) {
|
||||||
|
viewModel.report(
|
||||||
|
type = ReportType.PROFILE,
|
||||||
|
userId = memberId
|
||||||
|
) { dismiss() }
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show(screenWidth)
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityUserProfileBinding
|
import kr.co.vividnext.sodalive.databinding.ActivityUserProfileBinding
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityBinding
|
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityBinding
|
||||||
|
import kr.co.vividnext.sodalive.dialog.MemberProfileDialog
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.UserProfileCheersAdapter
|
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.GetCommunityPostListResponse
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
|
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
|
||||||
|
@ -382,6 +383,14 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
cancelButtonTitle = "취소",
|
cancelButtonTitle = "취소",
|
||||||
cancelButtonClick = {}
|
cancelButtonClick = {}
|
||||||
).show(screenWidth)
|
).show(screenWidth)
|
||||||
|
},
|
||||||
|
onClickProfile = {
|
||||||
|
MemberProfileDialog(
|
||||||
|
activity = this@UserProfileActivity,
|
||||||
|
layoutInflater = layoutInflater,
|
||||||
|
memberId = it,
|
||||||
|
screenWidth = screenWidth
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ class UserProfileCheersAdapter(
|
||||||
private val modifyReply: (Long, String?) -> Unit,
|
private val modifyReply: (Long, String?) -> Unit,
|
||||||
private val modifyCheers: (Long, String) -> Unit,
|
private val modifyCheers: (Long, String) -> Unit,
|
||||||
private val onClickReport: (Long) -> Unit,
|
private val onClickReport: (Long) -> Unit,
|
||||||
private val onClickDelete: (Long) -> Unit
|
private val onClickDelete: (Long) -> Unit,
|
||||||
|
private val onClickProfile: (Long) -> Unit
|
||||||
) : RecyclerView.Adapter<UserProfileCheersAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<UserProfileCheersAdapter.ViewHolder>() {
|
||||||
|
|
||||||
val items = mutableListOf<GetCheersResponseItem>()
|
val items = mutableListOf<GetCheersResponseItem>()
|
||||||
|
@ -35,6 +36,12 @@ class UserProfileCheersAdapter(
|
||||||
binding.llCheerReply.visibility = View.GONE
|
binding.llCheerReply.visibility = View.GONE
|
||||||
binding.rlCheerReply.visibility = View.GONE
|
binding.rlCheerReply.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.ivProfile.setOnClickListener {
|
||||||
|
if (SharedPreferenceManager.userId != cheers.memberId) {
|
||||||
|
onClickProfile(cheers.memberId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.ivProfile.load(cheers.profileUrl) {
|
binding.ivProfile.load(cheers.profileUrl) {
|
||||||
crossfade(true)
|
crossfade(true)
|
||||||
placeholder(R.drawable.ic_place_holder)
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
|
|
@ -17,7 +17,8 @@ class CreatorCommunityCommentAdapter(
|
||||||
private val creatorId: Long,
|
private val creatorId: Long,
|
||||||
private val modifyComment: (Long, String) -> Unit,
|
private val modifyComment: (Long, String) -> Unit,
|
||||||
private val onClickDelete: (Long) -> Unit,
|
private val onClickDelete: (Long) -> Unit,
|
||||||
private val onItemClick: (GetCommunityPostCommentListItem) -> Unit
|
private val onItemClick: (GetCommunityPostCommentListItem) -> Unit,
|
||||||
|
private val onClickProfile: (Long) -> Unit
|
||||||
) : RecyclerView.Adapter<CreatorCommunityCommentAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<CreatorCommunityCommentAdapter.ViewHolder>() {
|
||||||
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
||||||
|
|
||||||
|
@ -33,6 +34,12 @@ class CreatorCommunityCommentAdapter(
|
||||||
transformations(CircleCropTransformation())
|
transformations(CircleCropTransformation())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.ivCommentProfile.setOnClickListener {
|
||||||
|
if (SharedPreferenceManager.userId != item.writerId) {
|
||||||
|
onClickProfile(item.writerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.tvComment.text = item.comment
|
binding.tvComment.text = item.comment
|
||||||
binding.tvCommentDate.text = item.date
|
binding.tvCommentDate.text = item.date
|
||||||
binding.tvCommentNickname.text = item.nickname
|
binding.tvCommentNickname.text = item.nickname
|
||||||
|
|
|
@ -20,6 +20,7 @@ import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentListBinding
|
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentListBinding
|
||||||
|
import kr.co.vividnext.sodalive.dialog.MemberProfileDialog
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
@ -106,6 +107,14 @@ class CreatorCommunityCommentListFragment : BaseFragment<FragmentAudioContentCom
|
||||||
},
|
},
|
||||||
onItemClick = {
|
onItemClick = {
|
||||||
(parentFragment as CreatorCommunityCommentFragment).onClickComment(it)
|
(parentFragment as CreatorCommunityCommentFragment).onClickComment(it)
|
||||||
|
},
|
||||||
|
onClickProfile = {
|
||||||
|
MemberProfileDialog(
|
||||||
|
activity = requireActivity(),
|
||||||
|
layoutInflater = layoutInflater,
|
||||||
|
memberId = it,
|
||||||
|
screenWidth = screenWidth
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ import kr.co.vividnext.sodalive.extensions.loadUrl
|
||||||
class CreatorCommunityCommentReplyAdapter(
|
class CreatorCommunityCommentReplyAdapter(
|
||||||
private val creatorId: Long,
|
private val creatorId: Long,
|
||||||
private val modifyComment: (Long, String) -> Unit,
|
private val modifyComment: (Long, String) -> Unit,
|
||||||
private val onClickDelete: (Long) -> Unit
|
private val onClickDelete: (Long) -> Unit,
|
||||||
|
private val onClickProfile: (Long) -> Unit
|
||||||
) : RecyclerView.Adapter<CreatorCommunityCommentReplyViewHolder>() {
|
) : RecyclerView.Adapter<CreatorCommunityCommentReplyViewHolder>() {
|
||||||
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
||||||
override fun onCreateViewHolder(
|
override fun onCreateViewHolder(
|
||||||
|
@ -46,7 +47,8 @@ class CreatorCommunityCommentReplyAdapter(
|
||||||
showOptionMenu = { context, view, commentId, writerId, creatorId, onClickModify ->
|
showOptionMenu = { context, view, commentId, writerId, creatorId, onClickModify ->
|
||||||
showOptionMenu(context, view, commentId, writerId, creatorId, onClickModify)
|
showOptionMenu(context, view, commentId, writerId, creatorId, onClickModify)
|
||||||
},
|
},
|
||||||
modifyComment = modifyComment
|
modifyComment = modifyComment,
|
||||||
|
onClickProfile = onClickProfile
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,9 +130,16 @@ class CreatorCommunityCommentReplyItemViewHolder(
|
||||||
private val showOptionMenu: (
|
private val showOptionMenu: (
|
||||||
Context, View, Long, Long, Long, onClickModify: () -> Unit
|
Context, View, Long, Long, Long, onClickModify: () -> Unit
|
||||||
) -> Unit,
|
) -> Unit,
|
||||||
private val modifyComment: (Long, String) -> Unit
|
private val modifyComment: (Long, String) -> Unit,
|
||||||
|
private val onClickProfile: (Long) -> Unit
|
||||||
) : CreatorCommunityCommentReplyViewHolder(binding) {
|
) : CreatorCommunityCommentReplyViewHolder(binding) {
|
||||||
override fun bind(item: GetCommunityPostCommentListItem) {
|
override fun bind(item: GetCommunityPostCommentListItem) {
|
||||||
|
binding.ivCommentProfile.setOnClickListener {
|
||||||
|
if (SharedPreferenceManager.userId != item.writerId) {
|
||||||
|
onClickProfile(item.writerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.ivCommentProfile.load(item.profileUrl) {
|
binding.ivCommentProfile.load(item.profileUrl) {
|
||||||
crossfade(true)
|
crossfade(true)
|
||||||
placeholder(R.drawable.ic_place_holder)
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
|
|
@ -21,6 +21,7 @@ import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentReplyBinding
|
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentReplyBinding
|
||||||
|
import kr.co.vividnext.sodalive.dialog.MemberProfileDialog
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
@ -127,6 +128,14 @@ class CreatorCommunityCommentReplyFragment : BaseFragment<FragmentAudioContentCo
|
||||||
cancelButtonClick = {}
|
cancelButtonClick = {}
|
||||||
).show(screenWidth)
|
).show(screenWidth)
|
||||||
},
|
},
|
||||||
|
onClickProfile = {
|
||||||
|
MemberProfileDialog(
|
||||||
|
activity = requireActivity(),
|
||||||
|
layoutInflater = layoutInflater,
|
||||||
|
memberId = it,
|
||||||
|
screenWidth = screenWidth
|
||||||
|
).show()
|
||||||
|
}
|
||||||
).apply {
|
).apply {
|
||||||
items.add(originalComment!!)
|
items.add(originalComment!!)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import kr.co.vividnext.sodalive.base.SodaDialog
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityUserProfileFantalkAllBinding
|
import kr.co.vividnext.sodalive.databinding.ActivityUserProfileFantalkAllBinding
|
||||||
|
import kr.co.vividnext.sodalive.dialog.MemberProfileDialog
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.UserProfileCheersAdapter
|
import kr.co.vividnext.sodalive.explorer.profile.cheers.UserProfileCheersAdapter
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.report.CheersReportDialog
|
import kr.co.vividnext.sodalive.report.CheersReportDialog
|
||||||
|
@ -121,6 +122,14 @@ class UserProfileFantalkAllViewActivity : BaseActivity<ActivityUserProfileFantal
|
||||||
cancelButtonTitle = "취소",
|
cancelButtonTitle = "취소",
|
||||||
cancelButtonClick = {}
|
cancelButtonClick = {}
|
||||||
).show(screenWidth)
|
).show(screenWidth)
|
||||||
|
},
|
||||||
|
onClickProfile = {
|
||||||
|
MemberProfileDialog(
|
||||||
|
activity = this@UserProfileFantalkAllViewActivity,
|
||||||
|
layoutInflater = layoutInflater,
|
||||||
|
memberId = it,
|
||||||
|
screenWidth = screenWidth
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package kr.co.vividnext.sodalive.user
|
||||||
|
|
||||||
|
import androidx.annotation.Keep
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
data class GetMemberProfileResponse(
|
||||||
|
@SerializedName("memberId") val memberId: Long,
|
||||||
|
@SerializedName("nickname") val nickname: String,
|
||||||
|
@SerializedName("profileImageUrl") val profileImageUrl: String,
|
||||||
|
@SerializedName("isBlocked") val isBlocked: Boolean
|
||||||
|
)
|
|
@ -26,6 +26,7 @@ import retrofit2.http.Multipart
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
import retrofit2.http.PUT
|
import retrofit2.http.PUT
|
||||||
import retrofit2.http.Part
|
import retrofit2.http.Part
|
||||||
|
import retrofit2.http.Path
|
||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
|
|
||||||
interface UserApi {
|
interface UserApi {
|
||||||
|
@ -157,4 +158,10 @@ interface UserApi {
|
||||||
fun getBlockedMemberIdList(
|
fun getBlockedMemberIdList(
|
||||||
@Header("Authorization") authHeader: String
|
@Header("Authorization") authHeader: String
|
||||||
): Single<ApiResponse<List<Long>>>
|
): Single<ApiResponse<List<Long>>>
|
||||||
|
|
||||||
|
@GET("/member/profile/{id}")
|
||||||
|
fun getMemberProfile(
|
||||||
|
@Path("id") id: Long,
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Single<ApiResponse<GetMemberProfileResponse>>
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,4 +124,9 @@ class UserRepository(private val userApi: UserApi) {
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getBlockedMemberIdList(token: String) = userApi.getBlockedMemberIdList(authHeader = token)
|
fun getBlockedMemberIdList(token: String) = userApi.getBlockedMemberIdList(authHeader = token)
|
||||||
|
|
||||||
|
fun getMemberProfile(
|
||||||
|
id: Long,
|
||||||
|
token: String
|
||||||
|
) = userApi.getMemberProfile(id = id, authHeader = token)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
package kr.co.vividnext.sodalive.user
|
||||||
|
|
||||||
|
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.report.ReportRepository
|
||||||
|
import kr.co.vividnext.sodalive.report.ReportRequest
|
||||||
|
import kr.co.vividnext.sodalive.report.ReportType
|
||||||
|
|
||||||
|
class UserViewModel(
|
||||||
|
private val repository: UserRepository,
|
||||||
|
private val reportRepository: ReportRepository
|
||||||
|
) : BaseViewModel() {
|
||||||
|
private val _memberProfile = MutableLiveData<GetMemberProfileResponse>()
|
||||||
|
val memberProfile: LiveData<GetMemberProfileResponse>
|
||||||
|
get() = _memberProfile
|
||||||
|
|
||||||
|
private var _isLoading = MutableLiveData(false)
|
||||||
|
val isLoading: LiveData<Boolean>
|
||||||
|
get() = _isLoading
|
||||||
|
|
||||||
|
private val _toastLiveData = MutableLiveData<String?>()
|
||||||
|
val toastLiveData: LiveData<String?>
|
||||||
|
get() = _toastLiveData
|
||||||
|
|
||||||
|
fun getMemberProfile(id: Long, onSuccess: () -> Unit) {
|
||||||
|
_isLoading.value = true
|
||||||
|
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.getMemberProfile(
|
||||||
|
id = id,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
if (it.success && it.data != null) {
|
||||||
|
_memberProfile.value = it.data!!
|
||||||
|
onSuccess()
|
||||||
|
} 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 memberBlock(memberId: Long, onSuccess: () -> Unit) {
|
||||||
|
_isLoading.value = true
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.memberBlock(
|
||||||
|
userId = memberId,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
|
||||||
|
if (it.success) {
|
||||||
|
_toastLiveData.postValue("차단하였습니다.")
|
||||||
|
onSuccess()
|
||||||
|
} else {
|
||||||
|
val message = it.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
_toastLiveData.postValue(message)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun memberUnBlock(memberId: Long, onSuccess: () -> Unit) {
|
||||||
|
_isLoading.value = true
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.memberUnBlock(
|
||||||
|
userId = memberId,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
|
||||||
|
if (it.success) {
|
||||||
|
_toastLiveData.postValue("차단이 해제 되었습니다.")
|
||||||
|
onSuccess()
|
||||||
|
} else {
|
||||||
|
val message = it.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
_toastLiveData.postValue(message)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun report(
|
||||||
|
type: ReportType,
|
||||||
|
userId: Long,
|
||||||
|
reason: String = "프로필 신고",
|
||||||
|
onSuccess: () -> Unit
|
||||||
|
) {
|
||||||
|
_isLoading.value = true
|
||||||
|
|
||||||
|
val request = ReportRequest(type, reason, reportedMemberId = userId)
|
||||||
|
compositeDisposable.add(
|
||||||
|
reportRepository.report(
|
||||||
|
request = request,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
if (it.message != null) {
|
||||||
|
_toastLiveData.postValue(it.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"신고가 접수되었습니다."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_isLoading.value = false
|
||||||
|
onSuccess()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("신고가 접수되었습니다.")
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
<?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:layout_gravity="center_vertical"
|
||||||
|
android:background="@drawable/bg_round_corner_8_222222"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="13.3dp"
|
||||||
|
android:paddingTop="13.3dp"
|
||||||
|
android:paddingBottom="20dp">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rl_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="13.3dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="프로필"
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="14.7sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_close"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_close_white" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_nickname"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="21.3dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="18.3sp"
|
||||||
|
tools:text="닉네임" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_profile"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="21.3dp"
|
||||||
|
android:contentDescription="@null" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="21dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_block_member"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_round_corner_8_transparent_3bb9f1"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingVertical="13dp"
|
||||||
|
android:text="사용자 차단"
|
||||||
|
android:textColor="@color/color_3bb9f1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_report_member"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_round_corner_8_transparent_3bb9f1"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingVertical="13dp"
|
||||||
|
android:text="사용자 신고"
|
||||||
|
android:textColor="@color/color_3bb9f1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_report_member_profile"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_round_corner_8_transparent_3bb9f1"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingVertical="13dp"
|
||||||
|
android:text="프로필 신고"
|
||||||
|
android:textColor="@color/color_3bb9f1" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
Loading…
Reference in New Issue