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 14b533e9..70432bd0 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
@@ -65,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.fantalk.write.CreatorChannelFanTalkWriteActivity
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
@@ -103,6 +104,7 @@ class CreatorChannelActivity :
private var isOwnerFabExpanded: Boolean = false
private var isOwnerFabAnimating: Boolean = false
private var isDonationFloatingButtonVisible: Boolean = false
+ private var isFanTalkFixedPlusVisible: Boolean = false
private lateinit var loadingDialog: LoadingDialog
private val baseTitleBarHeight: Int by lazy { 60.dpToPx().toInt() }
private val liveCoordinator: CreatorChannelLiveCoordinator by lazy {
@@ -130,6 +132,14 @@ class CreatorChannelActivity :
refreshCreatorChannelCommunity()
}
}
+ private val fanTalkWriteLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) { result ->
+ if (result.resultCode == RESULT_OK) {
+ refreshCreatorChannelFanTalk()
+ homeActionDelegate?.refreshHome()
+ }
+ }
private val liveRoomCreateLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
@@ -192,6 +202,7 @@ class CreatorChannelActivity :
binding.btnCreatorChannelDonationWrite.setOnClickListener {
findDonationFragment()?.onCreatorChannelDonationFloatingButtonClicked()
}
+ binding.btnCreatorChannelFantalkFixedPlus.setOnClickListener { openFanTalkWrite() }
binding.btnCreatorChannelOwnerCta.setOnClickListener { onOwnerCtaClicked() }
binding.tvChatButton.setOnClickListener {
currentHeader?.characterId?.let { characterId -> homeActionDelegate?.createChatRoom(characterId) }
@@ -410,6 +421,7 @@ class CreatorChannelActivity :
}
updateOwnerFabVisibility()
updateDonationFloatingButtonVisibility()
+ updateFanTalkFixedPlusVisibility()
updateOwnerCtaVisibility()
updateCreatorChannelTabViewportHeight()
updateViewPagerHeight()
@@ -445,6 +457,7 @@ class CreatorChannelActivity :
bindTitleBar(header)
updateOwnerFabVisibility()
updateDonationFloatingButtonVisibility()
+ updateFanTalkFixedPlusVisibility()
updateOwnerCtaVisibility()
if (binding.viewPager.currentItem == CreatorChannelTab.Audio.ordinal) {
binding.viewPager.post {
@@ -551,6 +564,15 @@ class CreatorChannelActivity :
}
}
+ override fun onCreatorChannelFanTalkWriteClicked() {
+ openFanTalkWrite()
+ }
+
+ override fun onCreatorChannelFanTalkFloatingButtonVisibilityChanged(isVisible: Boolean) {
+ isFanTalkFixedPlusVisible = isVisible
+ updateFanTalkFixedPlusVisibility()
+ }
+
override fun onCreatorChannelDonationContentChanged() {
updateViewPagerHeight {
postCheckCreatorChannelCurrentTabNeedsMore()
@@ -822,6 +844,21 @@ class CreatorChannelActivity :
binding.btnCreatorChannelDonationWrite.isVisible = shouldShowDonationFloatingButton
}
+ private fun updateFanTalkFixedPlusVisibility() {
+ val shouldShowFanTalkFixedPlus =
+ isFanTalkFixedPlusVisible && binding.viewPager.currentItem == CreatorChannelTab.FanTalk.ordinal
+ binding.btnCreatorChannelFantalkFixedPlus.isVisible = shouldShowFanTalkFixedPlus
+ }
+
+ private fun openFanTalkWrite() {
+ if (creatorId <= 0L) return
+ if (SharedPreferenceManager.token.isBlank()) {
+ showLoginActivity()
+ return
+ }
+ fanTalkWriteLauncher.launch(CreatorChannelFanTalkWriteActivity.newIntent(this, creatorId))
+ }
+
private fun onOwnerFabCommunityClicked() {
collapseOwnerFab(animate = false)
communityWriteLauncher.launch(Intent(this, CreatorCommunityWriteActivity::class.java))
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.kt
index 7191f7aa..44e59a36 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.kt
@@ -43,6 +43,7 @@ class CreatorChannelFanTalkFragment : BaseFragment
+
+
+
+
+
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 26ba7ed9..0b65c31a 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
@@ -164,6 +164,38 @@ class CreatorChannelActivitySourceTest {
assertTrue(source.contains("DmChatRoomActivity.newIntentByCreatorId(this, creatorId)"))
}
+ @Test
+ fun `FanTalk fixed plus source는 Activity overlay와 write result refresh 계약을 연결한다`() {
+ val source = projectFile(
+ "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt"
+ ).readText()
+ val layout = projectFile("app/src/main/res/layout/activity_creator_channel.xml").readText()
+ val repository = projectFile(
+ "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelRepository.kt"
+ ).readText()
+ val appDi = projectFile("app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt").readText()
+
+ assertTrue(layout.contains("android:id=\"@+id/btn_creator_channel_fantalk_fixed_plus\""))
+ assertTrue(layout.contains("android:src=\"@drawable/ic_plus_no_bg\""))
+ assertTrue(layout.contains("app:tint=\"@color/white\""))
+ assertTrue(layout.contains("app:layout_constraintBottom_toBottomOf=\"parent\""))
+ assertTrue(layout.contains("app:layout_constraintEnd_toEndOf=\"parent\""))
+ assertTrue(source.contains("private val fanTalkWriteLauncher = registerForActivityResult"))
+ assertTrue(source.contains("CreatorChannelFanTalkWriteActivity.newIntent(this, creatorId)"))
+ assertTrue(source.contains("private fun openFanTalkWrite()"))
+ assertTrue(source.contains("if (creatorId <= 0L) return"))
+ assertTrue(source.contains("if (SharedPreferenceManager.token.isBlank())"))
+ assertTrue(source.contains("showLoginActivity()"))
+ assertTrue(source.contains("refreshCreatorChannelFanTalk()"))
+ assertTrue(source.contains("homeActionDelegate?.refreshHome()"))
+ assertTrue(source.contains("onCreatorChannelFanTalkWriteClicked()"))
+ assertTrue(source.contains("onCreatorChannelFanTalkFloatingButtonVisibilityChanged(isVisible: Boolean)"))
+ assertTrue(source.contains("updateFanTalkFixedPlusVisibility()"))
+ assertTrue(repository.contains("fun writeFanTalk(creatorId: Long, content: String, token: String)"))
+ assertTrue(repository.contains("parentCheersId = null"))
+ assertTrue(appDi.contains("CreatorChannelFanTalkWriteViewModel"))
+ }
+
@Test
fun `Phase 10 컨테이너 layout은 TabLayout과 ViewPager2를 가진다`() {
val layout = projectFile("app/src/main/res/layout/activity_creator_channel.xml").readText()
diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragmentLayoutTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragmentLayoutTest.kt
index 7dde5418..6c3e97a5 100644
--- a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragmentLayoutTest.kt
+++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragmentLayoutTest.kt
@@ -72,7 +72,8 @@ class CreatorChannelFanTalkFragmentLayoutTest {
assertTrue(layout.contains("android:background=\"@drawable/bg_creator_channel_fantalk_empty_button\""))
assertTrue(layout.contains("android:layout_marginStart=\"@dimen/spacing_6\""))
assertTrue(layout.contains("tools:listitem=\"@layout/item_creator_channel_fantalk\""))
- assertTrue(layout.contains("@drawable/ic_new_fantalk_plus"))
+ assertFalse(layout.contains("@drawable/ic_new_fantalk_plus"))
+ assertTrue(layout.contains("@drawable/ic_plus_no_bg"))
assertEquals(ContextCompat.getColor(root.context, R.color.gray_500), emptyMessage.currentTextColor)
assertEquals(ContextCompat.getColor(root.context, R.color.white), emptyButtonLabel.currentTextColor)
assertTrue(
@@ -193,6 +194,27 @@ class CreatorChannelFanTalkFragmentLayoutTest {
assertTrue(adapter.contains("tvCreatorChannelFantalkReport.setOnClickListener { onReportClick(item) }"))
}
+ @Test
+ fun `팬톡 write entry source는 empty 버튼과 fixed plus visibility를 Host로 위임한다`() {
+ val fragment = projectFile(
+ "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.kt"
+ ).readText()
+ val layout = projectFile("app/src/main/res/layout/fragment_creator_channel_fantalk.xml").readText()
+
+ assertTrue(fragment.contains("fun onCreatorChannelFanTalkWriteClicked()"))
+ assertTrue(fragment.contains("fun onCreatorChannelFanTalkFloatingButtonVisibilityChanged(isVisible: Boolean)"))
+ assertTrue(fragment.contains("layoutCreatorChannelFantalkEmptyWriteButton.setOnClickListener"))
+ assertTrue(fragment.contains("host.onCreatorChannelFanTalkWriteClicked()"))
+ assertTrue(fragment.contains("host.onCreatorChannelFanTalkFloatingButtonVisibilityChanged(true)"))
+ assertTrue(fragment.contains("host.onCreatorChannelFanTalkFloatingButtonVisibilityChanged(false)"))
+ assertFalse(fragment.contains("btnCreatorChannelFantalkWrite.setOnClickListener { }"))
+ assertFalse(fragment.contains("btnCreatorChannelFantalkWrite.isVisible = true"))
+ assertTrue(layout.contains("@+id/layout_creator_channel_fantalk_empty_write_button"))
+ assertTrue(layout.contains("android:id=\"@+id/btn_creator_channel_fantalk_write\""))
+ assertTrue(layout.contains("android:visibility=\"gone\""))
+ assertFalse(layout.contains("@drawable/ic_new_fantalk_plus"))
+ }
+
private fun inflateView(layoutResId: Int): View {
val context = ApplicationProvider.getApplicationContext()
return LayoutInflater.from(context).inflate(layoutResId, null, false)