refactor(creator): 라이브 sort popup을 공통 컴포넌트로 전환한다
This commit is contained in:
@@ -12,11 +12,11 @@ import kr.co.vividnext.sodalive.databinding.FragmentCreatorChannelLiveBinding
|
|||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelLiveResponse
|
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelLiveResponse
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.model.toLabelResId
|
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.model.toReplayUiModel
|
import kr.co.vividnext.sodalive.v2.creator.channel.live.model.toReplayUiModel
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.ui.CreatorChannelLiveReplayAdapter
|
import kr.co.vividnext.sodalive.v2.creator.channel.live.ui.CreatorChannelLiveReplayAdapter
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.ui.CreatorChannelLiveSortPopup
|
import kr.co.vividnext.sodalive.v2.creator.channel.model.toLabelResId
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.ui.formatCreatorChannelLiveDateTime
|
import kr.co.vividnext.sodalive.v2.creator.channel.ui.formatCreatorChannelLiveDateTime
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.ui.CreatorChannelSortPopup
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
class CreatorChannelLiveFragment : BaseFragment<FragmentCreatorChannelLiveBinding>(
|
class CreatorChannelLiveFragment : BaseFragment<FragmentCreatorChannelLiveBinding>(
|
||||||
@@ -28,7 +28,7 @@ class CreatorChannelLiveFragment : BaseFragment<FragmentCreatorChannelLiveBindin
|
|||||||
host.onCreatorChannelLiveReplayClicked(item.audioContentId)
|
host.onCreatorChannelLiveReplayClicked(item.audioContentId)
|
||||||
}
|
}
|
||||||
private var lastContentLayoutKey: CreatorChannelLiveContentLayoutKey? = null
|
private var lastContentLayoutKey: CreatorChannelLiveContentLayoutKey? = null
|
||||||
private var sortPopup: CreatorChannelLiveSortPopup? = null
|
private var sortPopup: CreatorChannelSortPopup? = null
|
||||||
private var currentContentState: CreatorChannelLiveUiState.Content? = null
|
private var currentContentState: CreatorChannelLiveUiState.Content? = null
|
||||||
private var emptyMinHeight: Int = 0
|
private var emptyMinHeight: Int = 0
|
||||||
private val creatorId: Long by lazy { arguments?.getLong(ARG_CREATOR_ID) ?: 0L }
|
private val creatorId: Long by lazy { arguments?.getLong(ARG_CREATOR_ID) ?: 0L }
|
||||||
@@ -162,7 +162,7 @@ class CreatorChannelLiveFragment : BaseFragment<FragmentCreatorChannelLiveBindin
|
|||||||
|
|
||||||
private fun showSortPopup(state: CreatorChannelLiveUiState.Content) {
|
private fun showSortPopup(state: CreatorChannelLiveUiState.Content) {
|
||||||
sortPopup?.dismiss()
|
sortPopup?.dismiss()
|
||||||
sortPopup = CreatorChannelLiveSortPopup(
|
sortPopup = CreatorChannelSortPopup(
|
||||||
anchor = binding.layoutCreatorChannelLiveSortButton,
|
anchor = binding.layoutCreatorChannelLiveSortButton,
|
||||||
selectedSort = state.selectedSort,
|
selectedSort = state.selectedSort,
|
||||||
onSortSelected = { sort -> viewModel.changeSort(sort) }
|
onSortSelected = { sort -> viewModel.changeSort(sort) }
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.creator.channel.live.model
|
package kr.co.vividnext.sodalive.v2.creator.channel.live.model
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
|
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
|
||||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
|
|
||||||
@@ -18,22 +15,6 @@ fun CreatorChannelAudioContentResponse.toReplayUiModel(): CreatorChannelLiveRepl
|
|||||||
status = toReplayStatus()
|
status = toReplayStatus()
|
||||||
)
|
)
|
||||||
|
|
||||||
@StringRes
|
|
||||||
fun ContentSort.toLabelResId(): Int = when (this) {
|
|
||||||
ContentSort.LATEST -> R.string.screen_audio_content_sort_newest
|
|
||||||
ContentSort.POPULAR -> R.string.screen_audio_content_sort_popularity
|
|
||||||
ContentSort.OWNED -> R.string.creator_channel_live_sort_owned
|
|
||||||
ContentSort.PRICE_HIGH -> R.string.screen_audio_content_sort_price_high
|
|
||||||
ContentSort.PRICE_LOW -> R.string.screen_audio_content_sort_price_low
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ContentSort.toSortOptionUiModel(selectedSort: ContentSort): CreatorChannelLiveSortOptionUiModel =
|
|
||||||
CreatorChannelLiveSortOptionUiModel(
|
|
||||||
sort = this,
|
|
||||||
labelResId = toLabelResId(),
|
|
||||||
isSelected = this == selectedSort
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun CreatorChannelAudioContentResponse.toAudioContentTags(): Set<AudioContentTag> = buildSet {
|
private fun CreatorChannelAudioContentResponse.toAudioContentTags(): Set<AudioContentTag> = buildSet {
|
||||||
if (isOriginalSeries == true) add(AudioContentTag.Original)
|
if (isOriginalSeries == true) add(AudioContentTag.Original)
|
||||||
if (isFirstContent) add(AudioContentTag.First)
|
if (isFirstContent) add(AudioContentTag.First)
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.creator.channel.live.model
|
package kr.co.vividnext.sodalive.v2.creator.channel.live.model
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
|
||||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
|
|
||||||
data class CreatorChannelLiveReplayUiModel(
|
data class CreatorChannelLiveReplayUiModel(
|
||||||
@@ -21,9 +19,3 @@ sealed interface CreatorChannelLiveReplayStatus {
|
|||||||
data object Rented : CreatorChannelLiveReplayStatus
|
data object Rented : CreatorChannelLiveReplayStatus
|
||||||
data class Price(val price: Int) : CreatorChannelLiveReplayStatus
|
data class Price(val price: Int) : CreatorChannelLiveReplayStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
data class CreatorChannelLiveSortOptionUiModel(
|
|
||||||
val sort: ContentSort,
|
|
||||||
@param:StringRes val labelResId: Int,
|
|
||||||
val isSelected: Boolean
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.creator.channel.live.ui
|
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.graphics.Outline
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.PopupWindow
|
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.FrameLayout
|
|
||||||
import android.view.ViewOutlineProvider
|
|
||||||
import androidx.core.graphics.drawable.toDrawable
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.live.model.toSortOptionUiModel
|
|
||||||
|
|
||||||
class CreatorChannelLiveSortPopup(
|
|
||||||
private val anchor: View,
|
|
||||||
private val selectedSort: ContentSort,
|
|
||||||
private val onSortSelected: (ContentSort) -> Unit
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val popupWindow: PopupWindow = PopupWindow(anchor.context).apply {
|
|
||||||
contentView = createContentView()
|
|
||||||
width = ViewGroup.LayoutParams.WRAP_CONTENT
|
|
||||||
height = ViewGroup.LayoutParams.WRAP_CONTENT
|
|
||||||
isOutsideTouchable = true
|
|
||||||
isFocusable = true
|
|
||||||
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun show() {
|
|
||||||
val content = popupWindow.contentView
|
|
||||||
content.measure(
|
|
||||||
View.MeasureSpec.makeMeasureSpec(anchor.rootView.width, View.MeasureSpec.AT_MOST),
|
|
||||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
|
||||||
)
|
|
||||||
popupWindow.showAsDropDown(anchor, calculateHorizontalOffset(content.measuredWidth), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dismiss() {
|
|
||||||
popupWindow.dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createContentView(): View {
|
|
||||||
val root = FrameLayout(anchor.context)
|
|
||||||
val view = LayoutInflater.from(anchor.context).inflate(
|
|
||||||
R.layout.view_creator_channel_live_sort_menu,
|
|
||||||
root,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
view.clipToOutline = true
|
|
||||||
view.outlineProvider = object : ViewOutlineProvider() {
|
|
||||||
override fun getOutline(view: View, outline: Outline) {
|
|
||||||
outline.setRoundRect(0, 0, view.width, view.height, view.resources.getDimension(R.dimen.radius_14))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val container = view.findViewById<LinearLayout>(R.id.layout_creator_channel_live_sort_options)
|
|
||||||
val sample = view.findViewById<TextView>(R.id.tv_creator_channel_live_sort_option_sample)
|
|
||||||
container.removeView(sample)
|
|
||||||
|
|
||||||
ContentSort.entries.map { it.toSortOptionUiModel(selectedSort) }.forEach { option ->
|
|
||||||
val row = TextView(anchor.context).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
||||||
)
|
|
||||||
typeface = sample.typeface
|
|
||||||
includeFontPadding = false
|
|
||||||
setPadding(sample.paddingStart, sample.paddingTop, sample.paddingEnd, sample.paddingBottom)
|
|
||||||
setText(option.labelResId)
|
|
||||||
setTextColor(sample.currentTextColor)
|
|
||||||
textSize = 16f
|
|
||||||
if (option.isSelected) {
|
|
||||||
setBackgroundResource(R.drawable.bg_creator_channel_live_sort_selected)
|
|
||||||
}
|
|
||||||
setOnClickListener {
|
|
||||||
if (option.sort != selectedSort) {
|
|
||||||
onSortSelected(option.sort)
|
|
||||||
}
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
container.addView(row)
|
|
||||||
}
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateHorizontalOffset(popupWidth: Int): Int {
|
|
||||||
val visibleDisplayFrame = Rect()
|
|
||||||
anchor.rootView.getWindowVisibleDisplayFrame(visibleDisplayFrame)
|
|
||||||
|
|
||||||
val anchorLocation = IntArray(2)
|
|
||||||
anchor.getLocationOnScreen(anchorLocation)
|
|
||||||
val popupRight = anchorLocation[0] + popupWidth
|
|
||||||
return if (popupRight > visibleDisplayFrame.right) {
|
|
||||||
visibleDisplayFrame.right - popupRight
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@color/gray_900" />
|
|
||||||
<stroke
|
|
||||||
android:width="1dp"
|
|
||||||
android:color="@color/gray_700" />
|
|
||||||
<corners android:radius="@dimen/radius_14" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@color/gray_800" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/layout_creator_channel_live_sort_options"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/bg_creator_channel_live_sort_popup"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_creator_channel_live_sort_option_sample"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fontFamily="@font/medium"
|
|
||||||
android:includeFontPadding="false"
|
|
||||||
android:paddingHorizontal="@dimen/spacing_12"
|
|
||||||
android:paddingVertical="@dimen/spacing_8"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
Reference in New Issue
Block a user