feat(chat): 채팅 모듈 하드코딩 문구를 I18n 키로 통일한다

This commit is contained in:
Yu Sung
2026-03-31 16:30:48 +09:00
parent 222520d5e9
commit 47085dc1ca
27 changed files with 464 additions and 128 deletions

View File

@@ -34,7 +34,7 @@ struct CharacterDetailView: View {
var body: some View {
BaseView(isLoading: $viewModel.isLoading) {
VStack(spacing: 0) {
DetailNavigationBar(title: String(localized: "캐릭터 정보")) {
DetailNavigationBar(title: I18n.Chat.Character.detailTitle) {
if presentationMode.wrappedValue.isPresented {
presentationMode.wrappedValue.dismiss()
} else {
@@ -77,7 +77,7 @@ struct CharacterDetailView: View {
if let others = viewModel.characterDetail?.others, !others.isEmpty {
VStack(spacing: 16) {
HStack {
Text("장르의 다른 캐릭터")
Text(I18n.Chat.Character.detailOtherCharactersTitle)
.appFont(size: 26, weight: .bold)
.foregroundColor(.white)
@@ -178,6 +178,13 @@ extension CharacterDetailView {
// MARK: - Profile Section
extension CharacterDetailView {
private func isMaleGender(_ gender: String) -> Bool {
let normalizedGender = gender
.trimmingCharacters(in: .whitespacesAndNewlines)
.lowercased()
return normalizedGender == "남성" || normalizedGender == "male"
}
private var profileSection: some View {
VStack(alignment: .leading, spacing: 16) {
if viewModel.characterDetail?.mbti != nil ||
@@ -189,7 +196,7 @@ extension CharacterDetailView {
Text(viewModel.characterDetail?.translated?.gender ?? gender)
.appFont(size: 14, weight: .regular)
.foregroundColor(
gender == "남성" ?
isMaleGender(gender) ?
Color.button :
Color.mainRed
)
@@ -201,7 +208,7 @@ extension CharacterDetailView {
RoundedRectangle(cornerRadius: 4)
.stroke(lineWidth: 1)
.foregroundColor(
gender == "남성" ?
isMaleGender(gender) ?
Color.button :
Color.mainRed
)
@@ -209,7 +216,7 @@ extension CharacterDetailView {
}
if let age = viewModel.characterDetail?.age {
Text("\(age)")
Text(I18n.Chat.Character.age(age))
.appFont(size: 14, weight: .regular)
.foregroundColor(Color(hex: "B0BEC5"))
.padding(.horizontal, 7)
@@ -252,7 +259,7 @@ extension CharacterDetailView {
if let characterType = viewModel.characterDetail?.characterType {
HStack(spacing: 8) {
Text(characterType.rawValue)
Text(characterType == .Clone ? I18n.Chat.Character.typeClone : I18n.Chat.Character.typeCharacter)
.appFont(size: 12, weight: .regular)
.foregroundColor(.white)
.padding(.horizontal, 5)
@@ -282,7 +289,7 @@ extension CharacterDetailView {
private func worldViewSection(backgrounds: String) -> some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("[세계관 및 작품 소개]")
Text(I18n.Chat.Character.detailWorldViewTitle)
.appFont(size: 18, weight: .bold)
.foregroundColor(.white)
@@ -300,7 +307,7 @@ extension CharacterDetailView {
private func originalWorkSection(title: String, link: String) -> some View {
VStack(spacing: 8) {
HStack {
Text("원작")
Text(I18n.Chat.Character.detailOriginalTitle)
.appFont(size: 16, weight: .bold)
.fontWeight(.bold)
.foregroundColor(.white)
@@ -321,7 +328,7 @@ extension CharacterDetailView {
UIApplication.shared.open(url)
}
}) {
Text("원작 보러가기")
Text(I18n.Chat.Character.detailOriginalLinkButton)
.appFont(size: 16, weight: .bold)
.fontWeight(.bold)
.foregroundColor(Color(hex: "3BB9F1"))
@@ -342,7 +349,7 @@ extension CharacterDetailView {
private func personalitySection(personalities: String) -> some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("[성격 및 특징]")
Text(I18n.Chat.Character.detailPersonalityTitle)
.appFont(size: 18, weight: .bold)
.foregroundColor(.white)
@@ -354,24 +361,19 @@ extension CharacterDetailView {
//
VStack(alignment: .leading, spacing: 16) {
HStack {
Text("⚠️ 캐릭터톡 대화 가이드")
Text(I18n.Chat.Character.detailConversationGuideTitle)
.appFont(size: 16, weight: .bold)
.foregroundColor(Color(hex: "B0BEC5"))
Spacer()
}
Text("""
보이스온의 오픈월드 캐릭터톡은 대화의 자유도가 높아 대화에 참여하는 당신은 누구든 될 수 있습니다. 세계관 속 연관 캐릭터가 되어 대화를 하거나 완전히 새로운 인물이 되어 캐릭터와 당신만의 스토리를 만들어 갈 수 있습니다.
""")
Text(I18n.Chat.Character.detailConversationGuideDescription1)
.appFont(size: 16, weight: .regular)
.foregroundColor(Color(hex: "AEAEB2"))
.multilineTextAlignment(.leading)
Text("""
오픈월드 캐릭터톡은 캐릭터를 정교하게 설계하였지만, 대화가 어색하거나 불완전할 수도 있습니다.
대화 도중 캐릭터의 대화가 이상하거나 새로운 캐릭터로 대화를 나누고 싶다면 대화를 초기화 하고 새롭게 캐릭터와 대화를 나눠보세요.
""")
Text(I18n.Chat.Character.detailConversationGuideDescription2)
.appFont(size: 16, weight: .regular)
.foregroundColor(Color(hex: "AEAEB2"))
.multilineTextAlignment(.leading)
@@ -393,7 +395,7 @@ extension CharacterDetailView {
// MARK: - Chat Button
extension CharacterDetailView {
private var chatButton: some View {
Text("대화하기")
Text(I18n.Chat.Character.detailChatButton)
.appFont(size: 18, weight: .bold)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
@@ -450,7 +452,7 @@ struct CharacterExpandableTextView: View {
.foregroundColor(Color(hex: "607D8B"))
.rotationEffect(.degrees(isExpanded ? 180 : 0))
Text(isExpanded ? "간략히" : "더보기")
Text(isExpanded ? I18n.Chat.Character.detailCollapse : I18n.Chat.Character.detailExpand)
.appFont(size: 16, weight: .regular)
.foregroundColor(Color(hex: "607D8B"))
}

View File

@@ -76,7 +76,7 @@ struct CharacterDetailGalleryView: View {
VStack(spacing: 8) {
// ( % , , )
HStack {
Text("\(viewModel.ownershipPercentage)% 보유중")
Text(I18n.Chat.Character.DetailGallery.ownership(viewModel.ownershipPercentage))
.appFont(size: 18, weight: .bold)
.foregroundColor(.white)
@@ -91,7 +91,7 @@ struct CharacterDetailGalleryView: View {
.appFont(size: 16, weight: .regular)
.foregroundColor(.white)
Text("\(viewModel.totalCount)")
Text(I18n.Chat.Character.DetailGallery.totalCount(viewModel.totalCount))
.appFont(size: 16, weight: .regular)
.foregroundColor(.white)
}