콘텐츠 메시지 다국어 처리
This commit is contained in:
@@ -36,7 +36,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestPart("request") requestString: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.createAudioContent(
|
||||
@@ -57,7 +57,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestPart("request") requestString: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.modifyAudioContent(
|
||||
@@ -74,7 +74,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestBody request: UploadCompleteRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.uploadComplete(
|
||||
@@ -91,7 +91,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@PathVariable id: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.deleteAudioContent(
|
||||
@@ -111,7 +111,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getAudioContentList(
|
||||
@@ -134,7 +134,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getDetail(
|
||||
@@ -151,7 +151,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@PathVariable id: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(service.generateUrl(contentId = id, member = member))
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestBody request: AddAllPlaybackTrackingRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.addAllPlaybackTracking(request, member))
|
||||
}
|
||||
@@ -170,7 +170,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestBody request: PutAudioContentLikeRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.audioContentLike(request, member))
|
||||
}
|
||||
@@ -179,7 +179,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
fun getAudioContentRankingSort(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.getContentRankingSortTypeList())
|
||||
}
|
||||
@@ -221,7 +221,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@PathVariable id: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.pinToTheTop(contentId = id, member = member))
|
||||
}
|
||||
@@ -232,7 +232,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@PathVariable id: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.unpinAtTheTop(contentId = id, member = member))
|
||||
}
|
||||
@@ -248,7 +248,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getLatestContentByTheme(
|
||||
|
||||
@@ -31,6 +31,7 @@ import kr.co.vividnext.sodalive.extensions.convertLocalDateTime
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.i18n.translation.LanguageTranslationEvent
|
||||
import kr.co.vividnext.sodalive.i18n.translation.LanguageTranslationTargetType
|
||||
import kr.co.vividnext.sodalive.i18n.translation.PapagoTranslationService
|
||||
@@ -74,6 +75,7 @@ class AudioContentService(
|
||||
private val audioContentCloudFront: AudioContentCloudFront,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
|
||||
private val contentThemeTranslationRepository: ContentThemeTranslationRepository,
|
||||
@@ -117,7 +119,7 @@ class AudioContentService(
|
||||
val request = objectMapper.readValue(requestString, ModifyAudioContentRequest::class.java)
|
||||
|
||||
val audioContent = repository.findByIdAndCreatorId(request.contentId, member.id!!)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
if (request.title != null) audioContent.title = request.title
|
||||
if (request.detail != null) audioContent.detail = request.detail
|
||||
@@ -189,7 +191,7 @@ class AudioContentService(
|
||||
@Transactional
|
||||
fun deleteAudioContent(audioContentId: Long, member: Member) {
|
||||
val audioContent = repository.findByIdAndCreatorId(audioContentId, member.id!!)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
audioContent.isActive = false
|
||||
audioContent.releaseDate = null
|
||||
@@ -203,7 +205,7 @@ class AudioContentService(
|
||||
member: Member
|
||||
): CreateAudioContentResponse {
|
||||
// coverImage 체크
|
||||
if (coverImage == null) throw SodaException("커버이미지를 선택해 주세요.")
|
||||
if (coverImage == null) throw SodaException(messageKey = "content.error.cover_image_required")
|
||||
|
||||
// request 내용 파싱
|
||||
val request = objectMapper.readValue(requestString, CreateAudioContentRequest::class.java)
|
||||
@@ -222,18 +224,18 @@ class AudioContentService(
|
||||
|
||||
// contentFile 체크
|
||||
if (contentFile == null) {
|
||||
throw SodaException("콘텐츠를 선택해 주세요.")
|
||||
throw SodaException(messageKey = "content.error.content_required")
|
||||
}
|
||||
|
||||
// 테마 체크
|
||||
val theme = themeQueryRepository.findThemeByIdAndActive(id = request.themeId)
|
||||
?: throw SodaException("잘못된 테마입니다. 다시 선택해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_theme")
|
||||
|
||||
if ((request.themeId == 12L || request.themeId == 13L || request.themeId == 14L) && request.price < 5) {
|
||||
throw SodaException("알람, 모닝콜, 슬립콜 테마의 콘텐츠는 5캔 이상의 유료콘텐츠로 등록이 가능합니다.")
|
||||
throw SodaException(messageKey = "content.error.alarm_theme_price_min")
|
||||
}
|
||||
|
||||
if (request.price in 1..4) throw SodaException("콘텐츠의 최소금액은 5캔 입니다.")
|
||||
if (request.price in 1..4) throw SodaException(messageKey = "content.error.minimum_price")
|
||||
|
||||
val isFullDetailVisible = if (request.price >= 50) {
|
||||
request.isFullDetailVisible
|
||||
@@ -388,34 +390,34 @@ class AudioContentService(
|
||||
if (previewStartTime != null && previewEndTime != null) {
|
||||
val startTimeArray = previewStartTime.split(":")
|
||||
if (startTimeArray.size != 3) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
|
||||
for (time in startTimeArray) {
|
||||
if (time.length != 2) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
}
|
||||
|
||||
val endTimeArray = previewEndTime.split(":")
|
||||
if (endTimeArray.size != 3) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
|
||||
for (time in endTimeArray) {
|
||||
if (time.length != 2) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
}
|
||||
|
||||
val timeDifference = timeDifference(previewStartTime, previewEndTime)
|
||||
|
||||
if (timeDifference < 15000) {
|
||||
throw SodaException("미리 듣기의 최소 시간은 15초 입니다.")
|
||||
throw SodaException(messageKey = "content.error.preview_time_minimum")
|
||||
}
|
||||
} else {
|
||||
if (previewStartTime != null || previewEndTime != null) {
|
||||
throw SodaException("미리 듣기 시작 시간과 종료 시간 둘 다 입력을 하거나 둘 다 입력 하지 않아야 합니다.")
|
||||
throw SodaException(messageKey = "content.error.preview_time_both_required")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,10 +447,10 @@ class AudioContentService(
|
||||
@Transactional
|
||||
fun uploadComplete(contentId: Long, content: String, duration: String) {
|
||||
val keyFileName = content.split("/").last()
|
||||
if (!keyFileName.startsWith(contentId.toString())) throw SodaException("잘못된 요청입니다.")
|
||||
if (!keyFileName.startsWith(contentId.toString())) throw SodaException(messageKey = "common.error.invalid_request")
|
||||
|
||||
val audioContent = repository.findByIdOrNull(contentId)
|
||||
?: throw SodaException("잘못된 요청입니다.")
|
||||
?: throw SodaException(messageKey = "common.error.invalid_request")
|
||||
|
||||
audioContent.content = content
|
||||
audioContent.duration = duration
|
||||
@@ -456,7 +458,7 @@ class AudioContentService(
|
||||
applicationEventPublisher.publishEvent(
|
||||
FcmEvent(
|
||||
type = FcmEventType.INDIVIDUAL,
|
||||
title = "콘텐츠 등록완료",
|
||||
title = formatMessage("content.notification.upload_complete_title"),
|
||||
message = audioContent.title,
|
||||
recipients = listOf(audioContent.member!!.id!!),
|
||||
isAuth = null,
|
||||
@@ -471,7 +473,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = contentId,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -483,7 +485,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = contentId,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -505,7 +507,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = audioContent.id!!,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -517,7 +519,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = audioContent.id!!,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -538,12 +540,12 @@ class AudioContentService(
|
||||
|
||||
// 오디오 콘텐츠 조회 (content_id, 제목, 내용, 테마, 태그, 19여부, 이미지, 콘텐츠 PATH)
|
||||
val audioContent = repository.findByIdOrNull(id)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
// 크리에이터(유저) 정보
|
||||
val creatorId = audioContent.member!!.id!!
|
||||
val creator = explorerQueryRepository.getMember(creatorId)
|
||||
?: throw SodaException("없는 사용자 입니다.")
|
||||
?: throw SodaException(messageKey = "content.error.user_not_found")
|
||||
|
||||
val creatorFollowing = explorerQueryRepository.getCreatorFollowing(
|
||||
creatorId = creatorId,
|
||||
@@ -557,7 +559,9 @@ class AudioContentService(
|
||||
|
||||
// 차단된 사용자 체크
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = creatorId)
|
||||
if (isBlocked && !isExistsAudioContent) throw SodaException("${creator.nickname}님의 요청으로 콘텐츠 접근이 제한됩니다.")
|
||||
if (isBlocked && !isExistsAudioContent) {
|
||||
throw SodaException(formatMessage("content.error.access_restricted_by_creator", creator.nickname))
|
||||
}
|
||||
|
||||
val orderSequence = if (isExistsAudioContent) {
|
||||
limitedEditionOrderRepository.getOrderSequence(
|
||||
@@ -595,7 +599,7 @@ class AudioContentService(
|
||||
audioContent.releaseDate != null &&
|
||||
audioContent.releaseDate!! < LocalDateTime.now()
|
||||
) {
|
||||
throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
}
|
||||
|
||||
// 댓글
|
||||
@@ -628,11 +632,13 @@ class AudioContentService(
|
||||
audioContent.releaseDate != null &&
|
||||
audioContent.releaseDate!! >= LocalDateTime.now()
|
||||
) {
|
||||
val releaseDatePattern = messageSource.getMessage("content.release_date.format", langContext.lang)
|
||||
?: "yyyy년 MM월 dd일 HH시 mm분 오픈예정"
|
||||
audioContent.releaseDate!!
|
||||
.atZone(ZoneId.of("UTC"))
|
||||
.withZoneSameInstant(ZoneId.of("Asia/Seoul"))
|
||||
.toLocalDateTime()
|
||||
.format(DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 HH시 mm분 오픈예정"))
|
||||
.format(DateTimeFormatter.ofPattern(releaseDatePattern, langContext.lang.locale))
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -1114,8 +1120,13 @@ class AudioContentService(
|
||||
limit: Long,
|
||||
sortType: String = "매출"
|
||||
): GetAudioContentRanking {
|
||||
val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일")
|
||||
val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일")
|
||||
val normalizedSortType = normalizeRankingSortType(sortType)
|
||||
val startDatePattern = messageSource.getMessage("content.ranking.date.start_format", langContext.lang)
|
||||
?: "yyyy년 MM월 dd일"
|
||||
val endDatePattern = messageSource.getMessage("content.ranking.date.end_format", langContext.lang)
|
||||
?: "MM월 dd일"
|
||||
val startDateFormatter = DateTimeFormatter.ofPattern(startDatePattern, langContext.lang.locale)
|
||||
val endDateFormatter = DateTimeFormatter.ofPattern(endDatePattern, langContext.lang.locale)
|
||||
|
||||
val contentRankingItemList = repository
|
||||
.getAudioContentRanking(
|
||||
@@ -1126,7 +1137,7 @@ class AudioContentService(
|
||||
contentType = contentType,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
sortType = sortType
|
||||
sortType = normalizedSortType
|
||||
)
|
||||
|
||||
return GetAudioContentRanking(
|
||||
@@ -1137,16 +1148,19 @@ class AudioContentService(
|
||||
}
|
||||
|
||||
fun getContentRankingSortTypeList(): List<String> {
|
||||
return listOf("매출", "댓글", "좋아요")
|
||||
val salesLabel = messageSource.getMessage("content.ranking.sort_type.sales", langContext.lang) ?: "매출"
|
||||
val commentLabel = messageSource.getMessage("content.ranking.sort_type.comment", langContext.lang) ?: "댓글"
|
||||
val likeLabel = messageSource.getMessage("content.ranking.sort_type.like", langContext.lang) ?: "좋아요"
|
||||
return listOf(salesLabel, commentLabel, likeLabel)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun pinToTheTop(contentId: Long, member: Member) {
|
||||
val audioContent = repository.findByIdAndCreatorId(contentId = contentId, creatorId = member.id!!)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
if (audioContent.releaseDate != null && audioContent.releaseDate!! >= LocalDateTime.now()) {
|
||||
throw SodaException("콘텐츠 오픈 후 채널에 고정이 가능합니다.")
|
||||
throw SodaException(messageKey = "content.error.pin_available_after_open")
|
||||
}
|
||||
|
||||
var pinContent = pinContentRepository.findByContentIdAndMemberId(
|
||||
@@ -1176,14 +1190,14 @@ class AudioContentService(
|
||||
val pinContent = pinContentRepository.findByContentIdAndMemberId(
|
||||
contentId = contentId,
|
||||
memberId = member.id!!
|
||||
) ?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
) ?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
pinContent.isActive = false
|
||||
}
|
||||
|
||||
fun generateUrl(contentId: Long, member: Member): GenerateUrlResponse {
|
||||
val audioContent = repository.findByIdOrNull(contentId)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
val isExistsAudioContent = orderRepository.isExistOrdered(
|
||||
memberId = member.id!!,
|
||||
@@ -1312,4 +1326,28 @@ class AudioContentService(
|
||||
.distinct()
|
||||
.toList()
|
||||
}
|
||||
|
||||
private fun normalizeRankingSortType(sortType: String?): String {
|
||||
val trimmed = sortType?.trim().orEmpty()
|
||||
val internalTypes = setOf("매출", "댓글", "좋아요", "후원")
|
||||
if (trimmed in internalTypes) return trimmed
|
||||
|
||||
val salesLabel = messageSource.getMessage("content.ranking.sort_type.sales", langContext.lang)
|
||||
val commentLabel = messageSource.getMessage("content.ranking.sort_type.comment", langContext.lang)
|
||||
val likeLabel = messageSource.getMessage("content.ranking.sort_type.like", langContext.lang)
|
||||
val donationLabel = messageSource.getMessage("content.ranking.sort_type.donation", langContext.lang)
|
||||
|
||||
return when (trimmed) {
|
||||
salesLabel -> "매출"
|
||||
commentLabel -> "댓글"
|
||||
likeLabel -> "좋아요"
|
||||
donationLabel -> "후원"
|
||||
else -> "매출"
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestBody request: CreateCategoryRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.createCategory(request = request, member = member))
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestBody request: ModifyCategoryRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.modifyCategory(request = request, member = member))
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestBody request: UpdateCategoryOrdersRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.updateCategoryOrders(request = request, member = member))
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@PathVariable("id") categoryId: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.deleteCategory(categoryId = categoryId, member = member))
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestParam creatorId: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.getCategoryList(creatorId = creatorId, memberId = member.id!!))
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class CategoryService(
|
||||
@Transactional
|
||||
fun modifyCategory(request: ModifyCategoryRequest, member: Member) {
|
||||
val category = repository.findByIdAndMemberId(categoryId = request.categoryId, memberId = member.id!!)
|
||||
?: throw SodaException("잘못된 요청입니다.")
|
||||
?: throw SodaException(messageKey = "common.error.invalid_request")
|
||||
|
||||
if (!request.title.isNullOrBlank()) {
|
||||
validateTitle(title = request.title)
|
||||
@@ -108,7 +108,7 @@ class CategoryService(
|
||||
@Transactional
|
||||
fun deleteCategory(categoryId: Long, member: Member) {
|
||||
val category = repository.findByIdAndMemberId(categoryId = categoryId, memberId = member.id!!)
|
||||
?: throw SodaException("잘못된 요청입니다.")
|
||||
?: throw SodaException(messageKey = "common.error.invalid_request")
|
||||
category.isActive = false
|
||||
|
||||
categoryContentRepository.deleteByCategoryId(categoryId = categoryId)
|
||||
@@ -128,7 +128,7 @@ class CategoryService(
|
||||
@Transactional
|
||||
fun getCategoryList(creatorId: Long, memberId: Long): List<GetCategoryListResponse> {
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = creatorId)
|
||||
if (isBlocked) throw SodaException("잘못된 접근입니다.")
|
||||
if (isBlocked) throw SodaException(messageKey = "category.error.invalid_access")
|
||||
|
||||
// 기본 카테고리 목록 조회 (원본 언어 기준)
|
||||
val baseList = repository.findByCreatorId(creatorId = creatorId)
|
||||
@@ -205,6 +205,6 @@ class CategoryService(
|
||||
}
|
||||
|
||||
private fun validateTitle(title: String) {
|
||||
if (title.length < 2) throw SodaException("카테고리명은 2글자 이상 입력하세요")
|
||||
if (title.length < 2) throw SodaException(messageKey = "category.error.title_min_length")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class AudioContentCommentController(
|
||||
@RequestBody request: RegisterCommentRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
val commentId = service.registerComment(
|
||||
comment = request.comment,
|
||||
@@ -62,7 +62,7 @@ class AudioContentCommentController(
|
||||
@RequestBody request: ModifyCommentRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.modifyComment(request = request, member = member))
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class AudioContentCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getCommentList(
|
||||
@@ -93,7 +93,7 @@ class AudioContentCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
): ApiResponse<GetAudioContentCommentListResponse> {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
return ApiResponse.ok(
|
||||
service.getCommentReplyList(
|
||||
|
||||
@@ -7,6 +7,8 @@ import kr.co.vividnext.sodalive.content.LanguageDetectTargetType
|
||||
import kr.co.vividnext.sodalive.content.order.OrderRepository
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
@@ -24,6 +26,8 @@ class AudioContentCommentService(
|
||||
private val audioContentRepository: AudioContentRepository,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
private val orderRepository: OrderRepository,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val cloudFrontHost: String
|
||||
@@ -38,11 +42,13 @@ class AudioContentCommentService(
|
||||
languageCode: String?
|
||||
): Long {
|
||||
val audioContent = audioContentRepository.findByIdOrNull(id = audioContentId)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
val creator = audioContent.member!!
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = creator.id!!)
|
||||
if (isBlocked) throw SodaException("${creator.nickname}님의 요청으로 댓글쓰기가 제한됩니다.")
|
||||
if (isBlocked) {
|
||||
throw SodaException(formatMessage("content.comment.error.blocked_by_creator", creator.nickname))
|
||||
}
|
||||
|
||||
val (isExistsAudioContent, _) = orderRepository.isExistOrderedAndOrderType(
|
||||
memberId = member.id!!,
|
||||
@@ -50,7 +56,7 @@ class AudioContentCommentService(
|
||||
)
|
||||
|
||||
if (isSecret && !isExistsAudioContent) {
|
||||
throw SodaException("콘텐츠 구매 후 비밀댓글을 등록할 수 있습니다.")
|
||||
throw SodaException(messageKey = "content.comment.error.secret_requires_purchase")
|
||||
}
|
||||
|
||||
val audioContentComment = AudioContentComment(comment = comment, languageCode = languageCode, isSecret = isSecret)
|
||||
@@ -78,9 +84,9 @@ class AudioContentCommentService(
|
||||
member.nickname
|
||||
},
|
||||
message = if (parent != null) {
|
||||
"댓글에 답글을 달았습니다.: ${audioContent.title}"
|
||||
formatMessage("content.comment.notification.reply", audioContent.title)
|
||||
} else {
|
||||
"콘텐츠에 댓글을 달았습니다.: ${audioContent.title}"
|
||||
formatMessage("content.comment.notification.new", audioContent.title)
|
||||
},
|
||||
contentId = audioContentId,
|
||||
commentParentId = parentId,
|
||||
@@ -105,7 +111,7 @@ class AudioContentCommentService(
|
||||
@Transactional
|
||||
fun modifyComment(request: ModifyCommentRequest, member: Member) {
|
||||
val audioContentComment = repository.findByIdOrNull(request.commentId)
|
||||
?: throw SodaException("잘못된 접근 입니다.\n확인 후 다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.comment.error.invalid_access_retry")
|
||||
|
||||
if (audioContentComment.member!!.id!! == member.id!!) {
|
||||
if (request.comment != null) {
|
||||
@@ -164,4 +170,9 @@ class AudioContentCommentService(
|
||||
|
||||
return GetAudioContentCommentListResponse(totalCount, commentList)
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class AudioContentDonationController(private val service: AudioContentDonationSe
|
||||
@RequestBody request: AudioContentDonationRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.donation(request = request, member = member))
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ class AudioContentDonationService(
|
||||
) {
|
||||
@Transactional
|
||||
fun donation(request: AudioContentDonationRequest, member: Member) {
|
||||
if (request.donationCan < 1) throw SodaException("1캔 이상 후원하실 수 있습니다.")
|
||||
if (request.comment.isBlank()) throw SodaException("함께 보낼 메시지를 입력하세요.")
|
||||
if (request.donationCan < 1) throw SodaException(messageKey = "content.donation.error.minimum_can")
|
||||
if (request.comment.isBlank()) throw SodaException(messageKey = "content.donation.error.comment_required")
|
||||
|
||||
val audioContent = queryRepository.findByIdAndActive(request.contentId)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
canPaymentService.spendCan(
|
||||
memberId = member.id!!,
|
||||
|
||||
@@ -22,7 +22,7 @@ class AudioContentMainController(
|
||||
fun newContentUploadCreatorList(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getNewContentUploadCreatorList(
|
||||
@@ -36,7 +36,7 @@ class AudioContentMainController(
|
||||
fun getMainBannerList(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getAudioContentMainBannerList(
|
||||
@@ -50,7 +50,7 @@ class AudioContentMainController(
|
||||
fun getMainOrderList(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
orderService.getAudioContentMainOrderList(
|
||||
@@ -68,7 +68,7 @@ class AudioContentMainController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getNewContentByTheme(
|
||||
@@ -87,7 +87,7 @@ class AudioContentMainController(
|
||||
@RequestParam("contentType", required = false) contentType: ContentType? = null,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getThemeList(
|
||||
@@ -105,7 +105,7 @@ class AudioContentMainController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getNewContentFor2WeeksByTheme(
|
||||
@@ -125,7 +125,7 @@ class AudioContentMainController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getAudioContentCurationListWithPaging(
|
||||
|
||||
@@ -47,6 +47,177 @@ class SodaMessageSource {
|
||||
)
|
||||
)
|
||||
|
||||
private val contentErrorMessages = mapOf(
|
||||
"content.error.invalid_content_retry" to mapOf(
|
||||
Lang.KO to "잘못된 콘텐츠 입니다.\n다시 시도해 주세요.",
|
||||
Lang.EN to "Invalid content.\nPlease try again.",
|
||||
Lang.JA to "不正なコンテンツです。\nもう一度お試しください。"
|
||||
),
|
||||
"content.error.cover_image_required" to mapOf(
|
||||
Lang.KO to "커버이미지를 선택해 주세요.",
|
||||
Lang.EN to "Please select a cover image.",
|
||||
Lang.JA to "カバー画像を選択してください。"
|
||||
),
|
||||
"content.error.content_required" to mapOf(
|
||||
Lang.KO to "콘텐츠를 선택해 주세요.",
|
||||
Lang.EN to "Please select content.",
|
||||
Lang.JA to "コンテンツを選択してください。"
|
||||
),
|
||||
"content.error.invalid_theme" to mapOf(
|
||||
Lang.KO to "잘못된 테마입니다. 다시 선택해 주세요.",
|
||||
Lang.EN to "Invalid theme. Please select again.",
|
||||
Lang.JA to "不正なテーマです。もう一度選択してください。"
|
||||
),
|
||||
"content.error.alarm_theme_price_min" to mapOf(
|
||||
Lang.KO to "알람, 모닝콜, 슬립콜 테마의 콘텐츠는 5캔 이상의 유료콘텐츠로 등록이 가능합니다.",
|
||||
Lang.EN to "Alarm, Morning Call, and Sleep Call themes require paid content of at least 5 cans.",
|
||||
Lang.JA to "アラーム、モーニングコール、スリープコールのテーマは5缶以上の有料コンテンツのみ登録できます。"
|
||||
),
|
||||
"content.error.minimum_price" to mapOf(
|
||||
Lang.KO to "콘텐츠의 최소금액은 5캔 입니다.",
|
||||
Lang.EN to "The minimum price for content is 5 cans.",
|
||||
Lang.JA to "コンテンツの最低価格は5缶です。"
|
||||
),
|
||||
"content.error.preview_time_format" to mapOf(
|
||||
Lang.KO to "미리 듣기 시간 형식은 00:30:00 과 같아야 합니다",
|
||||
Lang.EN to "Preview time format must be like 00:30:00.",
|
||||
Lang.JA to "プレビュー時間の形式は00:30:00のようにする必要があります。"
|
||||
),
|
||||
"content.error.preview_time_minimum" to mapOf(
|
||||
Lang.KO to "미리 듣기의 최소 시간은 15초 입니다.",
|
||||
Lang.EN to "The minimum preview time is 15 seconds.",
|
||||
Lang.JA to "プレビューの最小時間は15秒です。"
|
||||
),
|
||||
"content.error.preview_time_both_required" to mapOf(
|
||||
Lang.KO to "미리 듣기 시작 시간과 종료 시간 둘 다 입력을 하거나 둘 다 입력 하지 않아야 합니다.",
|
||||
Lang.EN to "You must enter both preview start and end times, or neither.",
|
||||
Lang.JA to "プレビューの開始時間と終了時間は両方入力するか、両方入力しないでください。"
|
||||
),
|
||||
"content.error.user_not_found" to mapOf(
|
||||
Lang.KO to "없는 사용자 입니다.",
|
||||
Lang.EN to "User not found.",
|
||||
Lang.JA to "ユーザーが見つかりません。"
|
||||
),
|
||||
"content.error.access_restricted_by_creator" to mapOf(
|
||||
Lang.KO to "%s님의 요청으로 콘텐츠 접근이 제한됩니다.",
|
||||
Lang.EN to "Access to content is restricted at %s's request.",
|
||||
Lang.JA to "%sさんの要請によりコンテンツへのアクセスが制限されています。"
|
||||
),
|
||||
"content.error.pin_available_after_open" to mapOf(
|
||||
Lang.KO to "콘텐츠 오픈 후 채널에 고정이 가능합니다.",
|
||||
Lang.EN to "You can pin it to the channel after the content is opened.",
|
||||
Lang.JA to "コンテンツ公開後にチャンネルへ固定できます。"
|
||||
)
|
||||
)
|
||||
|
||||
private val contentNotificationMessages = mapOf(
|
||||
"content.notification.upload_complete_title" to mapOf(
|
||||
Lang.KO to "콘텐츠 등록완료",
|
||||
Lang.EN to "Content registration complete",
|
||||
Lang.JA to "コンテンツ登録完了"
|
||||
),
|
||||
"content.notification.uploaded_message" to mapOf(
|
||||
Lang.KO to "콘텐츠를 업로드 하였습니다. - %s",
|
||||
Lang.EN to "Content uploaded. - %s",
|
||||
Lang.JA to "コンテンツをアップロードしました。- %s"
|
||||
)
|
||||
)
|
||||
|
||||
private val contentFormatMessages = mapOf(
|
||||
"content.release_date.format" to mapOf(
|
||||
Lang.KO to "yyyy년 MM월 dd일 HH시 mm분 오픈예정",
|
||||
Lang.EN to "MMM dd, yyyy HH:mm 'Opens soon'",
|
||||
Lang.JA to "yyyy年 MM月 dd日 HH時 mm分 公開予定"
|
||||
),
|
||||
"content.ranking.date.start_format" to mapOf(
|
||||
Lang.KO to "yyyy년 MM월 dd일",
|
||||
Lang.EN to "MMM dd, yyyy",
|
||||
Lang.JA to "yyyy年 MM月 dd日"
|
||||
),
|
||||
"content.ranking.date.end_format" to mapOf(
|
||||
Lang.KO to "MM월 dd일",
|
||||
Lang.EN to "MMM dd",
|
||||
Lang.JA to "MM月 dd日"
|
||||
)
|
||||
)
|
||||
|
||||
private val contentRankingMessages = mapOf(
|
||||
"content.ranking.sort_type.sales" to mapOf(
|
||||
Lang.KO to "매출",
|
||||
Lang.EN to "Sales",
|
||||
Lang.JA to "売上"
|
||||
),
|
||||
"content.ranking.sort_type.comment" to mapOf(
|
||||
Lang.KO to "댓글",
|
||||
Lang.EN to "Comments",
|
||||
Lang.JA to "コメント"
|
||||
),
|
||||
"content.ranking.sort_type.like" to mapOf(
|
||||
Lang.KO to "좋아요",
|
||||
Lang.EN to "Likes",
|
||||
Lang.JA to "いいね"
|
||||
),
|
||||
"content.ranking.sort_type.donation" to mapOf(
|
||||
Lang.KO to "후원",
|
||||
Lang.EN to "Donations",
|
||||
Lang.JA to "支援"
|
||||
)
|
||||
)
|
||||
|
||||
private val contentCommentMessages = mapOf(
|
||||
"content.comment.error.blocked_by_creator" to mapOf(
|
||||
Lang.KO to "%s님의 요청으로 댓글쓰기가 제한됩니다.",
|
||||
Lang.EN to "Commenting is restricted at %s's request.",
|
||||
Lang.JA to "%sさんの要請によりコメントの投稿が制限されています。"
|
||||
),
|
||||
"content.comment.error.secret_requires_purchase" to mapOf(
|
||||
Lang.KO to "콘텐츠 구매 후 비밀댓글을 등록할 수 있습니다.",
|
||||
Lang.EN to "You can post a secret comment after purchasing the content.",
|
||||
Lang.JA to "コンテンツ購入後に秘密コメントを登録できます。"
|
||||
),
|
||||
"content.comment.notification.reply" to mapOf(
|
||||
Lang.KO to "댓글에 답글을 달았습니다.: %s",
|
||||
Lang.EN to "Replied to a comment: %s",
|
||||
Lang.JA to "コメントに返信しました: %s"
|
||||
),
|
||||
"content.comment.notification.new" to mapOf(
|
||||
Lang.KO to "콘텐츠에 댓글을 달았습니다.: %s",
|
||||
Lang.EN to "Commented on content: %s",
|
||||
Lang.JA to "コンテンツにコメントしました: %s"
|
||||
),
|
||||
"content.comment.error.invalid_access_retry" to mapOf(
|
||||
Lang.KO to "잘못된 접근 입니다.\n확인 후 다시 시도해 주세요.",
|
||||
Lang.EN to "Invalid access.\nPlease check and try again.",
|
||||
Lang.JA to "不正なアクセスです。\n確認して再度お試しください。"
|
||||
)
|
||||
)
|
||||
|
||||
private val contentDonationMessages = mapOf(
|
||||
"content.donation.error.minimum_can" to mapOf(
|
||||
Lang.KO to "1캔 이상 후원하실 수 있습니다.",
|
||||
Lang.EN to "You can donate at least 1 can.",
|
||||
Lang.JA to "1缶以上寄付できます。"
|
||||
),
|
||||
"content.donation.error.comment_required" to mapOf(
|
||||
Lang.KO to "함께 보낼 메시지를 입력하세요.",
|
||||
Lang.EN to "Please enter a message to send.",
|
||||
Lang.JA to "一緒に送るメッセージを入力してください。"
|
||||
)
|
||||
)
|
||||
|
||||
private val categoryMessages = mapOf(
|
||||
"category.error.invalid_access" to mapOf(
|
||||
Lang.KO to "잘못된 접근입니다.",
|
||||
Lang.EN to "Invalid access.",
|
||||
Lang.JA to "不正なアクセスです。"
|
||||
),
|
||||
"category.error.title_min_length" to mapOf(
|
||||
Lang.KO to "카테고리명은 2글자 이상 입력하세요",
|
||||
Lang.EN to "Category name must be at least 2 characters.",
|
||||
Lang.JA to "カテゴリ名は2文字以上入力してください。"
|
||||
)
|
||||
)
|
||||
|
||||
private val alarmMessages = mapOf(
|
||||
"alarm.error.already_purchased" to mapOf(
|
||||
Lang.KO to "이미 구매하셨습니다",
|
||||
@@ -1952,6 +2123,13 @@ class SodaMessageSource {
|
||||
fun getMessage(key: String, lang: Lang): String? {
|
||||
val messageGroups = listOf(
|
||||
commonMessages,
|
||||
contentErrorMessages,
|
||||
contentNotificationMessages,
|
||||
contentFormatMessages,
|
||||
contentRankingMessages,
|
||||
contentCommentMessages,
|
||||
contentDonationMessages,
|
||||
categoryMessages,
|
||||
alarmMessages,
|
||||
auditionMessages,
|
||||
auditionRequestMessages,
|
||||
|
||||
Reference in New Issue
Block a user