하트 랭킹 추가

This commit is contained in:
2024-11-12 00:32:21 +09:00
parent c15e9c203e
commit 3136b47838
9 changed files with 523 additions and 0 deletions

View File

@@ -24,6 +24,7 @@ import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationRequest
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationResponse
import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse
import kr.co.vividnext.sodalive.live.room.kick_out.LiveRoomKickOutRequest
import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartListResponse
import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartTotalResponse
import kr.co.vividnext.sodalive.live.room.like.LiveRoomLikeHeartRequest
import kr.co.vividnext.sodalive.live.room.profile.GetLiveRoomUserProfileResponse
@@ -226,4 +227,10 @@ interface LiveApi {
@Path("id") id: Long,
@Header("Authorization") authHeader: String
): Single<ApiResponse<GetLiveRoomHeartTotalResponse>>
@GET("/live/room/{id}/heart-list")
fun heartStatus(
@Path("id") id: Long,
@Header("Authorization") authHeader: String
): Single<ApiResponse<GetLiveRoomHeartListResponse>>
}

View File

@@ -256,4 +256,9 @@ class LiveRepository(
roomId,
authHeader = token
)
fun heartStatus(roomId: Long, token: String) = api.heartStatus(
roomId,
authHeader = token
)
}

View File

@@ -87,6 +87,7 @@ import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessageViewMo
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationRankingDialog
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationResponse
import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse
import kr.co.vividnext.sodalive.live.room.like.LiveRoomHeartRankingDialog
import kr.co.vividnext.sodalive.live.room.profile.LiveRoomProfileDialog
import kr.co.vividnext.sodalive.live.room.profile.LiveRoomProfileListAdapter
import kr.co.vividnext.sodalive.live.room.profile.LiveRoomUserProfileDialog
@@ -538,6 +539,13 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
roomId = roomId
).show()
}
binding.llHeart.setOnClickListener {
LiveRoomHeartRankingDialog(
activity = this,
layoutInflater = layoutInflater,
getHeartRanking = { viewModel.heartStatus(roomId, it) }
).show()
}
setupChatAdapter()
setupSpeakerListAdapter()

View File

