feat(i18n): 메시지 모듈 하드코딩 문구를 I18n 키로 통일한다

This commit is contained in:
Yu Sung
2026-03-31 22:01:30 +09:00
parent 4c170e0f97
commit 9369a52ba2
11 changed files with 226 additions and 51 deletions

View File

@@ -13,7 +13,7 @@ struct MessageFilterTabView: View {
var body: some View {
HStack(spacing: 6.7) {
Text("받은 메시지")
Text(I18n.Message.FilterTab.received)
.appFont(size: 12, weight: .medium)
.foregroundColor(Color(hex: currentFilterTab == .receive ? "3bb9f1" : "777777"))
.padding(.horizontal, 25)
@@ -31,7 +31,7 @@ struct MessageFilterTabView: View {
}
}
Text("보낸 메시지")
Text(I18n.Message.FilterTab.sent)
.appFont(size: 12, weight: .medium)
.foregroundColor(Color(hex: currentFilterTab == .sent ? "3bb9f1" : "777777"))
.padding(.horizontal, 25)
@@ -49,7 +49,7 @@ struct MessageFilterTabView: View {
}
}
Text("보관함")
Text(I18n.Message.FilterTab.archive)
.appFont(size: 12, weight: .medium)
.foregroundColor(Color(hex: currentFilterTab == .keep ? "3bb9f1" : "777777"))
.padding(.horizontal, 25)

View File

@@ -17,11 +17,11 @@ struct MessageView: View {
Color.black
VStack {
DetailNavigationBar(title: String(localized: "메시지"))
DetailNavigationBar(title: I18n.Message.title)
Tab()
Text("※ 보관하지 않은 받은 메시지는 3일 후, 자동 삭제됩니다.")
Text(I18n.Message.autoDeleteNotice)
.appFont(size: 13.3, weight: .medium)
.padding(.top, 20)
@@ -50,7 +50,7 @@ struct MessageView: View {
}
}) {
VStack(spacing: 0) {
Text("문자")
Text(I18n.Message.Tab.text)
.appFont(size: 16.7, weight: .medium)
.foregroundColor(Color(hex: viewModel.currentTab == .text ? "eeeeee" : "777777"))
.frame(width: tabWidth, height: 50)
@@ -69,7 +69,7 @@ struct MessageView: View {
}
}) {
VStack(spacing: 0) {
Text("음성")
Text(I18n.Message.Tab.voice)
.appFont(size: 16.7, weight: .medium)
.foregroundColor(Color(hex: viewModel.currentTab == .voice ? "eeeeee" : "777777"))
.frame(width: tabWidth, height: 50)

View File

@@ -28,11 +28,11 @@ struct TextMessageDetailView: View {
VStack(spacing: 0) {
switch messageBox {
case .receive:
DetailNavigationBar(title: "받은 메시지 상세") { back() }
DetailNavigationBar(title: I18n.Message.Text.Detail.receivedTitle) { back() }
case .sent:
DetailNavigationBar(title: "보낸 메시지 상세") { back() }
DetailNavigationBar(title: I18n.Message.Text.Detail.sentTitle) { back() }
case .keep:
DetailNavigationBar(title: "저장한 메시지 상세") { back() }
DetailNavigationBar(title: I18n.Message.Text.Detail.keptTitle) { back() }
}
HStack(spacing: 13.3) {
@@ -70,7 +70,7 @@ struct TextMessageDetailView: View {
Text(messageItem.date.convertDateFormat(
from: "yyyy-MM-dd hh:mm:ss",
to: "yyyy년 MM월 dd일 E요일 HH:mm"
to: I18n.Message.Text.Detail.dateFormat
))
.appFont(size: 15, weight: .medium)
.foregroundColor(Color(hex: "bbbbbb"))
@@ -93,7 +93,7 @@ struct TextMessageDetailView: View {
if messageBox == .receive {
HStack(spacing: 6.7) {
Text("답장")
Text(I18n.Message.Text.Detail.reply)
.appFont(size: 14.7, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
.frame(
@@ -106,7 +106,7 @@ struct TextMessageDetailView: View {
AppState.shared.setAppStep(step: .writeTextMessage(userId: messageItem.senderId, nickname: messageItem.senderNickname))
}
Text("보관")
Text(I18n.Message.Text.Detail.keep)
.appFont(size: 14.7, weight: .bold)
.foregroundColor(Color(hex: "3bb9f1"))
.frame(
@@ -117,15 +117,15 @@ struct TextMessageDetailView: View {
.cornerRadius(6.7)
.onTapGesture {
if messageItem.isKept {
viewModel.errorMessage = "이미 보관된 메시지 입니다"
viewModel.errorMessage = I18n.Message.Text.Detail.alreadyKept
viewModel.isShowPopup = true
return
} else {
viewModel.keepTextMessage()
}
}
Text("삭제")
Text(I18n.Common.delete)
.appFont(size: 14.7, weight: .bold)
.foregroundColor(Color(hex: "3bb9f1"))
.frame(
@@ -141,7 +141,7 @@ struct TextMessageDetailView: View {
.frame(width: screenSize().width - 26.7)
.padding(.vertical, 26.7)
} else {
Text("삭제")
Text(I18n.Common.delete)
.appFont(size: 14.7, weight: .bold)
.foregroundColor(Color(hex: "3bb9f1"))
.frame(

View File

@@ -24,7 +24,7 @@ final class TextMessageDetailViewModel: ObservableObject {
func deleteMessage(onSuccess: @escaping () -> Void) {
if messageId <= 0 {
errorMessage = "메시지를 삭제하지 못했습니다\n잠시 후 다시 시도해 주세요."
errorMessage = I18n.Message.Text.Detail.deleteFailed
isShowPopup = true
return
}
@@ -48,7 +48,7 @@ final class TextMessageDetailViewModel: ObservableObject {
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
if decoded.success {
self.errorMessage = "삭제되었습니다."
self.errorMessage = I18n.Message.Text.Detail.deleteSuccess
self.isShowPopup = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
onSuccess()
@@ -58,13 +58,13 @@ final class TextMessageDetailViewModel: ObservableObject {
self.errorMessage = message
self.isShowPopup = true
} else {
self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요."
self.errorMessage = I18n.Message.Text.Detail.deleteFailed
}
self.isShowPopup = true
}
} catch {
self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요."
self.errorMessage = I18n.Message.Text.Detail.deleteFailed
self.isShowPopup = true
}
}
@@ -73,7 +73,7 @@ final class TextMessageDetailViewModel: ObservableObject {
func keepTextMessage() {
if messageId <= 0 {
errorMessage = "메시지를 저장하지 못했습니다\n잠시 후 다시 시도해 주세요."
errorMessage = I18n.Message.Text.Detail.keepFailed
isShowPopup = true
return
}
@@ -96,20 +96,20 @@ final class TextMessageDetailViewModel: ObservableObject {
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
if decoded.success {
self.errorMessage = "보관되었습니다."
self.errorMessage = I18n.Message.Text.Detail.keepSuccess
self.isShowPopup = true
} else {
if let message = decoded.message {
self.errorMessage = message
self.isShowPopup = true
} else {
self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요."
self.errorMessage = I18n.Message.Text.Detail.keepFailed
}
self.isShowPopup = true
}
} catch {
self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요."
self.errorMessage = I18n.Message.Text.Detail.keepFailed
self.isShowPopup = true
}
}

View File

@@ -18,11 +18,11 @@ struct SelectRecipientView: View {
var body: some View {
BaseView {
VStack(spacing: 20) {
DetailNavigationBar(title: String(localized: "받는 사람 검색")) {
DetailNavigationBar(title: I18n.Message.Text.SelectRecipient.title) {
isShowing = false
}
TextField("닉네임을 입력해주세요", text: $viewModel.searchNickname)
TextField(I18n.Message.Text.SelectRecipient.nicknamePlaceholder, text: $viewModel.searchNickname)
.autocapitalization(.none)
.disableAutocorrection(true)
.appFont(size: 13.3, weight: .medium)

View File

@@ -51,13 +51,13 @@ final class SelectRecipientViewModel: ObservableObject {
DEBUG_LOG("message: \(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
}
}
@@ -86,13 +86,13 @@ final class SelectRecipientViewModel: 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
}
}

View File

@@ -68,7 +68,7 @@ struct TextMessageView: View {
.resizable()
.frame(width: 60, height: 60)
Text("메시지가 없습니다.\n친구들과 소통해보세요!")
Text(I18n.Message.Text.emptyState)
.multilineTextAlignment(.center)
.appFont(size: 10.7, weight: .medium)
.foregroundColor(Color(hex: "bbbbbb"))

View File

@@ -21,19 +21,19 @@ struct TextMessageWriteView: View {
BaseView(isLoading: $viewModel.isLoading) {
VStack(spacing: 0) {
HStack(spacing: 0) {
Text("취소")
Text(I18n.Common.cancel)
.appFont(size: 16.7, weight: .medium)
.foregroundColor(Color(hex: "3bb9f1").opacity(0))
Spacer()
Text("새로운 메시지")
Text(I18n.Message.Text.Write.title)
.appFont(size: 18.3, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Spacer()
Text("취소")
Text(I18n.Common.cancel)
.appFont(size: 16.7, weight: .medium)
.foregroundColor(Color(hex: "3bb9f1"))
.onTapGesture {
@@ -51,7 +51,7 @@ struct TextMessageWriteView: View {
Spacer()
HStack(spacing: 13.3) {
Text("받는 사람")
Text(I18n.Message.Text.Write.recipientLabel)
.appFont(size: 16.7, weight: .medium)
.foregroundColor(Color(hex: "777777"))

View File

@@ -36,14 +36,14 @@ class SoundManager: NSObject, ObservableObject {
audioSession.requestRecordPermission() { [weak self] allowed in
DispatchQueue.main.async {
if !allowed {
self?.errorMessage = "권한을 허용하지 않으시면 음성메시지 서비스를 이용하실 수 없습니다."
self?.errorMessage = I18n.Message.Voice.Sound.permissionDenied
self?.isShowPopup = true
self?.onClose = true
}
}
}
} catch {
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
errorMessage = I18n.Message.Voice.Sound.commonError
isShowPopup = true
onClose = true
}
@@ -71,7 +71,7 @@ class SoundManager: NSObject, ObservableObject {
}
isRecording = true
} catch {
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
errorMessage = I18n.Message.Voice.Sound.commonError
isShowPopup = true
}
}
@@ -112,7 +112,7 @@ class SoundManager: NSObject, ObservableObject {
self.duration = self.player.duration
} catch {
self.errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
self.errorMessage = I18n.Message.Voice.Sound.commonError
self.isShowPopup = true
}
@@ -147,7 +147,7 @@ class SoundManager: NSObject, ObservableObject {
try FileManager.default.removeItem(at: getAudioFileURL())
duration = 0
} catch {
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
errorMessage = I18n.Message.Voice.Sound.commonError
isShowPopup = true
}
}