fix(home): 커뮤니티 상세 이동을 연결한다

This commit is contained in:
2026-07-10 10:38:42 +09:00
parent abd084cff8
commit 17f77351ad
4 changed files with 63 additions and 29 deletions

View File

@@ -6,14 +6,12 @@ import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import kr.co.vividnext.sodalive.R import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseFragment import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.common.ToastMessage import kr.co.vividnext.sodalive.common.ToastMessage
import kr.co.vividnext.sodalive.common.formatUtcRelativeTimeText import kr.co.vividnext.sodalive.common.formatUtcRelativeTimeText
import kr.co.vividnext.sodalive.databinding.FragmentV2MainHomeBinding import kr.co.vividnext.sodalive.databinding.FragmentV2MainHomeBinding
import kr.co.vividnext.sodalive.databinding.ViewSectionTitleBinding import kr.co.vividnext.sodalive.databinding.ViewSectionTitleBinding
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
import kr.co.vividnext.sodalive.following.FollowingCreatorActivity import kr.co.vividnext.sodalive.following.FollowingCreatorActivity
import kr.co.vividnext.sodalive.chat.talk.room.ChatRoomActivity import kr.co.vividnext.sodalive.chat.talk.room.ChatRoomActivity
import kr.co.vividnext.sodalive.home.pushnotification.PushNotificationListActivity import kr.co.vividnext.sodalive.home.pushnotification.PushNotificationListActivity
@@ -22,6 +20,7 @@ import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity
import kr.co.vividnext.sodalive.search.SearchActivity import kr.co.vividnext.sodalive.search.SearchActivity
import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivity import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivity
import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveCoordinator import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveCoordinator
import kr.co.vividnext.sodalive.v2.creator.channel.community.detail.CreatorChannelCommunityDetailActivity
import kr.co.vividnext.sodalive.v2.live.onair.HomeOnAirLiveActivity import kr.co.vividnext.sodalive.v2.live.onair.HomeOnAirLiveActivity
import kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatRoomActivity import kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatRoomActivity
import kr.co.vividnext.sodalive.v2.main.chat.model.ChatRoomListUiItem import kr.co.vividnext.sodalive.v2.main.chat.model.ChatRoomListUiItem
@@ -617,16 +616,9 @@ class HomeMainFragment : BaseFragment<FragmentV2MainHomeBinding>(
} }
private fun openPopularCommunityPost(item: FeedItem.Community) { private fun openPopularCommunityPost(item: FeedItem.Community) {
val creatorId = item.creatorId.toLongOrNull() ?: return
val postId = item.postId.toLongOrNull() ?: return val postId = item.postId.toLongOrNull() ?: return
ensureMainV2NavigationAllowed { ensureMainV2NavigationAllowed {
startActivity( startActivity(CreatorChannelCommunityDetailActivity.newIntent(requireContext(), postId))
Intent(requireContext(), CreatorCommunityAllActivity::class.java).apply {
putExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, creatorId)
putExtra(Constants.EXTRA_COMMUNITY_POST_ID, postId)
putExtra(Constants.EXTRA_COMMUNITY_EXIST_ORDERED, item.existOrdered)
}
)
} }
} }

View File

@@ -7,11 +7,11 @@ import kr.co.vividnext.sodalive.BuildConfig
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
import kr.co.vividnext.sodalive.settings.event.EventItem import kr.co.vividnext.sodalive.settings.event.EventItem
import kr.co.vividnext.sodalive.v2.common.CreatorActivityType import kr.co.vividnext.sodalive.v2.common.CreatorActivityType
import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivity import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivity
import kr.co.vividnext.sodalive.v2.creator.channel.community.detail.CreatorChannelCommunityDetailActivity
import kr.co.vividnext.sodalive.v2.widget.characterchatthumbnail.CharacterChatThumbnailItem import kr.co.vividnext.sodalive.v2.widget.characterchatthumbnail.CharacterChatThumbnailItem
import kr.co.vividnext.sodalive.v2.widget.feed.FeedItem import kr.co.vividnext.sodalive.v2.widget.feed.FeedItem
import java.util.Locale import java.util.Locale
@@ -136,7 +136,7 @@ data class HomeRecommendationRecentlyActiveCreatorUiModel(
sealed interface HomeRecommendationRecentlyActiveCreatorRoute { sealed interface HomeRecommendationRecentlyActiveCreatorRoute {
data class AudioContent(val contentId: Long) : HomeRecommendationRecentlyActiveCreatorRoute data class AudioContent(val contentId: Long) : HomeRecommendationRecentlyActiveCreatorRoute
data class Community(val creatorId: Long) : HomeRecommendationRecentlyActiveCreatorRoute data class Community(val postId: Long) : HomeRecommendationRecentlyActiveCreatorRoute
} }
fun HomeRecommendationRecentlyActiveCreatorUiModel.toHomeRecommendationRecentlyActiveCreatorRoute(): fun HomeRecommendationRecentlyActiveCreatorUiModel.toHomeRecommendationRecentlyActiveCreatorRoute():
@@ -160,11 +160,8 @@ fun HomeRecommendationRecentlyActiveCreatorRoute.toHomeRecommendationRecentlyAct
} }
} }
is HomeRecommendationRecentlyActiveCreatorRoute.Community -> { is HomeRecommendationRecentlyActiveCreatorRoute.Community ->
Intent(context, CreatorCommunityAllActivity::class.java).apply { CreatorChannelCommunityDetailActivity.newIntent(context, postId)
putExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, creatorId)
}
}
} }
} }

