From a7ef5a81476826b7e7bf335c8ae073197c450cb3 Mon Sep 17 00:00:00 2001 From: klaus Date: Tue, 13 Feb 2024 00:34:34 +0900 Subject: [PATCH] =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20-=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EB=8A=94=20=EC=98=88=EC=95=BD=EC=9E=90(=EC=B0=B8=EC=97=AC?= =?UTF-8?q?=EC=9E=90)=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../live/room/detail/LiveRoomDetailAdapter.kt | 50 +++++++++ .../room/detail/LiveRoomDetailFragment.kt | 104 ++++++++++++++++++ .../res/layout/fragment_live_room_detail.xml | 96 ++++++++++++++++ .../layout/item_live_detail_user_summary.xml | 8 ++ .../res/layout/item_live_room_detail_user.xml | 1 + 5 files changed, 259 insertions(+) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailAdapter.kt create mode 100644 app/src/main/res/layout/item_live_detail_user_summary.xml diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailAdapter.kt new file mode 100644 index 0000000..7a64b1c --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailAdapter.kt @@ -0,0 +1,50 @@ +package kr.co.vividnext.sodalive.live.room.detail + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import coil.load +import coil.transform.RoundedCornersTransformation +import kr.co.vividnext.sodalive.R +import kr.co.vividnext.sodalive.databinding.ItemLiveRoomDetailUserBinding +import kr.co.vividnext.sodalive.extensions.dpToPx + +class LiveRoomDetailAdapter( + private val onClick: (GetRoomDetailUser) -> Unit +) : RecyclerView.Adapter() { + + val items = mutableListOf() + + inner class ViewHolder( + private val binding: ItemLiveRoomDetailUserBinding + ) : RecyclerView.ViewHolder(binding.root) { + fun bind(item: GetRoomDetailUser) { + binding.tvNickname.text = item.nickname + binding.ivProfile.load(item.profileImageUrl) { + crossfade(true) + placeholder(R.drawable.ic_place_holder) + transformations(RoundedCornersTransformation(23.4f.dpToPx())) + } + binding.root.setOnClickListener { onClick(item) } + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ViewHolder { + return ViewHolder( + ItemLiveRoomDetailUserBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(items[position]) + } + + override fun getItemCount() = items.count() +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailFragment.kt index 45d5b8a..46f44dc 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailFragment.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/detail/LiveRoomDetailFragment.kt @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.live.room.detail import android.annotation.SuppressLint import android.content.Intent +import android.graphics.Rect import android.net.Uri import android.os.Bundle import android.view.LayoutInflater @@ -9,9 +10,13 @@ import android.view.View import android.view.ViewGroup import android.webkit.URLUtil import android.widget.FrameLayout +import android.widget.LinearLayout import android.widget.Toast +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView import coil.load import coil.transform.CircleCropTransformation +import coil.transform.RoundedCornersTransformation import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialogFragment import kr.co.vividnext.sodalive.R @@ -19,8 +24,10 @@ 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.FragmentLiveRoomDetailBinding +import kr.co.vividnext.sodalive.databinding.ItemLiveDetailUserSummaryBinding import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity import kr.co.vividnext.sodalive.extensions.convertDateFormat +import kr.co.vividnext.sodalive.extensions.dpToPx import org.koin.android.ext.android.inject import java.util.Locale @@ -36,7 +43,9 @@ class LiveRoomDetailFragment( private val viewModel: LiveRoomDetailViewModel by inject() private lateinit var binding: FragmentLiveRoomDetailBinding + private var isAllProfileOpen = false + private lateinit var adapter: LiveRoomDetailAdapter private lateinit var loadingDialog: LoadingDialog private lateinit var roomDetail: GetRoomDetailResponse @@ -59,11 +68,33 @@ class LiveRoomDetailFragment( val behavior = BottomSheetBehavior.from(bottomSheet!!) behavior.state = BottomSheetBehavior.STATE_EXPANDED + setupAdapter() bindData() binding.ivClose.setOnClickListener { dismiss() } viewModel.getDetail(roomId) { dismiss() } } + private fun setupAdapter() { + val recyclerView = binding.rvParticipate + adapter = LiveRoomDetailAdapter {} + + recyclerView.layoutManager = GridLayoutManager(requireContext(), 5) + recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() { + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + super.getItemOffsets(outRect, view, parent, state) + + outRect.top = 13.3f.dpToPx().toInt() + outRect.bottom = 13.3f.dpToPx().toInt() + } + }) + recyclerView.adapter = adapter + } + private fun bindData() { viewModel.isLoading.observe(viewLifecycleOwner) { if (it) { @@ -125,6 +156,7 @@ class LiveRoomDetailFragment( binding.ivShare2.setOnClickListener { shareRoom(response) } if (response.channelName.isNullOrBlank()) { + binding.tvParticipateExpression.text = "예약자" when { response.manager.id == SharedPreferenceManager.userId -> { binding.llStartDelete.visibility = View.VISIBLE @@ -173,6 +205,52 @@ class LiveRoomDetailFragment( } binding.llStartDelete.visibility = View.GONE } + + if (response.manager.id == SharedPreferenceManager.userId) { + setParticipantUserSummary(response.participatingUsers) + + binding.llParticipateWrapper.visibility = View.VISIBLE + binding.tvParticipate.text = response.numberOfParticipants.toString() + binding.tvTotal.text = "/${response.numberOfParticipantsTotal}" + + binding.tvOpenAllProfile.visibility = if (response.numberOfParticipants <= 0) { + View.GONE + } else { + View.VISIBLE + } + + binding.tvOpenAllProfile.setOnClickListener { + isAllProfileOpen = !isAllProfileOpen + if (isAllProfileOpen) { + binding.llProfiles.visibility = View.GONE + binding.rvParticipate.visibility = View.VISIBLE + binding.tvParticipateExpression.visibility = View.VISIBLE + binding.tvOpenAllProfile.text = "닫기" + binding.tvOpenAllProfile.setCompoundDrawablesWithIntrinsicBounds( + R.drawable.ic_live_detail_top, + 0, + 0, + 0 + ) + } else { + binding.llProfiles.visibility = View.VISIBLE + binding.rvParticipate.visibility = View.GONE + binding.tvParticipateExpression.visibility = View.GONE + binding.tvOpenAllProfile.text = "펼쳐보기" + binding.tvOpenAllProfile.setCompoundDrawablesWithIntrinsicBounds( + R.drawable.ic_live_detail_bottom, + 0, + 0, + 0 + ) + } + } + + adapter.items.addAll(response.participatingUsers) + adapter.notifyDataSetChanged() + } else { + binding.llParticipateWrapper.visibility = View.GONE + } } private fun setManagerProfile(manager: GetRoomDetailManager) { @@ -244,6 +322,32 @@ class LiveRoomDetailFragment( } } + private fun setParticipantUserSummary(participatingUsers: List) { + val userCount = if (participatingUsers.size > 10) { + 10 + } else { + participatingUsers.size + } + + for (index in 0 until userCount) { + val user = participatingUsers[index] + val itemView = ItemLiveDetailUserSummaryBinding.inflate(layoutInflater) + itemView.ivProfile.load(user.profileImageUrl) { + crossfade(true) + placeholder(R.drawable.ic_place_holder) + transformations(RoundedCornersTransformation(16.7f.dpToPx())) + } + + val lp = LinearLayout.LayoutParams(33.3f.dpToPx().toInt(), 33.3f.dpToPx().toInt()) + if (index > 0) { + lp.setMargins(-16.7f.dpToPx().toInt(), 0, 0, 0) + } + itemView.root.layoutParams = lp + + binding.llProfiles.addView(itemView.root) + } + } + private fun shareRoom(response: GetRoomDetailResponse) { viewModel.shareRoomLink( response.roomId, diff --git a/app/src/main/res/layout/fragment_live_room_detail.xml b/app/src/main/res/layout/fragment_live_room_detail.xml index 7c7497d..b8e32f0 100644 --- a/app/src/main/res/layout/fragment_live_room_detail.xml +++ b/app/src/main/res/layout/fragment_live_room_detail.xml @@ -91,6 +91,102 @@ tools:text="300" /> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_live_room_detail_user.xml b/app/src/main/res/layout/item_live_room_detail_user.xml index a6c9d7c..483cafc 100644 --- a/app/src/main/res/layout/item_live_room_detail_user.xml +++ b/app/src/main/res/layout/item_live_room_detail_user.xml @@ -20,6 +20,7 @@ android:layout_height="wrap_content" android:ellipsize="end" android:fontFamily="@font/gmarket_sans_medium" + android:layout_marginTop="8dp" android:lines="1" android:textColor="@color/color_bbbbbb" android:textSize="12sp"