라이브 메인 - UI, Api 적용
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package kr.co.vividnext.sodalive.live
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class GetRoomListResponse(
|
||||
@SerializedName("roomId") val roomId: Long,
|
||||
@SerializedName("title") val title: String,
|
||||
@SerializedName("content") val content: String,
|
||||
@SerializedName("beginDateTime") val beginDateTime: String,
|
||||
@SerializedName("numberOfParticipate") val numberOfParticipate: Int,
|
||||
@SerializedName("numberOfPeople") val numberOfPeople: Int,
|
||||
@SerializedName("coverImageUrl") val coverImageUrl: String,
|
||||
@SerializedName("isAdult") val isAdult: Boolean,
|
||||
@SerializedName("price") val price: Int,
|
||||
@SerializedName("tags") val tags: List<String>,
|
||||
@SerializedName("channelName") val channelName: String?,
|
||||
@SerializedName("managerNickname") val managerNickname: String,
|
||||
@SerializedName("managerId") val managerId: Long,
|
||||
@SerializedName("isReservation") val isReservation: Boolean,
|
||||
@SerializedName("isPrivateRoom") val isPrivateRoom: Boolean
|
||||
)
|
20
app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt
Normal file
20
app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
package kr.co.vividnext.sodalive.live
|
||||
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface LiveApi {
|
||||
@GET("/live/room")
|
||||
fun roomList(
|
||||
@Query("timezone") timezone: String,
|
||||
@Query("dateString") dateString: String?,
|
||||
@Query("status") status: LiveRoomStatus,
|
||||
@Query("page") page: Int,
|
||||
@Query("size") size: Int,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Flowable<ApiResponse<List<GetRoomListResponse>>>
|
||||
}
|
@@ -1,7 +1,403 @@
|
||||
package kr.co.vividnext.sodalive.live
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.webkit.URLUtil
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.zhpan.bannerview.BaseBannerAdapter
|
||||
import com.zhpan.indicator.enums.IndicatorSlideMode
|
||||
import com.zhpan.indicator.enums.IndicatorStyle
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.FragmentLiveBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import kr.co.vividnext.sodalive.live.event_banner.EventBannerAdapter
|
||||
import kr.co.vividnext.sodalive.live.now.LiveNowAdapter
|
||||
import kr.co.vividnext.sodalive.live.recommend.RecommendLiveAdapter
|
||||
import kr.co.vividnext.sodalive.live.recommend_channel.LiveRecommendChannelAdapter
|
||||
import kr.co.vividnext.sodalive.live.reservation.LiveReservationAdapter
|
||||
import kr.co.vividnext.sodalive.settings.notification.MemberRole
|
||||
import org.koin.android.ext.android.inject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
|
||||
private val viewModel: LiveViewModel by inject()
|
||||
|
||||
private lateinit var liveNowAdapter: LiveNowAdapter
|
||||
private lateinit var liveReservationAdapter: LiveReservationAdapter
|
||||
private lateinit var liveRecommendChannelAdapter: LiveRecommendChannelAdapter
|
||||
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
|
||||
private var message = ""
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
setupView()
|
||||
setupRecommendLive()
|
||||
setupRecommendChannel()
|
||||
setupLiveNow()
|
||||
setupLiveReservation()
|
||||
setupEvent()
|
||||
|
||||
message = "라이브를 불러오고 있습니다."
|
||||
viewModel.getSummary()
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
||||
|
||||
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
||||
it?.let { Toast.makeText(requireActivity(), it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth, message)
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
binding.ivMakeRoom.visibility =
|
||||
if (SharedPreferenceManager.role == MemberRole.CREATOR.name) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
binding.ivMakeRoom.setOnClickListener {}
|
||||
|
||||
binding.swipeRefreshLayout.setOnRefreshListener { refreshSummary() }
|
||||
|
||||
val ivHowToUseLp = binding.ivHowToUse.layoutParams as LinearLayout.LayoutParams
|
||||
ivHowToUseLp.width = screenWidth
|
||||
ivHowToUseLp.height = (200 * screenWidth) / 1080
|
||||
binding.ivHowToUse.layoutParams = ivHowToUseLp
|
||||
binding.ivHowToUse.setOnClickListener {
|
||||
val url = "https://blog.naver.com/yozmlive"
|
||||
if (URLUtil.isValidUrl(url)) {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshSummary() {
|
||||
liveNowAdapter.clear()
|
||||
liveRecommendChannelAdapter.clear()
|
||||
liveReservationAdapter.clear()
|
||||
|
||||
message = "라이브를 불러오고 있습니다."
|
||||
viewModel.getSummary()
|
||||
|
||||
binding.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun setupRecommendLive() {
|
||||
val layoutParams = binding
|
||||
.layoutRecommendLive
|
||||
.pager
|
||||
.layoutParams as LinearLayout.LayoutParams
|
||||
|
||||
val pagerWidth = screenWidth.toDouble() - 26.7f.dpToPx()
|
||||
val pagerHeight = (pagerWidth * 0.53).roundToInt()
|
||||
layoutParams.width = pagerWidth.roundToInt()
|
||||
layoutParams.height = pagerHeight
|
||||
|
||||
binding
|
||||
.layoutRecommendLive
|
||||
.pager
|
||||
.layoutParams = layoutParams
|
||||
|
||||
binding.layoutRecommendLive.pager.apply {
|
||||
adapter = RecommendLiveAdapter(pagerWidth.roundToInt(), pagerHeight) {
|
||||
} as BaseBannerAdapter<Any>
|
||||
|
||||
setLifecycleRegistry(lifecycle)
|
||||
setScrollDuration(1000)
|
||||
setInterval(4 * 1000)
|
||||
}.create()
|
||||
|
||||
binding
|
||||
.layoutRecommendLive
|
||||
.pager
|
||||
.setIndicatorView(binding.layoutRecommendLive.indicator2)
|
||||
.setIndicatorStyle(IndicatorStyle.ROUND_RECT)
|
||||
.setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
|
||||
.setIndicatorVisibility(View.GONE)
|
||||
.setIndicatorSliderColor(
|
||||
ContextCompat.getColor(requireContext(), R.color.color_909090),
|
||||
ContextCompat.getColor(requireContext(), R.color.color_9970ff)
|
||||
)
|
||||
.setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
|
||||
.setIndicatorHeight(4f.dpToPx().toInt())
|
||||
|
||||
viewModel.recommendLiveData.observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty()) {
|
||||
binding.layoutRecommendLive.root.visibility = View.VISIBLE
|
||||
binding.layoutRecommendLive.pager.refreshData(it)
|
||||
} else {
|
||||
binding.layoutRecommendLive.root.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupRecommendChannel() {
|
||||
liveRecommendChannelAdapter = LiveRecommendChannelAdapter(
|
||||
onClick = {},
|
||||
onClickMore = {}
|
||||
)
|
||||
|
||||
binding.layoutRecommendChannel.rvRecommendChannel.layoutManager = LinearLayoutManager(
|
||||
requireContext(),
|
||||
LinearLayoutManager.HORIZONTAL,
|
||||
false
|
||||
)
|
||||
|
||||
binding
|
||||
.layoutRecommendChannel
|
||||
.rvRecommendChannel
|
||||
.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
|
||||
when (parent.getChildAdapterPosition(view)) {
|
||||
0 -> {
|
||||
outRect.left = 0.dpToPx().toInt()
|
||||
outRect.right = 8.3f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
liveRecommendChannelAdapter.itemCount - 1 -> {
|
||||
outRect.left = 8.3f.dpToPx().toInt()
|
||||
outRect.right = 0.dpToPx().toInt()
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.left = 8.3f.dpToPx().toInt()
|
||||
outRect.right = 8.3f.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
binding.layoutRecommendChannel.rvRecommendChannel.adapter = liveRecommendChannelAdapter
|
||||
binding.layoutRecommendChannel.ivSwitch.setOnClickListener {
|
||||
viewModel.toggleIsFollowedCreatorLive()
|
||||
}
|
||||
|
||||
viewModel.recommendChannelLiveData.observe(viewLifecycleOwner) {
|
||||
binding.layoutRecommendChannel.root.visibility = View.VISIBLE
|
||||
liveRecommendChannelAdapter.addItems(it)
|
||||
binding.layoutRecommendChannel.rvRecommendChannel.requestLayout()
|
||||
binding.layoutRecommendChannel.root.requestLayout()
|
||||
}
|
||||
|
||||
viewModel.isFollowedCreatorLive.observe(viewLifecycleOwner) {
|
||||
liveRecommendChannelAdapter.isFollowedCreatorLive = it
|
||||
liveRecommendChannelAdapter.clear()
|
||||
|
||||
if (it) {
|
||||
binding.layoutRecommendChannel.ivSwitch.setImageResource(R.drawable.btn_toggle_on_big)
|
||||
binding.layoutRecommendChannel.llTitle2.visibility = View.VISIBLE
|
||||
binding.layoutRecommendChannel.llTitle1.visibility = View.GONE
|
||||
} else {
|
||||
binding.layoutRecommendChannel.ivSwitch.setImageResource(R.drawable.btn_toggle_off_big)
|
||||
binding.layoutRecommendChannel.llTitle1.visibility = View.VISIBLE
|
||||
binding.layoutRecommendChannel.llTitle2.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun setupLiveNow() {
|
||||
binding
|
||||
.layoutLiveNow
|
||||
.tvAllView
|
||||
.setOnClickListener {}
|
||||
|
||||
val recyclerView = binding
|
||||
.layoutLiveNow
|
||||
.rvSudaNow
|
||||
|
||||
liveNowAdapter = LiveNowAdapter {}
|
||||
|
||||
recyclerView.layoutManager = LinearLayoutManager(
|
||||
requireContext(),
|
||||
LinearLayoutManager.HORIZONTAL,
|
||||
false
|
||||
)
|
||||
|
||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
|
||||
when (parent.getChildAdapterPosition(view)) {
|
||||
0 -> {
|
||||
outRect.left = 13.3f.dpToPx().toInt()
|
||||
outRect.right = 5.dpToPx().toInt()
|
||||
}
|
||||
|
||||
liveNowAdapter.itemCount - 1 -> {
|
||||
outRect.left = 5.dpToPx().toInt()
|
||||
outRect.right = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.left = 5.dpToPx().toInt()
|
||||
outRect.right = 5.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
recyclerView.adapter = liveNowAdapter
|
||||
|
||||
viewModel.liveNowLiveData.observe(viewLifecycleOwner) {
|
||||
if (liveNowAdapter.items.isEmpty() && it.isEmpty()) {
|
||||
recyclerView.visibility = View.GONE
|
||||
binding.layoutLiveNow.tvAllView.visibility = View.GONE
|
||||
binding.layoutLiveNow.llNoItems.visibility = View.VISIBLE
|
||||
binding.layoutLiveNow.tvMakeRoom.setOnClickListener {}
|
||||
|
||||
recyclerView.requestLayout()
|
||||
binding.layoutLiveNow.llNoItems.requestLayout()
|
||||
} else {
|
||||
binding.layoutLiveNow.tvAllView.visibility = View.VISIBLE
|
||||
binding.layoutLiveNow.llNoItems.visibility = View.GONE
|
||||
liveNowAdapter.items.addAll(it)
|
||||
liveNowAdapter.notifyDataSetChanged()
|
||||
recyclerView.visibility = View.VISIBLE
|
||||
recyclerView.requestLayout()
|
||||
}
|
||||
|
||||
binding.layoutLiveNow.root.requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun setupLiveReservation() {
|
||||
val recyclerView = binding
|
||||
.layoutLiveReservation
|
||||
.rvSudaReservation
|
||||
|
||||
liveReservationAdapter = LiveReservationAdapter(isMain = true) {}
|
||||
|
||||
recyclerView.layoutManager = LinearLayoutManager(
|
||||
requireContext(),
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false
|
||||
)
|
||||
|
||||
recyclerView.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 -> {
|
||||
outRect.top = 0f.dpToPx().toInt()
|
||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
liveReservationAdapter.itemCount - 1 -> {
|
||||
outRect.top = 6.7f.dpToPx().toInt()
|
||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.top = 6.7f.dpToPx().toInt()
|
||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
recyclerView.adapter = liveReservationAdapter
|
||||
|
||||
viewModel.liveReservationLiveData.observe(viewLifecycleOwner) {
|
||||
if (liveReservationAdapter.items.isEmpty() && it.isEmpty()) {
|
||||
recyclerView.visibility = View.GONE
|
||||
binding.layoutLiveReservation.tvAllView.visibility = View.GONE
|
||||
binding.layoutLiveReservation.llNoItems.visibility = View.VISIBLE
|
||||
binding.layoutLiveReservation.tvMakeRoom.setOnClickListener {}
|
||||
|
||||
recyclerView.requestLayout()
|
||||
binding.layoutLiveReservation.llNoItems.requestLayout()
|
||||
} else {
|
||||
binding.layoutLiveReservation.tvAllView.visibility = View.VISIBLE
|
||||
binding.layoutLiveReservation.llNoItems.visibility = View.GONE
|
||||
liveReservationAdapter.items.addAll(it)
|
||||
liveReservationAdapter.notifyDataSetChanged()
|
||||
|
||||
recyclerView.visibility = View.VISIBLE
|
||||
recyclerView.requestLayout()
|
||||
}
|
||||
|
||||
binding.layoutLiveReservation.root.requestLayout()
|
||||
}
|
||||
|
||||
binding.layoutLiveReservation.tvAllView.setOnClickListener {}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun setupEvent() {
|
||||
val imageSliderLp = binding.eventBannerSlider.layoutParams
|
||||
imageSliderLp.width = screenWidth
|
||||
imageSliderLp.height = (screenWidth * 300) / 1000
|
||||
binding.eventBannerSlider.layoutParams = imageSliderLp
|
||||
|
||||
binding.eventBannerSlider.apply {
|
||||
adapter = EventBannerAdapter(requireContext()) {} as BaseBannerAdapter<Any>
|
||||
setLifecycleRegistry(lifecycle)
|
||||
setScrollDuration(800)
|
||||
}.create()
|
||||
|
||||
binding.eventBannerSlider
|
||||
.setIndicatorView(binding.indicator)
|
||||
.setIndicatorStyle(IndicatorStyle.ROUND_RECT)
|
||||
.setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
|
||||
.setIndicatorVisibility(View.GONE)
|
||||
.setIndicatorSliderColor(
|
||||
ContextCompat.getColor(requireContext(), R.color.color_909090),
|
||||
ContextCompat.getColor(requireContext(), R.color.color_9970ff)
|
||||
)
|
||||
.setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
|
||||
.setIndicatorHeight(4f.dpToPx().toInt())
|
||||
|
||||
viewModel.eventLiveData.observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty()) {
|
||||
binding.eventBannerSlider.visibility = View.VISIBLE
|
||||
binding.eventBannerSlider.refreshData(it)
|
||||
} else {
|
||||
binding.eventBannerSlider.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,25 @@
|
||||
package kr.co.vividnext.sodalive.live
|
||||
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||
import java.util.TimeZone
|
||||
|
||||
class LiveRepository(private val api: LiveApi) {
|
||||
fun roomList(
|
||||
dateString: String? = null,
|
||||
status: LiveRoomStatus,
|
||||
page: Int,
|
||||
size: Int,
|
||||
token: String
|
||||
): Flowable<ApiResponse<List<GetRoomListResponse>>> {
|
||||
return api.roomList(
|
||||
timezone = TimeZone.getDefault().id,
|
||||
dateString = dateString,
|
||||
status = status,
|
||||
page = page - 1,
|
||||
size = size,
|
||||
authHeader = token
|
||||
)
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package kr.co.vividnext.sodalive.live
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.live.recommend.GetRecommendLiveResponse
|
||||
import kr.co.vividnext.sodalive.settings.event.GetEventResponse
|
||||
|
||||
data class LiveSummary(
|
||||
@SerializedName("liveNow") val liveNow: ApiResponse<List<GetRoomListResponse>>,
|
||||
@SerializedName("liveReservation") val liveReservation: ApiResponse<List<GetRoomListResponse>>,
|
||||
@SerializedName("event") val event: ApiResponse<GetEventResponse>,
|
||||
@SerializedName("recommendLive") val recommendLive: ApiResponse<List<GetRecommendLiveResponse>>,
|
||||
)
|
241
app/src/main/java/kr/co/vividnext/sodalive/live/LiveViewModel.kt
Normal file
241
app/src/main/java/kr/co/vividnext/sodalive/live/LiveViewModel.kt
Normal file
@@ -0,0 +1,241 @@
|
||||
package kr.co.vividnext.sodalive.live
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.orhanobut.logger.Logger
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
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.live.recommend.GetRecommendLiveResponse
|
||||
import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository
|
||||
import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||
import kr.co.vividnext.sodalive.settings.event.EventItem
|
||||
import kr.co.vividnext.sodalive.settings.event.EventRepository
|
||||
|
||||
class LiveViewModel(
|
||||
private val repository: LiveRepository,
|
||||
private val eventRepository: EventRepository,
|
||||
private val liveRecommendRepository: LiveRecommendRepository
|
||||
) : BaseViewModel() {
|
||||
private var _isLoading = MutableLiveData(false)
|
||||
val isLoading: LiveData<Boolean>
|
||||
get() = _isLoading
|
||||
|
||||
private val _toastLiveData = MutableLiveData<String?>()
|
||||
val toastLiveData: LiveData<String?>
|
||||
get() = _toastLiveData
|
||||
|
||||
private val _recommendLiveData = MutableLiveData<List<GetRecommendLiveResponse>>()
|
||||
val recommendLiveData: LiveData<List<GetRecommendLiveResponse>>
|
||||
get() = _recommendLiveData
|
||||
|
||||
private val _isFollowedCreatorLive = MutableLiveData(
|
||||
SharedPreferenceManager.isFollowedCreatorLive
|
||||
)
|
||||
val isFollowedCreatorLive: LiveData<Boolean>
|
||||
get() = _isFollowedCreatorLive
|
||||
|
||||
private val _recommendChannelLiveData = MutableLiveData<List<GetRecommendChannelResponse>>()
|
||||
val recommendChannelLiveData: LiveData<List<GetRecommendChannelResponse>>
|
||||
get() = _recommendChannelLiveData
|
||||
|
||||
private val _liveNowLiveData = MutableLiveData<List<GetRoomListResponse>>()
|
||||
val liveNowLiveData: LiveData<List<GetRoomListResponse>>
|
||||
get() = _liveNowLiveData
|
||||
|
||||
private val _liveReservationLiveData = MutableLiveData<List<GetRoomListResponse>>()
|
||||
val liveReservationLiveData: LiveData<List<GetRoomListResponse>>
|
||||
get() = _liveReservationLiveData
|
||||
|
||||
private val _eventLiveData = MutableLiveData<List<EventItem>>()
|
||||
val eventLiveData: LiveData<List<EventItem>>
|
||||
get() = _eventLiveData
|
||||
|
||||
var page = 1
|
||||
var isLast = false
|
||||
private val pageSize = 10
|
||||
|
||||
fun toggleIsFollowedCreatorLive() {
|
||||
val isOn = !_isFollowedCreatorLive.value!!
|
||||
SharedPreferenceManager.isFollowedCreatorLive = isOn
|
||||
_isFollowedCreatorLive.value = isOn
|
||||
if (_isFollowedCreatorLive.value!!) {
|
||||
getFollowedChannelList()
|
||||
} else {
|
||||
getRecommendChannelList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFollowedChannelList() {
|
||||
compositeDisposable.add(
|
||||
liveRecommendRepository.getFollowingChannelList(
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
_recommendChannelLiveData.postValue(it.data!!)
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getRecommendChannelList() {
|
||||
compositeDisposable.add(
|
||||
liveRecommendRepository.getRecommendChannelList(
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
_recommendChannelLiveData.postValue(it.data!!)
|
||||
} 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 getSummary() {
|
||||
if (!_isLoading.value!!) {
|
||||
if (_isFollowedCreatorLive.value!!) {
|
||||
getFollowedChannelList()
|
||||
} else {
|
||||
getRecommendChannelList()
|
||||
}
|
||||
|
||||
val liveNow = repository.roomList(
|
||||
status = LiveRoomStatus.NOW,
|
||||
page = 1,
|
||||
size = pageSize,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
|
||||
val liveReservation = repository.roomList(
|
||||
status = LiveRoomStatus.RESERVATION,
|
||||
page = 1,
|
||||
size = pageSize,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
|
||||
val event = eventRepository.getEvents(
|
||||
0,
|
||||
5,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
|
||||
val recommendLive = liveRecommendRepository.getRecommendLive(
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
|
||||
_isLoading.postValue(true)
|
||||
|
||||
compositeDisposable.add(
|
||||
Flowable.combineLatest(
|
||||
liveNow,
|
||||
liveReservation,
|
||||
event,
|
||||
recommendLive,
|
||||
) { t1, t2, t3, t4 -> LiveSummary(t1, t2, t3, t4) }
|
||||
.subscribe(
|
||||
{
|
||||
val now = it.liveNow
|
||||
if (now.success && now.data != null) {
|
||||
_liveNowLiveData.postValue(now.data!!)
|
||||
if (now.data.isNotEmpty()) {
|
||||
page += 1
|
||||
} else {
|
||||
isLast = true
|
||||
}
|
||||
} else {
|
||||
if (now.message != null) {
|
||||
_toastLiveData.postValue(now.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val reservation = it.liveReservation
|
||||
if (reservation.success && reservation.data != null) {
|
||||
_liveReservationLiveData.postValue(reservation.data!!)
|
||||
if (reservation.data.isNotEmpty()) {
|
||||
page += 1
|
||||
} else {
|
||||
isLast = true
|
||||
}
|
||||
} else {
|
||||
if (reservation.message != null) {
|
||||
_toastLiveData.postValue(reservation.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val eventResponse = it.event
|
||||
if (eventResponse.success && eventResponse.data != null) {
|
||||
val data = eventResponse.data
|
||||
_eventLiveData.postValue(data.eventList)
|
||||
} else {
|
||||
_eventLiveData.postValue(emptyList())
|
||||
}
|
||||
|
||||
val recommendLiveResponse = it.recommendLive
|
||||
if (
|
||||
recommendLiveResponse.success &&
|
||||
recommendLiveResponse.data != null
|
||||
) {
|
||||
val data = recommendLiveResponse.data
|
||||
_recommendLiveData.postValue(data!!)
|
||||
} else {
|
||||
_recommendLiveData.postValue(emptyList())
|
||||
}
|
||||
|
||||
_isLoading.postValue(false)
|
||||
},
|
||||
{
|
||||
_isLoading.postValue(false)
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package kr.co.vividnext.sodalive.live.event_banner
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.ImageView
|
||||
import coil.load
|
||||
import com.zhpan.bannerview.BaseBannerAdapter
|
||||
import com.zhpan.bannerview.BaseViewHolder
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.settings.event.EventItem
|
||||
|
||||
class EventBannerAdapter(
|
||||
private val context: Context,
|
||||
private val itemClick: (EventItem) -> Unit
|
||||
) : BaseBannerAdapter<EventItem>() {
|
||||
|
||||
override fun bindData(
|
||||
holder: BaseViewHolder<EventItem>,
|
||||
data: EventItem,
|
||||
position: Int,
|
||||
pageSize: Int
|
||||
) {
|
||||
val ivThumbnail = holder.findViewById<ImageView>(R.id.iv_thumbnail)
|
||||
ivThumbnail.load(data.thumbnailImageUrl) {
|
||||
crossfade(true)
|
||||
|
||||
val layoutParams = ivThumbnail.layoutParams
|
||||
val screenWidth = context.resources.displayMetrics.widthPixels
|
||||
layoutParams.width = screenWidth
|
||||
layoutParams.height = (screenWidth * 300) / 1000
|
||||
ivThumbnail.layoutParams = layoutParams
|
||||
}
|
||||
ivThumbnail.setOnClickListener { itemClick(data) }
|
||||
}
|
||||
|
||||
override fun getLayoutId(viewType: Int): Int {
|
||||
return R.layout.item_event_slider
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
package kr.co.vividnext.sodalive.live.now
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
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.ItemLiveNowBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import kr.co.vividnext.sodalive.live.GetRoomListResponse
|
||||
|
||||
class LiveNowAdapter(
|
||||
private val onClick: (GetRoomListResponse) -> Unit
|
||||
) : RecyclerView.Adapter<LiveNowAdapter.ViewHolder>() {
|
||||
|
||||
var items = mutableListOf<GetRoomListResponse>()
|
||||
|
||||
inner class ViewHolder(
|
||||
private val binding: ItemLiveNowBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(item: GetRoomListResponse) {
|
||||
binding.ivCover.load(item.coverImageUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
||||
}
|
||||
binding.tvManager.text = item.managerNickname
|
||||
binding.tvNumberOfMembers.text = "${item.numberOfParticipate}"
|
||||
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
|
||||
if (item.price > 0) {
|
||||
binding.tvPrice.text = "유료"
|
||||
binding.tvPrice.setBackgroundResource(R.drawable.bg_round_corner_10_881609)
|
||||
} else {
|
||||
binding.tvPrice.text = "무료"
|
||||
binding.tvPrice.setBackgroundResource(R.drawable.bg_round_corner_10_643bc8)
|
||||
}
|
||||
|
||||
binding.iv19.visibility = if (item.isAdult) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
|
||||
binding.root.setOnClickListener { onClick(item) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||
ItemLiveNowBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.count()
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun clear() {
|
||||
items.clear()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class GetRecommendLiveResponse(
|
||||
@SerializedName("imageUrl")
|
||||
val imageUrl: String,
|
||||
@SerializedName("creatorId")
|
||||
val creatorId: Long
|
||||
)
|
@@ -0,0 +1,25 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
|
||||
interface LiveRecommendApi {
|
||||
@GET("/live/recommend")
|
||||
fun getRecommendLive(
|
||||
@Header("Authorization") authHeader: String
|
||||
): Flowable<ApiResponse<List<GetRecommendLiveResponse>>>
|
||||
|
||||
@GET("/live/recommend/channel")
|
||||
fun getRecommendChannelList(
|
||||
@Header("Authorization") authHeader: String
|
||||
): Flowable<ApiResponse<List<GetRecommendChannelResponse>>>
|
||||
|
||||
@GET("/live/following/channel")
|
||||
fun getFollowingChannelList(
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<List<GetRecommendChannelResponse>>>
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
class LiveRecommendRepository(private val api: LiveRecommendApi) {
|
||||
fun getRecommendLive(token: String) = api.getRecommendLive(authHeader = token)
|
||||
fun getRecommendChannelList(token: String) = api.getRecommendChannelList(authHeader = token)
|
||||
fun getFollowingChannelList(token: String) = api.getFollowingChannelList(authHeader = token)
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.zhpan.bannerview.BaseBannerAdapter
|
||||
import com.zhpan.bannerview.BaseViewHolder
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
|
||||
class RecommendLiveAdapter(
|
||||
private val itemWidth: Int,
|
||||
private val itemHeight: Int,
|
||||
private val onClick: (Long) -> Unit
|
||||
) : BaseBannerAdapter<GetRecommendLiveResponse>() {
|
||||
override fun bindData(
|
||||
holder: BaseViewHolder<GetRecommendLiveResponse>,
|
||||
data: GetRecommendLiveResponse,
|
||||
position: Int,
|
||||
pageSize: Int
|
||||
) {
|
||||
val ivRecommendLive = holder.findViewById<ImageView>(R.id.iv_recommend_live)
|
||||
val layoutParams = ivRecommendLive.layoutParams as FrameLayout.LayoutParams
|
||||
|
||||
layoutParams.width = itemWidth
|
||||
layoutParams.height = itemHeight
|
||||
|
||||
ivRecommendLive.load(data.imageUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(RoundedCornersTransformation(5.3f.dpToPx()))
|
||||
}
|
||||
ivRecommendLive.layoutParams = layoutParams
|
||||
ivRecommendLive.setOnClickListener { onClick(data.creatorId) }
|
||||
}
|
||||
|
||||
override fun getLayoutId(viewType: Int): Int {
|
||||
return R.layout.item_recommend_live
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend_channel
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class GetRecommendChannelResponse(
|
||||
@SerializedName("creatorId")
|
||||
val creatorId: Long,
|
||||
@SerializedName("nickname")
|
||||
val nickname: String,
|
||||
@SerializedName("profileImageUrl")
|
||||
val profileImageUrl: String,
|
||||
@SerializedName("isOnAir")
|
||||
val isOnAir: Boolean
|
||||
)
|
@@ -0,0 +1,142 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend_channel
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.databinding.ItemRecommendChannelBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
|
||||
class LiveRecommendChannelAdapter(
|
||||
private val onClick: (Long) -> Unit,
|
||||
private val onClickMore: () -> Unit,
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
var isFollowedCreatorLive = false
|
||||
|
||||
private val items = mutableListOf<GetRecommendChannelResponse>()
|
||||
|
||||
class FooterViewHolder(
|
||||
private val binding: ItemRecommendChannelBinding,
|
||||
private val onClickItem: () -> Unit
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind() {
|
||||
binding.ivRecommendChannel.setImageResource(R.drawable.btn_item_more)
|
||||
binding.tvRecommendChannelNickname.text = "더보기"
|
||||
|
||||
val layoutParams = binding.ivRecommendChannel.layoutParams as FrameLayout.LayoutParams
|
||||
layoutParams.width = 60f.dpToPx().toInt()
|
||||
layoutParams.height = 60f.dpToPx().toInt()
|
||||
|
||||
binding.ivRecommendChannel.layoutParams = layoutParams
|
||||
binding.ivRecommendChannelBg.layoutParams = layoutParams
|
||||
|
||||
binding.tvRecommendChannel.visibility = View.GONE
|
||||
binding.ivRecommendChannelBg.visibility = View.GONE
|
||||
binding.root.setOnClickListener { onClickItem() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val VIEW_TYPE = 1
|
||||
}
|
||||
}
|
||||
|
||||
class ViewHolder(
|
||||
private val binding: ItemRecommendChannelBinding,
|
||||
private val onClickItem: (Long) -> Unit
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(item: GetRecommendChannelResponse) {
|
||||
binding.ivRecommendChannel.load(item.profileImageUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(RoundedCornersTransformation(30f.dpToPx()))
|
||||
}
|
||||
binding.tvRecommendChannelNickname.text = item.nickname
|
||||
|
||||
val layoutParams = binding.ivRecommendChannel.layoutParams as FrameLayout.LayoutParams
|
||||
layoutParams.width = 60f.dpToPx().toInt()
|
||||
layoutParams.height = 60f.dpToPx().toInt()
|
||||
|
||||
binding.ivRecommendChannel.layoutParams = layoutParams
|
||||
binding.ivRecommendChannelBg.layoutParams = layoutParams
|
||||
|
||||
if (item.isOnAir) {
|
||||
binding.tvRecommendChannel.visibility = View.VISIBLE
|
||||
binding.ivRecommendChannelBg.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.tvRecommendChannel.visibility = View.GONE
|
||||
binding.ivRecommendChannelBg.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.root.setOnClickListener { onClickItem(item.creatorId) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val VIEW_TYPE = 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return if (viewType == FooterViewHolder.VIEW_TYPE) {
|
||||
FooterViewHolder(
|
||||
ItemRecommendChannelBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
),
|
||||
onClickItem = onClickMore
|
||||
)
|
||||
} else {
|
||||
ViewHolder(
|
||||
ItemRecommendChannelBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
),
|
||||
onClickItem = onClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
if (holder is FooterViewHolder) {
|
||||
holder.bind()
|
||||
} else {
|
||||
(holder as ViewHolder).bind(items[position])
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return if (isFollowedCreatorLive) {
|
||||
items.size + 1
|
||||
} else {
|
||||
items.size
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (position == items.size) {
|
||||
FooterViewHolder.VIEW_TYPE
|
||||
} else {
|
||||
ViewHolder.VIEW_TYPE
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun clear() {
|
||||
items.clear()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun addItems(items: List<GetRecommendChannelResponse>) {
|
||||
this.items.addAll(items)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
package kr.co.vividnext.sodalive.live.reservation
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
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.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.ItemLiveReservationBinding
|
||||
import kr.co.vividnext.sodalive.databinding.ItemMyLiveReservationBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||
import kr.co.vividnext.sodalive.live.GetRoomListResponse
|
||||
|
||||
class LiveReservationAdapter(
|
||||
private val isMain: Boolean = false,
|
||||
private val onClick: (GetRoomListResponse) -> Unit
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
var items = mutableListOf<GetRoomListResponse>()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return if (viewType == 1) {
|
||||
MyLiveViewHolder(
|
||||
ItemMyLiveReservationBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
} else {
|
||||
ViewHolder(
|
||||
ItemLiveReservationBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
if (isMyLive(item)) {
|
||||
(holder as MyLiveViewHolder).bind(item, position)
|
||||
} else {
|
||||
(holder as ViewHolder).bind(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.count()
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (isMyLive(items[position])) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
private fun isMyLive(item: GetRoomListResponse) =
|
||||
item.managerId == SharedPreferenceManager.userId && isMain
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun clear() {
|
||||
items.clear()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
inner class ViewHolder(
|
||||
private val binding: ItemLiveReservationBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(item: GetRoomListResponse) {
|
||||
binding.ivCover.load(item.coverImageUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
||||
}
|
||||
binding.tvDate.text = item.beginDateTime
|
||||
binding.tvNickname.text = item.managerNickname
|
||||
binding.tvTitle.text = item.title
|
||||
binding.root.setOnClickListener { onClick(item) }
|
||||
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
|
||||
if (item.isReservation) {
|
||||
binding.tvPrice.visibility = View.GONE
|
||||
binding.tvCompleteReservation.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.tvPrice.visibility = View.VISIBLE
|
||||
binding.tvCompleteReservation.visibility = View.GONE
|
||||
|
||||
binding.tvPrice.text = if (item.price <= 0) {
|
||||
"무료"
|
||||
} else {
|
||||
"${item.price.moneyFormat()}코인"
|
||||
}
|
||||
}
|
||||
|
||||
binding.iv19.visibility = if (item.isAdult) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class MyLiveViewHolder(
|
||||
private val binding: ItemMyLiveReservationBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(item: GetRoomListResponse, position: Int) {
|
||||
binding.tvMyLive.visibility = if (position == 0) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
binding.ivCover.load(item.coverImageUrl) {
|
||||
crossfade(true)
|
||||
placeholder(R.drawable.bg_placeholder)
|
||||
transformations(RoundedCornersTransformation(4f.dpToPx()))
|
||||
}
|
||||
binding.tvDate.text = item.beginDateTime
|
||||
binding.tvNickname.text = item.managerNickname
|
||||
binding.tvTitle.text = item.title
|
||||
binding.root.setOnClickListener { onClick(item) }
|
||||
|
||||
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
|
||||
binding.iv19.visibility = if (item.isAdult) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package kr.co.vividnext.sodalive.live.room
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
enum class LiveRoomStatus {
|
||||
@SerializedName("NOW") NOW,
|
||||
@SerializedName("RESERVATION") RESERVATION
|
||||
}
|
Reference in New Issue
Block a user