View File

@@ -27,10 +27,10 @@ import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.formatUtcRelativeTimeText import kr.co.vividnext.sodalive.common.formatUtcRelativeTimeText
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
import kr.co.vividnext.sodalive.settings.event.EventItem import kr.co.vividnext.sodalive.settings.event.EventItem
import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivity import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivity
import kr.co.vividnext.sodalive.v2.creator.channel.community.detail.CreatorChannelCommunityDetailActivity
import kr.co.vividnext.sodalive.v2.main.home.data.HomeActiveCreatorItem import kr.co.vividnext.sodalive.v2.main.home.data.HomeActiveCreatorItem
import kr.co.vividnext.sodalive.v2.main.home.data.HomeAiCharacterItem import kr.co.vividnext.sodalive.v2.main.home.data.HomeAiCharacterItem
import kr.co.vividnext.sodalive.v2.main.home.data.HomeBannerItem import kr.co.vividnext.sodalive.v2.main.home.data.HomeBannerItem
@@ -948,8 +948,8 @@ class HomeMainFragmentLayoutTest {
assertEquals(AudioContentDetailActivity::class.java.name, audioIntent.component?.className) assertEquals(AudioContentDetailActivity::class.java.name, audioIntent.component?.className)
assertEquals(11L, audioIntent.getLongExtra(Constants.EXTRA_AUDIO_CONTENT_ID, 0L)) assertEquals(11L, audioIntent.getLongExtra(Constants.EXTRA_AUDIO_CONTENT_ID, 0L))
assertEquals(CreatorCommunityAllActivity::class.java.name, communityIntent.component?.className) assertEquals(CreatorChannelCommunityDetailActivity::class.java.name, communityIntent.component?.className)
assertEquals(13L, communityIntent.getLongExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, 0L)) assertEquals(13L, communityIntent.getLongExtra("extra_post_id", 0L))
} }
@Test @Test

View File

