From 8db913812d9b1acdb689917a3d1e20d9258d8a7f Mon Sep 17 00:00:00 2001 From: klaus Date: Mon, 22 Jun 2026 22:07:12 +0900 Subject: [PATCH] =?UTF-8?q?feat(creator):=20=ED=9B=84=EC=9B=90=20=ED=83=AD?= =?UTF-8?q?=20Activity=20=EC=97=B0=EA=B2=B0=EC=9D=84=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../creator/channel/CreatorChannelActivity.kt | 58 ++++++++++++++++++- .../CreatorChannelActivitySourceTest.kt | 35 ++++++++++- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt index b9db801a..e618897b 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt @@ -42,6 +42,7 @@ import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCo import kr.co.vividnext.sodalive.explorer.profile.creator_community.modify.CreatorCommunityModifyActivity import kr.co.vividnext.sodalive.explorer.profile.creator_community.modify.ModifyCommunityPostRequest import kr.co.vividnext.sodalive.explorer.profile.creator_community.write.CreatorCommunityWriteActivity +import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewActivity import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.extensions.loadUrl import kr.co.vividnext.sodalive.extensions.moneyFormat @@ -64,6 +65,7 @@ import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelLiveRespon 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.fantalk.CreatorChannelFanTalkFragment +import kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationFragment 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.CreatorChannelScrollState @@ -85,7 +87,8 @@ class CreatorChannelActivity : CreatorChannelAudioFragment.Host, CreatorChannelSeriesFragment.Host, CreatorChannelCommunityFragment.Host, - CreatorChannelFanTalkFragment.Host { + CreatorChannelFanTalkFragment.Host, + CreatorChannelDonationFragment.Host { private val liveViewModel: LiveViewModel by inject() private val myPageViewModel: MyPageViewModel by inject() @@ -435,6 +438,9 @@ class CreatorChannelActivity : CreatorChannelTab.FanTalk.ordinal -> binding.viewPager.post { findFanTalkFragment()?.onCreatorChannelFanTalkTabSelected() } + CreatorChannelTab.Donation.ordinal -> binding.viewPager.post { + findDonationFragment()?.onCreatorChannelDonationTabSelected() + } } } } @@ -468,6 +474,11 @@ class CreatorChannelActivity : findFanTalkFragment()?.onCreatorChannelFanTalkTabSelected() } } + if (binding.viewPager.currentItem == CreatorChannelTab.Donation.ordinal) { + binding.viewPager.post { + findDonationFragment()?.onCreatorChannelDonationTabSelected() + } + } } override fun onCreatorChannelFollowProgressChanged(inProgress: Boolean) { @@ -548,6 +559,31 @@ class CreatorChannelActivity : } } + override fun onCreatorChannelDonationContentChanged() { + updateViewPagerHeight { + postCheckCreatorChannelCurrentTabNeedsMore() + } + } + + override fun onCreatorChannelDonationRequested( + onSubmit: (can: Int, isSecret: Boolean, message: String) -> Unit + ) { + if (currentHeader?.isOwner == true) return + showCreatorChannelDonationDialog(onSubmit) + } + + override fun onCreatorChannelDonationRankingAllClicked() { + startActivity( + Intent(this, UserProfileDonationAllViewActivity::class.java).apply { + putExtra(Constants.EXTRA_USER_ID, creatorId) + } + ) + } + + override fun onCreatorChannelDonationCompleted() { + homeActionDelegate?.refreshHome() + } + override fun onCreatorChannelFanTalkDeleteClicked(fanTalkId: Long) { SodaDialog( activity = this, @@ -809,6 +845,14 @@ class CreatorChannelActivity : val header = currentHeader ?: return if (header.isOwner) return + showCreatorChannelDonationDialog { can, isSecret, message -> + homeActionDelegate?.postChannelDonation(can = can, isSecret = isSecret, message = message) + } + } + + private fun showCreatorChannelDonationDialog( + onSubmit: (can: Int, isSecret: Boolean, message: String) -> Unit + ) { val dialog = LiveRoomDonationDialog( this, LayoutInflater.from(this), @@ -817,7 +861,7 @@ class CreatorChannelActivity : secretToggleLabelResId = R.string.screen_user_profile_channel_donation_secret, applySecretMissionMessageHint = false ) { can, message, isSecret -> - homeActionDelegate?.postChannelDonation(can = can, isSecret = isSecret, message = message) + onSubmit(can, isSecret, message) } dialog.show(screenWidth - 26.7f.dpToPx().toInt()) } @@ -857,6 +901,11 @@ class CreatorChannelActivity : return supportFragmentManager.findFragmentByTag(fragmentTag) as? CreatorChannelFanTalkFragment } + private fun findDonationFragment(): CreatorChannelDonationFragment? { + val fragmentTag = "f${CreatorChannelTab.Donation.ordinal}" + return supportFragmentManager.findFragmentByTag(fragmentTag) as? CreatorChannelDonationFragment + } + private fun notifyCurrentCreatorChannelTabScrolledToBottom() { when (binding.viewPager.currentItem) { CreatorChannelTab.Live.ordinal -> findLiveFragment()?.onCreatorChannelLiveScrolledToBottom() @@ -864,6 +913,7 @@ class CreatorChannelActivity : CreatorChannelTab.Series.ordinal -> findSeriesFragment()?.onCreatorChannelSeriesScrolledToBottom() CreatorChannelTab.Community.ordinal -> findCommunityFragment()?.onCreatorChannelCommunityScrolledToBottom() CreatorChannelTab.FanTalk.ordinal -> findFanTalkFragment()?.onCreatorChannelFanTalkScrolledToBottom() + CreatorChannelTab.Donation.ordinal -> findDonationFragment()?.onCreatorChannelDonationScrolledToBottom() } } @@ -872,7 +922,8 @@ class CreatorChannelActivity : position == CreatorChannelTab.Audio.ordinal || position == CreatorChannelTab.Series.ordinal || position == CreatorChannelTab.Community.ordinal || - position == CreatorChannelTab.FanTalk.ordinal + position == CreatorChannelTab.FanTalk.ordinal || + position == CreatorChannelTab.Donation.ordinal } private fun ensureLoginAndAdultAuth(isAdult: Boolean, onAuthed: () -> Unit) { @@ -971,6 +1022,7 @@ class CreatorChannelActivity : CreatorChannelTab.Audio.ordinal -> findAudioFragment()?.onCreatorChannelAudioViewportHeightChanged(minHeight) CreatorChannelTab.Series.ordinal -> findSeriesFragment()?.onCreatorChannelSeriesViewportHeightChanged(minHeight) CreatorChannelTab.FanTalk.ordinal -> findFanTalkFragment()?.onCreatorChannelFanTalkViewportHeightChanged(minHeight) + CreatorChannelTab.Donation.ordinal -> findDonationFragment()?.onCreatorChannelDonationViewportHeightChanged(minHeight) } } diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt index 60cdbd93..c909f6cd 100644 --- a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt @@ -417,7 +417,33 @@ class CreatorChannelActivitySourceTest { assertTrue(pagerAdapter.contains("CreatorChannelTab.Audio -> CreatorChannelAudioFragment.newInstance(creatorId)")) assertTrue(pagerAdapter.contains("CreatorChannelTab.Series -> CreatorChannelSeriesFragment.newInstance(creatorId)")) assertTrue(pagerAdapter.contains("CreatorChannelTab.FanTalk -> CreatorChannelFanTalkFragment.newInstance(creatorId)")) - assertFalse(source.contains("CreatorChannelTab.Donation ->")) + assertTrue(pagerAdapter.contains("CreatorChannelTab.Donation -> CreatorChannelDonationFragment.newInstance(creatorId)")) + } + + @Test + fun `Donation tab source는 Fragment Host pagination height action navigation을 Activity에 연결한다`() { + val source = projectFile( + "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt" + ).readText() + val adapter = projectFile( + "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapter.kt" + ).readText() + + assertTrue(adapter.contains("CreatorChannelDonationFragment.newInstance(creatorId)")) + assertTrue(source.contains("CreatorChannelDonationFragment.Host")) + assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationFragment")) + assertTrue(source.contains("findDonationFragment()?.onCreatorChannelDonationTabSelected()")) + assertTrue(source.contains("if (binding.viewPager.currentItem == CreatorChannelTab.Donation.ordinal)")) + assertTrue(source.contains("private fun findDonationFragment(): CreatorChannelDonationFragment?")) + assertTrue(source.contains("findDonationFragment()?.onCreatorChannelDonationScrolledToBottom()")) + assertTrue(source.contains("position == CreatorChannelTab.Donation.ordinal")) + assertTrue(source.contains("findDonationFragment()?.onCreatorChannelDonationViewportHeightChanged(minHeight)")) + assertTrue(source.contains("override fun onCreatorChannelDonationContentChanged()")) + assertTrue(source.contains("override fun onCreatorChannelDonationRequested")) + assertTrue(source.contains("private fun showCreatorChannelDonationDialog(")) + assertTrue(source.contains("homeActionDelegate?.refreshHome()")) + assertTrue(source.contains("UserProfileDonationAllViewActivity::class.java")) + assertTrue(source.contains("putExtra(Constants.EXTRA_USER_ID, creatorId)")) } @Test @@ -843,6 +869,7 @@ class CreatorChannelActivitySourceTest { fragment.contains("viewModel.postChannelDonation(can = can, isSecret = isSecret, message = message)") ) assertTrue(fragment.contains("host.onCreatorChannelDonationClicked()")) + assertTrue(activity.contains("showCreatorChannelDonationDialog")) assertTrue(activity.contains("LiveRoomDonationDialog")) assertTrue(activity.contains("isLiveDonation = true")) assertTrue(activity.contains("messageMaxLength = 100")) @@ -892,7 +919,11 @@ class CreatorChannelActivitySourceTest { val en = projectFile("app/src/main/res/values-en/strings.xml").readText() val ja = projectFile("app/src/main/res/values-ja/strings.xml").readText() - assertTrue(ko.contains("name=\"creator_channel_donation_empty_title\">처음으로 크리에이터를\\n후원해 보세요!")) + assertTrue( + ko.contains( + "name=\"creator_channel_donation_empty_title\">아직 후원이 없습니다.\\n처음으로 크리에이터를 후원해 보세요!" + ) + ) assertTrue(en.contains("creator_channel_donation_empty_title")) assertTrue(ja.contains("creator_channel_donation_empty_title")) }