feat(creator): 채널 홈 오디오 섹션을 재구성한다

This commit is contained in:
2026-06-15 15:01:41 +09:00
parent edb7d98de7
commit 5fde0bc469
4 changed files with 182 additions and 37 deletions

View File

@@ -4,6 +4,7 @@ import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.v2.creator.channel.ui.calculateCreatorChannelDonationCardWidthDp
import kr.co.vividnext.sodalive.v2.creator.channel.ui.calculateCreatorChannelDonationHeaderColorRes
import kr.co.vividnext.sodalive.v2.creator.channel.ui.calculateCreatorChannelNoticeCardWidthDp
import kr.co.vividnext.sodalive.v2.creator.channel.ui.calculateCreatorChannelAudioItemWidthDp
import kr.co.vividnext.sodalive.v2.creator.channel.ui.calculateCreatorChannelScheduleTimelineLineCount
import kr.co.vividnext.sodalive.v2.creator.channel.ui.formatCreatorChannelScheduleDate
import kr.co.vividnext.sodalive.v2.creator.channel.ui.formatCreatorChannelScheduleDayOfWeek
@@ -461,7 +462,7 @@ class CreatorChannelHomeActivitySourceTest {
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeActivity.kt"
).readText()
assertTrue(source.contains("CreatorChannelHomeSectionAdapter(::onScheduleClicked)"))
assertTrue(source.contains("CreatorChannelHomeSectionAdapter(::onScheduleClicked"))
assertTrue(source.contains("private fun onScheduleClicked(schedule: CreatorChannelScheduleResponse)"))
assertTrue(source.contains("CreatorActivityType.Audio"))
assertTrue(source.contains("CreatorActivityType.LiveReplay"))
@@ -474,16 +475,71 @@ class CreatorChannelHomeActivitySourceTest {
}
@Test
fun `section adapter source는 오디오 텐츠를 단일 가로 스크롤 row로 표시한다`() {
fun `오디오 텐츠 섹션은 전용 row 카드와 RecyclerView grid로 최대 9개를 렌더링한다`() {
val adapter = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt"
).readText()
val audioLayout = projectFile("app/src/main/res/layout/item_creator_channel_home_audio.xml").readText()
val audioItemLayout = projectFile(
"app/src/main/res/layout/item_creator_channel_home_audio_content.xml"
).readText()
val audioCardView = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeAudioContentCardView.kt"
).readText()
assertTrue(audioLayout.contains("@layout/view_section_title"))
assertTrue(audioLayout.contains("@+id/rv_audio_contents"))
assertFalse(audioLayout.contains("@+id/ll_section_items"))
assertTrue(audioItemLayout.contains("CreatorChannelHomeAudioContentCardView"))
assertTrue(audioItemLayout.contains("<LinearLayout"))
assertTrue(audioItemLayout.contains("@+id/layout_audio_content_card"))
assertTrue(audioItemLayout.contains("@+id/iv_audio_content_thumbnail"))
assertTrue(audioItemLayout.contains("@+id/iv_audio_content_original_tag"))
assertTrue(audioItemLayout.contains("@+id/tv_audio_content_title"))
assertTrue(audioItemLayout.contains("@+id/tv_audio_content_secondary"))
assertTrue(audioItemLayout.contains("android:layout_width=\"88dp\""))
assertTrue(audioItemLayout.contains("android:layout_height=\"88dp\""))
assertFalse(audioItemLayout.contains("kr.co.vividnext.sodalive.v2.widget.AudioContentCardView"))
assertFalse(audioItemLayout.contains("android:clipToOutline"))
assertFalse(audioCardView.contains("GridLayout"))
assertTrue(audioCardView.contains("clipToOutline = true"))
assertTrue(audioCardView.contains("ViewOutlineProvider"))
assertTrue(audioCardView.contains("outline.setRoundRect"))
assertTrue(audioCardView.contains("R.dimen.radius_14"))
assertTrue(audioCardView.contains("originalTag.isVisible = audioContent.isOriginalSeries == true"))
assertTrue(adapter.contains("private fun bindAudioContents"))
assertTrue(adapter.contains("item.audioContents.forEach { audioContent ->"))
assertTrue(adapter.contains("row.addView(createAudioTile(audioContent))"))
assertTrue(adapter.contains("sectionItems?.addView(createHorizontalScrollRow(row))"))
assertFalse(adapter.contains("item.audioContents.forEach { audioContent ->\n addAudioCard(audioContent)"))
assertTrue(adapter.contains("private val audioContentsRecyclerView: RecyclerView?"))
assertTrue(adapter.contains("GridLayoutManager(itemView.context, AUDIO_GRID_SPAN_COUNT, RecyclerView.HORIZONTAL, false)"))
assertTrue(adapter.contains("val visibleAudioContents = item.audioContents.take(MAX_AUDIO_ITEM_COUNT)"))
assertTrue(adapter.contains("private val audioContentGridAdapter = AudioContentGridAdapter("))
assertTrue(adapter.contains("setupAudioContentsRecyclerView()"))
assertTrue(adapter.contains("audioContentGridAdapter.submitItems(visibleAudioContents)"))
assertTrue(adapter.contains("calculateCreatorChannelAudioItemWidthDp"))
assertTrue(adapter.contains("R.layout.item_creator_channel_home_audio_content"))
assertTrue(adapter.contains("onAudioContentClick(audioContent)"))
assertTrue(adapter.contains("private const val MAX_AUDIO_ITEM_COUNT = 9"))
assertFalse(adapter.contains("adapter = AudioContentGridAdapter("))
assertFalse(adapter.contains("row.addView(createAudioTile(audioContent))"))
assertFalse(adapter.contains("private fun createAudioTile"))
}
@Test
fun `오디오 컨텐츠 item width는 402dp 기준 최대 346dp이고 작은 화면에서는 비율 축소한다`() {
assertEquals(346, calculateCreatorChannelAudioItemWidthDp(402))
assertEquals(346, calculateCreatorChannelAudioItemWidthDp(430))
assertEquals(310, calculateCreatorChannelAudioItemWidthDp(360))
}
@Test
fun `오디오 컨텐츠 클릭은 콘텐츠 상세 이동 계약을 연결한다`() {
val source = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeActivity.kt"
).readText()
assertTrue(source.contains("CreatorChannelHomeSectionAdapter(::onScheduleClicked, ::onAudioContentClicked)"))
assertTrue(source.contains("private fun onAudioContentClicked(audioContent: CreatorChannelAudioContentResponse)"))
assertTrue(source.contains("AudioContentDetailActivity::class.java"))
assertTrue(source.contains("putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, audioContent.audioContentId)"))
}
@Test
@@ -552,7 +608,6 @@ class CreatorChannelHomeActivitySourceTest {
@Test
fun `section item layouts는 legacy generic card id를 제거하고 동적 컨테이너만 둔다`() {
val layoutNames = listOf(
"audio",
"series",
"community",
"fantalk",