@@ -21,6 +21,7 @@ import kr.co.vividnext.sodalive.live.LiveRepository
import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationStatusResponse
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationResponse
import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse
import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartListResponse
import kr.co.vividnext.sodalive.live.room.menu.GetMenuPresetResponse
import kr.co.vividnext.sodalive.live.room.profile.GetLiveRoomUserProfileResponse
import kr.co.vividnext.sodalive.live.room.update.EditLiveRoomInfoRequest
@@ -716,6 +717,34 @@ class LiveRoomViewModel(
)
}
fun heartStatus(roomId: Long, onSuccess: (GetLiveRoomHeartListResponse) -> Unit) {
_isLoading.value = true
compositeDisposable.add(
repository.heartStatus(roomId, token = "Bearer ${SharedPreferenceManager.token}")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
_isLoading.value = false
if (it.success && it.data != null) {
onSuccess(it.data)
} else {
_toastLiveData.postValue(
"하트 현황을 가져오지 못했습니다\n다시 시도해 주세요."
)
}
},
{
_isLoading.value = false
it.message?.let { message -> Logger.e(message) }
_toastLiveData.postValue(
"하트 현황을 가져오지 못했습니다\n다시 시도해 주세요."
)
}
)
)
}
fun getUserRank(userId: Long): Int {
// 방장 -> -2
// 스탭 -> -3

View File

@@ -0,0 +1,18 @@
package kr.co.vividnext.sodalive.live.room.like
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
@Keep
data class GetLiveRoomHeartListResponse(
@SerializedName("heartList") val heartList: List<GetLiveRoomHeartListItem>,
@SerializedName("totalCount") val totalCount: Int,
@SerializedName("totalHeart") val totalHeart: Int
)
@Keep
data class GetLiveRoomHeartListItem(
@SerializedName("profileImage") val profileImage: String,
@SerializedName("nickname") val nickname: String,
@SerializedName("heart") val heart: Int
)

View File

@@ -0,0 +1,144 @@
package kr.co.vividnext.sodalive.live.room.like
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.databinding.ItemLiveRoomHeartRankingBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.extensions.moneyFormat
class LiveRoomHeartRankingAdapter :
RecyclerView.Adapter<LiveRoomHeartRankingAdapter.ViewHolder>() {
val items = mutableListOf<GetLiveRoomHeartListItem>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
parent.context,
ItemLiveRoomHeartRankingBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position], position)
}
override fun getItemCount() = items.count()
inner class ViewHolder(
private val context: Context,
private val binding: ItemLiveRoomHeartRankingBinding
) : RecyclerView.ViewHolder(binding.root) {
@SuppressLint("SetTextI18n")
fun bind(item: GetLiveRoomHeartListItem, position: Int) {
binding.tvRank.text = "${position + 1}"
binding.tvNickname.text = item.nickname
binding.tvHeart.text = item.heart.moneyFormat()
binding.ivProfile.load(item.profileImage) {
crossfade(true)
placeholder(R.drawable.ic_place_holder)
transformations(CircleCropTransformation())
}
val lp = binding.rlHeartRanking.layoutParams as FrameLayout.LayoutParams
when (position) {
0 -> {
binding.ivBg.setImageResource(R.drawable.bg_circle_ffdc00_ffb600)
binding.ivBg.visibility = View.VISIBLE
binding.ivCrown.setImageResource(R.drawable.ic_crown_1)
binding.ivCrown.visibility = View.VISIBLE
binding.root.setBackgroundResource(
if (items.size == 1) {
R.drawable.bg_round_corner_4_7_13181b
} else {
R.drawable.bg_top_round_corner_4_7_13181b
}
)
lp.setMargins(
0,
20.dpToPx().toInt(),
0,
if (items.size == 1) {
20.dpToPx().toInt()
} else {
13.3f.dpToPx().toInt()
}
)
binding.rlHeartRanking.layoutParams = lp
}
1 -> {
binding.ivBg.setImageResource(R.drawable.bg_circle_ffffff_9f9f9f)
binding.ivBg.visibility = View.VISIBLE
binding.ivCrown.setImageResource(R.drawable.ic_crown_2)
binding.ivCrown.visibility = View.VISIBLE
if (items.size == 2) {
binding.root.setBackgroundResource(
R.drawable.bg_bottom_round_corner_4_7_13181b
)
} else {
binding.root.setBackgroundColor(
ContextCompat.getColor(context, R.color.color_13181b)
)
}
lp.setMargins(
0,
0,
0,
if (items.size == 2) {
20.dpToPx().toInt()
} else {
13.3f.dpToPx().toInt()
}
)
binding.rlHeartRanking.layoutParams = lp
}
2 -> {
binding.ivBg.setImageResource(R.drawable.bg_circle_e6a77a_c67e4a)
binding.ivBg.visibility = View.VISIBLE
binding.ivCrown.setImageResource(R.drawable.ic_crown_3)
binding.ivCrown.visibility = View.VISIBLE
binding.root.setBackgroundResource(
R.drawable.bg_bottom_round_corner_4_7_13181b
)
lp.setMargins(
0,
0,
0,
20.dpToPx().toInt()
)
binding.rlHeartRanking.layoutParams = lp
}
else -> {
binding.ivBg.setImageResource(0)
binding.ivBg.visibility = View.GONE
binding.ivCrown.visibility = View.GONE
binding.root.setBackgroundResource(0)
binding.root.background = null
lp.setMargins(0, 0, 0, 0)
binding.rlHeartRanking.layoutParams = lp
}
}
}
}
}

View File

@@ -0,0 +1,85 @@
package kr.co.vividnext.sodalive.live.room.like
import android.annotation.SuppressLint
import android.graphics.Rect
import android.view.LayoutInflater
import android.view.View
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog
import kr.co.vividnext.sodalive.databinding.DialogLiveRoomHeartRankingBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.extensions.moneyFormat
@SuppressLint("NotifyDataSetChanged")
class LiveRoomHeartRankingDialog(
private val activity: FragmentActivity,
layoutInflater: LayoutInflater,
getHeartRanking: ((GetLiveRoomHeartListResponse) -> Unit) -> Unit
) {
private val bottomSheetDialog: BottomSheetDialog = BottomSheetDialog(activity)
private val dialogView = DialogLiveRoomHeartRankingBinding.inflate(layoutInflater)
private val adapter = LiveRoomHeartRankingAdapter()
init {
bottomSheetDialog.setContentView(dialogView.root)
bottomSheetDialog.setCancelable(false)
dialogView.ivClose.setOnClickListener { bottomSheetDialog.dismiss() }
setupRecyclerView()
getHeartRanking {
adapter.items.clear()
adapter.items.addAll(it.heartList)
adapter.notifyDataSetChanged()
dialogView.tvTotalHeart.text = it.totalHeart.moneyFormat()
dialogView.tvTotalCount.text = it.totalCount.moneyFormat()
}
}
private fun setupRecyclerView() {
dialogView.rvHeartRanking.layoutManager = LinearLayoutManager(
activity,
LinearLayoutManager.VERTICAL,
false
)
dialogView.rvHeartRanking.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, 1, 2 -> {
outRect.top = 0
outRect.bottom = 0
}
3 -> {
outRect.top = 20.dpToPx().toInt()
outRect.bottom = 6.7f.dpToPx().toInt()
}
else -> {
outRect.top = 6.7f.dpToPx().toInt()
outRect.bottom = 6.7f.dpToPx().toInt()
}
}
}
})
dialogView.rvHeartRanking.adapter = adapter
}
fun show() {
bottomSheetDialog.show()
}
}