diff --git a/assets/l10n/intl_vi.arb b/assets/l10n/intl_vi.arb index dcb25cc94..2089d4d59 100644 --- a/assets/l10n/intl_vi.arb +++ b/assets/l10n/intl_vi.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2025-03-05 13:01:52.197829", + "@@last_modified": "2025-03-10 10:26:28.474786", "about": "Giới thiệu", "@about": { "type": "String", @@ -3304,7 +3304,7 @@ }, "botModeValidation": "Vui lòng chọn một chế độ trò chuyện", "clickBestOption": "Chọn phương án tốt nhất để dịch tin nhắn của bạn!", - "completeActivitiesToUnlock": "Hoàn thành các hoạt động từ vựng để mở khóa phần âm thanh và bản dịch!", + "completeActivitiesToUnlock": "Hoàn thành các hoạt động từ vựng được đánh dấu để mở khóa", "botSettingsSubtitle": "Mời bot kiểm duyệt hoặc khởi tạo hoạt động trò chuyện", "invitePeople": "Mời người dùng", "invitePeopleChatSubtitle": "Mời người dùng hoặc quản trị viên đến cuộc trò chuyện này", @@ -3568,7 +3568,6 @@ "video": "Video", "nan": "Không áp dụng", "activityPlannerOverviewInstructionsBody": "Chọn chủ đề, chế độ, mục tiêu học tập và tạo hoạt động cho cuộc trò chuyện!", - "completeActivitiesToUnlock": "Hoàn thành các hoạt động từ vựng được đánh dấu để mở khóa", "myBookmarkedActivities": "Hoạt động đã đánh dấu", "noBookmarkedActivities": "Chưa có hoạt động nào được đánh dấu", "activityTitle": "Tiêu đề hoạt động", @@ -3739,5 +3738,60 @@ } }, "downloadGboard": "Tải Gboard", - "autocorrectNotAvailable": "Rất tiếc, nền tảng của bạn hiện không được hỗ trợ cho tính năng này. Hãy theo dõi để biết thêm thông tin phát triển!" -} + "autocorrectNotAvailable": "Rất tiếc, nền tảng của bạn hiện không được hỗ trợ cho tính năng này. Hãy theo dõi để biết thêm thông tin phát triển!", + "takeAPhoto": "Chụp một bức ảnh", + "recordAVideo": "Ghi lại một video", + "optionalMessage": "(Tùy chọn) tin nhắn...", + "notSupportedOnThisDevice": "Không được hỗ trợ trên thiết bị này", + "pleaseUpdateApp": "Vui lòng cập nhật ứng dụng để tiếp tục.", + "chooseEmojiInstructionsBody": "Chọn một biểu tượng cảm xúc cho từ này! Không có câu trả lời sai và bạn có thể chuyển đổi bất cứ lúc nào! 😄", + "pickAnEmojiFor": "Chọn một biểu tượng cảm xúc cho ${lemma}", + "knockSpaceSuccess": "Bạn đã yêu cầu tham gia không gian này! Một quản trị viên sẽ phản hồi yêu cầu của bạn khi họ nhận được nó 😄", + "joinByCode": "Tham gia bằng mã", + "createASpace": "Tạo một không gian", + "@@locale": "vi", + "@takeAPhoto": { + "type": "String", + "placeholders": {} + }, + "@recordAVideo": { + "type": "String", + "placeholders": {} + }, + "@optionalMessage": { + "type": "String", + "placeholders": {} + }, + "@notSupportedOnThisDevice": { + "type": "String", + "placeholders": {} + }, + "@pleaseUpdateApp": { + "type": "String", + "placeholders": {} + }, + "@chooseEmojiInstructionsBody": { + "type": "String", + "placeholders": {} + }, + "@pickAnEmojiFor": { + "type": "String", + "placeholders": { + "lemma": { + "type": "String" + } + } + }, + "@knockSpaceSuccess": { + "type": "String", + "placeholders": {} + }, + "@joinByCode": { + "type": "String", + "placeholders": {} + }, + "@createASpace": { + "type": "String", + "placeholders": {} + } +} \ No newline at end of file diff --git a/scripts/translate.py b/scripts/translate.py index e23ccdfbc..386cab8d7 100644 --- a/scripts/translate.py +++ b/scripts/translate.py @@ -8,6 +8,8 @@ Usage: python scripts/translate.py """ +from typing import Any + def load_needed_translations() -> dict[str, list[str]]: import json @@ -78,7 +80,11 @@ def save_translations(lang_code: str, translations: dict[str, str]) -> None: f.write(json.dumps(existing_data, indent=2, ensure_ascii=False)) -def reconcile_metadata(lang_code: str, translation_keys: list[str]) -> None: +def reconcile_metadata( + lang_code: str, + translation_keys: list[str], + english_translations_dict: dict[str, Any], +) -> None: """ For each translation key, update its metadata (the key prefixed with '@') by merging any existing metadata with computed metadata. For basic translations, if no metadata exists, @@ -95,7 +101,7 @@ def reconcile_metadata(lang_code: str, translation_keys: list[str]) -> None: # Case 1: Basic translations, no placeholders. if "{" not in translation: if not existing_meta: - translations[meta_key] = {"type": "text", "placeholders": {}} + translations[meta_key] = {"type": "String", "placeholders": {}} # if metadata exists, leave it as is. # Case 2: Translations with placeholders (no pluralization). @@ -109,14 +115,27 @@ def reconcile_metadata(lang_code: str, translation_keys: list[str]) -> None: for placeholder in translation.split("{")[1:]: placeholder_name = placeholder.split("}")[0] computed_placeholders[placeholder_name] = {} + # Obtain placeholder type from english translation or default to {} + placeholder_type = ( + english_translations_dict.get(meta_key, {}) + .get("placeholders", {}) + .get(placeholder_name, {}) + .get("type") + ) + if placeholder_type: + computed_placeholders[placeholder_name]["type"] = placeholder_type if existing_meta: # Merge computed placeholders into existing metadata. - existing_meta.setdefault("type", "text") + existing_meta.setdefault("type", "String") existing_meta["placeholders"] = computed_placeholders translations[meta_key] = existing_meta else: + # Obtain type from english translation or default to "String". + translation_type = english_translations_dict.get(meta_key, {}).get( + "type", "String" + ) translations[meta_key] = { - "type": "text", + "type": translation_type, "placeholders": computed_placeholders, } @@ -130,13 +149,27 @@ def reconcile_metadata(lang_code: str, translation_keys: list[str]) -> None: p.strip() for p in prefix.split(",") if p.strip() != "" ] computed_placeholders = {ph: {} for ph in placeholders_list} + for ph in placeholders_list: + # Obtain placeholder type from english translation or default to {} + placeholder_type = ( + english_translations_dict.get(meta_key, {}) + .get("placeholders", {}) + .get(placeholder_name, {}) + .get("type") + ) + if placeholder_type: + computed_placeholders[ph]["type"] = placeholder_type if existing_meta: - existing_meta.setdefault("type", "text") + existing_meta.setdefault("type", "String") existing_meta["placeholders"] = computed_placeholders translations[meta_key] = existing_meta else: + # Obtain type from english translation or default to "String". + translation_type = english_translations_dict.get(meta_key, {}).get( + "type", "String" + ) translations[meta_key] = { - "type": "text", + "type": "String", "placeholders": computed_placeholders, } @@ -259,7 +292,7 @@ def translate(lang_code: str, lang_display_name: str) -> None: save_translations(lang_code, current_translations) # reconcile metadata - reconcile_metadata(lang_code, needed_translations) + reconcile_metadata(lang_code, needed_translations, english_translations_dict) """Example usage: