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

@@ -51,6 +51,271 @@ enum I18n {
)
}
}
enum Chat {
enum Auth {
static var authenticationError: String {
pick(
ko: "본인인증 중 오류가 발생했습니다.",
en: "An error occurred during identity verification.",
ja: "本人認証中にエラーが発生しました。"
)
}
static var dialogTitle: String {
pick(ko: "본인인증", en: "Identity verification", ja: "本人認証")
}
static var dialogDescription: String {
pick(
ko: "보이스온의 오픈월드 캐릭터톡은\n청소년 보호를 위해 본인인증한\n성인만 이용이 가능합니다.\n캐릭터톡 서비스를 이용하시려면\n본인인증을 하고 이용해주세요.",
en: "VoiceOn Open World Character Talk is available only to adults who complete identity verification for youth protection.\nPlease complete identity verification to use Character Talk.",
ja: "VoiceOnオープンワールドキャラクタートークは、青少年保護のため本人認証を完了した成人のみ利用できます。\nキャラクタートークを利用するには本人認証を完了してください。"
)
}
static var goToVerification: String {
pick(ko: "본인인증 하러가기", en: "Verify identity", ja: "本人認証へ")
}
}
enum Character {
static var popularSectionTitle: String {
pick(ko: "인기 캐릭터", en: "Popular characters", ja: "人気キャラクター")
}
static var newSectionTitle: String {
pick(ko: "신규 캐릭터", en: "New characters", ja: "新着キャラクター")
}
static var recommendSectionTitle: String {
pick(ko: "추천 캐릭터", en: "Recommended characters", ja: "おすすめキャラクター")
}
static var recentSectionTitle: String {
pick(ko: "최근 대화한 캐릭터", en: "Recently chatted characters", ja: "最近会話したキャラクター")
}
static var newBadge: String {
pick(ko: "N", en: "N", ja: "N")
}
static var typeCharacter: String {
pick(ko: "캐릭터", en: "Character", ja: "キャラクター")
}
static var typeClone: String {
pick(ko: "클론", en: "Clone", ja: "クローン")
}
static var detailTitle: String {
pick(ko: "캐릭터 정보", en: "Character info", ja: "キャラクター情報")
}
static var detailOtherCharactersTitle: String {
pick(ko: "장르의 다른 캐릭터", en: "Other characters in this genre", ja: "同ジャンルの他キャラクター")
}
static func age(_ age: Int) -> String {
pick(ko: "\(age)", en: "\(age)y", ja: "\(age)")
}
static var detailWorldViewTitle: String {
pick(ko: "[세계관 및 작품 소개]", en: "[Worldview & work introduction]", ja: "[世界観と作品紹介]")
}
static var detailOriginalTitle: String {
pick(ko: "원작", en: "Original work", ja: "原作")
}
static var detailOriginalLinkButton: String {
pick(ko: "원작 보러가기", en: "View original work", ja: "原作を見る")
}
static var detailPersonalityTitle: String {
pick(ko: "[성격 및 특징]", en: "[Personality & traits]", ja: "[性格と特徴]")
}
static var detailConversationGuideTitle: String {
pick(ko: "⚠️ 캐릭터톡 대화 가이드", en: "⚠️ Character Talk guide", ja: "⚠️ キャラクタートークガイド")
}
static var detailConversationGuideDescription1: String {
pick(
ko: "보이스온의 오픈월드 캐릭터톡은 대화의 자유도가 높아 대화에 참여하는 당신은 누구든 될 수 있습니다. 세계관 속 연관 캐릭터가 되어 대화를 하거나 완전히 새로운 인물이 되어 캐릭터와 당신만의 스토리를 만들어 갈 수 있습니다.",
en: "VoiceOn Open World Character Talk gives you high conversational freedom. You can become a related character in the world or a completely new persona and build your own story with the character.",
ja: "VoiceOnオープンワールドキャラクタートークは会話の自由度が高く、世界観の関連キャラクターとして会話したり、まったく新しい人物になってキャラクターとあなただけの物語を作れます。"
)
}
static var detailConversationGuideDescription2: String {
pick(
ko: "오픈월드 캐릭터톡은 캐릭터를 정교하게 설계하였지만, 대화가 어색하거나 불완전할 수도 있습니다.\n대화 도중 캐릭터의 대화가 이상하거나 새로운 캐릭터로 대화를 나누고 싶다면 대화를 초기화 하고 새롭게 캐릭터와 대화를 나눠보세요.",
en: "Open World Character Talk is designed carefully, but conversations may still feel awkward or incomplete.\nIf dialogue becomes unnatural or you want to chat as a new character, reset the conversation and start again.",
ja: "オープンワールドキャラクタートークは精密に設計されていますが、会話が不自然または不完全になる場合があります。\n会話中に不自然さを感じた場合や新しいキャラクターで会話したい場合は、会話を初期化して新しく始めてください。"
)
}
static var detailChatButton: String {
pick(ko: "대화하기", en: "Start chat", ja: "会話する")
}
static var detailCollapse: String {
pick(ko: "간략히", en: "Collapse", ja: "簡略表示")
}
static var detailExpand: String {
pick(ko: "더보기", en: "More", ja: "もっと見る")
}
enum NewList {
static var title: String {
pick(ko: "신규 캐릭터 전체보기", en: "All new characters", ja: "新着キャラクター一覧")
}
static var totalPrefix: String {
pick(ko: "전체", en: "Total", ja: "全体")
}
static var countUnit: String {
pick(ko: "", en: "", ja: "")
}
}
enum DetailGallery {
static func ownership(_ percentage: Int) -> String {
pick(ko: "\(percentage)% 보유중", en: "\(percentage)% owned", ja: "\(percentage)%保有中")
}
static func totalCount(_ count: Int) -> String {
pick(ko: "\(count)", en: "\(count)", ja: "\(count)")
}
}
}
enum Original {
static var adultBadge: String {
pick(ko: "19+", en: "19+", ja: "19+")
}
static var workIntroductionTitle: String {
pick(ko: "작품 소개", en: "Work introduction", ja: "作品紹介")
}
static var viewOriginalLinksTitle: String {
pick(ko: "원작 보러 가기", en: "View original links", ja: "原作リンクを見る")
}
static var detailInfoTitle: String {
pick(ko: "상세 정보", en: "Details", ja: "詳細情報")
}
static var writerLabel: String {
pick(ko: "작가", en: "Writer", ja: "作家")
}
static var studioLabel: String {
pick(ko: "제작사", en: "Studio", ja: "制作会社")
}
static var originalLabel: String {
pick(ko: "원작", en: "Original work", ja: "原作")
}
}
enum Talk {
static var emptyMessage: String {
pick(ko: "대화 중인 톡이 없습니다", en: "No active chats", ja: "進行中のトークがありません")
}
}
enum Room {
static var noticeForCharacter: String {
pick(
ko: "보이스온 AI캐릭터톡은 대화의 자유도가 높아 대화에 참여하는 당신은 누구든 될 수 있습니다.\n세계관 속 캐릭터로 대화를 하거나 새로운 인물로 캐릭터와 당신만의 스토리를 만들어보세요.\n※ AI캐릭터톡은 오픈베타 서비스 중이며, 캐릭터의 대화가 어색하거나 불완전할 수 있습니다.",
en: "VoiceOn AI Character Talk offers a high degree of conversational freedom.\nTalk as a character in the world or as a new persona and create your own story with the character.\n※ AI Character Talk is in open beta, so responses may be awkward or incomplete.",
ja: "VoiceOn AIキャラクタートークは会話の自由度が高く、会話に参加するあなたは誰にでもなれます。\n世界観のキャラクターとして会話したり、新しい人物としてキャラクターとあなただけの物語を作ってみてください。\n※ AIキャラクタートークはオープンベータ中のため、会話が不自然または不完全な場合があります。"
)
}
static var noticeForClone: String {
pick(
ko: "AI Clone은 크리에이터의 정보를 기반으로 대화하지만, 모든 정보를 완벽하게 반영하거나 실제 대화와 일치하지 않을 수 있습니다.",
en: "AI Clone chats based on creator information, but may not perfectly reflect all details or match real conversations.",
ja: "AI Cloneはクリエイター情報をもとに会話しますが、すべての情報を完全に反映したり実際の会話と一致しない場合があります。"
)
}
static var messagePlaceholder: String {
pick(ko: "메시지를 입력하세요.", en: "Enter a message.", ja: "メッセージを入力してください。")
}
static var resettingMessage: String {
pick(ko: "대화 초기화 중...", en: "Resetting conversation...", ja: "会話を初期化中...")
}
static var unlockImagePrompt: String {
pick(ko: "눌러서 잠금해제", en: "Tap to unlock", ja: "タップして解除")
}
static var typingAccessibilityLabel: String {
pick(ko: "입력 중", en: "Typing", ja: "入力中")
}
static var quotaWaitForFreeNotice: String {
pick(ko: "기다리면 무료 이용이 가능합니다.", en: "Wait for free usage.", ja: "待てば無料で利用できます。")
}
static func quotaPurchaseAction(chatCount: Int) -> String {
pick(
ko: "(채팅 \(chatCount)개) 바로 대화 시작",
en: "(\(chatCount) chats) Start now",
ja: "(チャット\(chatCount)件) すぐに会話開始"
)
}
static var backgroundSelectionTitle: String {
pick(ko: "배경 이미지 선택", en: "Select background image", ja: "背景画像を選択")
}
static var currentBackground: String {
pick(ko: "현재 배경", en: "Current background", ja: "現在の背景")
}
static var settingsTitle: String {
pick(ko: "대화 설정", en: "Chat settings", ja: "会話設定")
}
static var hideBackgroundImage: String {
pick(ko: "배경 이미지 끄기", en: "Hide background image", ja: "背景画像をオフ")
}
static var changeBackgroundImage: String {
pick(ko: "배경 이미지 변경", en: "Change background image", ja: "背景画像を変更")
}
static var resetConversationTitle: String {
pick(ko: "대화 초기화", en: "Reset conversation", ja: "会話を初期化")
}
static var resetWarningPrefix: String {
pick(ko: "⚠️ ", en: "⚠️ ", ja: "⚠️ ")
}
static var resetWarningDescription: String {
pick(
ko: "지금까지의 대화가 모두 초기화 되고, 이용자가 새로운 캐릭터가 되어 새롭게 대화를 시작합니다.",
en: "All previous messages are reset, and you start a new conversation as a new character.",
ja: "これまでの会話はすべて初期化され、利用者が新しいキャラクターとなって新しく会話を始めます。"
)
}
static var defaultCharacterName: String {
pick(ko: "캐릭터", en: "Character", ja: "キャラクター")
}
}
}
//
enum Search {
// : 2