feat(creator): 오디오 탭 mapper를 추가한다

This commit is contained in:
2026-06-19 17:39:31 +09:00
parent d0843d94ed
commit 845b36828b
3 changed files with 277 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
package kr.co.vividnext.sodalive.v2.creator.channel.audio.model
import kr.co.vividnext.sodalive.v2.creator.channel.audio.data.CreatorChannelAudioTabResponse
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
private const val ALL_THEME_TITLE = "전체"
fun CreatorChannelAudioTabResponse.toThemeUiModels(): List<CreatorChannelAudioThemeUiModel> =
listOf(
CreatorChannelAudioThemeUiModel(
themeId = null,
title = ALL_THEME_TITLE,
isSelected = effectiveSelectedThemeId() == null
)
) +
themes.map { theme ->
CreatorChannelAudioThemeUiModel(
themeId = theme.themeId,
title = theme.themeName,
isSelected = theme.themeId == effectiveSelectedThemeId()
)
}
fun CreatorChannelAudioTabResponse.effectiveSelectedThemeId(): Long? =
themeId?.takeIf { selectedThemeId -> themes.any { it.themeId == selectedThemeId } }
fun CreatorChannelAudioTabResponse.toRateUiModel(isOwner: Boolean): CreatorChannelAudioRateUiModel? =
if (!isOwner && effectiveSelectedThemeId() == null) {
CreatorChannelAudioRateUiModel(
ratePercent = purchasedAudioContentRate,
purchasedCount = purchasedAudioContentCount,
paidCount = paidAudioContentCount
)
} else {
null
}
fun List<CreatorChannelAudioContentResponse>.toAudioContentUiModels(): List<CreatorChannelAudioContentUiModel> =
mapNotNull { it.toAudioContentUiModel() }
private fun CreatorChannelAudioContentResponse.toAudioContentUiModel(): CreatorChannelAudioContentUiModel? {
val duration = duration ?: return null
return CreatorChannelAudioContentUiModel(
audioContentId = audioContentId,
title = title,
secondaryText = secondaryText(duration),
imageUrl = imageUrl,
price = price,
showAdultBadge = isAdult,
tags = toAudioContentTags(),
status = toAudioContentStatus()
)
}
private fun CreatorChannelAudioContentResponse.secondaryText(duration: String): String =
if (seriesName.isNullOrBlank()) {
duration
} else {
"$duration$seriesName"
}
private fun CreatorChannelAudioContentResponse.toAudioContentTags(): Set<AudioContentTag> = buildSet {
if (isOriginalSeries == true) add(AudioContentTag.Original)
if (isFirstContent) add(AudioContentTag.First)
if (isPointAvailable) add(AudioContentTag.Point)
if (price == 0) add(AudioContentTag.Free)
}
private fun CreatorChannelAudioContentResponse.toAudioContentStatus(): CreatorChannelAudioContentStatus = when {
isOwned -> CreatorChannelAudioContentStatus.Owned
isRented -> CreatorChannelAudioContentStatus.Rented
price == 0 -> CreatorChannelAudioContentStatus.Play
else -> CreatorChannelAudioContentStatus.Price(price)
}

View File

@@ -0,0 +1,33 @@
package kr.co.vividnext.sodalive.v2.creator.channel.audio.model
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
data class CreatorChannelAudioThemeUiModel(
val themeId: Long?,
val title: String,
val isSelected: Boolean
)
data class CreatorChannelAudioRateUiModel(
val ratePercent: Double,
val purchasedCount: Int,
val paidCount: Int
)
data class CreatorChannelAudioContentUiModel(
val audioContentId: Long,
val title: String,
val secondaryText: String,
val imageUrl: String?,
val price: Int,
val showAdultBadge: Boolean,
val tags: Set<AudioContentTag>,
val status: CreatorChannelAudioContentStatus
)
sealed interface CreatorChannelAudioContentStatus {
data object Play : CreatorChannelAudioContentStatus
data object Owned : CreatorChannelAudioContentStatus
data object Rented : CreatorChannelAudioContentStatus
data class Price(val price: Int) : CreatorChannelAudioContentStatus
}