feat(i18n): 콘텐츠 모듈 그룹2 하드코딩 문구를 I18n 키로 통일한다
This commit is contained in:
@@ -28,7 +28,7 @@ struct ContentCreateSelectThemeView: View {
|
||||
|
||||
VStack(spacing: 0) {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
Text("테마 선택")
|
||||
Text(I18n.CreateContent.selectTheme)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@ final class ContentCreateSelectThemeViewModel: ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ struct ContentCreateView: View {
|
||||
GeometryReader { proxy in
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
DetailNavigationBar(title: String(localized: "콘텐츠 등록"))
|
||||
DetailNavigationBar(title: I18n.CreateContent.registerTitle)
|
||||
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
VStack(spacing: 0) {
|
||||
Text("썸네일")
|
||||
Text(I18n.CreateContent.thumbnail)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -73,7 +73,7 @@ struct ContentCreateView: View {
|
||||
.frame(alignment: .bottomTrailing)
|
||||
.onTapGesture { isShowPhotoPicker = true }
|
||||
|
||||
Text("등록")
|
||||
Text(I18n.CreateContent.registerSectionTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -103,12 +103,12 @@ struct ContentCreateView: View {
|
||||
.padding(.top, 26.7)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
Text("제목")
|
||||
Text(I18n.CreateContent.titleLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
TextField("제목을 입력하세요", text: $viewModel.title)
|
||||
TextField(I18n.CreateContent.titlePlaceholder, text: $viewModel.title)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
@@ -121,16 +121,16 @@ struct ContentCreateView: View {
|
||||
.padding(.top, 13.3)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Text("내용")
|
||||
Text(I18n.CreateContent.contentLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("\(viewModel.detail.count)자")
|
||||
Text(I18n.CreateContent.characterCount(viewModel.detail.count))
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.mainRed)
|
||||
Text(" / 최대 500자")
|
||||
Text(I18n.CreateContent.max500CharactersSuffix)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
}
|
||||
@@ -146,7 +146,7 @@ struct ContentCreateView: View {
|
||||
.cornerRadius(6.7)
|
||||
.padding(.top, 13.3)
|
||||
|
||||
Text("테마")
|
||||
Text(I18n.CreateContent.themeLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -188,13 +188,13 @@ struct ContentCreateView: View {
|
||||
hideKeyboard()
|
||||
}
|
||||
|
||||
Text("태그")
|
||||
Text(I18n.CreateContent.tagLabel)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.top, 26.7)
|
||||
|
||||
TextField("예: #연애 #커버곡", text: $viewModel.hashtags)
|
||||
TextField(I18n.CreateContent.tagPlaceholderExample, text: $viewModel.hashtags)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
@@ -215,7 +215,7 @@ struct ContentCreateView: View {
|
||||
.padding(.top, 26.7)
|
||||
|
||||
VStack(spacing: 13.3) {
|
||||
Text("가격 설정")
|
||||
Text(I18n.CreateContent.priceSettingsTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -236,7 +236,7 @@ struct ContentCreateView: View {
|
||||
|
||||
if !viewModel.isFree {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("소장 설정")
|
||||
Text(I18n.CreateContent.ownershipSettingsTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -264,13 +264,13 @@ struct ContentCreateView: View {
|
||||
.padding(.top, 13.3)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
Text(viewModel.purchaseOption == .RENT_ONLY ? "대여 가격" : "소장 가격")
|
||||
Text(viewModel.purchaseOption == .RENT_ONLY ? I18n.CreateContent.rentPriceLabel : I18n.CreateContent.purchasePriceLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayd2)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
TextField("가격을 입력하세요(5캔 이상)", text: $viewModel.priceString)
|
||||
TextField(I18n.CreateContent.priceInputPlaceholder, text: $viewModel.priceString)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 14.7, weight: .bold)
|
||||
@@ -281,7 +281,7 @@ struct ContentCreateView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
Text("캔")
|
||||
Text(I18n.CreateContent.canUnit)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
}
|
||||
@@ -296,18 +296,18 @@ struct ContentCreateView: View {
|
||||
.frame(height: 1)
|
||||
.padding(.top, 11)
|
||||
|
||||
Text("※ 이용기간 대여 (5일) | 소장 (서비스종료시까지)")
|
||||
Text(I18n.CreateContent.rentalPeriodNotice)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.top, 13.3)
|
||||
|
||||
Text("※ 대여가격은 소장가격의 70%로 자동 반영")
|
||||
Text(I18n.CreateContent.rentalPriceAutoNotice)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
Text("※ 콘텐츠의 최소금액은 5캔 입니다")
|
||||
Text(I18n.CreateContent.minimumPriceNotice)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -316,7 +316,7 @@ struct ContentCreateView: View {
|
||||
|
||||
if viewModel.price > 0 && viewModel.purchaseOption != .RENT_ONLY {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("한정판 설정")
|
||||
Text(I18n.CreateContent.limitedEditionSettingsTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -336,7 +336,7 @@ struct ContentCreateView: View {
|
||||
}
|
||||
|
||||
if viewModel.isLimited {
|
||||
TextField("한정판 개수를 입력하세요", text: $viewModel.limitedString)
|
||||
TextField(I18n.CreateContent.limitedCountPlaceholder, text: $viewModel.limitedString)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.appFont(size: 14.7, weight: .bold)
|
||||
@@ -353,7 +353,7 @@ struct ContentCreateView: View {
|
||||
}
|
||||
|
||||
VStack(spacing: 13.3) {
|
||||
Text("포인트 사용")
|
||||
Text(I18n.CreateContent.pointUsageTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -375,7 +375,7 @@ struct ContentCreateView: View {
|
||||
.padding(.top, 26.7)
|
||||
|
||||
VStack(spacing: 13.3) {
|
||||
Text("미리듣기")
|
||||
Text(I18n.CreateContent.previewTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -398,19 +398,19 @@ struct ContentCreateView: View {
|
||||
|
||||
if viewModel.isGeneratePreview {
|
||||
VStack(spacing: 10) {
|
||||
Text("미리듣기 시간 설정")
|
||||
Text(I18n.CreateContent.previewTimeSettingsTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
Text("미리듣기 시간을 직접 설정하지 않으면 콘텐츠 앞부분 15초가 자동으로 설정됩니다. 미리듣기의 시간제한은 없습니다.")
|
||||
Text(I18n.CreateContent.previewTimeGuide)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.gray77)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
HStack(spacing: 13.3) {
|
||||
VStack(spacing: 5.3) {
|
||||
Text("시작 시간")
|
||||
Text(I18n.CreateContent.previewStartTimeLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayd2)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -429,7 +429,7 @@ struct ContentCreateView: View {
|
||||
}
|
||||
|
||||
VStack(spacing: 5.3) {
|
||||
Text("종료 시간")
|
||||
Text(I18n.CreateContent.previewEndTimeLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayd2)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -458,7 +458,7 @@ struct ContentCreateView: View {
|
||||
|
||||
if shouldShowAdultSetting {
|
||||
VStack(spacing: 13.3) {
|
||||
Text("연령 제한")
|
||||
Text(I18n.CreateContent.ageRestrictionTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -477,7 +477,7 @@ struct ContentCreateView: View {
|
||||
}
|
||||
}
|
||||
|
||||
Text("성인콘텐츠를 전체관람가로 등록할 시 발생하는 법적 책임은 회사와 상관없이 콘텐츠를 등록한 본인에게 있습니다.\n콘텐츠 내용은 물론 제목도 19금 여부를 체크해 주시기 바랍니다.")
|
||||
Text(I18n.CreateContent.adultLegalNotice)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.mainRed3)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -488,7 +488,7 @@ struct ContentCreateView: View {
|
||||
}
|
||||
|
||||
VStack(spacing: 13.3) {
|
||||
Text("댓글 가능 여부")
|
||||
Text(I18n.CreateContent.commentAvailabilityTitle)
|
||||
.appFont(size: 16.7, weight: .bold)
|
||||
.foregroundColor(Color.grayee)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -533,7 +533,7 @@ struct ContentCreateView: View {
|
||||
if viewModel.isActiveReservation {
|
||||
HStack(spacing: 13.3) {
|
||||
VStack(alignment: .leading, spacing: 6.7) {
|
||||
Text("예약 날짜")
|
||||
Text(I18n.CreateContent.reservationDateLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -554,7 +554,7 @@ struct ContentCreateView: View {
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 6.7) {
|
||||
Text("예약 시간")
|
||||
Text(I18n.CreateContent.reservationTimeLabel)
|
||||
.appFont(size: 13.3, weight: .medium)
|
||||
.foregroundColor(Color.grayee)
|
||||
|
||||
@@ -586,7 +586,7 @@ struct ContentCreateView: View {
|
||||
|
||||
VStack(spacing: 0) {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
Text("등록")
|
||||
Text(I18n.CreateContent.registerButton)
|
||||
.appFont(size: 18.3, weight: .bold)
|
||||
.foregroundColor(Color.white)
|
||||
.frame(height: 50)
|
||||
|
||||
@@ -154,7 +154,7 @@ final class ContentCreateViewModel: ObservableObject {
|
||||
mimeType: "image/*")
|
||||
)
|
||||
} else {
|
||||
errorMessage = "커버이미지를 업로드 하지 못했습니다.\n다시 선택해 주세요"
|
||||
errorMessage = I18n.CreateContent.coverImageUploadFailed
|
||||
isShowPopup = true
|
||||
isLoading = false
|
||||
return
|
||||
@@ -176,19 +176,19 @@ final class ContentCreateViewModel: ObservableObject {
|
||||
)
|
||||
)
|
||||
} else {
|
||||
errorMessage = "콘텐츠 파일을 업로드 하지 못했습니다.\n다시 선택해 주세요"
|
||||
errorMessage = I18n.CreateContent.contentFileUploadFailed
|
||||
isShowPopup = true
|
||||
isLoading = false
|
||||
return
|
||||
}
|
||||
} else {
|
||||
errorMessage = "콘텐츠 파일을 업로드 하지 못했습니다.\n다시 선택해 주세요"
|
||||
errorMessage = I18n.CreateContent.contentFileUploadFailed
|
||||
isShowPopup = true
|
||||
isLoading = false
|
||||
return
|
||||
}
|
||||
} else {
|
||||
errorMessage = "콘텐츠 파일을 업로드 하지 못했습니다.\n다시 선택해 주세요"
|
||||
errorMessage = I18n.CreateContent.contentFileUploadFailed
|
||||
isShowPopup = true
|
||||
isLoading = false
|
||||
return
|
||||
@@ -219,19 +219,19 @@ final class ContentCreateViewModel: ObservableObject {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
self.isLoading = false
|
||||
}
|
||||
@@ -240,37 +240,37 @@ final class ContentCreateViewModel: ObservableObject {
|
||||
|
||||
private func validateData() -> Bool {
|
||||
if title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
errorMessage = "제목을 입력해 주세요."
|
||||
errorMessage = I18n.CreateContent.titleRequired
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
if detail.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || detail.count < 5 {
|
||||
errorMessage = "내용을 5자 이상 입력해 주세요."
|
||||
errorMessage = I18n.CreateContent.detailMinLengthRequired
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
if theme == nil {
|
||||
errorMessage = "테마를 선택해 주세요."
|
||||
errorMessage = I18n.CreateContent.themeRequired
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
if coverImage == nil {
|
||||
errorMessage = "커버이미지를 선택해 주세요."
|
||||
errorMessage = I18n.CreateContent.coverImageRequired
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
if selectedFileUrl == nil {
|
||||
errorMessage = "오디오 콘텐츠를 선택해 주세요."
|
||||
errorMessage = I18n.CreateContent.audioContentRequired
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
if !isFree && price < 5 {
|
||||
errorMessage = "콘텐츠의 최소금액은 5캔 입니다."
|
||||
errorMessage = I18n.CreateContent.minimumPriceRequired
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
@@ -278,14 +278,14 @@ final class ContentCreateViewModel: ObservableObject {
|
||||
if previewStartTime.count > 0 && previewEndTime.count > 0 {
|
||||
let startTimeArray = previewStartTime.split(separator: ":")
|
||||
if startTimeArray.count != 3 {
|
||||
errorMessage = "미리 듣기 시간 형식은 00:30:00 과 같아야 합니다"
|
||||
errorMessage = I18n.CreateContent.previewTimeFormatInvalid
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
for time in startTimeArray {
|
||||
if time.count != 2 {
|
||||
errorMessage = "미리 듣기 시간 형식은 00:30:00 과 같아야 합니다"
|
||||
errorMessage = I18n.CreateContent.previewTimeFormatInvalid
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
@@ -293,14 +293,14 @@ final class ContentCreateViewModel: ObservableObject {
|
||||
|
||||
let endTimeArray = previewStartTime.split(separator: ":")
|
||||
if endTimeArray.count != 3 {
|
||||
errorMessage = "미리 듣기 시간 형식은 00:30:00 과 같아야 합니다"
|
||||
errorMessage = I18n.CreateContent.previewTimeFormatInvalid
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
for time in endTimeArray {
|
||||
if time.count != 2 {
|
||||
errorMessage = "미리 듣기 시간 형식은 00:30:00 과 같아야 합니다"
|
||||
errorMessage = I18n.CreateContent.previewTimeFormatInvalid
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
@@ -308,13 +308,13 @@ final class ContentCreateViewModel: ObservableObject {
|
||||
|
||||
let timeDifference = timeDifference(startTime: previewStartTime, endTime: previewEndTime)
|
||||
if timeDifference < 15.0 {
|
||||
errorMessage = "미리 듣기의 최소 시간은 15초 입니다"
|
||||
errorMessage = I18n.CreateContent.previewMinimumDurationError
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if previewStartTime.count > 0 || previewEndTime.count > 0 {
|
||||
errorMessage = "미리 듣기 시작 시간과 종료 시간 둘 다 입력을 하거나 둘 다 입력 하지 않아야 합니다."
|
||||
errorMessage = I18n.CreateContent.previewStartEndBothOrNone
|
||||
isShowPopup = true
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ struct QuarterTimePickerView: View {
|
||||
}
|
||||
|
||||
Button(action: { self.isShowing = false }) {
|
||||
Text("확인")
|
||||
Text(I18n.Common.confirm)
|
||||
.appFont(size: 16)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.padding(.vertical, 10)
|
||||
|
||||
@@ -28,7 +28,7 @@ struct SelectDatePicker: View {
|
||||
.frame(width: proxy.size.width)
|
||||
|
||||
Button(action: { self.isShowing = false }) {
|
||||
Text("확인")
|
||||
Text(I18n.Common.confirm)
|
||||
.appFont(size: 16)
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.padding(.vertical, 10)
|
||||
|
||||
Reference in New Issue
Block a user