From 88fcbe49f4722f048fac431a13443a8d2568ab57 Mon Sep 17 00:00:00 2001 From: klaus Date: Sun, 21 Jun 2026 22:32:33 +0900 Subject: [PATCH] =?UTF-8?q?feat(creator):=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=83=81=ED=83=9C=EC=97=90=20UI=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=EC=9D=84=20=EC=A0=81=EC=9A=A9=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kr/co/vividnext/sodalive/di/AppDI.kt | 5 +++- .../CreatorChannelCommunityViewModel.kt | 29 +++++++++++-------- .../CreatorChannelCommunityPaginationTest.kt | 3 +- .../CreatorChannelCommunityViewModelTest.kt | 3 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt index bc0b32dc..f81ebebe 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt @@ -68,6 +68,8 @@ import kr.co.vividnext.sodalive.chat.talk.TalkTabRepository import kr.co.vividnext.sodalive.chat.talk.TalkTabViewModel import kr.co.vividnext.sodalive.chat.talk.room.chatTalkRoomModule import kr.co.vividnext.sodalive.common.ApiBuilder +import kr.co.vividnext.sodalive.common.AndroidUtcRelativeTimeTextFormatter +import kr.co.vividnext.sodalive.common.UtcRelativeTimeTextFormatter import kr.co.vividnext.sodalive.explorer.ExplorerApi import kr.co.vividnext.sodalive.explorer.ExplorerRepository import kr.co.vividnext.sodalive.explorer.ExplorerViewModel @@ -215,6 +217,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { private val otherModule = module { single { GsonBuilder().create() } + single { AndroidUtcRelativeTimeTextFormatter(get()) } single { PlaybackTrackingDatabase.getDatabase(get()) } single { get().playbackTrackingDao() } } @@ -415,7 +418,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { CreatorChannelLiveViewModel(get()) } viewModel { CreatorChannelAudioViewModel(get()) } viewModel { CreatorChannelSeriesViewModel(get()) } - viewModel { CreatorChannelCommunityViewModel(get()) } + viewModel { CreatorChannelCommunityViewModel(get(), get()) } viewModel { PushNotificationListViewModel(get()) } viewModel { CharacterTabViewModel(get()) } viewModel { CharacterDetailViewModel(get()) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModel.kt index 38a35c4d..7a0d6cb4 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModel.kt @@ -8,12 +8,15 @@ import io.reactivex.rxjava3.schedulers.Schedulers import kr.co.vividnext.sodalive.base.BaseViewModel import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.common.SharedPreferenceManager -import kr.co.vividnext.sodalive.v2.creator.channel.community.data.CreatorChannelCommunityPostResponse +import kr.co.vividnext.sodalive.common.UtcRelativeTimeTextFormatter import kr.co.vividnext.sodalive.v2.creator.channel.community.data.CreatorChannelCommunityTabResponse +import kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityPostUiModel +import kr.co.vividnext.sodalive.v2.creator.channel.community.model.toCommunityPostUiModels import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelRepository class CreatorChannelCommunityViewModel( - private val repository: CreatorChannelRepository + private val repository: CreatorChannelRepository, + private val relativeTimeTextFormatter: UtcRelativeTimeTextFormatter ) : BaseViewModel() { private val _communityStateLiveData = MutableLiveData() @@ -61,7 +64,7 @@ class CreatorChannelCommunityViewModel( val current = _communityStateLiveData.value as? CreatorChannelCommunityUiState.Content ?: content if (response.success && data != null) { _communityStateLiveData.value = current.copy( - communityPosts = current.communityPosts + data.communityPosts, + communityPosts = current.communityPosts + data.toCommunityPostUiModels(), page = data.page, size = data.size, hasNext = data.hasNext, @@ -89,7 +92,7 @@ class CreatorChannelCommunityViewModel( requestCommunity(page = FIRST_PAGE, generation = generation) { response -> val data = response.data if (response.success && data != null) { - val communityPosts = data.communityPosts + val communityPosts = data.toCommunityPostUiModels() _communityStateLiveData.value = if (communityPosts.isEmpty() || data.communityPostCount == 0) { CreatorChannelCommunityUiState.Empty } else { @@ -137,7 +140,7 @@ class CreatorChannelCommunityViewModel( } private fun CreatorChannelCommunityTabResponse.toContentState( - communityPosts: List + communityPosts: List ) = CreatorChannelCommunityUiState.Content( communityPostCount = communityPostCount, communityPosts = communityPosts, @@ -149,24 +152,26 @@ class CreatorChannelCommunityViewModel( private fun authToken(): String = "Bearer ${SharedPreferenceManager.token}" + private fun CreatorChannelCommunityTabResponse.toCommunityPostUiModels(): List = + communityPosts.toCommunityPostUiModels( + relativeTimeTextFormatter = relativeTimeTextFormatter, + isOwner = isOwner, + currentUserId = SharedPreferenceManager.userId + ) + companion object { - val DEFAULT_PAGE_SIZE = 20 + const val DEFAULT_PAGE_SIZE = 20 private const val FIRST_PAGE = 0 } } -enum class CreatorChannelCommunityViewMode { - List, - Grid -} - sealed interface CreatorChannelCommunityUiState { data object Loading : CreatorChannelCommunityUiState data object Empty : CreatorChannelCommunityUiState data class Error(val message: String?) : CreatorChannelCommunityUiState data class Content( val communityPostCount: Int, - val communityPosts: List, + val communityPosts: List, val viewMode: CreatorChannelCommunityViewMode, val page: Int, val size: Int, diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityPaginationTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityPaginationTest.kt index 4265593f..880182a5 100644 --- a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityPaginationTest.kt +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityPaginationTest.kt @@ -12,6 +12,7 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.subjects.SingleSubject import kr.co.vividnext.sodalive.common.ApiResponse +import kr.co.vividnext.sodalive.common.AndroidUtcRelativeTimeTextFormatter import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.v2.creator.channel.community.data.CreatorChannelCommunityPostResponse import kr.co.vividnext.sodalive.v2.creator.channel.community.data.CreatorChannelCommunityTabResponse @@ -44,7 +45,7 @@ class CreatorChannelCommunityPaginationTest { SharedPreferenceManager.init(context) SharedPreferenceManager.token = "test-token" repository = org.mockito.kotlin.mock() - viewModel = CreatorChannelCommunityViewModel(repository) + viewModel = CreatorChannelCommunityViewModel(repository, AndroidUtcRelativeTimeTextFormatter(context)) } @After diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModelTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModelTest.kt index 3dcbafa7..b81e3afc 100644 --- a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModelTest.kt +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityViewModelTest.kt @@ -11,6 +11,7 @@ import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.plugins.RxJavaPlugins import io.reactivex.rxjava3.schedulers.Schedulers import kr.co.vividnext.sodalive.common.ApiResponse +import kr.co.vividnext.sodalive.common.AndroidUtcRelativeTimeTextFormatter import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.v2.creator.channel.community.data.CreatorChannelCommunityPostResponse import kr.co.vividnext.sodalive.v2.creator.channel.community.data.CreatorChannelCommunityTabResponse @@ -44,7 +45,7 @@ class CreatorChannelCommunityViewModelTest { SharedPreferenceManager.init(context) SharedPreferenceManager.token = "test-token" repository = org.mockito.kotlin.mock() - viewModel = CreatorChannelCommunityViewModel(repository) + viewModel = CreatorChannelCommunityViewModel(repository, AndroidUtcRelativeTimeTextFormatter(context)) } @After