feat(i18n): 탐색 프로필 하드코딩 문구를 I18n 키로 통일한다

This commit is contained in:
Yu Sung
2026-04-01 14:40:37 +09:00
parent bceec46ebc
commit 038d66e363
39 changed files with 599 additions and 247 deletions

View File

@@ -31,7 +31,7 @@ struct CreatorCommunityRecordingVoiceView: View {
VStack {
VStack(spacing: 0) {
HStack(spacing: 0) {
Text("음성녹음")
Text(I18n.Explorer.recordingTitle)
.appFont(size: 18.3, weight: .bold)
.foregroundColor(.white)
@@ -77,7 +77,7 @@ struct CreatorCommunityRecordingVoiceView: View {
HStack(spacing: 0) {
Spacer()
Text("삭제")
Text(I18n.Common.delete)
.appFont(size: 15.3, weight: .medium)
.foregroundColor(Color.graybb.opacity(0))
@@ -100,7 +100,7 @@ struct CreatorCommunityRecordingVoiceView: View {
Spacer()
Text("삭제")
Text(I18n.Common.delete)
.appFont(size: 15.3, weight: .medium)
.foregroundColor(Color.graybb)
.onTapGesture {
@@ -114,7 +114,7 @@ struct CreatorCommunityRecordingVoiceView: View {
.padding(.vertical, 52.3)
HStack(spacing: 13.3) {
Text("다시 녹음")
Text(I18n.Explorer.recordAgain)
.appFont(size: 18.3, weight: .bold)
.foregroundColor(Color.button)
.frame(width: (proxy.size.width - 40) / 3, height: 50)
@@ -130,7 +130,7 @@ struct CreatorCommunityRecordingVoiceView: View {
soundManager.recordMode = .RECORD
}
Text("녹음완료")
Text(I18n.Explorer.recordingComplete)
.appFont(size: 18.3, weight: .bold)
.foregroundColor(.white)
.frame(width: (proxy.size.width - 40) * 2 / 3, height: 50)
@@ -143,7 +143,7 @@ struct CreatorCommunityRecordingVoiceView: View {
self.fileName = tempFileName
self.isShowing = false
} catch {
errorMessage = "녹음파일을 생성하지 못했습니다.\n다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
errorMessage = I18n.Explorer.recordingFileCreateFailed
isShowPopup = true
}
}

View File

@@ -44,14 +44,14 @@ class CreatorCommunitySoundManager: NSObject, ObservableObject {
audioSession.requestRecordPermission() { [weak self] allowed in
DispatchQueue.main.async {
if !allowed {
self?.errorMessage = "권한을 허용하지 않으시면 음성녹음을 하실 수 없습니다."
self?.errorMessage = I18n.Explorer.recordingPermissionDenied
self?.isShowPopup = true
self?.onClose = true
}
}
}
} catch {
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
errorMessage = I18n.Message.Voice.Sound.commonError
isShowPopup = true
onClose = true
}
@@ -84,7 +84,7 @@ class CreatorCommunitySoundManager: NSObject, ObservableObject {
startTimer()
} catch {
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
errorMessage = I18n.Message.Voice.Sound.commonError
isShowPopup = true
}
isLoading = false
@@ -117,7 +117,7 @@ class CreatorCommunitySoundManager: NSObject, ObservableObject {
self.player?.delegate = self
self.player?.prepareToPlay()
} catch {
self.errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
self.errorMessage = I18n.Message.Voice.Sound.commonError
self.isShowPopup = true
}
@@ -142,7 +142,9 @@ class CreatorCommunitySoundManager: NSObject, ObservableObject {
func deleteAudioFile() {
do {
try FileManager.default.removeItem(at: getAudioFileURL())
} catch {}
} catch {
DEBUG_LOG("오디오 파일 삭제 실패: \(error)")
}
}
func getAudioFileURL() -> URL {

View File

@@ -19,7 +19,7 @@ struct CreatorCommunityWriteView: View {
@State private var isImageLoading = false
@State private var isShowRecordingVoiceView = false
@State private var fileName: String = "녹음"
@State private var fileName: String = I18n.Explorer.recordingDefaultFileName
private let imagePreviewSize: CGFloat = 110
@@ -30,12 +30,12 @@ struct CreatorCommunityWriteView: View {
GeometryReader { proxy in
ZStack {
VStack(spacing: 0) {
DetailNavigationBar(title: "게시글 등록")
DetailNavigationBar(title: I18n.Explorer.postWriteTitle)
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 0) {
VStack(spacing: 13.3) {
Text("이미지")
Text(I18n.Explorer.imageTitle)
.appFont(size: 16.7, weight: .bold)
.foregroundColor(Color.grayee)
.frame(maxWidth: .infinity, alignment: .leading)
@@ -75,7 +75,7 @@ struct CreatorCommunityWriteView: View {
.appFont(size: 13.3, weight: .medium)
.foregroundColor(Color.gray77)
Text("등록할 이미지가 없으면 이미지 없이 게시글만 등록 하셔도 됩니다.")
Text(I18n.Explorer.imageOptionalNotice)
.appFont(size: 13.3, weight: .medium)
.foregroundColor(Color.gray77)
}
@@ -85,7 +85,7 @@ struct CreatorCommunityWriteView: View {
if let _ = viewModel.postImageData {
VStack(spacing: 13.3) {
HStack(spacing: 0) {
Text("오디오 녹음")
Text(I18n.Explorer.audioRecordingTitle)
.appFont(size: 16.7, weight: .bold)
.foregroundColor(Color.grayee)
@@ -107,7 +107,7 @@ struct CreatorCommunityWriteView: View {
.onTapGesture { isShowRecordingVoiceView = true }
Text("※ 오디오 녹음은 최대 3분입니다")
Text(I18n.Explorer.audioRecordingMax3Minutes)
.appFont(size: 13.3, weight: .medium)
.foregroundColor(Color.gray77)
}
@@ -115,16 +115,16 @@ struct CreatorCommunityWriteView: View {
}
HStack(spacing: 0) {
Text("내용")
Text(I18n.Explorer.contentTitle)
.appFont(size: 16.7, weight: .bold)
.foregroundColor(Color.grayee)
Spacer()
Text("\(viewModel.content.count)")
Text("\(viewModel.content.count)\(I18n.Explorer.contentCharacterUnit)")
.appFont(size: 13.3, weight: .medium)
.foregroundColor(Color.mainRed)
Text(" / 최대 500자")
Text(I18n.Explorer.max500Chars)
.appFont(size: 13.3, weight: .medium)
.foregroundColor(Color.gray77)
}
@@ -141,14 +141,14 @@ struct CreatorCommunityWriteView: View {
.padding(.top, 13.3)
VStack(spacing: 13.3) {
Text("댓글 가능 여부")
Text(I18n.Explorer.commentAvailability)
.appFont(size: 16.7, weight: .bold)
.foregroundColor(Color.grayee)
.frame(maxWidth: .infinity, alignment: .leading)
HStack(spacing: 13.3) {
SelectButtonView(
title: "댓글 가능",
title: I18n.CreateContent.commentAllowed,
isChecked: viewModel.isAvailableComment
) {
if !viewModel.isAvailableComment {
@@ -157,7 +157,7 @@ struct CreatorCommunityWriteView: View {
}
SelectButtonView(
title: "댓글 불가",
title: I18n.CreateContent.commentNotAllowed,
isChecked: !viewModel.isAvailableComment
) {
if viewModel.isAvailableComment {
@@ -170,14 +170,14 @@ struct CreatorCommunityWriteView: View {
if UserDefaults.bool(forKey: .auth) {
VStack(spacing: 13.3) {
Text("연령 제한")
Text(I18n.Explorer.ageRestriction)
.appFont(size: 16.7, weight: .bold)
.foregroundColor(Color.grayee)
.frame(maxWidth: .infinity, alignment: .leading)
HStack(spacing: 13.3) {
SelectButtonView(
title: "전체 연령",
title: I18n.CreateContent.allAges,
isChecked: !viewModel.isAdult
) {
if viewModel.isAdult {
@@ -186,7 +186,7 @@ struct CreatorCommunityWriteView: View {
}
SelectButtonView(
title: "19세 이상",
title: I18n.CreateContent.over19,
isChecked: viewModel.isAdult
) {
if !viewModel.isAdult {
@@ -200,14 +200,14 @@ struct CreatorCommunityWriteView: View {
if let _ = viewModel.postImageData {
VStack(spacing: 13.3) {
Text("가격 설정")
Text(I18n.Explorer.priceSetting)
.appFont(size: 16.7, weight: .bold)
.foregroundColor(Color.grayee)
.frame(maxWidth: .infinity, alignment: .leading)
HStack(spacing: 13.3) {
SelectButtonView(
title: "무료",
title: I18n.CreateContent.free,
isChecked: viewModel.isPriceFree
) {
if !viewModel.isPriceFree {
@@ -216,7 +216,7 @@ struct CreatorCommunityWriteView: View {
}
SelectButtonView(
title: "유료",
title: I18n.CreateContent.paid,
isChecked: !viewModel.isPriceFree
) {
if viewModel.isPriceFree {
@@ -238,7 +238,7 @@ struct CreatorCommunityWriteView: View {
Spacer()
Text("")
Text(I18n.Explorer.canUnitCompact)
.appFont(size: 14.7, weight: .medium)
.foregroundColor(Color.button)
}
@@ -259,7 +259,7 @@ struct CreatorCommunityWriteView: View {
VStack(spacing: 0) {
HStack(spacing: 13.3) {
Text("닫기")
Text(I18n.Explorer.close)
.appFont(size: 18.3, weight: .bold)
.foregroundColor(Color.button)
.frame(maxWidth: .infinity)
@@ -275,7 +275,7 @@ struct CreatorCommunityWriteView: View {
AppState.shared.back()
}
Text("등록")
Text(I18n.Explorer.register)
.appFont(size: 18.3, weight: .bold)
.foregroundColor(Color.white)
.frame(maxWidth: .infinity)

View File

@@ -47,7 +47,7 @@ final class CreatorCommunityWriteViewModel: ObservableObject {
@Published var price = 0
@Published var soundData: Data? = nil
var placeholder = "내용을 입력하세요"
var placeholder = I18n.Explorer.inputContent
func setPostImage(_ image: UIImage) {
postImage = image
@@ -99,7 +99,7 @@ final class CreatorCommunityWriteViewModel: ObservableObject {
case .failure(let error):
ERROR_LOG(error.localizedDescription)
self.isLoading = false
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.errorMessage = I18n.Common.commonError
self.isShowPopup = true
}
} receiveValue: { [unowned self] response in
@@ -111,7 +111,7 @@ final class CreatorCommunityWriteViewModel: ObservableObject {
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
if decoded.success {
self.errorMessage = "게시물이 등록되었습니다."
self.errorMessage = I18n.Explorer.postCreated
self.isShowPopup = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
@@ -121,19 +121,19 @@ final class CreatorCommunityWriteViewModel: 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
}
@@ -142,13 +142,13 @@ final class CreatorCommunityWriteViewModel: ObservableObject {
private func validateData() -> Bool {
if content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || content.count < 5 {
errorMessage = "내용을 5자 이상 입력해 주세요."
errorMessage = I18n.Explorer.minContentLength(5)
isShowPopup = true
return false
}
if !isPriceFree && price < 5 {
errorMessage = "최소금액은 5캔 입니다."
errorMessage = I18n.Explorer.minPriceFiveCans
isShowPopup = true
return false
}