diff --git a/flutter_01.png b/flutter_01.png deleted file mode 100644 index 8ed4c34..0000000 Binary files a/flutter_01.png and /dev/null differ diff --git a/ios/fastlane/metadata/ko-KR/description.txt b/ios/fastlane/metadata/ko-KR/description.txt new file mode 100644 index 0000000..1182586 --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/description.txt @@ -0,0 +1,31 @@ +Conduit은 Open-WebUI를 위한 오픈소스 네이티브 모바일 클라이언트입니다. 자체 서버에 연결하여 AI 모델과 채팅하고, 대화를 관리하며, 자체 호스팅 AI를 안전하게 휴대하세요. + +주요 기능 +- 실시간 스트리밍 채팅 +- 모델 선택 +- 대화 검색 및 관리 +- 음성 입력 (음성-텍스트 변환) +- 검색 증강 생성(RAG)을 위한 파일 및 이미지 업로드 +- 기기 내 처리 음성 통화 +- 도구 지원 +- 구문 강조가 있는 마크다운 렌더링 +- 라이트, 다크, 시스템 테마 +- 안전한 자격 증명 저장 (Keychain/Keystore) + +요구사항 +- 기존 Open-WebUI 서버가 필요합니다. Conduit은 AI 모델을 호스팅하거나 제공하지 않습니다. +- 기본적으로 타사 서비스로 데이터가 전송되지 않으며, 모든 데이터는 구성된 서버에 남아 있습니다. + +권한 +- 마이크: 음성 입력 +- 카메라 및 사진/저장소: 이미지/파일 첨부 +- 네트워크: Open-WebUI 서버 연결 + +오픈소스: +Conduit은 오픈소스 프로젝트입니다. 지원, 문제 보고 또는 소스 코드 보기를 위해 GitHub 저장소를 방문하세요: + +https://github.com/cogwheel0/conduit + +----- + +면책 조항: 이것은 GNU 일반 공중 사용 허가서 v3.0(GPLv3)에 따라 라이선스된 독립적인 서드파티 애플리케이션이며 Open WebUI 프로젝트와 공식적으로 제휴되지 않았습니다. diff --git a/ios/fastlane/metadata/ko-KR/keywords.txt b/ios/fastlane/metadata/ko-KR/keywords.txt new file mode 100644 index 0000000..b6aaf5a --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/keywords.txt @@ -0,0 +1 @@ +conduit, openwebui, ai 채팅, llm 채팅, 자체 호스팅 ai, ollama diff --git a/ios/fastlane/metadata/ko-KR/marketing_url.txt b/ios/fastlane/metadata/ko-KR/marketing_url.txt new file mode 100644 index 0000000..7f98c98 --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/marketing_url.txt @@ -0,0 +1 @@ +https://github.com/cogwheel0/conduit/releases/tag/v2.2.0 diff --git a/ios/fastlane/metadata/ko-KR/name.txt b/ios/fastlane/metadata/ko-KR/name.txt new file mode 100644 index 0000000..fc4c544 --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/name.txt @@ -0,0 +1 @@ +Conduit: OpenWebUI 클라이언트 diff --git a/ios/fastlane/metadata/ko-KR/privacy_url.txt b/ios/fastlane/metadata/ko-KR/privacy_url.txt new file mode 100644 index 0000000..e5ebee6 --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/privacy_url.txt @@ -0,0 +1 @@ +https://github.com/cogwheel0/conduit/blob/main/PRIVACY_POLICY.md diff --git a/ios/fastlane/metadata/ko-KR/promotional_text.txt b/ios/fastlane/metadata/ko-KR/promotional_text.txt new file mode 100644 index 0000000..dbbfbdd --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/promotional_text.txt @@ -0,0 +1 @@ +서버 측 STS, 성능 개선 및 스트리밍 수정 diff --git a/ios/fastlane/metadata/ko-KR/subtitle.txt b/ios/fastlane/metadata/ko-KR/subtitle.txt new file mode 100644 index 0000000..f973743 --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/subtitle.txt @@ -0,0 +1 @@ +자체 호스팅 AI와 채팅 diff --git a/ios/fastlane/metadata/ko-KR/support_url.txt b/ios/fastlane/metadata/ko-KR/support_url.txt new file mode 100644 index 0000000..bc18197 --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/support_url.txt @@ -0,0 +1 @@ +https://github.com/cogwheel0/conduit/issues diff --git a/ios/fastlane/metadata/ko-KR/whatsnew.txt b/ios/fastlane/metadata/ko-KR/whatsnew.txt new file mode 100644 index 0000000..dbbfbdd --- /dev/null +++ b/ios/fastlane/metadata/ko-KR/whatsnew.txt @@ -0,0 +1 @@ +서버 측 STS, 성능 개선 및 스트리밍 수정 diff --git a/l10n.yaml b/l10n.yaml index 68e56ce..23cd2ea 100644 --- a/l10n.yaml +++ b/l10n.yaml @@ -12,3 +12,4 @@ preferred-supported-locales: - ru - nl - es + - kr diff --git a/lib/features/profile/views/app_customization_page.dart b/lib/features/profile/views/app_customization_page.dart index 86c81bf..f560c3b 100644 --- a/lib/features/profile/views/app_customization_page.dart +++ b/lib/features/profile/views/app_customization_page.dart @@ -1669,6 +1669,8 @@ class AppCustomizationPage extends ConsumerWidget { return AppLocalizations.of(context)!.russian; case 'zh': return AppLocalizations.of(context)!.chinese; + case 'kr': + return AppLocalizations.of(context)!.korean; default: return AppLocalizations.of(context)!.system; } @@ -1901,6 +1903,11 @@ class AppCustomizationPage extends ConsumerWidget { trailing: current == 'zh' ? const Icon(Icons.check) : null, onTap: () => Navigator.pop(context, 'zh'), ), + ListTile( + title: Text(AppLocalizations.of(context)!.korean), + trailing: current == 'kr' ? const Icon(Icons.check) : null, + onTap: () => Navigator.pop(context, 'kr'), + ), const SizedBox(height: Spacing.sm), ], ), diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index cf6a18c..253762b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -862,6 +862,10 @@ "@chinese": { "description": "Language name: Chinese." }, + "korean": "한국어", + "@korean": { + "description": "Language name: Korean." + }, "deleteMessagesTitle": "Delete Messages", "@deleteMessagesTitle": { "description": "Dialog title asking to confirm deletion of messages." diff --git a/lib/l10n/app_kr.arb b/lib/l10n/app_kr.arb new file mode 100644 index 0000000..33219c1 --- /dev/null +++ b/lib/l10n/app_kr.arb @@ -0,0 +1,360 @@ +{ + "@@locale": "kr", + "appTitle": "Conduit", + "retry": "다시 시도", + "back": "뒤로", + "you": "프로필", + "loadingProfile": "프로필 로딩 중...", + "unableToLoadProfile": "프로필을 불러올 수 없습니다", + "pleaseCheckConnection": "연결을 확인하고 다시 시도해주세요", + "connectionIssueTitle": "서버에 연결할 수 없습니다", + "connectionIssueSubtitle": "다시 연결하거나 로그아웃하여 다른 서버를 선택하세요.", + "account": "계정", + "supportConduit": "Conduit 지원하기", + "supportConduitSubtitle": "지속적인 개발을 위해 자금을 지원하여 Conduit을 독립적으로 유지하세요.", + "githubSponsorsTitle": "GitHub Sponsors", + "githubSponsorsSubtitle": "반복 후원자가 되어 로드맵 항목에 자금을 지원하세요.", + "buyMeACoffeeTitle": "Buy Me a Coffee", + "buyMeACoffeeSubtitle": "일회성 기부로 감사를 표하세요.", + "signOut": "로그아웃", + "endYourSession": "세션 종료", + "defaultModel": "기본 모델", + "autoSelect": "자동 선택", + "loadingModels": "모델 로딩 중...", + "failedToLoadModels": "모델을 불러오지 못했습니다", + "availableModels": "사용 가능한 모델", + "modelCapabilityMultimodal": "멀티모달", + "modelCapabilityReasoning": "추론", + "noResults": "결과 없음", + "searchModels": "모델 검색...", + "errorMessage": "문제가 발생했습니다. 다시 시도해주세요.", + "closeButtonSemantic": "닫기", + "loadingContent": "콘텐츠 로딩 중", + "loadingShort": "로딩 중", + "loadingAnnouncement": "로딩 중: {message}", + "errorAnnouncement": "오류: {error}", + "errorAnnouncementWithSuggestion": "오류: {error}. {suggestion}", + "successAnnouncement": "성공: {message}", + "noItems": "항목 없음", + "noItemsToDisplay": "표시할 항목이 없습니다", + "knowledgeBase": "지식 베이스", + "attachments": "첨부 파일", + "takePhoto": "사진 촬영", + "document": "문서", + "backToServerSetup": "서버 설정으로 돌아가기", + "connectedToServer": "서버에 연결됨", + "signIn": "로그인", + "enterCredentials": "AI 대화에 액세스하려면 자격 증명을 입력하세요", + "credentials": "자격 증명", + "apiKey": "API 키", + "usernameOrEmail": "사용자 이름 또는 이메일", + "password": "비밀번호", + "signInWithApiKey": "API 키로 로그인", + "connectToServer": "서버 연결", + "enterServerAddress": "시작하려면 Open-WebUI 서버 주소를 입력하세요", + "serverUrl": "서버 URL", + "serverUrlHint": "https://your-server.com", + "enterServerUrlSemantic": "서버 URL 또는 IP 주소를 입력하세요", + "headerName": "헤더 이름", + "headerValue": "헤더 값", + "headerValueHint": "api-key-123 또는 Bearer 토큰", + "addHeader": "헤더 추가", + "maximumHeadersReached": "최대 헤더 수에 도달했습니다", + "removeHeader": "헤더 제거", + "connecting": "연결 중...", + "connectToServerButton": "서버 연결", + "demoModeActive": "데모 모드 활성화", + "skipServerSetupTryDemo": "서버 설정 건너뛰고 데모 사용해보기", + "enterDemo": "데모 시작", + "demoBadge": "데모", + "serverNotOpenWebUI": "이것은 Open-WebUI 서버가 아닌 것 같습니다.", + "serverUrlEmpty": "서버 URL은 비어 있을 수 없습니다", + "invalidUrlFormat": "잘못된 URL 형식입니다. 입력을 확인해주세요.", + "onlyHttpHttps": "HTTP 및 HTTPS 프로토콜만 지원됩니다.", + "serverAddressRequired": "서버 주소가 필요합니다 (예: 192.168.1.10 또는 example.com).", + "portRange": "포트는 1부터 65535 사이여야 합니다.", + "invalidIpFormat": "잘못된 IP 주소 형식입니다. 192.168.1.10과 같은 형식을 사용하세요.", + "couldNotConnectGeneric": "연결할 수 없습니다. 주소를 다시 확인하고 시도해주세요.", + "weCouldntReachServer": "서버에 연결할 수 없습니다. 연결과 서버 실행 상태를 확인하세요.", + "connectionTimedOut": "연결 시간이 초과되었습니다. 서버가 바쁘거나 방화벽에 의해 차단되었을 수 있습니다.", + "useHttpOrHttpsOnly": "http:// 또는 https:// 만 사용하세요.", + "loginFailed": "로그인 실패", + "invalidCredentials": "사용자 이름 또는 비밀번호가 잘못되었습니다. 다시 시도해주세요.", + "serverRedirectingHttps": "서버가 요청을 리디렉션하고 있습니다. 서버의 HTTPS 구성을 확인하세요.", + "unableToConnectServer": "서버에 연결할 수 없습니다. 연결을 확인해주세요.", + "requestTimedOut": "요청 시간이 초과되었습니다. 다시 시도해주세요.", + "genericSignInFailed": "로그인할 수 없습니다. 자격 증명과 서버 설정을 확인하세요.", + "skip": "건너뛰기", + "next": "다음", + "done": "완료", + "onboardStartTitle": "안녕하세요, {username}", + "onboardStartSubtitle": "모델을 선택하여 시작하세요. 언제든지 새 채팅을 탭하세요.", + "onboardStartBullet1": "상단 바의 모델 이름을 탭하여 모델 전환", + "onboardStartBullet2": "새 채팅을 사용하여 컨텍스트 재설정", + "onboardAttachTitle": "컨텍스트 추가", + "onboardAttachSubtitle": "작업 공간 또는 사진의 콘텐츠로 답변에 근거를 둡니다.", + "onboardAttachBullet1": "작업 공간: PDF, 문서, 데이터셋", + "onboardAttachBullet2": "사진: 카메라 또는 갤러리", + "onboardSpeakTitle": "자연스럽게 말하기", + "onboardSpeakSubtitle": "마이크를 탭하여 실시간 파형 피드백으로 받아쓰기", + "onboardSpeakBullet1": "언제든지 중지 가능; 부분 텍스트는 보존됨", + "onboardSpeakBullet2": "빠른 메모나 긴 프롬프트에 적합", + "onboardQuickTitle": "빠른 작업", + "onboardQuickSubtitle": "메뉴를 열어 채팅, 작업 공간, 프로필 사이를 전환하세요.", + "onboardQuickBullet1": "메뉴를 탭하여 채팅, 작업 공간, 프로필 액세스", + "onboardQuickBullet2": "상단 바에서 새 채팅 시작 또는 모델 관리", + "attachmentLabel": "첨부", + "tools": "도구", + "voiceInput": "음성 입력", + "voice": "음성", + "voiceStatusListening": "듣는 중…", + "voiceStatusRecording": "녹음 중…", + "voiceHoldToTalk": "누르고 말하기", + "voiceAutoSend": "자동 전송", + "voiceTranscript": "전사", + "voicePromptSpeakNow": "지금 말하세요…", + "voicePromptTapStart": "시작을 탭하여 시작", + "voiceActionStop": "중지", + "voiceActionStart": "시작", + "voiceCallTitle": "음성 통화", + "voiceCallPause": "일시 정지", + "voiceCallResume": "재개", + "voiceCallStop": "중지", + "voiceCallEnd": "통화 종료", + "voiceCallReady": "준비됨", + "voiceCallConnecting": "연결 중...", + "voiceCallListening": "듣는 중", + "voiceCallPaused": "일시 정지됨", + "voiceCallProcessing": "생각 중...", + "voiceCallSpeaking": "말하는 중", + "voiceCallDisconnected": "연결 끊김", + "voiceCallErrorHelp": "다음을 확인하세요:\n• 마이크 권한이 부여되었는지\n• 기기에서 음성 인식이 사용 가능한지\n• 서버에 연결되어 있는지", + "messageInputLabel": "메시지 입력", + "messageInputHint": "메시지를 입력하세요", + "messageHintText": "Conduit에게 물어보기", + "stopGenerating": "생성 중지", + "send": "전송", + "codeCopiedToClipboard": "코드가 클립보드에 복사되었습니다.", + "sendMessage": "메시지 전송", + "file": "파일", + "chooseDifferentFile": "다른 파일 선택", + "photo": "사진", + "camera": "카메라", + "apiUnavailable": "API 서비스를 사용할 수 없습니다", + "unableToLoadImage": "이미지를 불러올 수 없습니다", + "notAnImageFile": "이미지 파일이 아닙니다: {fileName}", + "failedToLoadImage": "이미지 로드 실패: {error}", + "invalidDataUrl": "잘못된 데이터 URL 형식", + "failedToDecodeImage": "이미지 디코딩 실패", + "invalidImageFormat": "잘못된 이미지 형식", + "emptyImageData": "빈 이미지 데이터", + "confirm": "확인", + "continueAction": "계속", + "cancel": "취소", + "ok": "확인", + "previousLabel": "이전", + "nextLabel": "다음", + "inputField": "입력 필드", + "checkConnection": "연결 확인", + "openSettings": "설정 열기", + "goBack": "돌아가기", + "technicalDetails": "기술 세부 정보", + "requiredFieldLabel": "{label} *", + "requiredFieldHelper": "필수 필드", + "switchOnLabel": "켜짐", + "switchOffLabel": "꺼짐", + "dialogSemanticLabel": "대화 상자: {title}", + "save": "저장", + "chooseModel": "모델 선택", + "reviewerMode": "검토자 모드", + "selectLanguage": "언어 선택", + "newFolder": "새 폴더", + "folderName": "폴더 이름", + "newChat": "새 채팅", + "more": "더보기", + "clear": "지우기", + "searchConversations": "대화 검색...", + "create": "만들기", + "failedToCreateFolder": "폴더 생성 실패", + "failedToMoveChat": "채팅 이동 실패", + "failedToLoadChats": "채팅 로드 실패", + "failedToUpdatePin": "고정 업데이트 실패", + "failedToDeleteChat": "채팅 삭제 실패", + "manage": "관리", + "rename": "이름 변경", + "delete": "삭제", + "renameChat": "채팅 이름 변경", + "enterChatName": "채팅 이름 입력", + "failedToRenameChat": "채팅 이름 변경 실패", + "failedToUpdateArchive": "보관 업데이트 실패", + "unarchive": "보관 해제", + "archive": "보관", + "pin": "고정", + "unpin": "고정 해제", + "recent": "최근", + "system": "시스템", + "english": "English", + "deutsch": "Deutsch", + "francais": "Français", + "italiano": "Italiano", + "espanol": "Español", + "nederlands": "Nederlands", + "russian": "Русский", + "chinese": "中文", + "korean": "한국어", + "deleteMessagesTitle": "메시지 삭제", + "deleteMessagesMessage": "{count}개의 메시지를 삭제하시겠습니까?", + "routeNotFound": "경로를 찾을 수 없습니다: {routeName}", + "deleteChatTitle": "채팅 삭제", + "deleteChatMessage": "이 채팅은 영구적으로 삭제됩니다.", + "deleteFolderTitle": "폴더 삭제", + "deleteFolderMessage": "이 폴더와 할당 참조가 제거됩니다.", + "failedToDeleteFolder": "폴더 삭제 실패", + "aboutApp": "정보", + "aboutAppSubtitle": "Conduit 정보 및 링크", + "web": "웹", + "imageGen": "이미지 생성", + "pinned": "고정됨", + "folders": "폴더", + "archived": "보관됨", + "appLanguage": "앱 언어", + "darkMode": "다크 모드", + "webSearch": "웹 검색", + "webSearchDescription": "웹을 검색하고 답변에 소스를 인용합니다.", + "imageGeneration": "이미지 생성", + "imageGenerationDescription": "프롬프트에서 이미지를 생성합니다.", + "copy": "복사", + "ttsListen": "듣기", + "ttsStop": "중지", + "edit": "편집", + "regenerate": "재생성", + "noConversationsYet": "아직 대화가 없습니다", + "usernameOrEmailHint": "사용자 이름 또는 이메일을 입력하세요", + "passwordHint": "비밀번호를 입력하세요", + "enterApiKey": "API 키를 입력하세요", + "signingIn": "로그인 중...", + "advancedSettings": "고급 설정", + "customHeaders": "사용자 정의 헤더", + "customHeadersDescription": "인증, API 키 또는 특수 서버 요구사항을 위한 사용자 정의 HTTP 헤더를 추가하세요.", + "allowSelfSignedCertificates": "자체 서명된 인증서 신뢰", + "allowSelfSignedCertificatesDescription": "자체 서명된 경우에도 이 서버의 TLS 인증서를 수락합니다. 신뢰하는 서버에만 사용하세요.", + "headerNameEmpty": "헤더 이름은 비어 있을 수 없습니다", + "headerNameTooLong": "헤더 이름이 너무 깁니다 (최대 64자)", + "headerNameInvalidChars": "잘못된 헤더 이름입니다. 문자, 숫자 및 다음 기호만 사용하세요: !#$&-^_`|~", + "headerNameReserved": "예약된 헤더 \"{key}\"를 재정의할 수 없습니다", + "headerValueEmpty": "헤더 값은 비어 있을 수 없습니다", + "headerValueTooLong": "헤더 값이 너무 깁니다 (최대 1024자)", + "headerValueInvalidChars": "헤더 값에 잘못된 문자가 포함되어 있습니다. 인쇄 가능한 ASCII만 사용하세요.", + "headerValueUnsafe": "헤더 값에 잠재적으로 안전하지 않은 콘텐츠가 포함된 것으로 보입니다", + "headerAlreadyExists": "헤더 \"{key}\"가 이미 존재합니다. 업데이트하려면 먼저 제거하세요.", + "maxHeadersReachedDetail": "최대 10개의 사용자 정의 헤더가 허용됩니다. 더 추가하려면 일부를 제거하세요.", + "noModelsAvailable": "사용 가능한 모델 없음", + "followingSystem": "시스템 따름: {theme}", + "themeDark": "다크", + "themePalette": "강조 색상 팔레트", + "themePaletteConduitLabel": "Conduit", + "themePaletteConduitDescription": "Conduit을 위해 설계된 깔끔한 중립 테마.", + "themePaletteClaudeLabel": "Claude", + "themePaletteClaudeDescription": "Claude 웹 클라이언트에서 가져온 따뜻하고 촉각적인 팔레트.", + "themePaletteT3ChatLabel": "T3 Chat", + "themePaletteT3ChatDescription": "T3 Stack 브랜드에서 영감을 받은 장난스러운 그라디언트.", + "themePaletteCatppuccinLabel": "Catppuccin", + "themePaletteCatppuccinDescription": "부드러운 파스텔 팔레트.", + "themePaletteTangerineLabel": "Tangerine", + "themePaletteTangerineDescription": "따뜻한 오렌지와 슬레이트 팔레트.", + "themeLight": "라이트", + "currentlyUsingDarkTheme": "현재 다크 테마 사용 중", + "currentlyUsingLightTheme": "현재 라이트 테마 사용 중", + "aboutConduit": "Conduit 정보", + "versionLabel": "버전: {version} ({build})", + "githubRepository": "GitHub 저장소", + "unableToLoadAppInfo": "앱 정보를 불러올 수 없습니다", + "thinking": "생각 중…", + "thoughts": "생각", + "thoughtForDuration": "{duration} 동안 생각함", + "appCustomization": "사용자 정의", + "appCustomizationSubtitle": "테마, 언어, 음성 및 빠른 액션", + "quickActionsDescription": "채팅의 빠른 액션", + "quickActionsSelectedCount": "{count, plural, =0{선택된 액션 없음} one{액션 1개 선택됨} other{{count}개 액션 선택됨}}", + "autoSelectDescription": "앱이 최적의 모델을 선택하도록 허용", + "chatSettings": "채팅", + "sendOnEnter": "Enter로 전송", + "sendOnEnterDescription": "Enter로 전송 (소프트 키보드). Cmd/Ctrl+Enter도 사용 가능", + "sttSettings": "음성 텍스트 변환", + "sttEngineLabel": "인식 엔진", + "sttEngineAuto": "자동", + "sttEngineDevice": "기기에서", + "sttEngineServer": "서버", + "sttEngineAutoDescription": "사용 가능한 경우 기기에서 인식을 사용하고 서버로 폴백합니다.", + "sttEngineDeviceDescription": "오디오를 이 기기에서 유지합니다. 기기에서 음성 인식이 지원되지 않으면 음성 입력이 작동하지 않습니다.", + "sttEngineServerDescription": "항상 녹음을 OpenWebUI 서버로 전송하여 전사합니다.", + "sttDeviceUnavailableWarning": "이 기기에서 기기 음성 인식을 사용할 수 없습니다.", + "sttServerUnavailableWarning": "이 옵션을 사용하려면 전사가 활성화된 서버에 연결하세요.", + "sttSilenceDuration": "침묵 지속 시간", + "sttSilenceDurationDescription": "침묵 후 자동 녹음 중지 전 대기 시간", + "ttsEngineLabel": "엔진", + "ttsEngineAuto": "자동", + "ttsEngineDevice": "기기에서", + "ttsEngineServer": "서버", + "ttsEngineAutoDescription": "사용 가능한 경우 기기에서 음성을 사용하고 서버로 폴백합니다.", + "ttsEngineDeviceDescription": "합성을 이 기기에서 유지합니다. 기기에서 TTS가 지원되지 않으면 음성 재생이 작동하지 않습니다.", + "ttsEngineServerDescription": "항상 OpenWebUI 서버에서 오디오를 요청합니다.", + "ttsDeviceUnavailableWarning": "이 기기에서 기기 텍스트 음성 변환을 사용할 수 없습니다.", + "ttsServerUnavailableWarning": "이 옵션을 사용하려면 텍스트 음성 변환이 활성화된 서버에 연결하세요.", + "ttsSettings": "텍스트 음성 변환", + "ttsVoice": "음성", + "ttsSpeechRate": "말하기 속도", + "ttsPitch": "음높이", + "ttsVolume": "볼륨", + "ttsPreview": "음성 미리보기", + "ttsSystemDefault": "시스템 기본값", + "ttsSelectVoice": "음성 선택", + "ttsPreviewText": "선택한 음성의 미리보기입니다.", + "ttsNoVoicesAvailable": "사용 가능한 음성 없음", + "ttsVoicesForLanguage": "{language} 음성", + "ttsOtherVoices": "다른 언어", + "error": "오류", + "errorWithMessage": "오류: {message}", + "networkTimeoutError": "연결 시간이 초과되었습니다. 인터넷 연결을 확인하고 다시 시도해주세요.", + "networkUnreachableError": "서버에 연결할 수 없습니다. 서버 URL과 인터넷 연결을 확인하세요.", + "networkServerNotResponding": "서버가 응답하지 않습니다. 서버가 실행 중이고 액세스 가능한지 확인하세요.", + "networkGenericError": "네트워크 연결 문제입니다. 인터넷 연결을 확인해주세요.", + "serverError500": "서버에 문제가 발생했습니다. 이것은 보통 일시적입니다.", + "serverErrorUnavailable": "서버를 일시적으로 사용할 수 없습니다. 잠시 후 다시 시도해주세요.", + "serverErrorTimeout": "서버 응답 시간이 너무 깁니다. 다시 시도해주세요.", + "serverErrorGeneric": "서버에 문제가 발생했습니다. 나중에 다시 시도해주세요.", + "authSessionExpired": "세션이 만료되었습니다. 다시 로그인해주세요.", + "authForbidden": "이 작업을 수행할 권한이 없습니다.", + "authInvalidToken": "인증 토큰이 유효하지 않습니다. 다시 로그인해주세요.", + "authGenericError": "인증 문제입니다. 다시 로그인해주세요.", + "validationInvalidEmail": "유효한 이메일 주소를 입력해주세요.", + "validationWeakPassword": "비밀번호가 요구사항을 충족하지 않습니다. 확인하고 다시 시도해주세요.", + "validationMissingRequired": "모든 필수 필드를 채워주세요.", + "validationFormatError": "일부 정보의 형식이 잘못되었습니다. 확인하고 다시 시도해주세요.", + "validationGenericError": "입력을 확인하고 다시 시도해주세요.", + "fileNotFound": "파일을 찾을 수 없습니다. 이동되었거나 삭제되었을 수 있습니다.", + "fileAccessDenied": "파일에 액세스할 수 없습니다. 권한을 확인해주세요.", + "fileTooLarge": "파일이 너무 큽니다. 더 작은 파일을 선택해주세요.", + "fileGenericError": "파일 문제입니다. 다른 파일을 시도해주세요.", + "permissionCameraRequired": "카메라 권한이 필요합니다. 설정에서 활성화해주세요.", + "permissionStorageRequired": "저장소 권한이 필요합니다. 설정에서 활성화해주세요.", + "permissionMicrophoneRequired": "마이크 권한이 필요합니다. 설정에서 활성화해주세요.", + "permissionGenericError": "권한이 필요합니다. 설정에서 앱 권한을 확인해주세요.", + "actionRetryRequest": "요청을 다시 시도하세요.", + "actionVerifyConnection": "인터넷 연결을 확인하세요.", + "actionRetryOperation": "작업을 다시 시도하세요.", + "actionRetryAfterDelay": "잠시 기다린 후 다시 시도하세요.", + "actionSignInToAccount": "계정에 로그인하세요.", + "actionSelectAnotherFile": "다른 파일을 선택하세요.", + "actionOpenAppSettings": "앱 설정을 열어 권한을 부여하세요.", + "actionRetryAfterPermission": "권한을 부여한 후 다시 시도하세요.", + "actionReturnToPrevious": "이전 화면으로 돌아가세요.", + "display": "디스플레이", + "realtime": "실시간", + "transportMode": "전송 모드", + "mode": "모드", + "transportModePolling": "폴링 폴백", + "transportModeWs": "WebSocket 전용", + "transportModePollingInfo": "WebSocket이 차단되면 HTTP 폴링으로 폴백합니다. 가능하면 WebSocket으로 업그레이드합니다.", + "transportModeWsInfo": "오버헤드가 낮지만 엄격한 프록시/방화벽 뒤에서 실패할 수 있습니다." +} diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index a2c974f..7058ccb 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -10,6 +10,7 @@ import 'app_localizations_en.dart'; import 'app_localizations_es.dart'; import 'app_localizations_fr.dart'; import 'app_localizations_it.dart'; +import 'app_localizations_kr.dart'; import 'app_localizations_nl.dart'; import 'app_localizations_ru.dart'; import 'app_localizations_zh.dart'; @@ -108,6 +109,7 @@ abstract class AppLocalizations { Locale('ru'), Locale('nl'), Locale('es'), + Locale('kr'), ]; /// Application name displayed in the app and OS UI. @@ -1316,6 +1318,12 @@ abstract class AppLocalizations { /// **'中文'** String get chinese; + /// Language name: Korean. + /// + /// In en, this message translates to: + /// **'한국어'** + String get korean; + /// Dialog title asking to confirm deletion of messages. /// /// In en, this message translates to: @@ -2263,6 +2271,7 @@ class _AppLocalizationsDelegate 'es', 'fr', 'it', + 'kr', 'nl', 'ru', 'zh', @@ -2285,6 +2294,8 @@ AppLocalizations lookupAppLocalizations(Locale locale) { return AppLocalizationsFr(); case 'it': return AppLocalizationsIt(); + case 'kr': + return AppLocalizationsKr(); case 'nl': return AppLocalizationsNl(); case 'ru': diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 58fb7f9..ca58d18 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -657,6 +657,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get chinese => 'Chinesisch'; + @override + String get korean => '한국어'; + @override String get deleteMessagesTitle => 'Nachrichten löschen'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 7f2baba..25f1d5b 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -653,6 +653,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get chinese => '中文'; + @override + String get korean => '한국어'; + @override String get deleteMessagesTitle => 'Delete Messages'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 97abbd8..a525bb8 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -662,6 +662,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get chinese => 'Chinois'; + @override + String get korean => '한국어'; + @override String get deleteMessagesTitle => 'Supprimer les messages'; diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index f47fe4d..dd99854 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -654,6 +654,9 @@ class AppLocalizationsIt extends AppLocalizations { @override String get chinese => 'Cinese'; + @override + String get korean => '한국어'; + @override String get deleteMessagesTitle => 'Elimina messaggi'; diff --git a/scripts/release.sh b/scripts/release.sh index 33f2e18..3b2cb67 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -152,7 +152,7 @@ mkdir -p "$ANDROID_CHANGELOG_DIR" echo "$LINK" > "$ANDROID_CHANGELOG_DIR/$NEW_BUILD.txt" # iOS whatsnew for all locales (App Store requires it for each locale) -IOS_LOCALES=("default" "en-US" "de-DE" "es-ES" "fr-FR" "it" "nl-NL" "ru" "zh-Hans") +IOS_LOCALES=("default" "en-US" "de-DE" "es-ES" "fr-FR" "it" "nl-NL" "ru" "zh-Hans" "ko-KR") IOS_WHATSNEW_FILES=() for locale in "${IOS_LOCALES[@]}"; do IOS_WHATSNEW_PATH="ios/fastlane/metadata/$locale/whatsnew.txt"