diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt index ef93d9b..4f1cfd4 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt @@ -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> + + @GET("/live/room/{id}/heart-list") + fun heartStatus( + @Path("id") id: Long, + @Header("Authorization") authHeader: String + ): Single> } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt index 5feab7c..2acea0a 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt @@ -256,4 +256,9 @@ class LiveRepository( roomId, authHeader = token ) + + fun heartStatus(roomId: Long, token: String) = api.heartStatus( + roomId, + authHeader = token + ) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt index 62091cc..6004f3f 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt @@ -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(ActivityLiveRoomB roomId = roomId ).show() } + binding.llHeart.setOnClickListener { + LiveRoomHeartRankingDialog( + activity = this, + layoutInflater = layoutInflater, + getHeartRanking = { viewModel.heartStatus(roomId, it) } + ).show() + } setupChatAdapter() setupSpeakerListAdapter() diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt index c4e50e8..7312568 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomViewModel.kt @@ -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 diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/GetLiveRoomHeartListResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/GetLiveRoomHeartListResponse.kt new file mode 100644 index 0000000..884a168 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/GetLiveRoomHeartListResponse.kt @@ -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, + @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 +) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/LiveRoomHeartRankingAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/LiveRoomHeartRankingAdapter.kt new file mode 100644 index 0000000..3788b2b --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/LiveRoomHeartRankingAdapter.kt @@ -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() { + val items = mutableListOf() + + 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 + } + } + } + } +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/LiveRoomHeartRankingDialog.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/LiveRoomHeartRankingDialog.kt new file mode 100644 index 0000000..0fd3a76 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/like/LiveRoomHeartRankingDialog.kt @@ -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() + } +} diff --git a/app/src/main/res/layout/dialog_live_room_heart_ranking.xml b/app/src/main/res/layout/dialog_live_room_heart_ranking.xml new file mode 100644 index 0000000..ea8288c --- /dev/null +++ b/app/src/main/res/layout/dialog_live_room_heart_ranking.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_live_room_heart_ranking.xml b/app/src/main/res/layout/item_live_room_heart_ranking.xml new file mode 100644 index 0000000..1ec0d49 --- /dev/null +++ b/app/src/main/res/layout/item_live_room_heart_ranking.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +