feat(profile): 크리에이터 상세정보를 노출한다
This commit is contained in:
@@ -5,6 +5,7 @@ import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.explorer.profile.GetCheersResponse
|
||||
import kr.co.vividnext.sodalive.explorer.profile.GetCreatorProfileResponse
|
||||
import kr.co.vividnext.sodalive.explorer.profile.detail.GetCreatorDetailResponse
|
||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.PostWriteCheersRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.PutModifyCheersRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.donation.GetDonationAllResponse
|
||||
@@ -43,6 +44,12 @@ interface ExplorerApi {
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<GetCreatorProfileResponse>>
|
||||
|
||||
@GET("/explorer/profile/{id}/detail")
|
||||
fun getCreatorDetail(
|
||||
@Path("id") id: Long,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<GetCreatorDetailResponse>>
|
||||
|
||||
@GET("/explorer/profile/{id}/donation-rank")
|
||||
fun getCreatorProfileDonationRanking(
|
||||
@Path("id") id: Long,
|
||||
|
||||
@@ -27,6 +27,11 @@ class ExplorerRepository(
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun getCreatorDetail(id: Long, token: String) = api.getCreatorDetail(
|
||||
id = id,
|
||||
authHeader = token
|
||||
)
|
||||
|
||||
fun getCreatorProfileCheers(
|
||||
creatorId: Long,
|
||||
page: Int,
|
||||
|
||||
@@ -51,6 +51,7 @@ import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityP
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.relativeTimeText
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.write.CreatorCommunityWriteActivity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.detail.CreatorDetailDialog
|
||||
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
|
||||
@@ -711,6 +712,7 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||
if (creator.creatorId == SharedPreferenceManager.userId) {
|
||||
binding.ivNotification.visibility = View.GONE
|
||||
binding.tvNotificationCount.visibility = View.GONE
|
||||
binding.tvNotificationCount.setOnClickListener(null)
|
||||
binding.tvFollowerList.visibility = View.VISIBLE
|
||||
|
||||
binding.tvFollowerList.setOnClickListener {
|
||||
@@ -728,6 +730,17 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||
R.string.screen_user_profile_follower_count,
|
||||
creator.notificationRecipientCount.moneyFormat()
|
||||
)
|
||||
|
||||
binding.tvNotificationCount.setOnClickListener {
|
||||
viewModel.getCreatorDetail(creator.creatorId) { detail ->
|
||||
CreatorDetailDialog(
|
||||
activity = this@UserProfileActivity,
|
||||
layoutInflater = layoutInflater,
|
||||
screenWidth = screenWidth,
|
||||
detail = detail
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (creator.isFollow) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import kr.co.vividnext.sodalive.common.SodaLiveApplicationHolder
|
||||
import kr.co.vividnext.sodalive.common.Utils
|
||||
import kr.co.vividnext.sodalive.explorer.ExplorerRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.PutModifyCheersRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.detail.GetCreatorDetailResponse
|
||||
import kr.co.vividnext.sodalive.report.ReportRepository
|
||||
import kr.co.vividnext.sodalive.report.ReportRequest
|
||||
import kr.co.vividnext.sodalive.report.ReportType
|
||||
@@ -156,6 +157,43 @@ class UserProfileViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
fun getCreatorDetail(userId: Long, onSuccess: (GetCreatorDetailResponse) -> Unit) {
|
||||
_isLoading.value = true
|
||||
compositeDisposable.add(
|
||||
repository.getCreatorDetail(
|
||||
id = userId,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
_isLoading.value = false
|
||||
if (it.success && it.data != null) {
|
||||
onSuccess(it.data)
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
SodaLiveApplicationHolder.get()
|
||||
.getString(R.string.common_error_unknown)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue(
|
||||
SodaLiveApplicationHolder.get()
|
||||
.getString(R.string.common_error_unknown)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun follow(creatorId: Long, follow: Boolean = true, notify: Boolean = true) {
|
||||
_isLoading.value = true
|
||||
compositeDisposable.add(
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package kr.co.vividnext.sodalive.explorer.profile.detail
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.webkit.URLUtil
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.net.toUri
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.databinding.DialogCreatorDetailBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||
|
||||
class CreatorDetailDialog(
|
||||
private val activity: Activity,
|
||||
layoutInflater: LayoutInflater,
|
||||
private val screenWidth: Int,
|
||||
private val detail: GetCreatorDetailResponse
|
||||
) {
|
||||
|
||||
private data class SnsItem(
|
||||
val url: String,
|
||||
val iconResId: Int
|
||||
)
|
||||
|
||||
private val alertDialog: AlertDialog
|
||||
private val dialogView = DialogCreatorDetailBinding.inflate(layoutInflater)
|
||||
|
||||
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(Color.TRANSPARENT.toDrawable())
|
||||
|
||||
setupView()
|
||||
bindData()
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
dialogView.ivClose.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
private fun bindData() {
|
||||
dialogView.ivProfile.load(detail.profileImageUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.ic_place_holder)
|
||||
transformations(RoundedCornersTransformation(16f.dpToPx()))
|
||||
}
|
||||
dialogView.tvNickname.text = detail.nickname
|
||||
|
||||
dialogView.tvDebutValue.text = getDebutValue()
|
||||
dialogView.tvLiveCountValue.text = detail.activitySummary.liveCount.moneyFormat()
|
||||
dialogView.tvLiveTimeValue.text = detail.activitySummary.liveTime.moneyFormat()
|
||||
dialogView.tvLiveContributorCountValue.text = detail.activitySummary.liveContributorCount.moneyFormat()
|
||||
dialogView.tvContentCountValue.text = detail.activitySummary.contentCount.moneyFormat()
|
||||
|
||||
bindSnsItems()
|
||||
}
|
||||
|
||||
private fun getDebutValue(): String {
|
||||
val debutDate = detail.debutDate.trim()
|
||||
val dDay = detail.dDay.trim()
|
||||
if (debutDate.isBlank() && dDay.isBlank()) {
|
||||
return activity.getString(R.string.screen_creator_detail_debut_before)
|
||||
}
|
||||
|
||||
return "$debutDate ($dDay)"
|
||||
}
|
||||
|
||||
private fun bindSnsItems() {
|
||||
val snsItems = listOf(
|
||||
SnsItem(
|
||||
url = detail.youtubeUrl.trim(),
|
||||
iconResId = R.drawable.ic_sns_youtube
|
||||
),
|
||||
SnsItem(
|
||||
url = detail.instagramUrl.trim(),
|
||||
iconResId = R.drawable.ic_sns_instagram
|
||||
),
|
||||
SnsItem(
|
||||
url = detail.kakaoOpenChatUrl.trim(),
|
||||
iconResId = R.drawable.ic_sns_kakao
|
||||
),
|
||||
SnsItem(
|
||||
url = detail.fancimmUrl.trim(),
|
||||
iconResId = R.drawable.ic_sns_fancimm
|
||||
),
|
||||
SnsItem(
|
||||
url = detail.xUrl.trim(),
|
||||
iconResId = R.drawable.ic_sns_x
|
||||
)
|
||||
).filter { item ->
|
||||
item.url.isNotBlank() && URLUtil.isValidUrl(item.url)
|
||||
}
|
||||
|
||||
if (snsItems.isEmpty()) {
|
||||
dialogView.llSectionSns.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
dialogView.llSectionSns.visibility = View.VISIBLE
|
||||
dialogView.llSnsIcons.removeAllViews()
|
||||
|
||||
snsItems.forEachIndexed { index, item ->
|
||||
val imageView = ImageView(activity).apply {
|
||||
setImageResource(item.iconResId)
|
||||
layoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
if (index > 0) {
|
||||
marginStart = 12.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
setOnClickListener {
|
||||
openUrl(item.url)
|
||||
}
|
||||
}
|
||||
|
||||
dialogView.llSnsIcons.addView(imageView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun openUrl(url: String) {
|
||||
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
if (intent.resolveActivity(activity.packageManager) != null) {
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dismiss() {
|
||||
alertDialog.dismiss()
|
||||
}
|
||||
|
||||
fun show() {
|
||||
alertDialog.show()
|
||||
|
||||
val lp = WindowManager.LayoutParams()
|
||||
lp.copyFrom(alertDialog.window?.attributes)
|
||||
lp.width = screenWidth - (48.dpToPx()).toInt()
|
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
|
||||
alertDialog.window?.attributes = lp
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package kr.co.vividnext.sodalive.explorer.profile.detail
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kr.co.vividnext.sodalive.explorer.profile.GetCreatorActivitySummary
|
||||
|
||||
@Keep
|
||||
data class GetCreatorDetailResponse(
|
||||
@SerializedName("nickname") val nickname: String,
|
||||
@SerializedName("profileImageUrl") val profileImageUrl: String,
|
||||
@SerializedName("debutDate") val debutDate: String,
|
||||
@SerializedName("dday") val dDay: String,
|
||||
@SerializedName("activitySummary") val activitySummary: GetCreatorActivitySummary,
|
||||
@SerializedName("instagramUrl") val instagramUrl: String,
|
||||
@SerializedName("fancimmUrl") val fancimmUrl: String,
|
||||
@SerializedName("xurl") val xUrl: String,
|
||||
@SerializedName("youtubeUrl") val youtubeUrl: String,
|
||||
@SerializedName("kakaoOpenChatUrl") val kakaoOpenChatUrl: String
|
||||
)
|
||||
Reference in New Issue
Block a user