fix(creator): 오디오 탭 표시를 보정한다
This commit is contained in:
@@ -32,7 +32,6 @@ class CreatorChannelAudioFragment : BaseFragment<FragmentCreatorChannelAudioBind
|
|||||||
private var sortPopup: CreatorChannelSortPopup? = null
|
private var sortPopup: CreatorChannelSortPopup? = null
|
||||||
private var currentContentState: CreatorChannelAudioUiState.Content? = null
|
private var currentContentState: CreatorChannelAudioUiState.Content? = null
|
||||||
private var lastContentLayoutKey: CreatorChannelAudioContentLayoutKey? = null
|
private var lastContentLayoutKey: CreatorChannelAudioContentLayoutKey? = null
|
||||||
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 }
|
||||||
private val host: Host
|
private val host: Host
|
||||||
get() = requireActivity() as Host
|
get() = requireActivity() as Host
|
||||||
@@ -95,10 +94,8 @@ class CreatorChannelAudioFragment : BaseFragment<FragmentCreatorChannelAudioBind
|
|||||||
viewModel.loadMore()
|
viewModel.loadMore()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCreatorChannelAudioViewportHeightChanged(minHeight: Int) {
|
@Suppress("UNUSED_PARAMETER")
|
||||||
emptyMinHeight = minHeight.coerceAtLeast(0)
|
fun onCreatorChannelAudioViewportHeightChanged(minHeight: Int) = Unit
|
||||||
applyEmptyMinHeight()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onCreatorChannelAudioOwnerCtaVisibilityChanged(isVisible: Boolean) = with(binding) {
|
fun onCreatorChannelAudioOwnerCtaVisibilityChanged(isVisible: Boolean) = with(binding) {
|
||||||
val bottomPadding = if (isVisible) {
|
val bottomPadding = if (isVisible) {
|
||||||
@@ -110,10 +107,6 @@ class CreatorChannelAudioFragment : BaseFragment<FragmentCreatorChannelAudioBind
|
|||||||
layoutCreatorChannelAudioEmpty.updatePadding(bottom = bottomPadding)
|
layoutCreatorChannelAudioEmpty.updatePadding(bottom = bottomPadding)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun applyEmptyMinHeight() = with(binding) {
|
|
||||||
layoutCreatorChannelAudioEmpty.minimumHeight = emptyMinHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindLoading() = with(binding) {
|
private fun bindLoading() = with(binding) {
|
||||||
currentContentState = null
|
currentContentState = null
|
||||||
lastContentLayoutKey = null
|
lastContentLayoutKey = null
|
||||||
@@ -134,7 +127,6 @@ class CreatorChannelAudioFragment : BaseFragment<FragmentCreatorChannelAudioBind
|
|||||||
layoutCreatorChannelAudioRateCard.isVisible = false
|
layoutCreatorChannelAudioRateCard.isVisible = false
|
||||||
rvCreatorChannelAudioContents.isVisible = false
|
rvCreatorChannelAudioContents.isVisible = false
|
||||||
layoutCreatorChannelAudioEmpty.isVisible = true
|
layoutCreatorChannelAudioEmpty.isVisible = true
|
||||||
applyEmptyMinHeight()
|
|
||||||
tvCreatorChannelAudioErrorMessage.isVisible = false
|
tvCreatorChannelAudioErrorMessage.isVisible = false
|
||||||
btnCreatorChannelAudioRetry.isVisible = false
|
btnCreatorChannelAudioRetry.isVisible = false
|
||||||
host.onCreatorChannelAudioContentChanged()
|
host.onCreatorChannelAudioContentChanged()
|
||||||
@@ -204,11 +196,13 @@ class CreatorChannelAudioFragment : BaseFragment<FragmentCreatorChannelAudioBind
|
|||||||
ratePercentText
|
ratePercentText
|
||||||
)
|
)
|
||||||
tvCreatorChannelAudioRateMessage.text = rateMessage.highlightRatePercent(ratePercentText)
|
tvCreatorChannelAudioRateMessage.text = rateMessage.highlightRatePercent(ratePercentText)
|
||||||
tvCreatorChannelAudioRateCount.text = getString(
|
val purchasedCountText = rate.purchasedCount.moneyFormat()
|
||||||
|
val rateCount = getString(
|
||||||
R.string.creator_channel_audio_owned_rate_count,
|
R.string.creator_channel_audio_owned_rate_count,
|
||||||
rate.purchasedCount.moneyFormat(),
|
purchasedCountText,
|
||||||
rate.paidCount.moneyFormat()
|
rate.paidCount.moneyFormat()
|
||||||
)
|
)
|
||||||
|
tvCreatorChannelAudioRateCount.text = rateCount.highlightPaidCount(purchasedCountText)
|
||||||
viewCreatorChannelAudioRateFill.pivotX = 0f
|
viewCreatorChannelAudioRateFill.pivotX = 0f
|
||||||
viewCreatorChannelAudioRateFill.scaleX = (rate.ratePercent / 100.0).toFloat().coerceIn(0f, 1f)
|
viewCreatorChannelAudioRateFill.scaleX = (rate.ratePercent / 100.0).toFloat().coerceIn(0f, 1f)
|
||||||
}
|
}
|
||||||
@@ -228,6 +222,20 @@ class CreatorChannelAudioFragment : BaseFragment<FragmentCreatorChannelAudioBind
|
|||||||
return spannable
|
return spannable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun String.highlightPaidCount(purchasedCountText: String): SpannableString {
|
||||||
|
val spannable = SpannableString(this)
|
||||||
|
val start = purchasedCountText.length
|
||||||
|
if (start >= length) return spannable
|
||||||
|
|
||||||
|
spannable.setSpan(
|
||||||
|
ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.gray_500)),
|
||||||
|
start,
|
||||||
|
length,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
|
return spannable
|
||||||
|
}
|
||||||
|
|
||||||
interface Host {
|
interface Host {
|
||||||
fun isCreatorChannelOwner(): Boolean
|
fun isCreatorChannelOwner(): Boolean
|
||||||
fun onCreatorChannelAudioContentClicked(audioContentId: Long)
|
fun onCreatorChannelAudioContentClicked(audioContentId: Long)
|
||||||
|
|||||||
@@ -149,9 +149,9 @@
|
|||||||
android:id="@+id/layout_creator_channel_audio_empty"
|
android:id="@+id/layout_creator_channel_audio_empty"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:paddingTop="@dimen/spacing_48"
|
||||||
|
android:paddingBottom="@dimen/spacing_32"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
style="@style/Typography.Body3"
|
style="@style/Typography.Body3"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="top|center_horizontal"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/creator_channel_audio_empty_message"
|
android:text="@string/creator_channel_audio_empty_message"
|
||||||
android:textColor="@color/gray_500" />
|
android:textColor="@color/gray_500" />
|
||||||
|
|||||||
@@ -68,6 +68,25 @@ class CreatorChannelAudioFragmentLayoutTest {
|
|||||||
assertNotNull(sortBar.findViewById<ImageView>(R.id.iv_creator_channel_audio_sort))
|
assertNotNull(sortBar.findViewById<ImageView>(R.id.iv_creator_channel_audio_sort))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `오디오 empty 문구는 스크롤 없이 보이도록 상단 가시 영역에 배치한다`() {
|
||||||
|
val layout = projectFile("app/src/main/res/layout/fragment_creator_channel_audio.xml").readText()
|
||||||
|
|
||||||
|
assertTrue(layout.contains("android:id=\"@+id/layout_creator_channel_audio_empty\""))
|
||||||
|
assertTrue(layout.contains("android:paddingTop=\"@dimen/spacing_48\""))
|
||||||
|
assertTrue(layout.contains("android:layout_gravity=\"top|center_horizontal\""))
|
||||||
|
assertTrue(layout.contains("app:layout_constraintTop_toTopOf=\"parent\""))
|
||||||
|
assertTrue(!layout.contains("app:layout_constraintBottom_toBottomOf=\"parent\""))
|
||||||
|
assertTrue(
|
||||||
|
!layout.contains(
|
||||||
|
"android:id=\"@+id/layout_creator_channel_audio_empty\"" +
|
||||||
|
"\n android:layout_width=\"0dp\"" +
|
||||||
|
"\n android:layout_height=\"wrap_content\"" +
|
||||||
|
"\n android:gravity=\"center\""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `오디오 소장률 카드는 percent count track fill 영역을 제공한다`() {
|
fun `오디오 소장률 카드는 percent count track fill 영역을 제공한다`() {
|
||||||
val root = inflateView(R.layout.fragment_creator_channel_audio)
|
val root = inflateView(R.layout.fragment_creator_channel_audio)
|
||||||
@@ -123,7 +142,10 @@ class CreatorChannelAudioFragmentLayoutTest {
|
|||||||
assertTrue(fragment.contains("fun onCreatorChannelAudioTabSelected()"))
|
assertTrue(fragment.contains("fun onCreatorChannelAudioTabSelected()"))
|
||||||
assertTrue(fragment.contains("viewModel.loadAudio(creatorId, isOwner = host.isCreatorChannelOwner())"))
|
assertTrue(fragment.contains("viewModel.loadAudio(creatorId, isOwner = host.isCreatorChannelOwner())"))
|
||||||
assertTrue(fragment.contains("fun onCreatorChannelAudioViewportHeightChanged(minHeight: Int)"))
|
assertTrue(fragment.contains("fun onCreatorChannelAudioViewportHeightChanged(minHeight: Int)"))
|
||||||
assertTrue(fragment.contains("layoutCreatorChannelAudioEmpty.minimumHeight = emptyMinHeight"))
|
assertTrue(fragment.contains("@Suppress(\"UNUSED_PARAMETER\")"))
|
||||||
|
assertTrue(!fragment.contains("private var emptyMinHeight: Int = 0"))
|
||||||
|
assertTrue(!fragment.contains("layoutCreatorChannelAudioEmpty.minimumHeight"))
|
||||||
|
assertTrue(!fragment.contains("applyEmptyMinHeight()"))
|
||||||
assertTrue(fragment.contains("notifyContentChangedIfLayoutChanged(state)"))
|
assertTrue(fragment.contains("notifyContentChangedIfLayoutChanged(state)"))
|
||||||
assertTrue(fragment.contains("if (contentLayoutKey == lastContentLayoutKey) return"))
|
assertTrue(fragment.contains("if (contentLayoutKey == lastContentLayoutKey) return"))
|
||||||
assertTrue(fragment.contains("viewModel.audioStateLiveData.observe(viewLifecycleOwner)"))
|
assertTrue(fragment.contains("viewModel.audioStateLiveData.observe(viewLifecycleOwner)"))
|
||||||
@@ -147,6 +169,10 @@ class CreatorChannelAudioFragmentLayoutTest {
|
|||||||
assertTrue(fragment.contains("tvCreatorChannelAudioRateMessage.text"))
|
assertTrue(fragment.contains("tvCreatorChannelAudioRateMessage.text"))
|
||||||
assertTrue(fragment.contains("ForegroundColorSpan"))
|
assertTrue(fragment.contains("ForegroundColorSpan"))
|
||||||
assertTrue(fragment.contains("R.string.creator_channel_audio_owned_rate_count"))
|
assertTrue(fragment.contains("R.string.creator_channel_audio_owned_rate_count"))
|
||||||
|
assertTrue(fragment.contains("tvCreatorChannelAudioRateCount.text = rateCount.highlightPaidCount(purchasedCountText)"))
|
||||||
|
assertTrue(fragment.contains("private fun String.highlightPaidCount(purchasedCountText: String): SpannableString"))
|
||||||
|
assertTrue(fragment.contains("val start = purchasedCountText.length"))
|
||||||
|
assertTrue(fragment.contains("R.color.gray_500"))
|
||||||
assertTrue(fragment.contains("viewCreatorChannelAudioRateFill.pivotX = 0f"))
|
assertTrue(fragment.contains("viewCreatorChannelAudioRateFill.pivotX = 0f"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user