feat(home): 최근 활동 카드 이동을 연결한다

This commit is contained in:
2026-06-06 00:08:41 +09:00
parent c36eddb207
commit 4b4a23c92e
3 changed files with 122 additions and 1 deletions

View File

@@ -35,6 +35,8 @@ import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationRecentDebut
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationUiState import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationUiState
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerIntent import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerIntent
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerRoute import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerRoute
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationRecentlyActiveCreatorIntent
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationRecentlyActiveCreatorRoute
import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomeGenreCreatorGroups import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomeGenreCreatorGroups
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeAiCharacterAdapter import kr.co.vividnext.sodalive.v2.main.home.ui.HomeAiCharacterAdapter
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeBannerBinder import kr.co.vividnext.sodalive.v2.main.home.ui.HomeBannerBinder
@@ -55,7 +57,7 @@ class HomeMainFragment : BaseFragment<FragmentV2MainHomeBinding>(
private val homeRecommendationViewModel: HomeRecommendationViewModel by viewModel() private val homeRecommendationViewModel: HomeRecommendationViewModel by viewModel()
private val loadingDialog: LoadingDialog by lazy { LoadingDialog(requireActivity(), layoutInflater) } private val loadingDialog: LoadingDialog by lazy { LoadingDialog(requireActivity(), layoutInflater) }
private val liveAdapter = HomeLiveAdapter() private val liveAdapter = HomeLiveAdapter()
private val recentActivityCreatorAdapter = HomeRecentActivityCreatorAdapter() private val recentActivityCreatorAdapter = HomeRecentActivityCreatorAdapter { onRecentActivityClick(it) }
private val recentDebutCreatorAdapter = HomeRecentDebutCreatorAdapter { openCreatorProfile(it.creatorId) } private val recentDebutCreatorAdapter = HomeRecentDebutCreatorAdapter { openCreatorProfile(it.creatorId) }
private val firstAudioAdapter = HomeFirstAudioAdapter { openAudioContentDetail(it) } private val firstAudioAdapter = HomeFirstAudioAdapter { openAudioContentDetail(it) }
private val aiCharacterAdapter = HomeAiCharacterAdapter { openCharacterDetail(it.characterId) } private val aiCharacterAdapter = HomeAiCharacterAdapter { openCharacterDetail(it.characterId) }
@@ -273,6 +275,11 @@ class HomeMainFragment : BaseFragment<FragmentV2MainHomeBinding>(
startActivity(route.toHomeRecommendationBannerIntent(requireContext())) startActivity(route.toHomeRecommendationBannerIntent(requireContext()))
} }
private fun onRecentActivityClick(item: HomeRecommendationRecentlyActiveCreatorUiModel) {
val route = item.toHomeRecommendationRecentlyActiveCreatorRoute() ?: return
startActivity(route.toHomeRecommendationRecentlyActiveCreatorIntent(requireContext()))
}
private fun openCreatorProfile(creatorId: Long) { private fun openCreatorProfile(creatorId: Long) {
startActivity( startActivity(
Intent(requireContext(), UserProfileActivity::class.java).apply { Intent(requireContext(), UserProfileActivity::class.java).apply {

View File

@@ -4,9 +4,11 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import kr.co.vividnext.sodalive.BuildConfig import kr.co.vividnext.sodalive.BuildConfig
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.UserProfileActivity import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
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.widget.AudioContentTag import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
@@ -137,6 +139,41 @@ data class HomeRecommendationRecentlyActiveCreatorUiModel(
val targetId: Long? val targetId: Long?
) )
sealed interface HomeRecommendationRecentlyActiveCreatorRoute {
data class AudioContent(val contentId: Long) : HomeRecommendationRecentlyActiveCreatorRoute
data class Community(val creatorId: Long) : HomeRecommendationRecentlyActiveCreatorRoute
}
fun HomeRecommendationRecentlyActiveCreatorUiModel.toHomeRecommendationRecentlyActiveCreatorRoute():
HomeRecommendationRecentlyActiveCreatorRoute? {
val routeTargetId = targetId?.takeIf { it > 0 } ?: return null
return when (activityType) {
RecommendedActivityType.Live -> null
RecommendedActivityType.LiveReplay,
RecommendedActivityType.Audio -> HomeRecommendationRecentlyActiveCreatorRoute.AudioContent(routeTargetId)
RecommendedActivityType.Community -> HomeRecommendationRecentlyActiveCreatorRoute.Community(routeTargetId)
null -> null
}
}
fun HomeRecommendationRecentlyActiveCreatorRoute.toHomeRecommendationRecentlyActiveCreatorIntent(context: Context):
Intent {
return when (this) {
is HomeRecommendationRecentlyActiveCreatorRoute.AudioContent -> {
Intent(context, AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, contentId)
}
}
is HomeRecommendationRecentlyActiveCreatorRoute.Community -> {
Intent(context, CreatorCommunityAllActivity::class.java).apply {
putExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, creatorId)
}
}
}
}
data class HomeRecommendationCreatorUiModel( data class HomeRecommendationCreatorUiModel(
val creatorId: Long, val creatorId: Long,
val nickname: String, val nickname: String,

View File

@@ -23,10 +23,12 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import kr.co.vividnext.sodalive.R import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.BuildConfig import kr.co.vividnext.sodalive.BuildConfig
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.UserProfileActivity import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
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.main.home.data.HomeActiveCreatorItem import kr.co.vividnext.sodalive.v2.main.home.data.HomeActiveCreatorItem
@@ -46,8 +48,13 @@ import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationLiveUiModel
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPopularCommunityPostSection import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPopularCommunityPostSection
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPopularCommunityPostUiModel import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPopularCommunityPostUiModel
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPaidStatus import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPaidStatus
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationRecentlyActiveCreatorRoute
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationRecentlyActiveCreatorUiModel
import kr.co.vividnext.sodalive.v2.main.home.model.RecommendedActivityType
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerIntent import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerIntent
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerRoute import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationBannerRoute
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationRecentlyActiveCreatorIntent
import kr.co.vividnext.sodalive.v2.main.home.model.toHomeRecommendationRecentlyActiveCreatorRoute
import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomePopularCommunityPosts import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomePopularCommunityPosts
import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomeGenreCreatorGroups import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomeGenreCreatorGroups
import kr.co.vividnext.sodalive.v2.main.home.data.HomePopularCommunityPostItem import kr.co.vividnext.sodalive.v2.main.home.data.HomePopularCommunityPostItem
@@ -992,6 +999,62 @@ class HomeMainFragmentLayoutTest {
assertEquals(null, homeBanner(link = "mailto:test@example.com").toHomeRecommendationBannerRoute()) assertEquals(null, homeBanner(link = "mailto:test@example.com").toHomeRecommendationBannerRoute())
} }
@Test
fun `home recent activity route maps activity type to target destination`() {
assertEquals(
HomeRecommendationRecentlyActiveCreatorRoute.AudioContent(11L),
recentActivityCreator(RecommendedActivityType.LiveReplay, targetId = 11L)
.toHomeRecommendationRecentlyActiveCreatorRoute()
)
assertEquals(
HomeRecommendationRecentlyActiveCreatorRoute.AudioContent(12L),
recentActivityCreator(RecommendedActivityType.Audio, targetId = 12L)
.toHomeRecommendationRecentlyActiveCreatorRoute()
)
assertEquals(
HomeRecommendationRecentlyActiveCreatorRoute.Community(13L),
recentActivityCreator(RecommendedActivityType.Community, targetId = 13L)
.toHomeRecommendationRecentlyActiveCreatorRoute()
)
}
@Test
fun `home recent activity route ignores live unknown and missing target`() {
assertEquals(
null,
recentActivityCreator(RecommendedActivityType.Live, targetId = 10L)
.toHomeRecommendationRecentlyActiveCreatorRoute()
)
assertEquals(
null,
recentActivityCreator(activityType = null, targetId = 10L).toHomeRecommendationRecentlyActiveCreatorRoute()
)
assertEquals(
null,
recentActivityCreator(RecommendedActivityType.Audio, targetId = null)
.toHomeRecommendationRecentlyActiveCreatorRoute()
)
assertEquals(
null,
recentActivityCreator(RecommendedActivityType.Community, targetId = 0L)
.toHomeRecommendationRecentlyActiveCreatorRoute()
)
}
@Test
fun `home recent activity route creates expected intents`() {
val context = ApplicationProvider.getApplicationContext<Context>()
val audioIntent = HomeRecommendationRecentlyActiveCreatorRoute.AudioContent(11L)
.toHomeRecommendationRecentlyActiveCreatorIntent(context)
val communityIntent = HomeRecommendationRecentlyActiveCreatorRoute.Community(13L)
.toHomeRecommendationRecentlyActiveCreatorIntent(context)
assertEquals(AudioContentDetailActivity::class.java.name, audioIntent.component?.className)
assertEquals(11L, audioIntent.getLongExtra(Constants.EXTRA_AUDIO_CONTENT_ID, 0L))
assertEquals(CreatorCommunityAllActivity::class.java.name, communityIntent.component?.className)
assertEquals(13L, communityIntent.getLongExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, 0L))
}
@Test @Test
fun `home popular community adapter does not load original image for locked paid post`() { fun `home popular community adapter does not load original image for locked paid post`() {
val context = ApplicationProvider.getApplicationContext<Context>() val context = ApplicationProvider.getApplicationContext<Context>()
@@ -1356,6 +1419,20 @@ class HomeMainFragmentLayoutTest {
) )
} }
private fun recentActivityCreator(
activityType: RecommendedActivityType?,
targetId: Long?
): HomeRecommendationRecentlyActiveCreatorUiModel {
return HomeRecommendationRecentlyActiveCreatorUiModel(
nickname = "크리에이터",
profileImage = "",
activityType = activityType,
activityLabelResId = activityType?.labelResId,
activityAt = "방금 전",
targetId = targetId
)
}
private fun popularCommunityData( private fun popularCommunityData(
audioUrl: String?, audioUrl: String?,
createdAt: String = "2분 전" createdAt: String = "2분 전"