feat(creator): 커뮤니티 상태에 UI 모델을 적용한다

This commit is contained in:
2026-06-21 22:32:33 +09:00
parent f9501c156a
commit 88fcbe49f4
4 changed files with 25 additions and 15 deletions

View File

@@ -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<UtcRelativeTimeTextFormatter> { AndroidUtcRelativeTimeTextFormatter(get()) }
single { PlaybackTrackingDatabase.getDatabase(get()) }
single<PlaybackTrackingDao> { get<PlaybackTrackingDatabase>().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()) }

View File

@@ -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<CreatorChannelCommunityUiState>()
@@ -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<CreatorChannelCommunityPostResponse>
communityPosts: List<CreatorChannelCommunityPostUiModel>
) = CreatorChannelCommunityUiState.Content(
communityPostCount = communityPostCount,
communityPosts = communityPosts,
@@ -149,24 +152,26 @@ class CreatorChannelCommunityViewModel(
private fun authToken(): String = "Bearer ${SharedPreferenceManager.token}"
private fun CreatorChannelCommunityTabResponse.toCommunityPostUiModels(): List<CreatorChannelCommunityPostUiModel> =
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<CreatorChannelCommunityPostResponse>,
val communityPosts: List<CreatorChannelCommunityPostUiModel>,
val viewMode: CreatorChannelCommunityViewMode,
val page: Int,
val size: Int,