From 7e16b2f101311e89ab15e83a5c9b2cb5522b2562 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:17:36 +0900 Subject: [PATCH 1/5] [bugfix] Config Page: Appearance tab. Fix Ui Font setting that was not working. --- src-ui/app/App.jsx | 3 +-- src-ui/app/_index_css/root.css | 3 +-- src-ui/app/_index_css/variables.css | 2 ++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index e456d6c7..ab8f49a0 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -143,7 +143,6 @@ const UiSizeController = () => { useEffect(() => { document.documentElement.style.setProperty("font-size", `${font_size}%`); - document.documentElement.style.setProperty("font-family", `Yu Gothic UI`); }, [currentUiScaling.data]); return null; @@ -153,7 +152,7 @@ const UiSizeController = () => { const FontFamilyController = () => { const { currentSelectedFontFamily } = useSelectedFontFamily(); useEffect(() => { - document.documentElement.style.setProperty("font-family", `${currentSelectedFontFamily.data}`); + document.documentElement.style.setProperty("--font_family", currentSelectedFontFamily.data); }, [currentSelectedFontFamily.data]); return null; diff --git a/src-ui/app/_index_css/root.css b/src-ui/app/_index_css/root.css index b84dab43..d6bc751d 100644 --- a/src-ui/app/_index_css/root.css +++ b/src-ui/app/_index_css/root.css @@ -4,7 +4,6 @@ :root { font-size: 62.5%; color: #F2F2F2; - font-family: "Yu Gothic UI"; } * { @@ -24,7 +23,7 @@ html, body { height: 100%; - font-family: "Yu Gothic UI"; /* If not found the font family where 'root:' that is selected by user*/ + font-family: var(--font_family); /* If not found the font family where 'root:' that is selected by user*/ border-radius: 1.8rem; } diff --git a/src-ui/app/_index_css/variables.css b/src-ui/app/_index_css/variables.css index 9cd88d28..7d9f52f9 100644 --- a/src-ui/app/_index_css/variables.css +++ b/src-ui/app/_index_css/variables.css @@ -50,4 +50,6 @@ --main_page_topbar_height: 4.8rem; --config_page_sidebar_width: 18rem; --config_page_topbar_height: 8rem; + + --font_family: "Yu Gothic UI"; } \ No newline at end of file From 9e58bff26e3b5ad682a65270706b47b74b70daf1 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:35:28 +0900 Subject: [PATCH 2/5] [Update] Localization. Add zh-Hans.(yaml data from v2.2.9 and I changed its format to json) --- locales/config.js | 2 + locales/zh-Hans.json | 244 +++++++++++++++++++++++++++++++++++++++++++ src-ui/ui_configs.js | 1 + 3 files changed, 247 insertions(+) create mode 100644 locales/zh-Hans.json diff --git a/locales/config.js b/locales/config.js index 0c422a21..ee952cb7 100644 --- a/locales/config.js +++ b/locales/config.js @@ -5,6 +5,7 @@ import translation_en from "./en.json"; import translation_ja from "./ja.json"; import translation_ko from "./ko.json"; import translation_zh_Hant from "./zh-Hant.json"; +import translation_zh_Hans from "./zh-Hans.json"; const resources = { @@ -12,6 +13,7 @@ const resources = { ja: { translation: translation_ja }, ko: { translation: translation_ko }, "zh-Hant": { translation: translation_zh_Hant }, + "zh-Hans": { translation: translation_zh_Hans }, }; i18n diff --git a/locales/zh-Hans.json b/locales/zh-Hans.json new file mode 100644 index 00000000..2028be76 --- /dev/null +++ b/locales/zh-Hans.json @@ -0,0 +1,244 @@ +{ + "main_page": { + "translation": "翻译", + "transcription_send": "你的语音转文字", + "transcription_receive": "他人语音转文字", + "foreground": "顶层显示", + "language_settings": "语言设定", + "your_language": "你的语言", + "translate_each_other_label": "双向翻译", + "swap_button_label": "互换", + "target_language": "目标语言", + "translator": "翻译器", + "translator_ctranslate2": "离线翻译(默认)", + "textbox_tab_all": "全部", + "textbox_tab_sent": "发送", + "textbox_tab_received": "接受", + "textbox_tab_system": "系统", + "textbox_system_message": { + "enabled_translation": "翻译已启动.", + "disabled_translation": "翻译已关闭.", + "enabled_voice2chatbox": "正在翻译你的语音并转成文字.", + "disabled_voice2chatbox": "你的语音翻译结束了.", + "enabled_speaker2log": "正在翻译他人语音并转成文字.", + "disabled_speaker2log": "第三者的语音翻译结束了.", + "enabled_foreground": "顶层显示开启.", + "disabled_foreground": "顶层显示关闭.", + "auth_key_success": "授权密匙更新完毕", + "auth_key_error": "授权密匙错误或已达到翻译API(翻译器决定)使用次数上限.", + "no_mic_device_detected_error": "未检测到你的麦克风.", + "no_speaker_device_detected_error": "未检测到他人语音输入.", + "translation_engine_limit_error": "自动更换了翻译器.原因是对该翻译器请求太频繁,它暂时拒绝了接收翻译请求.如仍想使用原本翻译器,请稍等片刻后在重启VRCT.", + "detected_by_word_filter": "该单词 {{detected_message}} 被单词过滤器检测出所以没有发送.", + "selected_your_language": "[你的语言]设定为 {{your_language}} ", + "selected_target_language": "[目标语言]设定为 {{target_language}} ", + "switched_language_preset_tab": "已切换为第 {{tab_no}} 号语言设定", + "latest_language_setting": "现在,你的语言是 {{your_language}},目标语言是 {{target_language}} .", + "opened_web_page_booth": "在你的默认浏览器上打开了Booth页面", + "opened_web_page_vrct_documents": "在你的默认浏览器上打开了VRCT文档,有着关于VRCT的使用方法\n其他问题、请求、查询等请通过文档底部的链接或X (Twitter) 联系我们!" + }, + "update_available": "有新版本可供使用!", + "state_text_enabled": "启用", + "state_text_disabled": "停用", + "cover_message": "在设置窗口关闭前,VRCT的功能暂时停用", + "confirmation_message": { + "update_software": "下载新版本并自动启动\n会花少许时间,现在更新吗?", + "deny_update_software": "稍后再说", + "accept_update_software": "更新后自动启动", + "updating": "更新中...", + "detected_over_ui_size": "现在的界面大小: {{current_ui_size}}\nVRCT的窗口大小有可能会大于显示器\n请根据你的屏幕大小设置合适的VRCT的大小", + "deny_adjust_ui_size": "现在界面大小是合适的", + "accept_adjust_ui_size": "缩小界面大小并重新启动" + } + }, + "selectable_language_window": { + "title_your_language": "你的语言", + "title_target_language": "目标语言", + "go_back_button": "返回" + }, + "overlay_settings": { + "restore_default_settings": "恢复默认设置", + "opacity": "透明度", + "ui_scaling": "大小", + "x_position": "X轴(左右)", + "y_position": "Y轴(上下)", + "z_position": "Z轴(前后)", + "x_rotation": "X轴旋转", + "y_rotation": "Y轴旋转", + "z_rotation": "Z轴旋转", + "display_duration": "显示持续时间", + "fadeout_duration": "渐隐持续时间" + }, + "config_page": { + "config_title": "设定", + "compact_mode": "精简模式", + "version": "版本 {{version}}", + "restart_message": "重启并应用设定", + "common_error_message": { + "invalid_value": "无效的值" + }, + "side_menu_labels": { + "appearance": "外观", + "translation": "翻译", + "transcription": "转录", + "transcription_mic": "你的麦克风", + "transcription_speaker": "他人声音", + "transcription_internal_model": "转录模型", + "others": "其他", + "advanced_settings": "高级设置" + }, + "transparency": { + "label": "透明度", + "desc": "更改主视窗透明度" + }, + "appearance_theme": { + "label": "主题", + "desc": "更改主题配色" + }, + "ui_size": { + "label": "界面大小" + }, + "textbox_ui_size": { + "label": "文本框字体大小", + "desc": "你可以根据用户界面大小调整文本框中使用的字体大小。" + }, + "message_box_ratio": { + "label": "文本框大小", + "desc": "你可以根据界面比例调整文本框大小\n※可能不准确" + }, + "font_family": { + "label": "字体" + }, + "ui_language": { + "label": "界面语言" + }, + "to_restore_main_page_geometry": { + "label": "记录主界面位置", + "desc": "启动时,按照上次的大小和位置启动" + }, + "use_translation_feature": { + "label": "启用翻译功能", + "desc": "关闭此功能时,无法使用翻译功能.VRCT的启动速度会变得更快一些.这适用于不需要翻译功能,只将VRCT用作聊天框和转录工具的用户." + }, + "ctranslate2_weight_type": { + "label": "选择离线翻译模型", + "desc": "可以选择用于离线翻译的翻译模型", + "small": "普通模型 ({{capacity}})", + "large": "高精度模型 ({{capacity}})" + }, + "deepl_auth_key": { + "label": "DeepL 授权密匙", + "desc": "在使用的时候,使用时请在主屏幕上通过 DeepL_API 选择 {{translator}} \n※某些语言可能不支持", + "open_auth_key_webpage": "打开DeepL账号页面", + "auth_key_success": "授权密匙认证完成。", + "auth_key_error": "授权密匙错误或已达API使用上限" + }, + "mic_host": { + "label": "麦克风(host/driver)" + }, + "mic_device": { + "label": "麦克风 (设备)" + }, + "mic_dynamic_energy_threshold": { + "label_for_automatic": "麦克风输入阈值(当前设置:自动)", + "desc_for_automatic": "自动调整麦克风输入阈值", + "label_for_manual": "麦克风输入阈值(当前设置:手动)", + "desc_for_manual": "使用滑杆手动确定麦克风输入灵敏度。按下麦克风图标输入语音,并在监控音量的同时调节灵敏度。", + "error_message": "数值应为 0 至 {{max}} 之间。" + }, + "mic_record_timeout": { + "label": "语音输入结束后的静音时间", + "desc": "当检测到静音并经过设定的秒数后,语音输入即被视为完成。", + "error_message": "数值应为 0 至 [{{mic_phrase_timeout_label}}]" + }, + "mic_phrase_timeout": { + "label": "转录间隔", + "desc": "在经过设定的时间后执行转录", + "error_message": "转录间隔时间大于0秒且不能小于「{{mic_record_timeout_label}}」" + }, + "mic_max_phrase": { + "label": "麦克风发送时的最小单词数", + "desc": "转录字数的下限,只有超过这个数字,才会记录翻译结果并发送到VRC", + "error_message": "数值应为 0 以上" + }, + "mic_word_filter": { + "label": "单词过滤器", + "desc": "检测出被记录的单词时,不会发送这段话\n如要添加多个单词,可以用逗号来分割\n※不会记录重复的单词", + "add_button_label": "添加", + "count_desc": "现在被记录的单词数: {{count}}" + }, + "speaker_device": { + "label": "他人语音 (设备)" + }, + "speaker_dynamic_energy_threshold": { + "label_for_automatic": "他人语音接收阈值(当前设置:自动)", + "desc_for_automatic": "自动调节他人语音接收阈值", + "label_for_manual": "他人语音接收阈值(当前设置:手动)", + "desc_for_manual": "使用滑杆手动调整他人语音接收阈值.在按下耳机按钮时,请根据实际听到的声音调整该大小", + "error_message": "设定的数值从 0 到 {{max}} ", + "no_device_error_message": "未检测到他人语音" + }, + "speaker_record_timeout": { + "label": "语音接收结束后的静音时间", + "desc": "当检测到静音并经过设定的秒数后,语音接收即被视为完成。", + "error_message": "数值应为 0 至 「{{speaker_phrase_timeout_label}}」" + }, + "speaker_phrase_timeout": { + "label": "转录间隔", + "desc": "在经过设定的时间后执行转录", + "error_message": "转录间隔时间大于0秒且不能小于「{{speaker_record_timeout_label}}」" + }, + "speaker_max_phrase": { + "label": "语音接收时的最小单词数", + "desc": "转录字数的下限,只有超过这个数字,才会记录转录结果", + "error_message": "数值应为 0 以上" + }, + "use_whisper_feature": { + "label": "使用Whisper模型翻译", + "desc": "在某些语言中,语音识别的准确性可能会提高.语音识别的过程中,CPU占有率可能会提高,请根据你的pc性能来决定是否使用它." + }, + "whisper_weight_type": { + "label": "选择某个Whisper模型", + "desc": "通常来说,容量越大的模型精度也会越高,但也会增加文字显示所需要的时间和CPU的使用率。请浏览各个模型的文档\n※特别是大于medium容量的模型、因CPU性能原因甚至无法使用。", + "model_template": "{{model_name}} 模型 ({{capacity}})", + "recommended_model_template": "{{model_name}} 模型 ({{capacity}}) (推荐)" + }, + "enable_overlay_small_log": { + "label": "可使用Overlay", + "open_overlay_settings": "打开Overlay进阶设置" + }, + "auto_clear_the_message_box": { + "label": "发言后自动清空chatbox" + }, + "send_only_translated_messages": { + "label": "只发送翻译后的信息" + }, + "send_message_button_type": { + "label": "发送信息按钮", + "hide": "隐藏 (可使用回车发送信息)", + "show": "显示", + "show_and_disable_enter_key": "显示,并且停用‘回车发送信息’" + }, + "auto_export_message_logs": { + "label": "自动导出聊天记录", + "desc": "以文本文件的形式在logs文件夹中保存。" + }, + "vrc_mic_mute_sync": { + "label": "与VRC中的麦克风静音同步", + "desc": "当VRChat的麦克风处于静音时,不在VRChat中发送信息\n※存在少许延迟且不支持按键发言." + }, + "send_message_to_vrc": { + "label": "发送信息至VRChat", + "desc": "不发送信息至VRChat的情况下也能使用它,但该功能现在并未完成.在想要发送信息时,请不要忘记打开这个功能." + }, + "osc_ip_address": { + "label": "OSC IP 地址" + }, + "osc_port": { + "label": "OSC 端口" + }, + "open_config_filepath": { + "label": "打开设置文件" + } + } +} \ No newline at end of file diff --git a/src-ui/ui_configs.js b/src-ui/ui_configs.js index eaf3896f..a3634b91 100644 --- a/src-ui/ui_configs.js +++ b/src-ui/ui_configs.js @@ -8,6 +8,7 @@ export const ui_configs = { {id: "ja", label: "日本語"}, {id: "ko", label: "한국어"}, {id: "zh-Hant", label: "繁體中文"}, + {id: "zh-Hans", label: "简体中文"}, ] }; From 737cdf15cf95b4c60b926c63a48b5aa148ac8104 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:45:14 +0900 Subject: [PATCH 3/5] [bugfix] Fix the bug that the component was not re-rendering when even the Ui language is changed. --- locales/config.js | 3 ++- package-lock.json | 22 +++++++++++----------- package.json | 2 +- src-ui/app/App.jsx | 8 ++++++-- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/locales/config.js b/locales/config.js index ee952cb7..96ae9fc7 100644 --- a/locales/config.js +++ b/locales/config.js @@ -25,7 +25,8 @@ i18n debug: true, interpolation: { escapeValue: false // react already safes from xss - } + }, + // react: { useSuspense: false }, }); export default i18n; diff --git a/package-lock.json b/package-lock.json index 34b601e4..4ec8acc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "js-base64": "^3.7.7", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-i18next": "^14.1.2", + "react-i18next": "^15.1.1", "react-resizable-layout": "^0.7.2" }, "devDependencies": { @@ -2628,9 +2628,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4569,9 +4569,9 @@ } }, "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "dependencies": { "nice-try": "^1.0.4", @@ -5001,11 +5001,11 @@ } }, "node_modules/react-i18next": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.3.tgz", - "integrity": "sha512-wZnpfunU6UIAiJ+bxwOiTmBOAaB14ha97MjOEnLGac2RJ+h/maIYXZuTHlmyqQVX1UVHmU1YDTQ5vxLmwfXTjw==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.1.1.tgz", + "integrity": "sha512-R/Vg9wIli2P3FfeI8o1eNJUJue5LWpFsQePCHdQDmX0Co3zkr6kdT8gAseb/yGeWbNz1Txc4bKDQuZYsC0kQfw==", "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.25.0", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { diff --git a/package.json b/package.json index d60d775d..3a3ee0c2 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "js-base64": "^3.7.7", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-i18next": "^14.1.2", + "react-i18next": "^15.1.1", "react-resizable-layout": "^0.7.2" }, "devDependencies": { diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index ab8f49a0..dfabbafc 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -1,4 +1,6 @@ import { useEffect, useRef } from "react"; +import { useTranslation } from "react-i18next"; + import { useStartPython } from "@logics/useStartPython"; import { WindowTitleBar } from "./window_title_bar/WindowTitleBar"; import { MainPage } from "./main_page/MainPage"; @@ -11,6 +13,7 @@ import { useIsBackendReady } from "@logics_common"; export const App = () => { const { currentIsBackendReady } = useIsBackendReady(); const { WindowGeometryController } = useWindow(); + const { i18n } = useTranslation(); return (