@@ -35,11 +35,24 @@ class HomeMainFragmentLoginGuardSourceTest {
assertBeforeGuard(source, "val route = item.toHomeRecommendationBannerRoute() ?: return") assertBeforeGuard(source, "val route = item.toHomeRecommendationBannerRoute() ?: return")
assertBeforeGuard(source, "val route = item.toHomeRecommendationRecentlyActiveCreatorRoute() ?: return") assertBeforeGuard(source, "val route = item.toHomeRecommendationRecentlyActiveCreatorRoute() ?: return")
assertBeforeGuard(source, "val route = item.toHomeRecommendationAiCharacterRoute() ?: return") assertBeforeGuard(source, "val route = item.toHomeRecommendationAiCharacterRoute() ?: return")
assertBeforeGuard(source, "val creatorId = item.creatorId.toLongOrNull() ?: return")
assertBeforeGuard(source, "val postId = item.postId.toLongOrNull() ?: return") assertBeforeGuard(source, "val postId = item.postId.toLongOrNull() ?: return")
assertFalse(source.contains("requiresAdultContentAccess = true")) assertFalse(source.contains("requiresAdultContentAccess = true"))
} }
@Test
fun `HomeMainFragment 인기 커뮤니티는 커뮤니티 상세로 이동한다`() {
val source = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt"
).readText()
val clickSource = source.substringFrom("private fun openPopularCommunityPost(item: FeedItem.Community)")
assertTrue(clickSource.contains("CreatorChannelCommunityDetailActivity.newIntent(requireContext(), postId)"))
assertFalse(clickSource.contains("CreatorCommunityAllActivity"))
assertFalse(clickSource.contains("EXTRA_COMMUNITY_CREATOR_ID"))
assertFalse(clickSource.contains("EXTRA_COMMUNITY_POST_ID"))
assertFalse(clickSource.contains("EXTRA_COMMUNITY_EXIST_ORDERED"))
}
@Test @Test
fun `HomeMainFragment 팔로잉 탭 선택은 로그인 가드 통과 후 탭을 전환한다`() { fun `HomeMainFragment 팔로잉 탭 선택은 로그인 가드 통과 후 탭을 전환한다`() {
val source = projectFile( val source = projectFile(
@@ -86,9 +99,21 @@ class HomeMainFragmentLoginGuardSourceTest {
val clickSource = source.substringFrom("private fun onLiveClick(item: HomeRecommendationLiveUiModel)") val clickSource = source.substringFrom("private fun onLiveClick(item: HomeRecommendationLiveUiModel)")
assertTrue(clickSource.contains("ensureMainV2NavigationAllowed")) assertTrue(clickSource.contains("ensureMainV2NavigationAllowed"))
assertTrue(clickSource.contains("liveViewModel.getRoomDetail(item.roomId) { roomDetail ->")) assertTrue(clickSource.contains("liveViewModel.getRoomDetail(item.roomId) { roomDetail ->"))
assertBefore(clickSource, "if (!isAdded || view == null) return@getRoomDetail", "requiresAdultContentAccess = roomDetail.isAdult") assertBefore(
assertBefore(clickSource, "liveViewModel.getRoomDetail(item.roomId) { roomDetail ->", "requiresAdultContentAccess = roomDetail.isAdult") clickSource,
assertBefore(clickSource, "requiresAdultContentAccess = roomDetail.isAdult", "liveCoordinator.enterLiveRoom(item.roomId, roomDetail)") "if (!isAdded || view == null) return@getRoomDetail",
"requiresAdultContentAccess = roomDetail.isAdult"
)
assertBefore(
clickSource,
"liveViewModel.getRoomDetail(item.roomId) { roomDetail ->",
"requiresAdultContentAccess = roomDetail.isAdult"
)
assertBefore(
clickSource,
"requiresAdultContentAccess = roomDetail.isAdult",
"liveCoordinator.enterLiveRoom(item.roomId, roomDetail)"
)
assertFalse(clickSource.contains("= Unit")) assertFalse(clickSource.contains("= Unit"))
assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveCoordinator")) assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveCoordinator"))
@@ -107,14 +132,34 @@ class HomeMainFragmentLoginGuardSourceTest {
assertTrue(source.contains("private var isLiveEntryLoading = false")) assertTrue(source.contains("private var isLiveEntryLoading = false"))
val updateSource = source.substringFrom("private fun updateLoadingDialog()") val updateSource = source.substringFrom("private fun updateLoadingDialog()")
assertTrue(updateSource.contains("isRecommendationLoading || isCreatorRankingLoading || isFollowingLoading || isLiveEntryLoading")) val expectedLoadingExpression = "isRecommendationLoading || " +
"isCreatorRankingLoading || " +
"isFollowingLoading || " +
"isLiveEntryLoading"
assertTrue(updateSource.contains(expectedLoadingExpression))
assertTrue(updateSource.contains("loadingDialog.show(screenWidth)")) assertTrue(updateSource.contains("loadingDialog.show(screenWidth)"))
assertTrue(updateSource.contains("loadingDialog.dismiss()")) assertTrue(updateSource.contains("loadingDialog.dismiss()"))
assertLoadingObserverUsesUpdate(source, "homeRecommendationViewModel.isLoading.observe(viewLifecycleOwner)", "isRecommendationLoading = isLoading") assertLoadingObserverUsesUpdate(
assertLoadingObserverUsesUpdate(source, "homeCreatorRankingViewModel.isLoading.observe(viewLifecycleOwner)", "isCreatorRankingLoading = isLoading") source,
assertLoadingObserverUsesUpdate(source, "homeFollowingViewModel.isLoading.observe(viewLifecycleOwner)", "isFollowingLoading = isLoading") "homeRecommendationViewModel.isLoading.observe(viewLifecycleOwner)",
assertLoadingObserverUsesUpdate(source, "liveViewModel.isLoading.observe(viewLifecycleOwner)", "isLiveEntryLoading = isLoading") "isRecommendationLoading = isLoading"
)
assertLoadingObserverUsesUpdate(
source,
"homeCreatorRankingViewModel.isLoading.observe(viewLifecycleOwner)",
"isCreatorRankingLoading = isLoading"
)
assertLoadingObserverUsesUpdate(
source,
"homeFollowingViewModel.isLoading.observe(viewLifecycleOwner)",
"isFollowingLoading = isLoading"
)
assertLoadingObserverUsesUpdate(
source,
"liveViewModel.isLoading.observe(viewLifecycleOwner)",
"isLiveEntryLoading = isLoading"
)
} }
private fun assertGuardedStartActivity(source: String, functionSignature: String) { private fun assertGuardedStartActivity(source: String, functionSignature: String) {