feat(home): 홈 추천 UI 상태 모델을 추가한다
This commit is contained in:
@@ -1,6 +1,124 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.main.home.model
|
package kr.co.vividnext.sodalive.v2.main.home.model
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
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.HomeBannerItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.home.data.HomeCreatorItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.home.data.HomeFirstAudioContentItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.home.data.HomeGenreCreatorGroupItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.home.data.HomeLiveItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.home.data.HomePopularCommunityPostItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.home.data.HomeRecommendationResponse
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.characterchatthumbnail.CharacterChatThumbnailItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.feed.FeedItem
|
||||||
|
|
||||||
@StringRes
|
@StringRes
|
||||||
fun String.toRecommendedActivityTypeLabelRes(): Int? = RecommendedActivityType.from(this)?.labelResId
|
fun String.toRecommendedActivityTypeLabelRes(): Int? = RecommendedActivityType.from(this)?.labelResId
|
||||||
|
|
||||||
|
fun HomeRecommendationResponse.toContent(): HomeRecommendationUiState.Content = HomeRecommendationUiState.Content(
|
||||||
|
lives = HomeRecommendationLiveSection(lives.map { it.toUiModel() }),
|
||||||
|
banners = HomeRecommendationBannerSection(banners.map { it.toUiModel() }),
|
||||||
|
recentlyActiveCreators = HomeRecommendationRecentlyActiveCreatorSection(recentlyActiveCreators.map { it.toUiModel() }),
|
||||||
|
recentDebutCreators = HomeRecommendationRecentDebutCreatorSection(recentDebutCreators.map { it.toUiModel() }),
|
||||||
|
firstAudioContents = HomeRecommendationFirstAudioContentSection(firstAudioContents.map { it.toUiModel() }),
|
||||||
|
aiCharacters = HomeRecommendationAiCharacterSection(aiCharacters.map { it.toUiModel() }),
|
||||||
|
genreCreators = HomeRecommendationGenreCreatorSection(genreCreators.map { it.toUiModel() }),
|
||||||
|
cheerCreators = HomeRecommendationCheerCreatorSection(cheerCreators.map { it.toUiModel() }),
|
||||||
|
popularCommunityPosts = HomeRecommendationPopularCommunityPostSection(popularCommunityPosts.map { it.toUiModel() })
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomeLiveItem.toUiModel(): HomeRecommendationLiveUiModel = HomeRecommendationLiveUiModel(
|
||||||
|
liveId = liveId,
|
||||||
|
creatorId = creatorId,
|
||||||
|
imageUrl = imageUrl,
|
||||||
|
title = title,
|
||||||
|
creatorNickname = creatorNickname,
|
||||||
|
beginDateTime = beginDateTime
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomeBannerItem.toUiModel(): HomeRecommendationBannerUiModel = HomeRecommendationBannerUiModel(
|
||||||
|
bannerId = bannerId,
|
||||||
|
imageUrl = imageUrl,
|
||||||
|
type = type,
|
||||||
|
linkUrl = linkUrl,
|
||||||
|
targetId = targetId
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomeActiveCreatorItem.toUiModel(): HomeRecommendationRecentlyActiveCreatorUiModel {
|
||||||
|
val recommendedActivityType = RecommendedActivityType.from(activityType)
|
||||||
|
return HomeRecommendationRecentlyActiveCreatorUiModel(
|
||||||
|
creatorId = creatorId,
|
||||||
|
nickname = nickname,
|
||||||
|
profileImage = profileImage,
|
||||||
|
title = title,
|
||||||
|
activityType = recommendedActivityType,
|
||||||
|
activityLabelResId = recommendedActivityType?.labelResId,
|
||||||
|
activityAt = activityAt
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun HomeCreatorItem.toUiModel(): HomeRecommendationCreatorUiModel = HomeRecommendationCreatorUiModel(
|
||||||
|
creatorId = creatorId,
|
||||||
|
nickname = nickname,
|
||||||
|
profileImage = profileImage
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomeFirstAudioContentItem.toUiModel(): HomeRecommendationFirstAudioContentUiModel =
|
||||||
|
HomeRecommendationFirstAudioContentUiModel(
|
||||||
|
contentId = contentId,
|
||||||
|
creatorId = creatorId,
|
||||||
|
creatorNickname = creatorNickname,
|
||||||
|
creatorProfileImage = creatorProfileImage,
|
||||||
|
title = title,
|
||||||
|
price = price,
|
||||||
|
coverImage = coverImage,
|
||||||
|
releaseDate = releaseDate,
|
||||||
|
tags = buildSet {
|
||||||
|
add(AudioContentTag.First)
|
||||||
|
if (isPointAvailable) add(AudioContentTag.Point)
|
||||||
|
if (price == 0) add(AudioContentTag.Free)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomeAiCharacterItem.toUiModel(): HomeRecommendationAiCharacterUiModel = HomeRecommendationAiCharacterUiModel(
|
||||||
|
item = CharacterChatThumbnailItem(
|
||||||
|
characterId = characterId,
|
||||||
|
imageUrl = profileImage.orEmpty(),
|
||||||
|
characterName = name,
|
||||||
|
characterDescription = description,
|
||||||
|
chatMessageCount = totalChatCount,
|
||||||
|
hasOriginal = originalWorkTitle != null,
|
||||||
|
originalTitle = originalWorkTitle.orEmpty()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomeGenreCreatorGroupItem.toUiModel(): HomeRecommendationGenreCreatorGroupUiModel =
|
||||||
|
HomeRecommendationGenreCreatorGroupUiModel(
|
||||||
|
genre = genre,
|
||||||
|
creators = creators.map { it.toUiModel() }
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomePopularCommunityPostItem.toUiModel(): HomeRecommendationPopularCommunityPostUiModel =
|
||||||
|
HomeRecommendationPopularCommunityPostUiModel(
|
||||||
|
item = FeedItem.Community(
|
||||||
|
feedId = postId.toString(),
|
||||||
|
creatorId = creatorId.toString(),
|
||||||
|
creatorName = creatorNickname,
|
||||||
|
creatorImageUrl = creatorProfileImage.orEmpty(),
|
||||||
|
postId = postId.toString(),
|
||||||
|
bodyText = content,
|
||||||
|
keywordText = "",
|
||||||
|
createdAtText = createdAt,
|
||||||
|
commentCount = commentCount.toInt(),
|
||||||
|
likeCount = likeCount.toInt()
|
||||||
|
),
|
||||||
|
paidStatus = toPaidStatus()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun HomePopularCommunityPostItem.toPaidStatus(): HomeRecommendationPaidStatus = when {
|
||||||
|
price == 0 -> HomeRecommendationPaidStatus.Free
|
||||||
|
existOrdered -> HomeRecommendationPaidStatus.Purchased
|
||||||
|
else -> HomeRecommendationPaidStatus.Paid(price)
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.main.home.model
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.characterchatthumbnail.CharacterChatThumbnailItem
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.feed.FeedItem
|
||||||
|
|
||||||
|
data class HomeRecommendationLiveSection(
|
||||||
|
val items: List<HomeRecommendationLiveUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationBannerSection(
|
||||||
|
val items: List<HomeRecommendationBannerUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationRecentlyActiveCreatorSection(
|
||||||
|
val items: List<HomeRecommendationRecentlyActiveCreatorUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationRecentDebutCreatorSection(
|
||||||
|
val items: List<HomeRecommendationCreatorUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationFirstAudioContentSection(
|
||||||
|
val items: List<HomeRecommendationFirstAudioContentUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationAiCharacterSection(
|
||||||
|
val items: List<HomeRecommendationAiCharacterUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationGenreCreatorSection(
|
||||||
|
val groups: List<HomeRecommendationGenreCreatorGroupUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationCheerCreatorSection(
|
||||||
|
val items: List<HomeRecommendationCreatorUiModel>,
|
||||||
|
val isFollowCompleted: Boolean = false
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationPopularCommunityPostSection(
|
||||||
|
val items: List<HomeRecommendationPopularCommunityPostUiModel>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationLiveUiModel(
|
||||||
|
val liveId: Long,
|
||||||
|
val creatorId: Long,
|
||||||
|
val imageUrl: String?,
|
||||||
|
val title: String,
|
||||||
|
val creatorNickname: String,
|
||||||
|
val beginDateTime: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationBannerUiModel(
|
||||||
|
val bannerId: String?,
|
||||||
|
val imageUrl: String?,
|
||||||
|
val type: String?,
|
||||||
|
val linkUrl: String?,
|
||||||
|
val targetId: Long?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationRecentlyActiveCreatorUiModel(
|
||||||
|
val creatorId: Long,
|
||||||
|
val nickname: String,
|
||||||
|
val profileImage: String?,
|
||||||
|
val title: String?,
|
||||||
|
val activityType: RecommendedActivityType?,
|
||||||
|
val activityLabelResId: Int?,
|
||||||
|
val activityAt: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationCreatorUiModel(
|
||||||
|
val creatorId: Long,
|
||||||
|
val nickname: String,
|
||||||
|
val profileImage: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationFirstAudioContentUiModel(
|
||||||
|
val contentId: Long,
|
||||||
|
val creatorId: Long,
|
||||||
|
val creatorNickname: String,
|
||||||
|
val creatorProfileImage: String?,
|
||||||
|
val title: String,
|
||||||
|
val price: Int,
|
||||||
|
val coverImage: String?,
|
||||||
|
val releaseDate: String,
|
||||||
|
val tags: Set<AudioContentTag>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationAiCharacterUiModel(
|
||||||
|
val item: CharacterChatThumbnailItem
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationGenreCreatorGroupUiModel(
|
||||||
|
val genre: String,
|
||||||
|
val creators: List<HomeRecommendationCreatorUiModel>,
|
||||||
|
val isFollowCompleted: Boolean = false
|
||||||
|
)
|
||||||
|
|
||||||
|
data class HomeRecommendationPopularCommunityPostUiModel(
|
||||||
|
val item: FeedItem.Community,
|
||||||
|
val paidStatus: HomeRecommendationPaidStatus
|
||||||
|
)
|
||||||
|
|
||||||
|
sealed interface HomeRecommendationPaidStatus {
|
||||||
|
data object Free : HomeRecommendationPaidStatus
|
||||||
|
|
||||||
|
data object Purchased : HomeRecommendationPaidStatus
|
||||||
|
|
||||||
|
data class Paid(
|
||||||
|
val price: Int
|
||||||
|
) : HomeRecommendationPaidStatus
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.main.home.model
|
||||||
|
|
||||||
|
sealed interface HomeRecommendationUiState {
|
||||||
|
data object Loading : HomeRecommendationUiState
|
||||||
|
|
||||||
|
data class Content(
|
||||||
|
val lives: HomeRecommendationLiveSection,
|
||||||
|
val banners: HomeRecommendationBannerSection,
|
||||||
|
val recentlyActiveCreators: HomeRecommendationRecentlyActiveCreatorSection,
|
||||||
|
val recentDebutCreators: HomeRecommendationRecentDebutCreatorSection,
|
||||||
|
val firstAudioContents: HomeRecommendationFirstAudioContentSection,
|
||||||
|
val aiCharacters: HomeRecommendationAiCharacterSection,
|
||||||
|
val genreCreators: HomeRecommendationGenreCreatorSection,
|
||||||
|
val cheerCreators: HomeRecommendationCheerCreatorSection,
|
||||||
|
val popularCommunityPosts: HomeRecommendationPopularCommunityPostSection
|
||||||
|
) : HomeRecommendationUiState {
|
||||||
|
val isEmpty: Boolean = listOf(
|
||||||
|
lives.items,
|
||||||
|
banners.items,
|
||||||
|
recentlyActiveCreators.items,
|
||||||
|
recentDebutCreators.items,
|
||||||
|
firstAudioContents.items,
|
||||||
|
aiCharacters.items,
|
||||||
|
genreCreators.groups,
|
||||||
|
cheerCreators.items,
|
||||||
|
popularCommunityPosts.items
|
||||||
|
).all { it.isEmpty() }
|
||||||
|
}
|
||||||
|
|
||||||
|
data object Empty : HomeRecommendationUiState
|
||||||
|
|
||||||
|
data class Error(
|
||||||
|
val message: String? = null
|
||||||
|
) : HomeRecommendationUiState
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user