feat(creator): 커뮤니티 게시글 UI 모델을 추가한다

This commit is contained in:
2026-06-21 22:32:23 +09:00
parent efe12774f7
commit f9501c156a
5 changed files with 285 additions and 0 deletions

View File

@@ -64,6 +64,17 @@ fun formatUtcRelativeTimeText(context: Context, utcText: String?): String {
return context.getString(R.string.character_comment_time_years, years)
}
fun interface UtcRelativeTimeTextFormatter {
fun format(utcText: String?): String
}
class AndroidUtcRelativeTimeTextFormatter(context: Context) : UtcRelativeTimeTextFormatter {
private val applicationContext = context.applicationContext
override fun format(utcText: String?): String = formatUtcRelativeTimeText(applicationContext, utcText)
}
private fun parseServerUtcToMillis(utcText: String?): Long? {
if (utcText.isNullOrBlank()) return null

View File

@@ -0,0 +1,4 @@
package kr.co.vividnext.sodalive.v2.creator.channel.community
typealias CreatorChannelCommunityViewMode =
kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityViewMode

View File

@@ -0,0 +1,56 @@
package kr.co.vividnext.sodalive.v2.creator.channel.community.model
import kr.co.vividnext.sodalive.common.UtcRelativeTimeTextFormatter
import kr.co.vividnext.sodalive.v2.creator.channel.community.data.CreatorChannelCommunityPostResponse
private const val GRID_PREVIEW_MAX_LENGTH = 24
fun List<CreatorChannelCommunityPostResponse>.toCommunityPostUiModels(
relativeTimeTextFormatter: UtcRelativeTimeTextFormatter,
isOwner: Boolean,
currentUserId: Long
): List<CreatorChannelCommunityPostUiModel> = map {
it.toCommunityPostUiModel(relativeTimeTextFormatter, isOwner, currentUserId)
}
private fun CreatorChannelCommunityPostResponse.toCommunityPostUiModel(
relativeTimeTextFormatter: UtcRelativeTimeTextFormatter,
isOwner: Boolean,
currentUserId: Long
): CreatorChannelCommunityPostUiModel {
val isLocked = price > 0 && !existOrdered && !isOwner
val showOwnerActions = isOwner && creatorId == currentUserId
val showPlayButton = !isLocked && !audioUrl.isNullOrBlank() && !imageUrl.isNullOrBlank()
return CreatorChannelCommunityPostUiModel(
postId = postId,
creatorId = creatorId,
creatorNickname = creatorNickname,
creatorProfileUrl = creatorProfileUrl,
createdAtText = relativeTimeTextFormatter.format(createdAtUtc),
content = content,
imageUrl = imageUrl,
audioUrl = audioUrl,
price = price,
existOrdered = existOrdered,
likeCount = likeCount,
commentCount = commentCount,
showComment = isCommentAvailable,
showNotice = isPinned,
isLocked = isLocked,
showOwnerMore = showOwnerActions,
showOwnerTopPrice = showOwnerActions && price > 0,
showPlayButton = showPlayButton,
gridPreviewText = content.toGridPreviewText(),
imageMode = toImageMode(isLocked)
)
}
private fun CreatorChannelCommunityPostResponse.toImageMode(isLocked: Boolean): CreatorChannelCommunityImageMode = when {
isLocked -> CreatorChannelCommunityImageMode.LockedGray
imageUrl.isNullOrBlank() -> CreatorChannelCommunityImageMode.TextPreview
else -> CreatorChannelCommunityImageMode.Image
}
private fun String.toGridPreviewText(): String = replace("\n", " ")
.trim()
.take(GRID_PREVIEW_MAX_LENGTH)

View File

@@ -0,0 +1,48 @@
package kr.co.vividnext.sodalive.v2.creator.channel.community.model
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import kr.co.vividnext.sodalive.R
enum class CreatorChannelCommunityViewMode(
@StringRes val labelResId: Int,
@DrawableRes val iconResId: Int
) {
List(
labelResId = R.string.creator_channel_community_view_mode_list,
iconResId = R.drawable.ic_new_list
),
Grid(
labelResId = R.string.creator_channel_community_view_mode_grid,
iconResId = R.drawable.ic_new_grid
)
}
enum class CreatorChannelCommunityImageMode {
Image,
TextPreview,
LockedGray
}
data class CreatorChannelCommunityPostUiModel(
val postId: Long,
val creatorId: Long,
val creatorNickname: String,
val creatorProfileUrl: String,
val createdAtText: String,
val content: String,
val imageUrl: String?,
val audioUrl: String?,
val price: Int,
val existOrdered: Boolean,
val likeCount: Int,
val commentCount: Int,
val showComment: Boolean,
val showNotice: Boolean,
val isLocked: Boolean,
val showOwnerMore: Boolean,
val showOwnerTopPrice: Boolean,
val showPlayButton: Boolean,
val gridPreviewText: String,
val imageMode: CreatorChannelCommunityImageMode
)