feat(creator): 오디오 탭 activity 연동을 추가한다

This commit is contained in:
2026-06-19 21:04:08 +09:00
parent bcbc48540e
commit 757f242285
3 changed files with 148 additions and 68 deletions

View File

@@ -54,6 +54,7 @@ import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioConte
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.data.CreatorChannelScheduleResponse import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelScheduleResponse
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelSeriesResponse import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelSeriesResponse
import kr.co.vividnext.sodalive.v2.creator.channel.audio.CreatorChannelAudioFragment
import kr.co.vividnext.sodalive.v2.creator.channel.live.CreatorChannelLiveFragment import kr.co.vividnext.sodalive.v2.creator.channel.live.CreatorChannelLiveFragment
import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelHeaderUiModel import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelHeaderUiModel
import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelScrollState import kr.co.vividnext.sodalive.v2.creator.channel.model.CreatorChannelScrollState
@@ -68,7 +69,8 @@ import org.koin.android.ext.android.inject
class CreatorChannelActivity : class CreatorChannelActivity :
BaseActivity<ActivityCreatorChannelBinding>(ActivityCreatorChannelBinding::inflate), BaseActivity<ActivityCreatorChannelBinding>(ActivityCreatorChannelBinding::inflate),
CreatorChannelHomeFragment.Host, CreatorChannelHomeFragment.Host,
CreatorChannelLiveFragment.Host { CreatorChannelLiveFragment.Host,
CreatorChannelAudioFragment.Host {
private val liveViewModel: LiveViewModel by inject() private val liveViewModel: LiveViewModel by inject()
private val myPageViewModel: MyPageViewModel by inject() private val myPageViewModel: MyPageViewModel by inject()
@@ -129,7 +131,7 @@ class CreatorChannelActivity :
setStatusBarIconAppearance() setStatusBarIconAppearance()
setTitleBarTopInset() setTitleBarTopInset()
setupOwnerFabInsets() setupOwnerFabInsets()
setupLiveOwnerCtaInsets() setupOwnerCtaInsets()
setupScrollListener() setupScrollListener()
setupClickListeners() setupClickListeners()
setupLiveEntryObservers() setupLiveEntryObservers()
@@ -160,7 +162,7 @@ class CreatorChannelActivity :
binding.ownerFabCommunityButton.setOnClickListener { onOwnerFabCommunityClicked() } binding.ownerFabCommunityButton.setOnClickListener { onOwnerFabCommunityClicked() }
binding.ownerFabAudioButton.setOnClickListener { onOwnerFabAudioClicked() } binding.ownerFabAudioButton.setOnClickListener { onOwnerFabAudioClicked() }
binding.ownerFabLiveButton.setOnClickListener { onOwnerFabLiveClicked() } binding.ownerFabLiveButton.setOnClickListener { onOwnerFabLiveClicked() }
binding.btnCreatorChannelLiveOwnerCta.setOnClickListener { onLiveOwnerCtaClicked() } binding.btnCreatorChannelOwnerCta.setOnClickListener { onOwnerCtaClicked() }
binding.tvChatButton.setOnClickListener { binding.tvChatButton.setOnClickListener {
currentHeader?.characterId?.let { characterId -> homeActionDelegate?.createChatRoom(characterId) } currentHeader?.characterId?.let { characterId -> homeActionDelegate?.createChatRoom(characterId) }
} }
@@ -273,18 +275,18 @@ class CreatorChannelActivity :
} }
private fun onCreatorChannelNestedScrollChanged(scrollY: Int, oldScrollY: Int) { private fun onCreatorChannelNestedScrollChanged(scrollY: Int, oldScrollY: Int) {
if (binding.viewPager.currentItem != CreatorChannelTab.Live.ordinal) return if (!isCreatorChannelLoadMoreTab(binding.viewPager.currentItem)) return
if (scrollY <= oldScrollY) return if (scrollY <= oldScrollY) return
val contentHeight = binding.nestedScrollView.getChildAt(0)?.height ?: return val contentHeight = binding.nestedScrollView.getChildAt(0)?.height ?: return
val threshold = CREATOR_CHANNEL_LIVE_LOAD_MORE_THRESHOLD_DP.dpToPx().toInt() val threshold = CREATOR_CHANNEL_LOAD_MORE_THRESHOLD_DP.dpToPx().toInt()
val remainingScroll = calculateCreatorChannelLiveRemainingScroll( val remainingScroll = calculateCreatorChannelRemainingScroll(
contentHeight = contentHeight, contentHeight = contentHeight,
viewportHeight = binding.nestedScrollView.height, viewportHeight = binding.nestedScrollView.height,
scrollY = scrollY scrollY = scrollY
) )
if (remainingScroll <= threshold) { if (remainingScroll <= threshold) {
findLiveFragment()?.onCreatorChannelLiveScrolledToBottom() notifyCurrentCreatorChannelTabScrolledToBottom()
} }
} }
@@ -390,13 +392,16 @@ class CreatorChannelActivity :
collapseOwnerFab(animate = false) collapseOwnerFab(animate = false)
} }
updateOwnerFabVisibility() updateOwnerFabVisibility()
updateLiveOwnerCtaVisibility() updateOwnerCtaVisibility()
updateCreatorChannelLiveViewportHeight() updateCreatorChannelTabViewportHeight()
updateViewPagerHeight() updateViewPagerHeight()
if (position == CreatorChannelTab.Live.ordinal) { when (position) {
binding.viewPager.post { CreatorChannelTab.Live.ordinal -> binding.viewPager.post {
findLiveFragment()?.onCreatorChannelLiveTabSelected() findLiveFragment()?.onCreatorChannelLiveTabSelected()
} }
CreatorChannelTab.Audio.ordinal -> binding.viewPager.post {
findAudioFragment()?.onCreatorChannelAudioTabSelected()
}
} }
} }
} }
@@ -409,7 +414,12 @@ class CreatorChannelActivity :
bindHeader(header) bindHeader(header)
bindTitleBar(header) bindTitleBar(header)
updateOwnerFabVisibility() updateOwnerFabVisibility()
updateLiveOwnerCtaVisibility() updateOwnerCtaVisibility()
if (binding.viewPager.currentItem == CreatorChannelTab.Audio.ordinal) {
binding.viewPager.post {
findAudioFragment()?.onCreatorChannelAudioTabSelected()
}
}
} }
override fun onCreatorChannelFollowProgressChanged(inProgress: Boolean) { override fun onCreatorChannelFollowProgressChanged(inProgress: Boolean) {
@@ -444,28 +454,63 @@ class CreatorChannelActivity :
} }
override fun onCreatorChannelLiveContentChanged() { override fun onCreatorChannelLiveContentChanged() {
updateCreatorChannelLiveViewportHeight() updateCreatorChannelTabViewportHeight()
updateViewPagerHeight() updateViewPagerHeight()
postCheckCreatorChannelLiveNeedsMore() postCheckCreatorChannelCurrentTabNeedsMore()
}
override fun isCreatorChannelOwner(): Boolean = currentHeader?.isOwner == true
override fun onCreatorChannelAudioContentClicked(audioContentId: Long) {
startAudioContentDetail(audioContentId)
}
override fun onCreatorChannelAudioContentChanged() {
updateCreatorChannelTabViewportHeight()
updateViewPagerHeight()
postCheckCreatorChannelCurrentTabNeedsMore()
} }
private fun setupOwnerFabInsets() { private fun setupOwnerFabInsets() {
binding.viewPager.updatePadding(bottom = OWNER_FAB_CONTENT_BOTTOM_PADDING_DP.dpToPx().toInt()) binding.viewPager.updatePadding(bottom = OWNER_FAB_CONTENT_BOTTOM_PADDING_DP.dpToPx().toInt())
} }
private fun setupLiveOwnerCtaInsets() { private fun setupOwnerCtaInsets() {
updateLiveOwnerCtaVisibility() updateOwnerCtaVisibility()
} }
private fun updateLiveOwnerCtaVisibility() { private fun updateOwnerCtaVisibility() {
val shouldShowLiveOwnerCta = shouldShowLiveOwnerCta() val ownerCtaTab = currentOwnerCtaTab()
binding.layoutCreatorChannelLiveOwnerCta.isVisible = shouldShowLiveOwnerCta val shouldShowOwnerCta = ownerCtaTab != null
binding.btnCreatorChannelLiveOwnerCta.isEnabled = true binding.layoutCreatorChannelOwnerCta.isVisible = shouldShowOwnerCta
findLiveFragment()?.onCreatorChannelLiveOwnerCtaVisibilityChanged(shouldShowLiveOwnerCta) binding.btnCreatorChannelOwnerCta.isEnabled = true
when (ownerCtaTab) {
CreatorChannelTab.Live -> bindOwnerCta(
iconResId = R.drawable.ic_new_create_live,
textResId = R.string.creator_channel_live_start_button
)
CreatorChannelTab.Audio -> bindOwnerCta(
iconResId = R.drawable.ic_new_upload_audio,
textResId = R.string.creator_channel_audio_upload_button
)
else -> Unit
}
findLiveFragment()?.onCreatorChannelLiveOwnerCtaVisibilityChanged(ownerCtaTab == CreatorChannelTab.Live)
findAudioFragment()?.onCreatorChannelAudioOwnerCtaVisibilityChanged(ownerCtaTab == CreatorChannelTab.Audio)
} }
private fun shouldShowLiveOwnerCta(): Boolean { private fun bindOwnerCta(iconResId: Int, textResId: Int) {
return currentHeader?.isOwner == true && binding.viewPager.currentItem == CreatorChannelTab.Live.ordinal binding.ivCreatorChannelOwnerCta.setImageResource(iconResId)
binding.tvCreatorChannelOwnerCta.setText(textResId)
}
private fun currentOwnerCtaTab(): CreatorChannelTab? {
if (currentHeader?.isOwner != true) return null
return when (binding.viewPager.currentItem) {
CreatorChannelTab.Live.ordinal -> CreatorChannelTab.Live
CreatorChannelTab.Audio.ordinal -> CreatorChannelTab.Audio
else -> null
}
} }
private fun expandOwnerFab() { private fun expandOwnerFab() {
@@ -556,9 +601,12 @@ class CreatorChannelActivity :
liveRoomCreateLauncher.launch(Intent(this, LiveRoomCreateActivity::class.java)) liveRoomCreateLauncher.launch(Intent(this, LiveRoomCreateActivity::class.java))
} }
private fun onLiveOwnerCtaClicked() { private fun onOwnerCtaClicked() {
binding.btnCreatorChannelLiveOwnerCta.isEnabled = false binding.btnCreatorChannelOwnerCta.isEnabled = false
onOwnerFabLiveClicked() when (binding.viewPager.currentItem) {
CreatorChannelTab.Live.ordinal -> onOwnerFabLiveClicked()
CreatorChannelTab.Audio.ordinal -> onOwnerFabAudioClicked()
}
} }
override fun onCreatorChannelDonationClicked() { override fun onCreatorChannelDonationClicked() {
@@ -593,6 +641,22 @@ class CreatorChannelActivity :
return supportFragmentManager.findFragmentByTag(fragmentTag) as? CreatorChannelLiveFragment return supportFragmentManager.findFragmentByTag(fragmentTag) as? CreatorChannelLiveFragment
} }
private fun findAudioFragment(): CreatorChannelAudioFragment? {
val fragmentTag = "f${CreatorChannelTab.Audio.ordinal}"
return supportFragmentManager.findFragmentByTag(fragmentTag) as? CreatorChannelAudioFragment
}
private fun notifyCurrentCreatorChannelTabScrolledToBottom() {
when (binding.viewPager.currentItem) {
CreatorChannelTab.Live.ordinal -> findLiveFragment()?.onCreatorChannelLiveScrolledToBottom()
CreatorChannelTab.Audio.ordinal -> findAudioFragment()?.onCreatorChannelAudioScrolledToBottom()
}
}
private fun isCreatorChannelLoadMoreTab(position: Int): Boolean {
return position == CreatorChannelTab.Live.ordinal || position == CreatorChannelTab.Audio.ordinal
}
private fun ensureLoginAndAdultAuth(isAdult: Boolean, onAuthed: () -> Unit) { private fun ensureLoginAndAdultAuth(isAdult: Boolean, onAuthed: () -> Unit) {
if (SharedPreferenceManager.token.isBlank()) { if (SharedPreferenceManager.token.isBlank()) {
showLoginActivity() showLoginActivity()
@@ -659,7 +723,7 @@ class CreatorChannelActivity :
} }
private fun updateViewPagerHeight() { private fun updateViewPagerHeight() {
updateCreatorChannelLiveViewportHeight() updateCreatorChannelTabViewportHeight()
binding.viewPager.post { binding.viewPager.post {
val recyclerView = binding.viewPager.getChildAt(0) as? RecyclerView ?: return@post val recyclerView = binding.viewPager.getChildAt(0) as? RecyclerView ?: return@post
val currentPage = recyclerView.layoutManager?.findViewByPosition(binding.viewPager.currentItem) ?: return@post val currentPage = recyclerView.layoutManager?.findViewByPosition(binding.viewPager.currentItem) ?: return@post
@@ -675,15 +739,15 @@ class CreatorChannelActivity :
} }
} }
private fun updateCreatorChannelLiveViewportHeight() { private fun updateCreatorChannelTabViewportHeight() {
if (binding.viewPager.currentItem != CreatorChannelTab.Live.ordinal) return val minHeight = calculateCreatorChannelTabEmptyMinHeight()
when (binding.viewPager.currentItem) {
findLiveFragment()?.onCreatorChannelLiveViewportHeightChanged( CreatorChannelTab.Live.ordinal -> findLiveFragment()?.onCreatorChannelLiveViewportHeightChanged(minHeight)
calculateCreatorChannelLiveEmptyMinHeight() CreatorChannelTab.Audio.ordinal -> findAudioFragment()?.onCreatorChannelAudioViewportHeightChanged(minHeight)
) }
} }
private fun calculateCreatorChannelLiveEmptyMinHeight(): Int { private fun calculateCreatorChannelTabEmptyMinHeight(): Int {
val stickyScrollY = calculateCreatorChannelStickyScrollY() val stickyScrollY = calculateCreatorChannelStickyScrollY()
val visibleTabViewportHeight = binding.nestedScrollView.height - binding.tabLayout.height val visibleTabViewportHeight = binding.nestedScrollView.height - binding.tabLayout.height
val scrollRangeRequiredHeight = binding.nestedScrollView.height + val scrollRangeRequiredHeight = binding.nestedScrollView.height +
@@ -692,23 +756,23 @@ class CreatorChannelActivity :
return maxOf(visibleTabViewportHeight, scrollRangeRequiredHeight, 0) return maxOf(visibleTabViewportHeight, scrollRangeRequiredHeight, 0)
} }
private fun postCheckCreatorChannelLiveNeedsMore() { private fun postCheckCreatorChannelCurrentTabNeedsMore() {
binding.nestedScrollView.post { binding.nestedScrollView.post {
checkCreatorChannelLiveNeedsMore() checkCreatorChannelCurrentTabNeedsMore()
} }
} }
private fun checkCreatorChannelLiveNeedsMore() { private fun checkCreatorChannelCurrentTabNeedsMore() {
if (binding.viewPager.currentItem != CreatorChannelTab.Live.ordinal) return if (!isCreatorChannelLoadMoreTab(binding.viewPager.currentItem)) return
val contentHeight = binding.nestedScrollView.getChildAt(0)?.height ?: return val contentHeight = binding.nestedScrollView.getChildAt(0)?.height ?: return
val remainingScroll = calculateCreatorChannelLiveRemainingScroll( val remainingScroll = calculateCreatorChannelRemainingScroll(
contentHeight = contentHeight, contentHeight = contentHeight,
viewportHeight = binding.nestedScrollView.height, viewportHeight = binding.nestedScrollView.height,
scrollY = binding.nestedScrollView.scrollY scrollY = binding.nestedScrollView.scrollY
) )
if (remainingScroll <= 0) { if (remainingScroll <= 0) {
findLiveFragment()?.onCreatorChannelLiveScrolledToBottom() notifyCurrentCreatorChannelTabScrolledToBottom()
} }
} }
@@ -749,7 +813,7 @@ class CreatorChannelActivity :
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.btnCreatorChannelLiveOwnerCta.isEnabled = true binding.btnCreatorChannelOwnerCta.isEnabled = true
} }
override fun onDestroy() { override fun onDestroy() {
@@ -787,7 +851,7 @@ class CreatorChannelActivity :
private const val OWNER_FAB_SPRING_MASS = 1f private const val OWNER_FAB_SPRING_MASS = 1f
private const val OWNER_FAB_SPRING_STIFFNESS = 256f private const val OWNER_FAB_SPRING_STIFFNESS = 256f
private const val OWNER_FAB_SPRING_DAMPING = 24f private const val OWNER_FAB_SPRING_DAMPING = 24f
private const val CREATOR_CHANNEL_LIVE_LOAD_MORE_THRESHOLD_DP = 200 private const val CREATOR_CHANNEL_LOAD_MORE_THRESHOLD_DP = 200
fun newIntent(context: Context, creatorId: Long): Intent { fun newIntent(context: Context, creatorId: Long): Intent {
return Intent(context, CreatorChannelActivity::class.java).apply { return Intent(context, CreatorChannelActivity::class.java).apply {
@@ -797,7 +861,7 @@ class CreatorChannelActivity :
} }
} }
internal fun calculateCreatorChannelLiveRemainingScroll( internal fun calculateCreatorChannelRemainingScroll(
contentHeight: Int, contentHeight: Int,
viewportHeight: Int, viewportHeight: Int,
scrollY: Int scrollY: Int

View File

@@ -239,7 +239,7 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout <FrameLayout
android:id="@+id/layout_creator_channel_live_owner_cta" android:id="@+id/layout_creator_channel_owner_cta"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="100dp" android:layout_height="100dp"
android:background="@color/black" android:background="@color/black"
@@ -249,7 +249,7 @@
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent">
<LinearLayout <LinearLayout
android:id="@+id/btn_creator_channel_live_owner_cta" android:id="@+id/btn_creator_channel_owner_cta"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="52dp" android:layout_height="52dp"
android:layout_marginHorizontal="@dimen/spacing_14" android:layout_marginHorizontal="@dimen/spacing_14"
@@ -261,12 +261,14 @@
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <ImageView
android:id="@+id/iv_creator_channel_owner_cta"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:contentDescription="@null" android:contentDescription="@null"
android:src="@drawable/ic_new_create_live" /> android:src="@drawable/ic_new_create_live" />
<TextView <TextView
android:id="@+id/tv_creator_channel_owner_cta"
style="@style/Typography.Heading3" style="@style/Typography.Heading3"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -391,8 +391,12 @@ class CreatorChannelActivitySourceTest {
assertFalse(source.contains("private var selectedTab: CreatorChannelTab = CreatorChannelTab.Home")) assertFalse(source.contains("private var selectedTab: CreatorChannelTab = CreatorChannelTab.Home"))
assertFalse(source.contains("setOnClickListener { onTabClicked(tab) }")) assertFalse(source.contains("setOnClickListener { onTabClicked(tab) }"))
assertFalse(source.contains("private fun onTabClicked(tab: CreatorChannelTab)")) assertFalse(source.contains("private fun onTabClicked(tab: CreatorChannelTab)"))
val pagerAdapter = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapter.kt"
).readText()
assertFalse(source.contains("if (tab != CreatorChannelTab.Home) return")) assertFalse(source.contains("if (tab != CreatorChannelTab.Home) return"))
assertFalse(source.contains("CreatorChannelTab.Audio ->")) assertTrue(pagerAdapter.contains("CreatorChannelTab.Audio -> CreatorChannelAudioFragment.newInstance(creatorId)"))
assertFalse(source.contains("CreatorChannelTab.Series ->")) assertFalse(source.contains("CreatorChannelTab.Series ->"))
assertFalse(source.contains("CreatorChannelTab.Community ->")) assertFalse(source.contains("CreatorChannelTab.Community ->"))
assertFalse(source.contains("CreatorChannelTab.FanTalk ->")) assertFalse(source.contains("CreatorChannelTab.FanTalk ->"))
@@ -925,16 +929,19 @@ class CreatorChannelActivitySourceTest {
assertTrue(source.contains("private fun onCreatorChannelNestedScrollChanged(scrollY: Int, oldScrollY: Int)")) assertTrue(source.contains("private fun onCreatorChannelNestedScrollChanged(scrollY: Int, oldScrollY: Int)"))
assertTrue(source.contains("binding.nestedScrollView.getChildAt(0)?.height")) assertTrue(source.contains("binding.nestedScrollView.getChildAt(0)?.height"))
assertTrue(source.contains("binding.nestedScrollView.height")) assertTrue(source.contains("binding.nestedScrollView.height"))
assertTrue(source.contains("CREATOR_CHANNEL_LIVE_LOAD_MORE_THRESHOLD_DP.dpToPx().toInt()")) assertTrue(source.contains("CREATOR_CHANNEL_LOAD_MORE_THRESHOLD_DP.dpToPx().toInt()"))
assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveScrolledToBottom()")) assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveScrolledToBottom()"))
assertTrue(source.contains("findAudioFragment()?.onCreatorChannelAudioScrolledToBottom()"))
assertTrue(source.contains("private fun findLiveFragment(): CreatorChannelLiveFragment?")) assertTrue(source.contains("private fun findLiveFragment(): CreatorChannelLiveFragment?"))
assertTrue(source.contains("supportFragmentManager.findFragmentByTag")) assertTrue(source.contains("supportFragmentManager.findFragmentByTag"))
assertTrue(source.contains("override fun onCreatorChannelLiveContentChanged()")) assertTrue(source.contains("override fun onCreatorChannelLiveContentChanged()"))
assertTrue(source.contains("postCheckCreatorChannelLiveNeedsMore()")) assertTrue(source.contains("postCheckCreatorChannelCurrentTabNeedsMore()"))
assertTrue(source.contains("updateViewPagerHeight()")) assertTrue(source.contains("updateViewPagerHeight()"))
assertTrue(source.contains("updateCreatorChannelLiveViewportHeight()")) assertTrue(source.contains("updateCreatorChannelTabViewportHeight()"))
assertTrue(source.contains("if (position == CreatorChannelTab.Live.ordinal)")) assertTrue(source.contains("CreatorChannelTab.Live.ordinal -> binding.viewPager.post"))
assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveTabSelected()")) assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveTabSelected()"))
assertTrue(source.contains("CreatorChannelTab.Audio.ordinal -> binding.viewPager.post"))
assertTrue(source.contains("findAudioFragment()?.onCreatorChannelAudioTabSelected()"))
assertTrue(source.contains("binding.viewPager.offscreenPageLimit = CreatorChannelTab.entries.size - 1")) assertTrue(source.contains("binding.viewPager.offscreenPageLimit = CreatorChannelTab.entries.size - 1"))
assertFalse(source.contains("currentPage.minimumHeight = calculateCreatorChannelTabViewportHeight()")) assertFalse(source.contains("currentPage.minimumHeight = calculateCreatorChannelTabViewportHeight()"))
assertFalse(source.contains("private fun calculateCreatorChannelTabViewportHeight(): Int")) assertFalse(source.contains("private fun calculateCreatorChannelTabViewportHeight(): Int"))
@@ -950,10 +957,11 @@ class CreatorChannelActivitySourceTest {
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt" "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt"
).readText() ).readText()
assertTrue(source.contains("private fun updateCreatorChannelLiveViewportHeight()")) assertTrue(source.contains("private fun updateCreatorChannelTabViewportHeight()"))
assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveViewportHeightChanged")) assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveViewportHeightChanged(minHeight)"))
assertTrue(source.contains("calculateCreatorChannelLiveEmptyMinHeight()")) assertTrue(source.contains("findAudioFragment()?.onCreatorChannelAudioViewportHeightChanged(minHeight)"))
assertTrue(source.contains("private fun calculateCreatorChannelLiveEmptyMinHeight(): Int")) assertTrue(source.contains("calculateCreatorChannelTabEmptyMinHeight()"))
assertTrue(source.contains("private fun calculateCreatorChannelTabEmptyMinHeight(): Int"))
assertTrue(source.contains("val stickyScrollY = calculateCreatorChannelStickyScrollY()")) assertTrue(source.contains("val stickyScrollY = calculateCreatorChannelStickyScrollY()"))
assertTrue(source.contains("binding.nestedScrollView.height - binding.tabLayout.height")) assertTrue(source.contains("binding.nestedScrollView.height - binding.tabLayout.height"))
assertTrue(source.contains("val scrollRangeRequiredHeight = binding.nestedScrollView.height +")) assertTrue(source.contains("val scrollRangeRequiredHeight = binding.nestedScrollView.height +"))
@@ -989,18 +997,18 @@ class CreatorChannelActivitySourceTest {
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt" "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt"
).readText() ).readText()
assertTrue(source.contains("private fun postCheckCreatorChannelLiveNeedsMore()")) assertTrue(source.contains("private fun postCheckCreatorChannelCurrentTabNeedsMore()"))
assertTrue(source.contains("binding.nestedScrollView.post")) assertTrue(source.contains("binding.nestedScrollView.post"))
assertTrue(source.contains("checkCreatorChannelLiveNeedsMore()")) assertTrue(source.contains("checkCreatorChannelCurrentTabNeedsMore()"))
assertTrue(source.contains("if (binding.viewPager.currentItem != CreatorChannelTab.Live.ordinal) return")) assertTrue(source.contains("if (!isCreatorChannelLoadMoreTab(binding.viewPager.currentItem)) return"))
assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveScrolledToBottom()")) assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveScrolledToBottom()"))
} }
@Test @Test
fun `라이브 pagination remaining scroll helper는 content viewport scroll 차이를 계산한다`() { fun `라이브 pagination remaining scroll helper는 content viewport scroll 차이를 계산한다`() {
assertEquals(100, calculateCreatorChannelLiveRemainingScroll(contentHeight = 1000, viewportHeight = 700, scrollY = 200)) assertEquals(100, calculateCreatorChannelRemainingScroll(contentHeight = 1000, viewportHeight = 700, scrollY = 200))
assertEquals(0, calculateCreatorChannelLiveRemainingScroll(contentHeight = 1000, viewportHeight = 700, scrollY = 300)) assertEquals(0, calculateCreatorChannelRemainingScroll(contentHeight = 1000, viewportHeight = 700, scrollY = 300))
assertEquals(-20, calculateCreatorChannelLiveRemainingScroll(contentHeight = 1000, viewportHeight = 700, scrollY = 320)) assertEquals(-20, calculateCreatorChannelRemainingScroll(contentHeight = 1000, viewportHeight = 700, scrollY = 320))
} }
@Test @Test
@@ -1042,17 +1050,23 @@ class CreatorChannelActivitySourceTest {
).readText() ).readText()
val activityLayout = projectFile("app/src/main/res/layout/activity_creator_channel.xml").readText() val activityLayout = projectFile("app/src/main/res/layout/activity_creator_channel.xml").readText()
assertTrue(activityLayout.contains("android:id=\"@+id/layout_creator_channel_live_owner_cta\"")) assertTrue(activityLayout.contains("android:id=\"@+id/layout_creator_channel_owner_cta\""))
assertTrue(source.contains("updateLiveOwnerCtaVisibility()")) assertTrue(source.contains("updateOwnerCtaVisibility()"))
assertTrue(source.contains("if (binding.viewPager.currentItem == CreatorChannelTab.Audio.ordinal)"))
assertTrue(source.contains("findAudioFragment()?.onCreatorChannelAudioTabSelected()"))
assertTrue( assertTrue(
source.contains( source.contains(
"currentHeader?.isOwner == true && binding.viewPager.currentItem == CreatorChannelTab.Live.ordinal" "CreatorChannelTab.Live.ordinal -> CreatorChannelTab.Live"
) )
) )
assertTrue(source.contains("binding.layoutCreatorChannelLiveOwnerCta.isVisible = shouldShowLiveOwnerCta")) assertTrue(source.contains("binding.layoutCreatorChannelOwnerCta.isVisible = shouldShowOwnerCta"))
assertTrue(source.contains("findLiveFragment()?.onCreatorChannelLiveOwnerCtaVisibilityChanged(shouldShowLiveOwnerCta)")) assertTrue(
assertTrue(source.contains("return currentHeader?.isOwner == true")) source.contains(
assertTrue(source.contains("binding.btnCreatorChannelLiveOwnerCta.setOnClickListener { onLiveOwnerCtaClicked() }")) "findLiveFragment()?.onCreatorChannelLiveOwnerCtaVisibilityChanged(ownerCtaTab == CreatorChannelTab.Live)"
)
)
assertTrue(source.contains("if (currentHeader?.isOwner != true) return null"))
assertTrue(source.contains("binding.btnCreatorChannelOwnerCta.setOnClickListener { onOwnerCtaClicked() }"))
assertTrue(source.contains("onOwnerFabLiveClicked()")) assertTrue(source.contains("onOwnerFabLiveClicked()"))
assertTrue(source.contains("liveRoomCreateLauncher.launch(Intent(this, LiveRoomCreateActivity::class.java))")) assertTrue(source.contains("liveRoomCreateLauncher.launch(Intent(this, LiveRoomCreateActivity::class.java))"))
} }
@@ -1065,7 +1079,7 @@ class CreatorChannelActivitySourceTest {
assertFalse(source.contains("binding.ownerFabButton.updateLayoutParams<ConstraintLayout.LayoutParams>")) assertFalse(source.contains("binding.ownerFabButton.updateLayoutParams<ConstraintLayout.LayoutParams>"))
assertFalse(source.contains("binding.ownerFabExpandedContainer.updateLayoutParams<ConstraintLayout.LayoutParams>")) assertFalse(source.contains("binding.ownerFabExpandedContainer.updateLayoutParams<ConstraintLayout.LayoutParams>"))
assertFalse(source.contains("binding.layoutCreatorChannelLiveOwnerCta.updateLayoutParams<ConstraintLayout.LayoutParams>")) assertFalse(source.contains("binding.layoutCreatorChannelOwnerCta.updateLayoutParams<ConstraintLayout.LayoutParams>"))
assertFalse(source.contains("WindowInsetsCompat.Type.navigationBars()).bottom")) assertFalse(source.contains("WindowInsetsCompat.Type.navigationBars()).bottom"))
assertTrue( assertTrue(
source.contains( source.contains(