Merge branch 'develop'
This commit is contained in:
@@ -25,7 +25,7 @@ common_error:
|
|||||||
invalid_value_speaker_max_phrase: "You can set a number equal to or greater than 0."
|
invalid_value_speaker_max_phrase: "You can set a number equal to or greater than 0."
|
||||||
|
|
||||||
common_warning:
|
common_warning:
|
||||||
unable_to_use_osc_query: "The functions below have been automatically disabled because receiving OSC data is not possible due to OSC IP Address settings."
|
unable_to_use_osc_query: "The following functions have been automatically disabled due to the OSC IP Address settings preventing OSC data from being received."
|
||||||
|
|
||||||
main_page:
|
main_page:
|
||||||
translation: "Translation"
|
translation: "Translation"
|
||||||
@@ -211,6 +211,7 @@ config_page:
|
|||||||
|
|
||||||
others:
|
others:
|
||||||
section_label_sounds: "Sounds"
|
section_label_sounds: "Sounds"
|
||||||
|
section_label_message_formats: "Message Formats"
|
||||||
auto_clear_the_message_box:
|
auto_clear_the_message_box:
|
||||||
label: "Auto Clear Message box"
|
label: "Auto Clear Message box"
|
||||||
send_only_translated_messages:
|
send_only_translated_messages:
|
||||||
@@ -230,6 +231,25 @@ config_page:
|
|||||||
send_received_message_to_vrc:
|
send_received_message_to_vrc:
|
||||||
label: "Send Received Message To VRChat"
|
label: "Send Received Message To VRChat"
|
||||||
desc: "Send the message you received from the speaker's voice to VRChat's chatbox."
|
desc: "Send the message you received from the speaker's voice to VRChat's chatbox."
|
||||||
|
message_format_common:
|
||||||
|
example_view:
|
||||||
|
title: "Preview"
|
||||||
|
original_translated: "Original + Translation"
|
||||||
|
original_translated_multi: "Original + Translation (Multi-language)"
|
||||||
|
translated_only_multi: "Translation Only (Multi-language)"
|
||||||
|
translated_only: "Translation Only"
|
||||||
|
original_only: "Original Only"
|
||||||
|
settings:
|
||||||
|
title: "Settings"
|
||||||
|
original: "Original"
|
||||||
|
translated: "Translation"
|
||||||
|
for_multi_translation: "For Multi-Translation"
|
||||||
|
send_message_format:
|
||||||
|
label: "Message Format (Send)"
|
||||||
|
desc: "This allows you to change the format of the message that others see in VRChat."
|
||||||
|
received_message_format:
|
||||||
|
label: "Message Format (Speaker2Chatbox)"
|
||||||
|
desc: "Currently, it is used in Speaker2Chatbox."
|
||||||
|
|
||||||
hotkeys:
|
hotkeys:
|
||||||
toggle_vrct_visibility:
|
toggle_vrct_visibility:
|
||||||
@@ -245,7 +265,7 @@ config_page:
|
|||||||
downloaded_version: "Downloaded version: {{downloaded_version}}"
|
downloaded_version: "Downloaded version: {{downloaded_version}}"
|
||||||
latest_version: "Latest version: {{latest_version}}"
|
latest_version: "Latest version: {{latest_version}}"
|
||||||
available_after_updating: "Available after updating to the latest version"
|
available_after_updating: "Available after updating to the latest version"
|
||||||
unavailable_downloaded: "Currently unavailable due to incompatibility with the VRCT version in use"
|
unavailable_downloaded: "Currently Unavailable - Incompatible with the VRCT version in use"
|
||||||
no_latest_info: "Unable to retrieve the latest information"
|
no_latest_info: "Unable to retrieve the latest information"
|
||||||
using_latest_version: "Using the latest version"
|
using_latest_version: "Using the latest version"
|
||||||
available_latest_version: "Latest version available"
|
available_latest_version: "Latest version available"
|
||||||
@@ -273,16 +293,16 @@ config_page:
|
|||||||
save_success: "Settings have been saved."
|
save_success: "Settings have been saved."
|
||||||
|
|
||||||
plugin_notifications:
|
plugin_notifications:
|
||||||
downloading: Downloading the plugin.
|
downloading: "Downloading the plugin."
|
||||||
downloaded_success: Downloaded successfully.
|
downloaded_success: "Downloaded successfully."
|
||||||
downloaded_error: Download failed.
|
downloaded_error: "Download failed."
|
||||||
|
|
||||||
updating: Updating the plugin.
|
updating: "Updating the plugin."
|
||||||
updated_success: Updated successfully.
|
updated_success: "Updated successfully."
|
||||||
updated_error: Update failed.
|
updated_error: "Update failed."
|
||||||
|
|
||||||
disabled_out_of_support: The plugin has been disabled. It's not supported on this VRCT version.
|
disabled_out_of_support: "The plugin has been disabled. It's not supported on this VRCT version."
|
||||||
disabled_due_to_an_error: "An error was detected while running the plugin. Please report this to the plugin developer."
|
disabled_due_to_an_error: "An error was detected while running the plugin. Please report this to the plugin developer."
|
||||||
|
|
||||||
is_enabled: The plugin has enabled.
|
is_enabled: "The plugin enabled."
|
||||||
is_disabled: The plugin has disabled.
|
is_disabled: "The plugin disabled."
|
||||||
@@ -211,6 +211,7 @@ config_page:
|
|||||||
|
|
||||||
others:
|
others:
|
||||||
section_label_sounds: "サウンド"
|
section_label_sounds: "サウンド"
|
||||||
|
section_label_message_formats: "メッセージフォーマット"
|
||||||
auto_clear_the_message_box:
|
auto_clear_the_message_box:
|
||||||
label: "送信後はメッセージ入力欄を空にする"
|
label: "送信後はメッセージ入力欄を空にする"
|
||||||
send_only_translated_messages:
|
send_only_translated_messages:
|
||||||
@@ -230,6 +231,25 @@ config_page:
|
|||||||
send_received_message_to_vrc:
|
send_received_message_to_vrc:
|
||||||
label: "受信したメッセージをVRChatに送信する"
|
label: "受信したメッセージをVRChatに送信する"
|
||||||
desc: "スピーカーから聞き取り、文字起こしされたメッセージをVRChatに送信します。"
|
desc: "スピーカーから聞き取り、文字起こしされたメッセージをVRChatに送信します。"
|
||||||
|
message_format_common:
|
||||||
|
example_view:
|
||||||
|
title: "プレビュー"
|
||||||
|
original_translated: "原文 + 翻訳"
|
||||||
|
original_translated_multi: "原文 + 翻訳(多言語)"
|
||||||
|
translated_only_multi: "翻訳のみ(多言語)"
|
||||||
|
translated_only: "翻訳のみ"
|
||||||
|
original_only: "原文のみ"
|
||||||
|
settings:
|
||||||
|
title: "設定"
|
||||||
|
original: "原文"
|
||||||
|
translated: "翻訳"
|
||||||
|
for_multi_translation: "多言語翻訳用"
|
||||||
|
send_message_format:
|
||||||
|
label: メッセージフォーマット(送信)
|
||||||
|
desc: VRChatで相手に実際に見えるフォーマットを変更できます。
|
||||||
|
received_message_format:
|
||||||
|
label: メッセージフォーマット(Speaker2Chatbox)
|
||||||
|
desc: 今のところ、Speaker2Chatboxで送信した時の表示に使われます。
|
||||||
|
|
||||||
hotkeys:
|
hotkeys:
|
||||||
toggle_vrct_visibility:
|
toggle_vrct_visibility:
|
||||||
@@ -273,16 +293,16 @@ config_page:
|
|||||||
save_success: "設定を保存しました。"
|
save_success: "設定を保存しました。"
|
||||||
|
|
||||||
plugin_notifications:
|
plugin_notifications:
|
||||||
downloading: プラグインをダウンロード中。
|
downloading: "プラグインをダウンロード中。"
|
||||||
downloaded_success: プラグインのダウンロードが完了しました。
|
downloaded_success: "プラグインのダウンロードが完了しました。"
|
||||||
downloaded_error: プラグインのダウンロードに失敗しました。
|
downloaded_error: "プラグインのダウンロードに失敗しました。"
|
||||||
|
|
||||||
updating: プラグインをアップデート中。
|
updating: "プラグインをアップデート中。"
|
||||||
updated_success: プラグインのアップデートが完了しました。
|
updated_success: "プラグインのアップデートが完了しました。"
|
||||||
updated_error: プラグインのアップデートに失敗しました。
|
updated_error: "プラグインのアップデートに失敗しました。"
|
||||||
|
|
||||||
disabled_out_of_support: 現在のバージョンとの互換性がありません。プラグインを無効にしました。
|
disabled_out_of_support: "現在のバージョンとの互換性がありません。プラグインを無効にしました。"
|
||||||
disabled_due_to_an_error: プラグイン実行中にエラーを検知しました。プラグイン開発者に報告してください。
|
disabled_due_to_an_error: "プラグイン実行中にエラーを検知しました。プラグイン開発者に報告してください。"
|
||||||
|
|
||||||
is_enabled: プラグインを有効にしました。
|
is_enabled: "プラグインを有効にしました。"
|
||||||
is_disabled: プラグインを無効にしました。
|
is_disabled: "プラグインを無効にしました。"
|
||||||
193
locales/ko.yml
193
locales/ko.yml
@@ -9,11 +9,11 @@ common:
|
|||||||
common_error:
|
common_error:
|
||||||
no_device_mic: "마이크 디바이스를 찾지 못했습니다."
|
no_device_mic: "마이크 디바이스를 찾지 못했습니다."
|
||||||
no_device_speaker: "스피커 디바이스를 찾지 못했습니다."
|
no_device_speaker: "스피커 디바이스를 찾지 못했습니다."
|
||||||
threshold_invalid_value:
|
threshold_invalid_value: "{{min}}부터 {{max}}까지의 숫자로 설정할 수 있습니다."
|
||||||
failed_download_weight_ctranslate2:
|
failed_download_weight_ctranslate2: "CTranslate2 모델 다운로드에 실패했습니다."
|
||||||
failed_download_weight_whisper:
|
failed_download_weight_whisper: "Whisper 모델 다운로드에 실패했습니다."
|
||||||
translation_limit:
|
translation_limit: "번역 엔진 사용 제한에 도달했거나 일시적으로 이용 제한이 걸렸습니다."
|
||||||
deepl_auth_key_invalid_length:
|
deepl_auth_key_invalid_length: "DeepL 인증 키의 문자 수가 잘못되었습니다."
|
||||||
deepl_auth_key_failed_authentication: "인증키가 잘못되었거나 API 사용 제한이 상한에 도달했습니다."
|
deepl_auth_key_failed_authentication: "인증키가 잘못되었거나 API 사용 제한이 상한에 도달했습니다."
|
||||||
|
|
||||||
invalid_value_mic_record_timeout: "0 이상에서 '{{mic_phrase_timeout_label}}'보다 클 수 없습니다."
|
invalid_value_mic_record_timeout: "0 이상에서 '{{mic_phrase_timeout_label}}'보다 클 수 없습니다."
|
||||||
@@ -24,6 +24,9 @@ common_error:
|
|||||||
invalid_value_speaker_phrase_timeout: "0 이상에서 '{{speaker_record_timeout_label}}'보다 작을 수 없습니다."
|
invalid_value_speaker_phrase_timeout: "0 이상에서 '{{speaker_record_timeout_label}}'보다 작을 수 없습니다."
|
||||||
invalid_value_speaker_max_phrase: "0 이상의 숫자만 설정할 수 있습니다."
|
invalid_value_speaker_max_phrase: "0 이상의 숫자만 설정할 수 있습니다."
|
||||||
|
|
||||||
|
common_warning:
|
||||||
|
unable_to_use_osc_query: "OSC IP 주소 설정으로 인해 OSC 데이터 수신이 불가능하므로, 아래 기능이 자동으로 비활성화되었습니다."
|
||||||
|
|
||||||
main_page:
|
main_page:
|
||||||
translation: "번역"
|
translation: "번역"
|
||||||
transcription_send: "음성인식 (마이크)"
|
transcription_send: "음성인식 (마이크)"
|
||||||
@@ -39,7 +42,7 @@ main_page:
|
|||||||
translator_label_default: "기본값"
|
translator_label_default: "기본값"
|
||||||
|
|
||||||
translator_selector:
|
translator_selector:
|
||||||
is_selected_same_language:
|
is_selected_same_language: "'{{your_language}}'와 '{{target_language}}'에 동일한 언어가 선택되어 있으므로, 「{{ctranslate2}}」만 사용할 수 있습니다."
|
||||||
|
|
||||||
message_log:
|
message_log:
|
||||||
all: "전체"
|
all: "전체"
|
||||||
@@ -47,7 +50,7 @@ main_page:
|
|||||||
received: "수신"
|
received: "수신"
|
||||||
system: "시스템"
|
system: "시스템"
|
||||||
|
|
||||||
resend_button_on_hover_desc:
|
resend_button_on_hover_desc: "길게 눌러서 보내기"
|
||||||
|
|
||||||
state_text_enabled: "Enabled"
|
state_text_enabled: "Enabled"
|
||||||
state_text_disabled: "Disabled"
|
state_text_disabled: "Disabled"
|
||||||
@@ -60,32 +63,33 @@ main_page:
|
|||||||
updating: "업데이트 중..."
|
updating: "업데이트 중..."
|
||||||
|
|
||||||
update_modal:
|
update_modal:
|
||||||
cpu_desc:
|
cpu_desc: "처리 장치로 CPU만을 사용합니다."
|
||||||
cuda_desc:
|
cuda_desc: "처리 장치로 CPU와 NVIDIA GPU를 선택할 수 있습니다."
|
||||||
cuda_compare_cpu_desc:
|
cuda_compare_cpu_desc: "GPU 선택 시, CPU에 비해 처리가 빠릅니다."
|
||||||
cuda_disk_space_desc:
|
cuda_disk_space_desc: "약 {{size}}의 디스크 용량이 필요합니다."
|
||||||
close_modal:
|
close_modal: "닫기"
|
||||||
download_latest_and_restart:
|
download_latest_and_restart: "최신 버전이 다운로드되면 앱이 자동으로 재시작됩니다."
|
||||||
is_latest_version_already:
|
is_latest_version_already: "이미 최신 버전을 사용 중입니다."
|
||||||
is_current_compute_device:
|
is_current_compute_device: "현재 사용 중인 버전"
|
||||||
|
|
||||||
config_page:
|
config_page:
|
||||||
version: "버전 {{version}}"
|
version: "버전 {{version}}"
|
||||||
model_download_button_label:
|
model_download_button_label: "다운로드"
|
||||||
side_menu_labels:
|
side_menu_labels:
|
||||||
device:
|
device: "장치"
|
||||||
appearance: "모양"
|
appearance: "모양"
|
||||||
translation: "번역"
|
translation: "번역"
|
||||||
transcription: "음성인식"
|
transcription: "음성인식"
|
||||||
others: "기타"
|
others: "기타"
|
||||||
hotkeys:
|
hotkeys: "단축키"
|
||||||
|
plugins: "플러그인"
|
||||||
advanced_settings: "고급 설정"
|
advanced_settings: "고급 설정"
|
||||||
|
|
||||||
device:
|
device:
|
||||||
check_volume:
|
check_volume: "음량 확인"
|
||||||
label_auto_select:
|
label_auto_select: "자동 선택"
|
||||||
label_host: "호스트/드라이버"
|
label_host: "호스트/드라이버"
|
||||||
label_device:
|
label_device: "장치"
|
||||||
mic_host_device:
|
mic_host_device:
|
||||||
label: "마이크 장치"
|
label: "마이크 장치"
|
||||||
mic_dynamic_energy_threshold:
|
mic_dynamic_energy_threshold:
|
||||||
@@ -115,6 +119,9 @@ config_page:
|
|||||||
hide: "숨김 (Enter 키를 사용하여 전송)"
|
hide: "숨김 (Enter 키를 사용하여 전송)"
|
||||||
show: "표시"
|
show: "표시"
|
||||||
show_and_disable_enter_key: "표시 (Enter 키 전송 비활성화)"
|
show_and_disable_enter_key: "표시 (Enter 키 전송 비활성화)"
|
||||||
|
show_resend_button:
|
||||||
|
label: "재전송 버튼 표시"
|
||||||
|
desc: "보낸 메시지 로그에 마우스를 올리면 재전송 버튼이 표시됩니다. 클릭하면 편집 모드로 전환되며, 길게 누르면 재전송됩니다."
|
||||||
font_family:
|
font_family:
|
||||||
label: "폰트"
|
label: "폰트"
|
||||||
ui_language:
|
ui_language:
|
||||||
@@ -127,19 +134,19 @@ config_page:
|
|||||||
small: "일반 모델 ({{capacity}})"
|
small: "일반 모델 ({{capacity}})"
|
||||||
large: "정밀 모델 ({{capacity}})"
|
large: "정밀 모델 ({{capacity}})"
|
||||||
ctranslate2_compute_device:
|
ctranslate2_compute_device:
|
||||||
label:
|
label: "AI 번역 {{ctranslate2}} 처리 장치"
|
||||||
deepl_auth_key:
|
deepl_auth_key:
|
||||||
label: "DeepL 인증키"
|
label: "DeepL 인증키"
|
||||||
desc: "사용시 메인화면에 있는 {{translator}}를 DeepL_API로 변경해 주세요.\n지원하지 않는 언어도 있습니다."
|
desc: "사용시 메인화면에 있는 {{translator}}를 DeepL_API로 변경해 주세요.\n지원하지 않는 언어도 있습니다."
|
||||||
open_auth_key_webpage: "DeepL 계정 페이지 열기"
|
open_auth_key_webpage: "DeepL 계정 페이지 열기"
|
||||||
save:
|
save: "저장"
|
||||||
edit:
|
edit: "편집"
|
||||||
auth_key_success: "인증키 갱신이 완료되었습니다."
|
auth_key_success: "인증키 갱신이 완료되었습니다."
|
||||||
|
|
||||||
transcription:
|
transcription:
|
||||||
section_label_mic: "마이크"
|
section_label_mic: "마이크"
|
||||||
section_label_speaker: "스피커"
|
section_label_speaker: "스피커"
|
||||||
section_label_transcription_engines:
|
section_label_transcription_engines: "음성 인식 엔진"
|
||||||
mic_record_timeout:
|
mic_record_timeout:
|
||||||
label: "최대 무음 시간"
|
label: "최대 무음 시간"
|
||||||
desc: "무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다."
|
desc: "무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다."
|
||||||
@@ -164,46 +171,47 @@ config_page:
|
|||||||
label: "최대 입력 절(phrases) 수"
|
label: "최대 입력 절(phrases) 수"
|
||||||
desc: "식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 로그에 표시합니다."
|
desc: "식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 로그에 표시합니다."
|
||||||
select_transcription_engine:
|
select_transcription_engine:
|
||||||
label:
|
label: "음성 인식에 사용할 엔진"
|
||||||
whisper_weight_type:
|
whisper_weight_type:
|
||||||
label: "Whisper 모델 타입"
|
label: "Whisper 모델 타입"
|
||||||
desc:
|
desc: "용량이 큰 모델일수록 정확도는 높지만, 그만큼 CPU나 GPU를 많이 차지합니다. * 특히 medium보다 용량이 큰 모델은 CPU/GPU 성능에 따라 사용 자체가 어려울 수 있습니다."
|
||||||
model_template: "{{model_name}} 모델 ({{capacity}})"
|
model_template: "{{model_name}} 모델 ({{capacity}})"
|
||||||
recommended_model_template: "{{model_name}} 모델 ({{capacity}}) (권장)"
|
recommended_model_template: "{{model_name}} 모델 ({{capacity}}) (권장)"
|
||||||
whisper_compute_device:
|
whisper_compute_device:
|
||||||
label:
|
label: "Whisper에서 사용할 처리 장치"
|
||||||
|
|
||||||
vr:
|
vr:
|
||||||
single_line:
|
single_line: "한 줄"
|
||||||
multi_lines:
|
multi_lines: "여러 줄"
|
||||||
overlay_enable:
|
overlay_enable: "활성화"
|
||||||
restore_default_settings:
|
restore_default_settings: "초기값으로 되돌리기"
|
||||||
position:
|
position: "위치"
|
||||||
rotation:
|
rotation: "회전"
|
||||||
x_position:
|
x_position: "X축 (좌우)"
|
||||||
y_position:
|
y_position: "Y축 (상하)"
|
||||||
z_position:
|
z_position: "Z축 (앞뒤)"
|
||||||
x_rotation:
|
x_rotation: "X축 회전"
|
||||||
y_rotation:
|
y_rotation: "Y축 회전"
|
||||||
z_rotation:
|
z_rotation: "Z축 회전"
|
||||||
sample_text_button:
|
sample_text_button:
|
||||||
start:
|
start: "샘플 텍스트를\n오버레이에 전송"
|
||||||
stop:
|
stop: "전송 중지"
|
||||||
sample_text:
|
sample_text: "샘플 텍스트"
|
||||||
opacity:
|
opacity: "투명도"
|
||||||
ui_scaling:
|
ui_scaling: "UI 크기 조정"
|
||||||
display_duration:
|
display_duration: "표시 시간"
|
||||||
fadeout_duration:
|
fadeout_duration: "페이드 아웃 시간"
|
||||||
common_settings:
|
common_settings: "공통 설정"
|
||||||
tracker:
|
tracker: "표시할 트래커의 위치"
|
||||||
hmd:
|
hmd: "HMD"
|
||||||
left_hand:
|
left_hand: "왼손"
|
||||||
right_hand:
|
right_hand: "오른손"
|
||||||
overlay_show_only_translated_messages:
|
overlay_show_only_translated_messages:
|
||||||
label:
|
label: "번역된 메시지만 표시"
|
||||||
|
|
||||||
others:
|
others:
|
||||||
section_label_sounds:
|
section_label_sounds: "사운드"
|
||||||
|
section_label_message_formats: "메시지 형식"
|
||||||
auto_clear_the_message_box:
|
auto_clear_the_message_box:
|
||||||
label: "챗박스 자동 삭제"
|
label: "챗박스 자동 삭제"
|
||||||
send_only_translated_messages:
|
send_only_translated_messages:
|
||||||
@@ -212,27 +220,58 @@ config_page:
|
|||||||
label: "대화 로그 자동 저장"
|
label: "대화 로그 자동 저장"
|
||||||
desc: "logs 폴더에 텍스트 파일로 로그가 저장됩니다."
|
desc: "logs 폴더에 텍스트 파일로 로그가 저장됩니다."
|
||||||
vrc_mic_mute_sync:
|
vrc_mic_mute_sync:
|
||||||
label:
|
label: "VRC 마이크 음소거 동기화"
|
||||||
desc:
|
desc: "VRChat의 마이크가 음소거 상태인 동안에는 메시지를 VRChat에 전송하지 않습니다. * 약간의 지연이 발생할 수 있습니다. 또한 눌러서 말하기(Push-To-Talk) 기능은 지원되지 않습니다."
|
||||||
send_message_to_vrc:
|
send_message_to_vrc:
|
||||||
label: "VRChat에 메시지 전송"
|
label: "VRChat에 메시지 전송"
|
||||||
desc: "VRChat에 메시지를 보내지 않고 사용할 수 있는 방법이 있지만 지원되지 않습니다. VRChat에 메시지를 보내려면 이 기능을 활성화하세요."
|
desc: "VRChat에 메시지를 보내지 않고 사용할 수 있는 방법이 있지만 지원되지 않습니다. VRChat에 메시지를 보내려면 이 기능을 활성화하세요."
|
||||||
notification_vrc_sfx:
|
notification_vrc_sfx:
|
||||||
label:
|
label: "채팅 전송 시 채팅창 알림음 재생"
|
||||||
desc:
|
desc: "이 기능을 비활성화하면 다른 사람이 들을 수 있는 채팅창 알림음을 울리지 않고 조용히 전송합니다."
|
||||||
send_received_message_to_vrc:
|
send_received_message_to_vrc:
|
||||||
label:
|
label: "수신한 메시지를 VRChat에 전송"
|
||||||
desc:
|
desc: "스피커에서 인식된 내용을 텍스트로 변환한 메시지가 VRChat에 전송됩니다."
|
||||||
|
message_format_common:
|
||||||
|
example_view:
|
||||||
|
title: "미리 보기"
|
||||||
|
original_translated: "원문 + 번역문"
|
||||||
|
original_translated_multi: "원문 + 번역문 (다국어)"
|
||||||
|
translated_only_multi: "번역문만 (다국어)"
|
||||||
|
translated_only: "번역문만"
|
||||||
|
original_only: "원문만"
|
||||||
|
settings:
|
||||||
|
title: "설정"
|
||||||
|
original: "원문"
|
||||||
|
translated: "번역문"
|
||||||
|
for_multi_translation: "다국어 번역용"
|
||||||
|
send_message_format:
|
||||||
|
label: "메시지 형식 (송신)"
|
||||||
|
desc: "VRChat에서 상대방에게 실제로 보이는 형식을 변경할 수 있습니다."
|
||||||
|
received_message_format:
|
||||||
|
label: "메시지 형식 (Speaker2Chatbox)"
|
||||||
|
desc: "현재로서는 Speaker2Chatbox로 전송할 때의 표시용으로 사용됩니다."
|
||||||
|
|
||||||
hotkeys:
|
hotkeys:
|
||||||
toggle_vrct_visibility:
|
toggle_vrct_visibility:
|
||||||
label:
|
label: "VRCT 최소화/활성화 전환"
|
||||||
toggle_translation:
|
toggle_translation:
|
||||||
label:
|
label: "'{{translation}}' 켜기/끄기 전환"
|
||||||
toggle_transcription_send:
|
toggle_transcription_send:
|
||||||
label:
|
label: "'{{transcription_send}}' 켜기/끄기 전환"
|
||||||
toggle_transcription_receive:
|
toggle_transcription_receive:
|
||||||
label:
|
label: "'{{transcription_receive}}' 켜기/끄기 전환"
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
downloaded_version: "다운로드된 버전: {{downloaded_version}}"
|
||||||
|
latest_version: "최신 버전: {{latest_version}}"
|
||||||
|
available_after_updating: "최신 버전으로 업데이트 후 이용 가능"
|
||||||
|
unavailable_downloaded: "현재 사용 중인 VRCT 버전과의 호환성 문제로 인해 이용 불가"
|
||||||
|
no_latest_info: "최신 정보를 가져올 수 없습니다"
|
||||||
|
using_latest_version: "최신 버전을 사용 중"
|
||||||
|
available_latest_version: "최신 버전을 이용 가능"
|
||||||
|
unavailable_latest_version: "최신 버전은 현재 이용 불가"
|
||||||
|
available_in_latest_vrct_version: "VRCT 최신 버전에서 이용 가능"
|
||||||
|
unavailable_not_downloaded: "현재 이용 불가"
|
||||||
|
|
||||||
advanced_settings:
|
advanced_settings:
|
||||||
osc_ip_address:
|
osc_ip_address:
|
||||||
@@ -242,4 +281,28 @@ config_page:
|
|||||||
open_config_filepath:
|
open_config_filepath:
|
||||||
label: "설정 파일 열기"
|
label: "설정 파일 열기"
|
||||||
switch_compute_device:
|
switch_compute_device:
|
||||||
label:
|
label: "VRCT CPU/GPU 버전 전환"
|
||||||
|
enable_websocket:
|
||||||
|
label: "WebSocket 서버 활성화"
|
||||||
|
websocket_host:
|
||||||
|
label: "WebSocket 호스트"
|
||||||
|
websocket_port:
|
||||||
|
label: "WebSocket 포트"
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
save_success: "설정을 저장했습니다."
|
||||||
|
|
||||||
|
plugin_notifications:
|
||||||
|
downloading: "플러그인을 다운로드 중입니다."
|
||||||
|
downloaded_success: "플러그인 다운로드가 완료되었습니다."
|
||||||
|
downloaded_error: "플러그인 다운로드에 실패했습니다."
|
||||||
|
|
||||||
|
updating: "플러그인을 업데이트 중입니다."
|
||||||
|
updated_success: "플러그인 업데이트가 완료되었습니다."
|
||||||
|
updated_error: "플러그인 업데이트에 실패했습니다."
|
||||||
|
|
||||||
|
disabled_out_of_support: "현재 버전과 호환되지 않습니다. 플러그인을 비활성화했습니다."
|
||||||
|
disabled_due_to_an_error: "플러그인 실행 중 오류를 감지했습니다. 플러그인 개발자에게 보고해 주세요."
|
||||||
|
|
||||||
|
is_enabled: "플러그인을 활성화했습니다."
|
||||||
|
is_disabled: "플러그인을 비활성화했습니다."
|
||||||
@@ -1 +1,13 @@
|
|||||||
Thank you for considering translating VRCT's UI. However, please refrain from making any changes at this time. I am currently organizing the files, including reordering, adding, and removing elements, and some parts may change frequently until the UI becomes stable. (Note: This message was updated in February 2025.)
|
Thank you for considering contributing to VRCT's UI translations.
|
||||||
|
If you want to edit a language:
|
||||||
|
- If it already exists: edit the corresponding [xx].yml file.
|
||||||
|
- If it doesn’t exist: please open a GitHub issue or contact us through another channel. (If you know how to add a new language yourself, feel free to do so! Sorry for the complicated structure...)
|
||||||
|
|
||||||
|
Languages currently supported:
|
||||||
|
- en: English
|
||||||
|
- ja: 日本語
|
||||||
|
- ko: 한국어
|
||||||
|
- zh-Hant: 繁體中文
|
||||||
|
- zh-Hans: 简体中文
|
||||||
|
|
||||||
|
Last updated: 2025/09
|
||||||
@@ -24,6 +24,9 @@ common_error:
|
|||||||
invalid_value_speaker_phrase_timeout: "转录间隔时间大于0秒且不能小于「{{speaker_record_timeout_label}}」"
|
invalid_value_speaker_phrase_timeout: "转录间隔时间大于0秒且不能小于「{{speaker_record_timeout_label}}」"
|
||||||
invalid_value_speaker_max_phrase: "数值应为 0 以上"
|
invalid_value_speaker_max_phrase: "数值应为 0 以上"
|
||||||
|
|
||||||
|
common_warning:
|
||||||
|
unable_to_use_osc_query:
|
||||||
|
|
||||||
main_page:
|
main_page:
|
||||||
translation: "翻译"
|
translation: "翻译"
|
||||||
transcription_send: "你的语音转文字"
|
transcription_send: "你的语音转文字"
|
||||||
@@ -79,6 +82,7 @@ config_page:
|
|||||||
transcription: "转录"
|
transcription: "转录"
|
||||||
others: "其他"
|
others: "其他"
|
||||||
hotkeys:
|
hotkeys:
|
||||||
|
plugins:
|
||||||
advanced_settings: "高级设置"
|
advanced_settings: "高级设置"
|
||||||
|
|
||||||
device:
|
device:
|
||||||
@@ -115,6 +119,9 @@ config_page:
|
|||||||
hide: "隐藏 (可使用回车发送信息)"
|
hide: "隐藏 (可使用回车发送信息)"
|
||||||
show: "显示"
|
show: "显示"
|
||||||
show_and_disable_enter_key: "显示,并且停用‘回车发送信息’"
|
show_and_disable_enter_key: "显示,并且停用‘回车发送信息’"
|
||||||
|
show_resend_button:
|
||||||
|
label:
|
||||||
|
desc:
|
||||||
font_family:
|
font_family:
|
||||||
label: "字体"
|
label: "字体"
|
||||||
ui_language:
|
ui_language:
|
||||||
@@ -204,6 +211,7 @@ config_page:
|
|||||||
|
|
||||||
others:
|
others:
|
||||||
section_label_sounds:
|
section_label_sounds:
|
||||||
|
section_label_message_formats:
|
||||||
auto_clear_the_message_box:
|
auto_clear_the_message_box:
|
||||||
label: "发言后自动清空chatbox"
|
label: "发言后自动清空chatbox"
|
||||||
send_only_translated_messages:
|
send_only_translated_messages:
|
||||||
@@ -223,6 +231,25 @@ config_page:
|
|||||||
send_received_message_to_vrc:
|
send_received_message_to_vrc:
|
||||||
label:
|
label:
|
||||||
desc:
|
desc:
|
||||||
|
message_format_common:
|
||||||
|
example_view:
|
||||||
|
title:
|
||||||
|
original_translated:
|
||||||
|
original_translated_multi:
|
||||||
|
translated_only_multi:
|
||||||
|
translated_only:
|
||||||
|
original_only:
|
||||||
|
settings:
|
||||||
|
title:
|
||||||
|
original:
|
||||||
|
translated:
|
||||||
|
for_multi_translation:
|
||||||
|
send_message_format:
|
||||||
|
label:
|
||||||
|
desc:
|
||||||
|
received_message_format:
|
||||||
|
label:
|
||||||
|
desc:
|
||||||
|
|
||||||
hotkeys:
|
hotkeys:
|
||||||
toggle_vrct_visibility:
|
toggle_vrct_visibility:
|
||||||
@@ -234,6 +261,18 @@ config_page:
|
|||||||
toggle_transcription_receive:
|
toggle_transcription_receive:
|
||||||
label:
|
label:
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
downloaded_version:
|
||||||
|
latest_version:
|
||||||
|
available_after_updating:
|
||||||
|
unavailable_downloaded:
|
||||||
|
no_latest_info:
|
||||||
|
using_latest_version:
|
||||||
|
available_latest_version:
|
||||||
|
unavailable_latest_version:
|
||||||
|
available_in_latest_vrct_version:
|
||||||
|
unavailable_not_downloaded:
|
||||||
|
|
||||||
advanced_settings:
|
advanced_settings:
|
||||||
osc_ip_address:
|
osc_ip_address:
|
||||||
label: "OSC IP 地址"
|
label: "OSC IP 地址"
|
||||||
@@ -243,3 +282,27 @@ config_page:
|
|||||||
label: "打开设置文件"
|
label: "打开设置文件"
|
||||||
switch_compute_device:
|
switch_compute_device:
|
||||||
label:
|
label:
|
||||||
|
enable_websocket:
|
||||||
|
label:
|
||||||
|
websocket_host:
|
||||||
|
label:
|
||||||
|
websocket_port:
|
||||||
|
label:
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
save_success:
|
||||||
|
|
||||||
|
plugin_notifications:
|
||||||
|
downloading:
|
||||||
|
downloaded_success:
|
||||||
|
downloaded_error:
|
||||||
|
|
||||||
|
updating:
|
||||||
|
updated_success:
|
||||||
|
updated_error:
|
||||||
|
|
||||||
|
disabled_out_of_support:
|
||||||
|
disabled_due_to_an_error:
|
||||||
|
|
||||||
|
is_enabled:
|
||||||
|
is_disabled:
|
||||||
@@ -24,6 +24,9 @@ common_error:
|
|||||||
invalid_value_speaker_phrase_timeout: "不能小於「{{speaker_record_timeout_label}}」,應為 0 或更高。"
|
invalid_value_speaker_phrase_timeout: "不能小於「{{speaker_record_timeout_label}}」,應為 0 或更高。"
|
||||||
invalid_value_speaker_max_phrase: "可以設置 0 或更高的數值。"
|
invalid_value_speaker_max_phrase: "可以設置 0 或更高的數值。"
|
||||||
|
|
||||||
|
common_warning:
|
||||||
|
unable_to_use_osc_query:
|
||||||
|
|
||||||
main_page:
|
main_page:
|
||||||
translation: "翻譯"
|
translation: "翻譯"
|
||||||
transcription_send: "麥克風轉文字"
|
transcription_send: "麥克風轉文字"
|
||||||
@@ -79,6 +82,7 @@ config_page:
|
|||||||
transcription: "轉錄"
|
transcription: "轉錄"
|
||||||
others: "其他"
|
others: "其他"
|
||||||
hotkeys:
|
hotkeys:
|
||||||
|
plugins:
|
||||||
advanced_settings: "進階設定"
|
advanced_settings: "進階設定"
|
||||||
|
|
||||||
device:
|
device:
|
||||||
@@ -115,6 +119,9 @@ config_page:
|
|||||||
hide: "隱藏(使用 Enter 鍵發送)"
|
hide: "隱藏(使用 Enter 鍵發送)"
|
||||||
show: "顯示"
|
show: "顯示"
|
||||||
show_and_disable_enter_key: "顯示並停用 Enter 鍵發送"
|
show_and_disable_enter_key: "顯示並停用 Enter 鍵發送"
|
||||||
|
show_resend_button:
|
||||||
|
label:
|
||||||
|
desc:
|
||||||
font_family:
|
font_family:
|
||||||
label: "字型"
|
label: "字型"
|
||||||
ui_language:
|
ui_language:
|
||||||
@@ -204,6 +211,7 @@ config_page:
|
|||||||
|
|
||||||
others:
|
others:
|
||||||
section_label_sounds:
|
section_label_sounds:
|
||||||
|
section_label_message_formats:
|
||||||
auto_clear_the_message_box:
|
auto_clear_the_message_box:
|
||||||
label: "自動清除 Chatbox"
|
label: "自動清除 Chatbox"
|
||||||
send_only_translated_messages:
|
send_only_translated_messages:
|
||||||
@@ -223,6 +231,25 @@ config_page:
|
|||||||
send_received_message_to_vrc:
|
send_received_message_to_vrc:
|
||||||
label:
|
label:
|
||||||
desc:
|
desc:
|
||||||
|
message_format_common:
|
||||||
|
example_view:
|
||||||
|
title:
|
||||||
|
original_translated:
|
||||||
|
original_translated_multi:
|
||||||
|
translated_only_multi:
|
||||||
|
translated_only:
|
||||||
|
original_only:
|
||||||
|
settings:
|
||||||
|
title:
|
||||||
|
original:
|
||||||
|
translated:
|
||||||
|
for_multi_translation:
|
||||||
|
send_message_format:
|
||||||
|
label:
|
||||||
|
desc:
|
||||||
|
received_message_format:
|
||||||
|
label:
|
||||||
|
desc:
|
||||||
|
|
||||||
hotkeys:
|
hotkeys:
|
||||||
toggle_vrct_visibility:
|
toggle_vrct_visibility:
|
||||||
@@ -234,6 +261,18 @@ config_page:
|
|||||||
toggle_transcription_receive:
|
toggle_transcription_receive:
|
||||||
label:
|
label:
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
downloaded_version:
|
||||||
|
latest_version:
|
||||||
|
available_after_updating:
|
||||||
|
unavailable_downloaded:
|
||||||
|
no_latest_info:
|
||||||
|
using_latest_version:
|
||||||
|
available_latest_version:
|
||||||
|
unavailable_latest_version:
|
||||||
|
available_in_latest_vrct_version:
|
||||||
|
unavailable_not_downloaded:
|
||||||
|
|
||||||
advanced_settings:
|
advanced_settings:
|
||||||
osc_ip_address:
|
osc_ip_address:
|
||||||
label: "OSC IP 位址"
|
label: "OSC IP 位址"
|
||||||
@@ -243,3 +282,27 @@ config_page:
|
|||||||
label: "打開設定文件"
|
label: "打開設定文件"
|
||||||
switch_compute_device:
|
switch_compute_device:
|
||||||
label:
|
label:
|
||||||
|
enable_websocket:
|
||||||
|
label:
|
||||||
|
websocket_host:
|
||||||
|
label:
|
||||||
|
websocket_port:
|
||||||
|
label:
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
save_success:
|
||||||
|
|
||||||
|
plugin_notifications:
|
||||||
|
downloading:
|
||||||
|
downloaded_success:
|
||||||
|
downloaded_error:
|
||||||
|
|
||||||
|
updating:
|
||||||
|
updated_success:
|
||||||
|
updated_error:
|
||||||
|
|
||||||
|
disabled_out_of_support:
|
||||||
|
disabled_due_to_an_error:
|
||||||
|
|
||||||
|
is_enabled:
|
||||||
|
is_disabled:
|
||||||
@@ -11,7 +11,7 @@ from models.translation.translation_languages import translation_lang
|
|||||||
from models.translation.translation_utils import ctranslate2_weights
|
from models.translation.translation_utils import ctranslate2_weights
|
||||||
from models.transcription.transcription_languages import transcription_lang
|
from models.transcription.transcription_languages import transcription_lang
|
||||||
from models.transcription.transcription_whisper import _MODELS as whisper_models
|
from models.transcription.transcription_whisper import _MODELS as whisper_models
|
||||||
from utils import errorLogging
|
from utils import errorLogging, validateDictStructure
|
||||||
|
|
||||||
json_serializable_vars = {}
|
json_serializable_vars = {}
|
||||||
def json_serializable(var_name):
|
def json_serializable(var_name):
|
||||||
@@ -139,23 +139,44 @@ class Config:
|
|||||||
def SEND_MESSAGE_BUTTON_TYPE_LIST(self):
|
def SEND_MESSAGE_BUTTON_TYPE_LIST(self):
|
||||||
return self._SEND_MESSAGE_BUTTON_TYPE_LIST
|
return self._SEND_MESSAGE_BUTTON_TYPE_LIST
|
||||||
|
|
||||||
@property
|
|
||||||
def SEND_MESSAGE_FORMAT(self):
|
|
||||||
return self._SEND_MESSAGE_FORMAT
|
|
||||||
|
|
||||||
@property
|
|
||||||
def SEND_MESSAGE_FORMAT_WITH_T(self):
|
|
||||||
return self._SEND_MESSAGE_FORMAT_WITH_T
|
|
||||||
|
|
||||||
@property
|
|
||||||
def RECEIVED_MESSAGE_FORMAT(self):
|
|
||||||
return self._RECEIVED_MESSAGE_FORMAT
|
|
||||||
|
|
||||||
@property
|
|
||||||
def RECEIVED_MESSAGE_FORMAT_WITH_T(self):
|
|
||||||
return self._RECEIVED_MESSAGE_FORMAT_WITH_T
|
|
||||||
|
|
||||||
# Read Write
|
# Read Write
|
||||||
|
@property
|
||||||
|
@json_serializable('SEND_MESSAGE_FORMAT_PARTS')
|
||||||
|
def SEND_MESSAGE_FORMAT_PARTS(self):
|
||||||
|
return self._SEND_MESSAGE_FORMAT_PARTS
|
||||||
|
|
||||||
|
@SEND_MESSAGE_FORMAT_PARTS.setter
|
||||||
|
def SEND_MESSAGE_FORMAT_PARTS(self, value):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
valid_parts = {
|
||||||
|
"message": {"prefix": str, "suffix": str},
|
||||||
|
"separator": str,
|
||||||
|
"translation": {"prefix": str, "separator": str, "suffix": str},
|
||||||
|
"translation_first": bool
|
||||||
|
}
|
||||||
|
|
||||||
|
if validateDictStructure(value, valid_parts):
|
||||||
|
self._SEND_MESSAGE_FORMAT_PARTS = value
|
||||||
|
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@json_serializable('RECEIVED_MESSAGE_FORMAT_PARTS')
|
||||||
|
def RECEIVED_MESSAGE_FORMAT_PARTS(self):
|
||||||
|
return self._RECEIVED_MESSAGE_FORMAT_PARTS
|
||||||
|
|
||||||
|
@RECEIVED_MESSAGE_FORMAT_PARTS.setter
|
||||||
|
def RECEIVED_MESSAGE_FORMAT_PARTS(self, value):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
valid_parts = {
|
||||||
|
"message": {"prefix": str, "suffix": str},
|
||||||
|
"separator": str,
|
||||||
|
"translation": {"prefix": str, "separator": str, "suffix": str},
|
||||||
|
"translation_first": bool
|
||||||
|
}
|
||||||
|
if validateDictStructure(value, valid_parts):
|
||||||
|
self._RECEIVED_MESSAGE_FORMAT_PARTS = value
|
||||||
|
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ENABLE_TRANSLATION(self):
|
def ENABLE_TRANSLATION(self):
|
||||||
return self._ENABLE_TRANSLATION
|
return self._ENABLE_TRANSLATION
|
||||||
@@ -997,10 +1018,9 @@ class Config:
|
|||||||
self._WEBSOCKET_PORT = value
|
self._WEBSOCKET_PORT = value
|
||||||
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
||||||
|
|
||||||
|
|
||||||
def init_config(self):
|
def init_config(self):
|
||||||
# Read Only
|
# Read Only
|
||||||
self._VERSION = "3.2.1"
|
self._VERSION = "3.2.2"
|
||||||
if getattr(sys, 'frozen', False):
|
if getattr(sys, 'frozen', False):
|
||||||
self._PATH_LOCAL = os_path.dirname(sys.executable)
|
self._PATH_LOCAL = os_path.dirname(sys.executable)
|
||||||
else:
|
else:
|
||||||
@@ -1032,10 +1052,32 @@ class Config:
|
|||||||
self._SELECTABLE_COMPUTE_DEVICE_LIST.append({"device":"cuda", "device_index": i, "device_name": torch.cuda.get_device_name(i)})
|
self._SELECTABLE_COMPUTE_DEVICE_LIST.append({"device":"cuda", "device_index": i, "device_name": torch.cuda.get_device_name(i)})
|
||||||
self._SELECTABLE_COMPUTE_DEVICE_LIST.append({"device":"cpu", "device_index": 0, "device_name": "cpu"})
|
self._SELECTABLE_COMPUTE_DEVICE_LIST.append({"device":"cpu", "device_index": 0, "device_name": "cpu"})
|
||||||
self._SEND_MESSAGE_BUTTON_TYPE_LIST = ["show", "hide", "show_and_disable_enter_key"]
|
self._SEND_MESSAGE_BUTTON_TYPE_LIST = ["show", "hide", "show_and_disable_enter_key"]
|
||||||
self._SEND_MESSAGE_FORMAT = "[message]"
|
self._SEND_MESSAGE_FORMAT_PARTS = {
|
||||||
self._SEND_MESSAGE_FORMAT_WITH_T = "[message]\n[translation]"
|
"message": {
|
||||||
self._RECEIVED_MESSAGE_FORMAT = "[message]"
|
"prefix": "",
|
||||||
self._RECEIVED_MESSAGE_FORMAT_WITH_T = "[message]\n[translation]"
|
"suffix": ""
|
||||||
|
},
|
||||||
|
"separator": "\n",
|
||||||
|
"translation": {
|
||||||
|
"prefix": "",
|
||||||
|
"separator": "\n",
|
||||||
|
"suffix": ""
|
||||||
|
},
|
||||||
|
"translation_first": False,
|
||||||
|
}
|
||||||
|
self._RECEIVED_MESSAGE_FORMAT_PARTS = {
|
||||||
|
"message": {
|
||||||
|
"prefix": "",
|
||||||
|
"suffix": ""
|
||||||
|
},
|
||||||
|
"separator": "\n",
|
||||||
|
"translation": {
|
||||||
|
"prefix": "",
|
||||||
|
"separator": "\n",
|
||||||
|
"suffix": ""
|
||||||
|
},
|
||||||
|
"translation_first": False,
|
||||||
|
}
|
||||||
|
|
||||||
# Read Write
|
# Read Write
|
||||||
self._ENABLE_TRANSLATION = False
|
self._ENABLE_TRANSLATION = False
|
||||||
|
|||||||
@@ -306,11 +306,11 @@ class Controller:
|
|||||||
if config.SEND_MESSAGE_TO_VRC is True:
|
if config.SEND_MESSAGE_TO_VRC is True:
|
||||||
if config.SEND_ONLY_TRANSLATED_MESSAGES is True:
|
if config.SEND_ONLY_TRANSLATED_MESSAGES is True:
|
||||||
if config.ENABLE_TRANSLATION is False:
|
if config.ENABLE_TRANSLATION is False:
|
||||||
osc_message = self.messageFormatter("SEND", "", [message])
|
osc_message = self.messageFormatter("SEND", [], message)
|
||||||
else:
|
else:
|
||||||
osc_message = self.messageFormatter("SEND", "", translation)
|
osc_message = self.messageFormatter("SEND", translation, "")
|
||||||
else:
|
else:
|
||||||
osc_message = self.messageFormatter("SEND", translation, [message])
|
osc_message = self.messageFormatter("SEND", translation, message)
|
||||||
model.oscSendMessage(osc_message)
|
model.oscSendMessage(osc_message)
|
||||||
|
|
||||||
self.run(
|
self.run(
|
||||||
@@ -470,7 +470,13 @@ class Controller:
|
|||||||
model.updateOverlayLargeLog(overlay_image)
|
model.updateOverlayLargeLog(overlay_image)
|
||||||
|
|
||||||
if config.SEND_RECEIVED_MESSAGE_TO_VRC is True:
|
if config.SEND_RECEIVED_MESSAGE_TO_VRC is True:
|
||||||
osc_message = self.messageFormatter("RECEIVED", translation, [message])
|
if config.SEND_ONLY_TRANSLATED_MESSAGES is True:
|
||||||
|
if config.ENABLE_TRANSLATION is False:
|
||||||
|
osc_message = self.messageFormatter("RECEIVED", [], message)
|
||||||
|
else:
|
||||||
|
osc_message = self.messageFormatter("RECEIVED", translation, "")
|
||||||
|
else:
|
||||||
|
osc_message = self.messageFormatter("RECEIVED", translation, message)
|
||||||
model.oscSendMessage(osc_message)
|
model.oscSendMessage(osc_message)
|
||||||
|
|
||||||
# update textbox message log (Received)
|
# update textbox message log (Received)
|
||||||
@@ -573,11 +579,11 @@ class Controller:
|
|||||||
if config.SEND_MESSAGE_TO_VRC is True:
|
if config.SEND_MESSAGE_TO_VRC is True:
|
||||||
if config.SEND_ONLY_TRANSLATED_MESSAGES is True:
|
if config.SEND_ONLY_TRANSLATED_MESSAGES is True:
|
||||||
if config.ENABLE_TRANSLATION is False:
|
if config.ENABLE_TRANSLATION is False:
|
||||||
osc_message = self.messageFormatter("SEND", "", [message])
|
osc_message = self.messageFormatter("SEND", [], message)
|
||||||
else:
|
else:
|
||||||
osc_message = self.messageFormatter("SEND", "", translation)
|
osc_message = self.messageFormatter("SEND", translation, "")
|
||||||
else:
|
else:
|
||||||
osc_message = self.messageFormatter("SEND", translation, [message])
|
osc_message = self.messageFormatter("SEND", translation, message)
|
||||||
model.oscSendMessage(osc_message)
|
model.oscSendMessage(osc_message)
|
||||||
|
|
||||||
if config.OVERLAY_LARGE_LOG is True:
|
if config.OVERLAY_LARGE_LOG is True:
|
||||||
@@ -1450,6 +1456,24 @@ class Controller:
|
|||||||
config.WHISPER_WEIGHT_TYPE = str(data)
|
config.WHISPER_WEIGHT_TYPE = str(data)
|
||||||
return {"status":200, "result": config.WHISPER_WEIGHT_TYPE}
|
return {"status":200, "result": config.WHISPER_WEIGHT_TYPE}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getSendMessageFormatParts(*args, **kwargs) -> dict:
|
||||||
|
return {"status":200, "result":config.SEND_MESSAGE_FORMAT_PARTS}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setSendMessageFormatParts(data, *args, **kwargs) -> dict:
|
||||||
|
config.SEND_MESSAGE_FORMAT_PARTS = dict(data)
|
||||||
|
return {"status":200, "result":config.SEND_MESSAGE_FORMAT_PARTS}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getReceivedMessageFormatParts(*args, **kwargs) -> dict:
|
||||||
|
return {"status":200, "result":config.RECEIVED_MESSAGE_FORMAT_PARTS}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setReceivedMessageFormatParts(data, *args, **kwargs) -> dict:
|
||||||
|
config.RECEIVED_MESSAGE_FORMAT_PARTS = dict(data)
|
||||||
|
return {"status":200, "result":config.RECEIVED_MESSAGE_FORMAT_PARTS}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getAutoClearMessageBox(*args, **kwargs) -> dict:
|
def getAutoClearMessageBox(*args, **kwargs) -> dict:
|
||||||
return {"status":200, "result":config.AUTO_CLEAR_MESSAGE_BOX}
|
return {"status":200, "result":config.AUTO_CLEAR_MESSAGE_BOX}
|
||||||
@@ -1769,21 +1793,27 @@ class Controller:
|
|||||||
return {"status":200, "result":True}
|
return {"status":200, "result":True}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def messageFormatter(format_type:str, translation:list, message:list) -> str:
|
def messageFormatter(format_type:str, translation:list, message:str) -> str:
|
||||||
if format_type == "RECEIVED":
|
if format_type == "RECEIVED":
|
||||||
FORMAT_WITH_T = config.RECEIVED_MESSAGE_FORMAT_WITH_T
|
format_parts = config.RECEIVED_MESSAGE_FORMAT_PARTS
|
||||||
FORMAT = config.RECEIVED_MESSAGE_FORMAT
|
|
||||||
elif format_type == "SEND":
|
elif format_type == "SEND":
|
||||||
FORMAT_WITH_T = config.SEND_MESSAGE_FORMAT_WITH_T
|
format_parts = config.SEND_MESSAGE_FORMAT_PARTS
|
||||||
FORMAT = config.SEND_MESSAGE_FORMAT
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("format_type is not found", format_type)
|
raise ValueError("format_type is not found", format_type)
|
||||||
|
|
||||||
if len(translation) > 0:
|
message_part = format_parts["message"]["prefix"] + message + format_parts["message"]["suffix"]
|
||||||
osc_message = FORMAT_WITH_T.replace("[message]", "\n".join(message))
|
translation_part = format_parts["translation"]["prefix"] + format_parts["translation"]["separator"].join(translation) + format_parts["translation"]["suffix"]
|
||||||
osc_message = osc_message.replace("[translation]", "\n".join(translation))
|
|
||||||
|
if len(translation) > 0 and message != "":
|
||||||
|
# 翻訳とメッセージの順序を決定
|
||||||
|
if format_parts["translation_first"]:
|
||||||
|
osc_message = translation_part + format_parts["separator"] + message_part
|
||||||
|
else:
|
||||||
|
osc_message = message_part + format_parts["separator"] + translation_part
|
||||||
|
elif len(translation) > 0 and message == "":
|
||||||
|
osc_message = translation_part
|
||||||
else:
|
else:
|
||||||
osc_message = FORMAT.replace("[message]", "\n".join(message))
|
osc_message = message_part
|
||||||
return osc_message
|
return osc_message
|
||||||
|
|
||||||
def changeToCTranslate2Process(self) -> None:
|
def changeToCTranslate2Process(self) -> None:
|
||||||
|
|||||||
@@ -285,6 +285,11 @@ mapping = {
|
|||||||
"/set/disable/overlay_show_only_translated_messages": {"status": True, "variable":controller.setDisableOverlayShowOnlyTranslatedMessages},
|
"/set/disable/overlay_show_only_translated_messages": {"status": True, "variable":controller.setDisableOverlayShowOnlyTranslatedMessages},
|
||||||
|
|
||||||
# Others
|
# Others
|
||||||
|
"/get/data/send_message_format_parts": {"status": True, "variable":controller.getSendMessageFormatParts},
|
||||||
|
"/set/data/send_message_format_parts": {"status": True, "variable":controller.setSendMessageFormatParts},
|
||||||
|
"/get/data/received_message_format_parts": {"status": True, "variable":controller.getReceivedMessageFormatParts},
|
||||||
|
"/set/data/received_message_format_parts": {"status": True, "variable":controller.setReceivedMessageFormatParts},
|
||||||
|
|
||||||
"/get/data/auto_clear_message_box": {"status": True, "variable":controller.getAutoClearMessageBox},
|
"/get/data/auto_clear_message_box": {"status": True, "variable":controller.getAutoClearMessageBox},
|
||||||
"/set/enable/auto_clear_message_box": {"status": True, "variable":controller.setEnableAutoClearMessageBox},
|
"/set/enable/auto_clear_message_box": {"status": True, "variable":controller.setEnableAutoClearMessageBox},
|
||||||
"/set/disable/auto_clear_message_box": {"status": True, "variable":controller.setDisableAutoClearMessageBox},
|
"/set/disable/auto_clear_message_box": {"status": True, "variable":controller.setDisableAutoClearMessageBox},
|
||||||
@@ -591,14 +596,34 @@ if __name__ == "__main__":
|
|||||||
"display_duration": 5,
|
"display_duration": 5,
|
||||||
"fadeout_duration": 0.5,
|
"fadeout_duration": 0.5,
|
||||||
}
|
}
|
||||||
case "/set/data/send_message_format":
|
case "/set/data/send_message_format_parts":
|
||||||
data = "[message]"
|
data = {
|
||||||
case "/set/data/send_message_format_with_t":
|
"message": {
|
||||||
data = "[message]([translation])"
|
"prefix": "",
|
||||||
case "/set/data/received_message_format":
|
"suffix": ""
|
||||||
data = "[message]"
|
},
|
||||||
case "/set/data/received_message_format_with_t":
|
"between_separator": "\n",
|
||||||
data = "[message]([translation])"
|
"translation": {
|
||||||
|
"prefix": "(",
|
||||||
|
"separator": "\\",
|
||||||
|
"suffix": ")"
|
||||||
|
},
|
||||||
|
"translation_first": False,
|
||||||
|
}
|
||||||
|
case "/set/data/received_message_format_parts":
|
||||||
|
data = {
|
||||||
|
"message": {
|
||||||
|
"prefix": "",
|
||||||
|
"suffix": ""
|
||||||
|
},
|
||||||
|
"between_separator": "\n",
|
||||||
|
"translation": {
|
||||||
|
"prefix": "(",
|
||||||
|
"separator": "\\",
|
||||||
|
"suffix": ")"
|
||||||
|
},
|
||||||
|
"translation_first": True,
|
||||||
|
}
|
||||||
case "/set/data/osc_ip_address":
|
case "/set/data/osc_ip_address":
|
||||||
data = "127.0.0.1"
|
data = "127.0.0.1"
|
||||||
case "/set/data/osc_port":
|
case "/set/data/osc_port":
|
||||||
|
|||||||
@@ -10,6 +10,41 @@ import requests
|
|||||||
import ipaddress
|
import ipaddress
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
def validateDictStructure(data: dict, structure: dict) -> bool:
|
||||||
|
"""
|
||||||
|
辞書とその期待される構造(型)が完全に一致するかを判別する関数
|
||||||
|
Args:
|
||||||
|
data (dict): 検証対象の辞書
|
||||||
|
structure (dict): 期待される構造を定義した辞書値には型(str, int, bool等)や入れ子の辞書を指定
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 構造が完全に一致する場合True、そうでなければFalse
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not isinstance(data, dict) or not isinstance(structure, dict):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# キーの数と名前が完全に一致するかチェック
|
||||||
|
if set(data.keys()) != set(structure.keys()):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 各キーの値の型または構造をチェック
|
||||||
|
for key, expected_type_or_structure in structure.items():
|
||||||
|
if key not in data:
|
||||||
|
return False
|
||||||
|
|
||||||
|
value = data[key]
|
||||||
|
# 期待される型が辞書の場合(入れ子構造)
|
||||||
|
if isinstance(expected_type_or_structure, dict):
|
||||||
|
# 再帰的に検証(多重入れ子に対応)
|
||||||
|
if not validateDictStructure(value, expected_type_or_structure):
|
||||||
|
return False
|
||||||
|
# 期待される型が型オブジェクトの場合
|
||||||
|
else:
|
||||||
|
if not isinstance(value, expected_type_or_structure):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def isConnectedNetwork(url="http://www.google.com", timeout=3) -> bool:
|
def isConnectedNetwork(url="http://www.google.com", timeout=3) -> bool:
|
||||||
try:
|
try:
|
||||||
response = requests.get(url, timeout=timeout)
|
response = requests.get(url, timeout=timeout)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "VRCT",
|
"productName": "VRCT",
|
||||||
"version": "3.2.1",
|
"version": "3.2.2",
|
||||||
"identifier": "com.vrct.app",
|
"identifier": "com.vrct.app",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "",
|
"beforeDevCommand": "",
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ const _Entry = forwardRef((props, ref) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.entry_container}>
|
<div
|
||||||
<div
|
className={styles.entry_container}
|
||||||
className={input_wrapper_class_names}
|
style={{width: props.width || "100%" }}
|
||||||
style={{width: props.width || "20rem" }}
|
>
|
||||||
>
|
<div className={input_wrapper_class_names}>
|
||||||
<input
|
<input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
text={props.text ? props.text : "text"}
|
text={props.text ? props.text : "text"}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.entry_wrapper {
|
.entry_wrapper {
|
||||||
width: 10rem;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0.6rem;
|
padding: 0.6rem;
|
||||||
background-color: var(--dark_875_color);
|
background-color: var(--dark_875_color);
|
||||||
@@ -19,6 +18,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
resize: none;
|
resize: none;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
&.is_disabled {
|
&.is_disabled {
|
||||||
color: var(--dark_500_color);
|
color: var(--dark_500_color);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ export { SwitchBox } from "./switch_box/SwitchBox";
|
|||||||
export { ThresholdComponent } from "./threshold_component/ThresholdComponent";
|
export { ThresholdComponent } from "./threshold_component/ThresholdComponent";
|
||||||
export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter";
|
export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter";
|
||||||
export { DownloadModels } from "./download_models/DownloadModels";
|
export { DownloadModels } from "./download_models/DownloadModels";
|
||||||
|
export { MessageFormat } from "./message_format/MessageFormat";
|
||||||
@@ -0,0 +1,295 @@
|
|||||||
|
import styles from "./MessageFormat.module.scss";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { _Entry } from "../_atoms/_entry/_Entry";
|
||||||
|
import SwapImg from "@images/swap_icon.png";
|
||||||
|
import ArrowLeftSvg from "@images/arrow_left.svg?react";
|
||||||
|
import { useStore_IsBreakPoint } from "@store";
|
||||||
|
import { useAppearance } from "@logics_configs";
|
||||||
|
import { ui_configs } from "@ui_configs";
|
||||||
|
import { ResetButton } from "@common_components";
|
||||||
|
|
||||||
|
const ENTRY_WIDTH = "8rem";
|
||||||
|
|
||||||
|
const EXAMPLE_TEXTS = {
|
||||||
|
en: "Hello",
|
||||||
|
ja: "こんにちは",
|
||||||
|
ko: "안녕하세요",
|
||||||
|
fr: "Bonjour",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MessageFormat = (props) => {
|
||||||
|
const { currentIsBreakPoint } = useStore_IsBreakPoint();
|
||||||
|
const message_format_container_class = clsx(styles.container, {
|
||||||
|
[styles.is_break_point]: currentIsBreakPoint.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={message_format_container_class}>
|
||||||
|
<ExampleComponent
|
||||||
|
format={props.variable.data}
|
||||||
|
example_view_filter_variable={props.example_view_filter_variable}
|
||||||
|
exampleViewFilterToggleFunction={props.exampleViewFilterToggleFunction}
|
||||||
|
format_id={props.format_id}
|
||||||
|
/>
|
||||||
|
<div className={styles.border}></div>
|
||||||
|
<InputComponent
|
||||||
|
variable={props.variable.data}
|
||||||
|
setFunction={props.setFunction}
|
||||||
|
format_id={props.format_id}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ExampleComponent = ({ format, example_view_filter_variable, exampleViewFilterToggleFunction, format_id }) => {
|
||||||
|
const { currentUiLanguage } = useAppearance();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
||||||
|
const locale_base_path = "config_page.others.message_format_common.example_view.";
|
||||||
|
|
||||||
|
const label_title = t(locale_base_path + "title");
|
||||||
|
|
||||||
|
const label_original_translated = t(locale_base_path + "original_translated");
|
||||||
|
const label_original_translated_multi = t(locale_base_path + "original_translated_multi");
|
||||||
|
const label_translated_only_multi = t(locale_base_path + "translated_only_multi");
|
||||||
|
const label_translated_only = t(locale_base_path + "translated_only");
|
||||||
|
const label_original_only = t(locale_base_path + "original_only");
|
||||||
|
|
||||||
|
const createExampleMessage = (id) => {
|
||||||
|
// 言語順序を決定
|
||||||
|
let example_text_order = [];
|
||||||
|
switch (currentUiLanguage.data) {
|
||||||
|
case "ja":
|
||||||
|
example_text_order = ["ja", "en", "ko", "fr"];
|
||||||
|
break;
|
||||||
|
case "ko":
|
||||||
|
example_text_order = ["ko", "ja", "en", "fr"];
|
||||||
|
break;
|
||||||
|
default: // en
|
||||||
|
example_text_order = ["en", "ja", "ko", "fr"];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const original = EXAMPLE_TEXTS[example_text_order[0]];
|
||||||
|
const translations = example_text_order.slice(1).map(lang => EXAMPLE_TEXTS[lang]);
|
||||||
|
|
||||||
|
const originalPart = `${format.message.prefix}${original}${format.message.suffix}`;
|
||||||
|
const translationSingle = `${format.translation.prefix}${translations[0]}${format.translation.suffix}`;
|
||||||
|
const translationMulti = `${format.translation.prefix}${translations.join(format.translation.separator)}${format.translation.suffix}`;
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case "original_translated":
|
||||||
|
return format.translation_first
|
||||||
|
? `${translationSingle}${format.separator}${originalPart}`
|
||||||
|
: `${originalPart}${format.separator}${translationSingle}`;
|
||||||
|
|
||||||
|
case "original_only":
|
||||||
|
return originalPart;
|
||||||
|
|
||||||
|
case "translated_only":
|
||||||
|
return translationSingle;
|
||||||
|
|
||||||
|
case "translated_only_multi":
|
||||||
|
return translationMulti;
|
||||||
|
|
||||||
|
case "original_translated_multi":
|
||||||
|
return format.translation_first
|
||||||
|
? `${translationMulti}${format.separator}${originalPart}`
|
||||||
|
: `${originalPart}${format.separator}${translationMulti}`;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(`Unexpected id: ${id}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ExampleBox = ({label, example_text_id}) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.example_wrapper}>
|
||||||
|
<p className={styles.example_label}>{label}</p>
|
||||||
|
<div className={styles.example_chatbox}>
|
||||||
|
<p className={styles.example_text}>{createExampleMessage(example_text_id)}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const svg_class_names = clsx(styles.arrow_left_svg, {
|
||||||
|
[styles.to_down]: example_view_filter_variable[format_id] === "Simplified",
|
||||||
|
[styles.to_up]: example_view_filter_variable[format_id] === "All"
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const FilteredExampleBox = ({format_id, id}) => {
|
||||||
|
if (format_id === "send" && id === "Simplified") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ExampleBox label={label_original_translated} example_text_id="original_translated" />
|
||||||
|
<ExampleBox label={label_original_translated_multi} example_text_id="original_translated_multi" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else if ( format_id === "send" && id === "All") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ExampleBox label={label_original_translated} example_text_id="original_translated" />
|
||||||
|
<ExampleBox label={label_original_translated_multi} example_text_id="original_translated_multi" />
|
||||||
|
<ExampleBox label={label_translated_only_multi} example_text_id="translated_only_multi" />
|
||||||
|
<ExampleBox label={label_translated_only} example_text_id="translated_only" />
|
||||||
|
<ExampleBox label={label_original_only} example_text_id="original_only" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
} else if (format_id === "received") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ExampleBox label={label_original_translated} example_text_id="original_translated" />
|
||||||
|
<ExampleBox label={label_original_only} example_text_id="original_only" />
|
||||||
|
<ExampleBox label={label_translated_only} example_text_id="translated_only" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.example_container}>
|
||||||
|
<p className={styles.section_title}>{label_title}</p>
|
||||||
|
<div className={styles.example_view_container}>
|
||||||
|
<FilteredExampleBox format_id={format_id} id={example_view_filter_variable[format_id]} />
|
||||||
|
</div>
|
||||||
|
{ format_id === "send" &&
|
||||||
|
<div className={styles.show_more_container} onClick={() => exampleViewFilterToggleFunction(format_id)}>
|
||||||
|
<ArrowLeftSvg className={svg_class_names}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const InputComponent = ({id, variable, setFunction, format_id }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const locale_base_path = "config_page.others.message_format_common.settings.";
|
||||||
|
const label_title = t(locale_base_path + "title");
|
||||||
|
|
||||||
|
const LABEL_ORIGINAL = t(locale_base_path + "original");
|
||||||
|
const LABEL_TRANSLATED = t(locale_base_path + "translated");
|
||||||
|
const LABEL_FOR_MULTI_TRANSLATION = t(locale_base_path + "for_multi_translation");
|
||||||
|
|
||||||
|
const replaceValue = (value) => {
|
||||||
|
if (value === "") return "";
|
||||||
|
|
||||||
|
const replaced = value.replace(/\\n/g, "\n");
|
||||||
|
return replaced;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (parent_key, child_key) => (e) => {
|
||||||
|
const rawValue = e.target.value;
|
||||||
|
const parsedValue = replaceValue(rawValue);
|
||||||
|
|
||||||
|
if (child_key !== undefined) {
|
||||||
|
setFunction({
|
||||||
|
...variable,
|
||||||
|
[parent_key]: {
|
||||||
|
...variable[parent_key],
|
||||||
|
[child_key]: parsedValue
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setFunction({
|
||||||
|
...variable,
|
||||||
|
[parent_key]: parsedValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const toUiValue = (v) => {
|
||||||
|
if (typeof v === "string") {
|
||||||
|
return v.replace(/\n/g, "\\n");
|
||||||
|
}
|
||||||
|
console.log("Empty");
|
||||||
|
|
||||||
|
return v ?? "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetFunction = () => {
|
||||||
|
if (format_id === "send") {
|
||||||
|
setFunction(ui_configs.send_message_format_parts);
|
||||||
|
} else if (format_id === "received") {
|
||||||
|
setFunction(ui_configs.received_message_format_parts);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const SwapButton = ({ variable, setFunction }) => {
|
||||||
|
const swapMessageAndTranslate = () => {
|
||||||
|
setFunction({ ...variable, translation_first: !variable.translation_first });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.swap_button_wrapper} onClick={swapMessageAndTranslate}>
|
||||||
|
<p className={styles.swap_text}>{variable.translation_first ? LABEL_TRANSLATED : LABEL_ORIGINAL}</p>
|
||||||
|
<img className={styles.swap_img} src={SwapImg} alt="Swap Icon" />
|
||||||
|
<p className={styles.swap_text}>{variable.translation_first ? LABEL_ORIGINAL : LABEL_TRANSLATED}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.message_format_settings_container}>
|
||||||
|
<p className={styles.section_title}>{label_title}</p>
|
||||||
|
<div className={styles.message_format_settings_wrapper}>
|
||||||
|
<div className={styles.swap_button_container}>
|
||||||
|
<SwapButton variable={variable} setFunction={setFunction} />
|
||||||
|
</div>
|
||||||
|
{ !variable.translation_first ?
|
||||||
|
<div className={styles.input_wrapper}>
|
||||||
|
<div className={styles.input_contents}>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.message.prefix)} width={ENTRY_WIDTH} onChange={handleChange("message", "prefix")} />
|
||||||
|
<p className={styles.preset_text}>{LABEL_ORIGINAL}</p>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.message.suffix)} width={ENTRY_WIDTH} onChange={handleChange("message", "suffix")} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.input_contents}>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.separator)} width={ENTRY_WIDTH} onChange={handleChange("separator")} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.input_contents}>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.translation.prefix)} width={ENTRY_WIDTH} onChange={handleChange("translation", "prefix")} />
|
||||||
|
<p className={styles.preset_text}>{LABEL_TRANSLATED}</p>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.translation.suffix)} width={ENTRY_WIDTH} onChange={handleChange("translation", "suffix")} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className={styles.input_wrapper}>
|
||||||
|
<div className={styles.input_contents}>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.translation.prefix)} width={ENTRY_WIDTH} onChange={handleChange("translation", "prefix")} />
|
||||||
|
<p className={styles.preset_text}>{LABEL_TRANSLATED}</p>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.translation.suffix)} width={ENTRY_WIDTH} onChange={handleChange("translation", "suffix")} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.input_contents}>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.separator)} width={ENTRY_WIDTH} onChange={handleChange("separator")} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.input_contents}>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.message.prefix)} width={ENTRY_WIDTH} onChange={handleChange("message", "prefix")} />
|
||||||
|
<p className={styles.preset_text}>{LABEL_ORIGINAL}</p>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.message.suffix)} width={ENTRY_WIDTH} onChange={handleChange("message", "suffix")} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{ format_id === "send" &&
|
||||||
|
<div className={styles.multi_translation_input_wrapper}>
|
||||||
|
<p className={styles.multi_translation_title}>{LABEL_FOR_MULTI_TRANSLATION}</p>
|
||||||
|
<div className={styles.input_contents}>
|
||||||
|
<p className={styles.preset_text}>{LABEL_TRANSLATED}</p>
|
||||||
|
<_Entry ui_variable={toUiValue(variable.translation.separator)} width={ENTRY_WIDTH} onChange={handleChange("translation", "separator")} />
|
||||||
|
<p className={styles.preset_text}>{LABEL_TRANSLATED}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div className={styles.reset_button_wrapper}>
|
||||||
|
<ResetButton onClickFunction={resetFunction}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
gap: 2.6rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
&.is_break_point {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2.2rem;
|
||||||
|
align-items: center;
|
||||||
|
.border {
|
||||||
|
height: 0.1rem;
|
||||||
|
width: 60%;
|
||||||
|
margin: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.show_more_container {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
.example_container {
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
.message_format_settings_container {
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.border {
|
||||||
|
height: auto;
|
||||||
|
width: 0.1rem;
|
||||||
|
background-color: var(--dark_800_color);
|
||||||
|
margin: 3.2rem 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section_title {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example_container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
min-width: 14rem;
|
||||||
|
max-width: 34rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example_view_container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example_wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
}
|
||||||
|
.example_label {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
text-align: start;
|
||||||
|
width: 100%;
|
||||||
|
color: var(--dark_basic_text_color);
|
||||||
|
}
|
||||||
|
.example_chatbox {
|
||||||
|
padding: 0.6rem;
|
||||||
|
background-color: #3A4554;
|
||||||
|
border-radius: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example_text {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show_more_container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.6rem 0;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 0.6rem;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--dark_850_color);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: var(--dark_875_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow_left_svg {
|
||||||
|
width: 2rem;
|
||||||
|
color: var(--dark_450_color);
|
||||||
|
&.to_down {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
&.to_up {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.message_format_settings_container {
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message_format_settings_wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3.8rem;
|
||||||
|
width: 34rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swap_button_container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swap_button_wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
padding: 0.6rem 1.2rem;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
background-color: var(--dark_850_color);
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--dark_800_color);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: var(--dark_900_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.swap_text {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swap_img {
|
||||||
|
width: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.input_wrapper {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input_contents {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
color: var(--dark_basic_text_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preset_text {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
text-align: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: var(--dark_basic_text_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multi_translation_input_wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--dark_basic_text_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multi_translation_title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reset_button_wrapper {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
WordFilter,
|
WordFilter,
|
||||||
WordFilterListToggleComponent,
|
WordFilterListToggleComponent,
|
||||||
DownloadModels,
|
DownloadModels,
|
||||||
|
MessageFormat,
|
||||||
} from "../_components/";
|
} from "../_components/";
|
||||||
import { Checkbox } from "@common_components";
|
import { Checkbox } from "@common_components";
|
||||||
|
|
||||||
@@ -130,3 +131,16 @@ export const WordFilterContainer = (props) => (
|
|||||||
export const DownloadModelsContainer = (props) => (
|
export const DownloadModelsContainer = (props) => (
|
||||||
<CommonContainer Component={DownloadModels} {...props} />
|
<CommonContainer Component={DownloadModels} {...props} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const MessageFormatContainer = (props) => {
|
||||||
|
return (
|
||||||
|
<div className={clsx(styles.container, styles.flex_column)}>
|
||||||
|
<div className={styles.label_only_section}>
|
||||||
|
<LabelComponent label={props.label} desc={props.desc} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.message_format_section}>
|
||||||
|
<MessageFormat {...props}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -37,7 +37,7 @@ export const PosterShowcaseWorldsContents = () => {
|
|||||||
);
|
);
|
||||||
if (poster.x_post_num !== null) {
|
if (poster.x_post_num !== null) {
|
||||||
return (
|
return (
|
||||||
<a href={`https://x.com/Shiina_12siy/status/${poster.x_post_num}`} target="_blank" rel="noreferrer" className={class_names} key={index}>
|
<a href={`https://x.com/Shiina_12siy/status/${poster.x_post_num}`} target="_blank" rel="noreferrer" className={class_names} key={index}>
|
||||||
{content}
|
{content}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ const UiScalingContainer = () => {
|
|||||||
asyncUpdateBreakPoint();
|
asyncUpdateBreakPoint();
|
||||||
}, [currentUiScaling.data]);
|
}, [currentUiScaling.data]);
|
||||||
|
|
||||||
|
// [Duplicated]
|
||||||
const createMarks = (min, max) => {
|
const createMarks = (min, max) => {
|
||||||
const marks = [];
|
const marks = [];
|
||||||
for (let value = min; value <= max; value += 10) {
|
for (let value = min; value <= max; value += 10) {
|
||||||
@@ -111,6 +112,7 @@ export const MessageLogUiScalingContainer = () => {
|
|||||||
setUiMessageLogUiScaling(currentMessageLogUiScaling.data);
|
setUiMessageLogUiScaling(currentMessageLogUiScaling.data);
|
||||||
}, [currentMessageLogUiScaling.data]);
|
}, [currentMessageLogUiScaling.data]);
|
||||||
|
|
||||||
|
// [Duplicated]
|
||||||
const createMarks = (min, max) => {
|
const createMarks = (min, max) => {
|
||||||
const marks = [];
|
const marks = [];
|
||||||
for (let value = min; value <= max; value += 10) {
|
for (let value = min; value <= max; value += 10) {
|
||||||
@@ -207,6 +209,7 @@ const TransparencyContainer = () => {
|
|||||||
setUiTransparency(currentTransparency.data);
|
setUiTransparency(currentTransparency.data);
|
||||||
}, [currentTransparency.data]);
|
}, [currentTransparency.data]);
|
||||||
|
|
||||||
|
// [Duplicated]
|
||||||
const createMarks = (min, max) => {
|
const createMarks = (min, max) => {
|
||||||
const marks = [];
|
const marks = [];
|
||||||
for (let value = min; value <= max; value += 10) {
|
for (let value = min; value <= max; value += 10) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
CheckboxContainer,
|
CheckboxContainer,
|
||||||
|
MessageFormatContainer,
|
||||||
} from "../_templates/Templates";
|
} from "../_templates/Templates";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -39,6 +40,11 @@ export const Others = () => {
|
|||||||
<SectionLabelComponent label="Speaker2Chatbox" />
|
<SectionLabelComponent label="Speaker2Chatbox" />
|
||||||
<SendReceivedMessageToVrcContainer />
|
<SendReceivedMessageToVrcContainer />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<SectionLabelComponent label={t("config_page.others.section_label_message_formats")} />
|
||||||
|
<SendMessageFormatPartsContainer />
|
||||||
|
<ReceivedMessageFormatPartsContainer />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -152,3 +158,47 @@ const SendReceivedMessageToVrcContainer = () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SendMessageFormatPartsContainer = () => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const {
|
||||||
|
currentSendMessageFormatParts,
|
||||||
|
setSendMessageFormatParts,
|
||||||
|
currentMessageFormat_ExampleViewFilter,
|
||||||
|
toggleMessageFormat_ExampleViewFilter,
|
||||||
|
} = useOthers();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MessageFormatContainer
|
||||||
|
label={t("config_page.others.send_message_format.label")}
|
||||||
|
desc={t("config_page.others.send_message_format.desc")}
|
||||||
|
variable={currentSendMessageFormatParts}
|
||||||
|
setFunction={setSendMessageFormatParts}
|
||||||
|
example_view_filter_variable={currentMessageFormat_ExampleViewFilter.data}
|
||||||
|
exampleViewFilterToggleFunction={toggleMessageFormat_ExampleViewFilter}
|
||||||
|
format_id="send"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ReceivedMessageFormatPartsContainer = () => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const {
|
||||||
|
currentReceivedMessageFormatParts,
|
||||||
|
setReceivedMessageFormatParts,
|
||||||
|
currentMessageFormat_ExampleViewFilter,
|
||||||
|
toggleMessageFormat_ExampleViewFilter,
|
||||||
|
} = useOthers();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MessageFormatContainer
|
||||||
|
label={t("config_page.others.received_message_format.label")}
|
||||||
|
desc={t("config_page.others.received_message_format.desc")}
|
||||||
|
variable={currentReceivedMessageFormatParts}
|
||||||
|
setFunction={setReceivedMessageFormatParts}
|
||||||
|
example_view_filter_variable={currentMessageFormat_ExampleViewFilter.data}
|
||||||
|
exampleViewFilterToggleFunction={toggleMessageFormat_ExampleViewFilter}
|
||||||
|
format_id="received"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { useEffect, useRef, useState, useCallback } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { useI18n } from "@useI18n";
|
import { useI18n } from "@useI18n";
|
||||||
import { usePlugins } from "@logics_configs";
|
import { usePlugins } from "@logics_configs";
|
||||||
import styles from "./Plugins.module.scss";
|
import styles from "./Plugins.module.scss";
|
||||||
import { PluginsControlComponent } from "./plugins_control_component/PluginsControlComponent";
|
import { PluginsControlComponent } from "./plugins_control_component/PluginsControlComponent";
|
||||||
import { useNotificationStatus } from "@logics_common";
|
import { useNotificationStatus } from "@logics_common";
|
||||||
import ExternalLink from "@images/external_link.svg?react";
|
import { HomepageLinkButton } from "@common_components";
|
||||||
|
|
||||||
export const Plugins = () => {
|
export const Plugins = () => {
|
||||||
const {
|
const {
|
||||||
@@ -126,54 +126,3 @@ const PluginDownloadContainer = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const HomepageLinkButton = ({ homepage_link, speed = 40 /* px/s */ }) => {
|
|
||||||
const containerRef = useRef(null);
|
|
||||||
const textRef = useRef(null);
|
|
||||||
const [inlineStyle, setInlineStyle] = useState({});
|
|
||||||
|
|
||||||
const handleMouseEnter = useCallback(() => {
|
|
||||||
const container = containerRef.current;
|
|
||||||
const text = textRef.current;
|
|
||||||
if (!container || !text) return;
|
|
||||||
const overflow = text.scrollWidth - container.clientWidth;
|
|
||||||
if (overflow > 0) {
|
|
||||||
const duration = overflow / speed;
|
|
||||||
setInlineStyle({
|
|
||||||
transform: `translateX(-${overflow}px)`,
|
|
||||||
transition: `transform ${duration}s linear`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [speed]);
|
|
||||||
|
|
||||||
const handleMouseLeave = useCallback(() => {
|
|
||||||
setInlineStyle({
|
|
||||||
transform: 'translateX(0)',
|
|
||||||
transition: 'transform 0.3s ease-out',
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.open_homepage_button_wrapper}>
|
|
||||||
<a
|
|
||||||
className={styles.open_homepage_button}
|
|
||||||
href={homepage_link}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
onMouseEnter={handleMouseEnter}
|
|
||||||
onMouseLeave={handleMouseLeave}
|
|
||||||
>
|
|
||||||
<div className={styles.text_container} ref={containerRef}>
|
|
||||||
<p
|
|
||||||
className={styles.open_homepage_text}
|
|
||||||
ref={textRef}
|
|
||||||
style={inlineStyle}
|
|
||||||
>
|
|
||||||
{homepage_link}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<ExternalLink className={styles.external_link_svg} />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -57,44 +57,3 @@
|
|||||||
// white-space: nowrap;
|
// white-space: nowrap;
|
||||||
// text-overflow: ellipsis;
|
// text-overflow: ellipsis;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
.open_homepage_button_wrapper {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.open_homepage_button {
|
|
||||||
padding: 0.6rem 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 1rem;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
|
||||||
&:hover .external_link_svg {
|
|
||||||
color: var(--dark_200_color);
|
|
||||||
}
|
|
||||||
&:hover .open_homepage_text {
|
|
||||||
border-bottom: 0.1rem solid var(--dark_500_color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_container {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
flex: 1; /* テキスト部分をアイコンまで伸ばす */
|
|
||||||
}
|
|
||||||
|
|
||||||
.open_homepage_text {
|
|
||||||
margin: 0; /* pタグのデフォルトマージン除去 */
|
|
||||||
font-size: 1.4rem;
|
|
||||||
color: var(--sent_400_color);
|
|
||||||
white-space: nowrap;
|
|
||||||
display: inline-block;
|
|
||||||
transform: translateX(0);
|
|
||||||
border-bottom: 0.1rem solid var(--sent_400_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.external_link_svg {
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 1.6rem;
|
|
||||||
color: var(--dark_500_color);
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
import { useI18n } from "@useI18n";
|
import { useI18n } from "@useI18n";
|
||||||
import styles from "./Transcription.module.scss";
|
import styles from "./Transcription.module.scss";
|
||||||
import { updateLabelsById, genNumObjArray } from "@utils";
|
import { updateLabelsById, genNumObjArray } from "@utils";
|
||||||
@@ -12,6 +13,7 @@ import {
|
|||||||
RadioButtonContainer,
|
RadioButtonContainer,
|
||||||
DropdownMenuContainer,
|
DropdownMenuContainer,
|
||||||
ComputeDeviceContainer,
|
ComputeDeviceContainer,
|
||||||
|
SliderContainer,
|
||||||
} from "../_templates/Templates";
|
} from "../_templates/Templates";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -24,6 +26,7 @@ export const Transcription = () => {
|
|||||||
<Mic_Container />
|
<Mic_Container />
|
||||||
<Speaker_Container />
|
<Speaker_Container />
|
||||||
<TranscriptionEngine_Container />
|
<TranscriptionEngine_Container />
|
||||||
|
<Advanced_Container />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -354,3 +357,195 @@ const findKeyByDeviceValue = (devices, target_value) => {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const Advanced_Container = () => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<SectionLabelComponent label="Advanced Settings (Whisper Model)" />
|
||||||
|
{/* <SectionLabelComponent label={t("config_page.transcription.section_label_transcription_engines")} /> */}
|
||||||
|
<MicAvgLogprobContainer />
|
||||||
|
<MicNoSpeechProbContainer />
|
||||||
|
<SpeakerAvgLogprobContainer />
|
||||||
|
<SpeakerNoSpeechProbContainer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MicAvgLogprobContainer = () => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { currentMicAvgLogprob, setMicAvgLogprob } = useTranscription();
|
||||||
|
const [ui_mic_avg_logprob, setUiMicAvgLogprob] = useState(currentMicAvgLogprob.data);
|
||||||
|
|
||||||
|
const onchangeFunction = (value) => {
|
||||||
|
setUiMicAvgLogprob(value);
|
||||||
|
};
|
||||||
|
const onchangeCommittedFunction = (value) => {
|
||||||
|
setMicAvgLogprob(value);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
setUiMicAvgLogprob(currentMicAvgLogprob.data);
|
||||||
|
}, [currentMicAvgLogprob.data]);
|
||||||
|
|
||||||
|
// [Duplicated]
|
||||||
|
const createMarks = (min, max) => {
|
||||||
|
const marks = [];
|
||||||
|
for (let value = min; value <= max; value += 0.2) {
|
||||||
|
value = parseFloat(value.toFixed(1));
|
||||||
|
marks.push({ value, label: `${value}` });
|
||||||
|
}
|
||||||
|
return marks;
|
||||||
|
};
|
||||||
|
|
||||||
|
const marks = createMarks(-2, 0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SliderContainer
|
||||||
|
label="Mic Avg Logprob"
|
||||||
|
desc="Default: -0.8"
|
||||||
|
min="-2"
|
||||||
|
max="0"
|
||||||
|
onchangeCommittedFunction={onchangeCommittedFunction}
|
||||||
|
onchangeFunction={onchangeFunction}
|
||||||
|
variable={ui_mic_avg_logprob}
|
||||||
|
marks={marks}
|
||||||
|
step={0.1}
|
||||||
|
track={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MicNoSpeechProbContainer = () => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { currentMicNoSpeechProb, setMicNoSpeechProb } = useTranscription();
|
||||||
|
const [ui_mic_no_speech_prob, setUiMicNoSpeechProb] = useState(currentMicNoSpeechProb.data);
|
||||||
|
|
||||||
|
const onchangeFunction = (value) => {
|
||||||
|
setUiMicNoSpeechProb(value);
|
||||||
|
};
|
||||||
|
const onchangeCommittedFunction = (value) => {
|
||||||
|
setMicNoSpeechProb(value);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
setUiMicNoSpeechProb(currentMicNoSpeechProb.data);
|
||||||
|
}, [currentMicNoSpeechProb.data]);
|
||||||
|
|
||||||
|
// [Duplicated]
|
||||||
|
const createMarks = (min, max) => {
|
||||||
|
const marks = [];
|
||||||
|
for (let value = min; value <= max; value += 0.1) {
|
||||||
|
value = parseFloat(value.toFixed(1));
|
||||||
|
marks.push({ value, label: `${value}` });
|
||||||
|
}
|
||||||
|
return marks;
|
||||||
|
};
|
||||||
|
|
||||||
|
const marks = createMarks(0, 1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SliderContainer
|
||||||
|
label="Mic No Speech Prob"
|
||||||
|
desc="Default: 0.6"
|
||||||
|
min="0"
|
||||||
|
max="1"
|
||||||
|
onchangeCommittedFunction={onchangeCommittedFunction}
|
||||||
|
onchangeFunction={onchangeFunction}
|
||||||
|
variable={ui_mic_no_speech_prob}
|
||||||
|
marks={marks}
|
||||||
|
step={0.1}
|
||||||
|
track={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SpeakerAvgLogprobContainer = () => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { currentSpeakerAvgLogprob, setSpeakerAvgLogprob } = useTranscription();
|
||||||
|
const [ui_speaker_avg_logprob, setUiSpeakerAvgLogprob] = useState(currentSpeakerAvgLogprob.data);
|
||||||
|
|
||||||
|
const onchangeFunction = (value) => {
|
||||||
|
setUiSpeakerAvgLogprob(value);
|
||||||
|
};
|
||||||
|
const onchangeCommittedFunction = (value) => {
|
||||||
|
setSpeakerAvgLogprob(value);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
setUiSpeakerAvgLogprob(currentSpeakerAvgLogprob.data);
|
||||||
|
}, [currentSpeakerAvgLogprob.data]);
|
||||||
|
|
||||||
|
// [Duplicated]
|
||||||
|
const createMarks = (min, max) => {
|
||||||
|
const marks = [];
|
||||||
|
for (let value = min; value <= max; value += 0.2) {
|
||||||
|
value = parseFloat(value.toFixed(1));
|
||||||
|
marks.push({ value, label: `${value}` });
|
||||||
|
}
|
||||||
|
return marks;
|
||||||
|
};
|
||||||
|
|
||||||
|
const marks = createMarks(-2, 0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SliderContainer
|
||||||
|
label="Speaker Avg Logprob"
|
||||||
|
desc="Default: -0.8"
|
||||||
|
min="-2"
|
||||||
|
max="0"
|
||||||
|
onchangeCommittedFunction={onchangeCommittedFunction}
|
||||||
|
onchangeFunction={onchangeFunction}
|
||||||
|
variable={ui_speaker_avg_logprob}
|
||||||
|
marks={marks}
|
||||||
|
step={0.1}
|
||||||
|
track={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SpeakerNoSpeechProbContainer = () => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { currentSpeakerNoSpeechProb, setSpeakerNoSpeechProb } = useTranscription();
|
||||||
|
const [ui_speaker_no_speech_prob, setUiSpeakerNoSpeechProb] = useState(currentSpeakerNoSpeechProb.data);
|
||||||
|
|
||||||
|
const onchangeFunction = (value) => {
|
||||||
|
setUiSpeakerNoSpeechProb(value);
|
||||||
|
};
|
||||||
|
const onchangeCommittedFunction = (value) => {
|
||||||
|
setSpeakerNoSpeechProb(value);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
setUiSpeakerNoSpeechProb(currentSpeakerNoSpeechProb.data);
|
||||||
|
}, [currentSpeakerNoSpeechProb.data]);
|
||||||
|
|
||||||
|
// [Duplicated]
|
||||||
|
const createMarks = (min, max) => {
|
||||||
|
const marks = [];
|
||||||
|
for (let value = min; value <= max; value += 0.1) {
|
||||||
|
value = parseFloat(value.toFixed(1));
|
||||||
|
marks.push({ value, label: `${value}` });
|
||||||
|
}
|
||||||
|
return marks;
|
||||||
|
};
|
||||||
|
|
||||||
|
const marks = createMarks(0, 1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SliderContainer
|
||||||
|
label="Speaker No Speech Prob"
|
||||||
|
desc="Default: 0.6"
|
||||||
|
min="0"
|
||||||
|
max="1"
|
||||||
|
onchangeCommittedFunction={onchangeCommittedFunction}
|
||||||
|
onchangeFunction={onchangeFunction}
|
||||||
|
variable={ui_speaker_no_speech_prob}
|
||||||
|
marks={marks}
|
||||||
|
step={0.1}
|
||||||
|
track={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -14,12 +14,12 @@ import {
|
|||||||
SectionLabelComponent,
|
SectionLabelComponent,
|
||||||
} from "../_components/";
|
} from "../_components/";
|
||||||
|
|
||||||
|
import { ResetButton } from "@common_components";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useVr,
|
useVr,
|
||||||
} from "@logics_configs";
|
} from "@logics_configs";
|
||||||
|
|
||||||
import RedoSvg from "@images/redo.svg?react";
|
|
||||||
|
|
||||||
import SquareSvg from "@images/square.svg?react";
|
import SquareSvg from "@images/square.svg?react";
|
||||||
import TriangleSvg from "@images/triangle.svg?react";
|
import TriangleSvg from "@images/triangle.svg?react";
|
||||||
import { randomIntMinMax } from "@utils";
|
import { randomIntMinMax } from "@utils";
|
||||||
@@ -528,13 +528,6 @@ const CommonSettingsContainer = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ResetButton = ({onClickFunction}) => {
|
|
||||||
return (
|
|
||||||
<button className={styles.slider_reset_button} onClick={onClickFunction}>
|
|
||||||
<RedoSvg className={styles.slider_reset_svg}/>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const SendSampleTextToggleButton = () => {
|
const SendSampleTextToggleButton = () => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|||||||
@@ -301,34 +301,6 @@
|
|||||||
@include variable-button-wrapper(bottom, 50%, right, -60%, -45deg);
|
@include variable-button-wrapper(bottom, 50%, right, -60%, -45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.slider_reset_button {
|
|
||||||
background-color: var(--dark_875_color);
|
|
||||||
padding: 0.6rem;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
border-radius: 0.4rem;
|
|
||||||
flex-shrink: 0;
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--dark_825_color);
|
|
||||||
& .slider_reset_svg {
|
|
||||||
color: var(--dark_200_color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
background-color: var(--dark_925_color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider_reset_svg {
|
|
||||||
width: 1.4rem;
|
|
||||||
color: var(--dark_550_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.other_controls {
|
.other_controls {
|
||||||
margin-top: 6rem;
|
margin-top: 6rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState, isValidElement } from "react";
|
||||||
import { ToastContainer, toast, cssTransition } from "react-toastify";
|
import { ToastContainer, toast, cssTransition } from "react-toastify";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import ExternalLink from "@images/external_link.svg?react";
|
||||||
|
import styles from "./HomepageLinkButton.module.scss";
|
||||||
|
import { useRef, useState, useCallback } from "react";
|
||||||
|
|
||||||
|
export const HomepageLinkButton = ({ homepage_link, speed = 40 /* px/s */ }) => {
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
const textRef = useRef(null);
|
||||||
|
const [inlineStyle, setInlineStyle] = useState({});
|
||||||
|
|
||||||
|
const handleMouseEnter = useCallback(() => {
|
||||||
|
const container = containerRef.current;
|
||||||
|
const text = textRef.current;
|
||||||
|
if (!container || !text) return;
|
||||||
|
const overflow = text.scrollWidth - container.clientWidth;
|
||||||
|
if (overflow > 0) {
|
||||||
|
const duration = overflow / speed;
|
||||||
|
setInlineStyle({
|
||||||
|
transform: `translateX(-${overflow}px)`,
|
||||||
|
transition: `transform ${duration}s linear`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [speed]);
|
||||||
|
|
||||||
|
const handleMouseLeave = useCallback(() => {
|
||||||
|
setInlineStyle({
|
||||||
|
transform: 'translateX(0)',
|
||||||
|
transition: 'transform 0.3s ease-out',
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.open_homepage_button_wrapper}>
|
||||||
|
<a
|
||||||
|
className={styles.open_homepage_button}
|
||||||
|
href={homepage_link}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
>
|
||||||
|
<div className={styles.text_container} ref={containerRef}>
|
||||||
|
<p
|
||||||
|
className={styles.open_homepage_text}
|
||||||
|
ref={textRef}
|
||||||
|
style={inlineStyle}
|
||||||
|
>
|
||||||
|
{homepage_link}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<ExternalLink className={styles.external_link_svg} />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
.open_homepage_button_wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open_homepage_button {
|
||||||
|
padding: 0.6rem 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
&:hover .external_link_svg {
|
||||||
|
color: var(--dark_200_color);
|
||||||
|
}
|
||||||
|
&:hover .open_homepage_text {
|
||||||
|
border-bottom: 0.1rem solid var(--dark_500_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text_container {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open_homepage_text {
|
||||||
|
margin: 0; /* pタグのデフォルトマージン除去 */
|
||||||
|
font-size: 1.4rem;
|
||||||
|
color: var(--sent_400_color);
|
||||||
|
white-space: nowrap;
|
||||||
|
display: inline-block;
|
||||||
|
transform: translateX(0);
|
||||||
|
border-bottom: 0.1rem solid var(--sent_400_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.external_link_svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 1.6rem;
|
||||||
|
color: var(--dark_500_color);
|
||||||
|
}
|
||||||
@@ -1 +1,3 @@
|
|||||||
export { Checkbox } from "./checkbox/Checkbox";
|
export { Checkbox } from "./checkbox/Checkbox";
|
||||||
|
export { HomepageLinkButton } from "./homepage_link_button/HomepageLinkButton";
|
||||||
|
export { ResetButton } from "./reset_button/ResetButton";
|
||||||
10
src-ui/common_components/reset_button/ResetButton.jsx
Normal file
10
src-ui/common_components/reset_button/ResetButton.jsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import styles from "./ResetButton.module.scss";
|
||||||
|
import RedoSvg from "@images/redo.svg?react";
|
||||||
|
|
||||||
|
export const ResetButton = ({ onClickFunction }) => {
|
||||||
|
return (
|
||||||
|
<button className={styles.reset_button} onClick={onClickFunction}>
|
||||||
|
<RedoSvg className={styles.reset_svg}/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
.reset_button {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: var(--dark_875_color);
|
||||||
|
padding: 0.6rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--dark_825_color);
|
||||||
|
& .reset_svg {
|
||||||
|
color: var(--dark_200_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: var(--dark_925_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.reset_svg {
|
||||||
|
width: 1.4rem;
|
||||||
|
color: var(--dark_550_color);
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { useStore_IsVrctAvailable } from "@store";
|
|
||||||
import { useNotificationStatus } from "@logics_common";
|
|
||||||
|
|
||||||
export const useIsVrctAvailable = () => {
|
|
||||||
const { currentIsVrctAvailable, updateIsVrctAvailable } = useStore_IsVrctAvailable();
|
|
||||||
const { showNotification_Success, showNotification_Error } = useNotificationStatus();
|
|
||||||
|
|
||||||
const handleAiModelsAvailability = (is_ai_models_available) => {
|
|
||||||
if (is_ai_models_available === false) {
|
|
||||||
updateIsVrctAvailable(false);
|
|
||||||
showNotification_Error("AI models have not been detected. Check the network connection and restart VRCT (it will download automatically, normally).", { hide_duration: null });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
currentIsVrctAvailable,
|
|
||||||
updateIsVrctAvailable,
|
|
||||||
|
|
||||||
handleAiModelsAvailability,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
33
src-ui/logics/common/useIsVrctAvailable.jsx
Normal file
33
src-ui/logics/common/useIsVrctAvailable.jsx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { useStore_IsVrctAvailable } from "@store";
|
||||||
|
import { useNotificationStatus } from "@logics_common";
|
||||||
|
import { HomepageLinkButton } from "@common_components";
|
||||||
|
|
||||||
|
export const useIsVrctAvailable = () => {
|
||||||
|
const { currentIsVrctAvailable, updateIsVrctAvailable } = useStore_IsVrctAvailable();
|
||||||
|
const { showNotification_Success, showNotification_Error } = useNotificationStatus();
|
||||||
|
|
||||||
|
const handleAiModelsAvailability = (is_ai_models_available) => {
|
||||||
|
if (is_ai_models_available === false) {
|
||||||
|
updateIsVrctAvailable(false);
|
||||||
|
const ErrorComponent = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>AI models have not been detected. Check the network connection and restart VRCT (it will download automatically, normally).</p>
|
||||||
|
<p>If this error occurs frequently, try the following:</p>
|
||||||
|
<HomepageLinkButton
|
||||||
|
homepage_link="https://github.com/misyaguziya/VRCT/wiki/Manual-Installation-of-AI-Model-Weights"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
showNotification_Error(ErrorComponent, { hide_duration: null });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentIsVrctAvailable,
|
||||||
|
updateIsVrctAvailable,
|
||||||
|
|
||||||
|
handleAiModelsAvailability,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -6,6 +6,9 @@ import {
|
|||||||
useStore_EnableSendMessageToVrc,
|
useStore_EnableSendMessageToVrc,
|
||||||
useStore_EnableNotificationVrcSfx,
|
useStore_EnableNotificationVrcSfx,
|
||||||
useStore_EnableSendReceivedMessageToVrc,
|
useStore_EnableSendReceivedMessageToVrc,
|
||||||
|
useStore_MessageFormat_ExampleViewFilter,
|
||||||
|
useStore_SendMessageFormatParts,
|
||||||
|
useStore_ReceivedMessageFormatParts,
|
||||||
} from "@store";
|
} from "@store";
|
||||||
import { useStdoutToPython } from "@useStdoutToPython";
|
import { useStdoutToPython } from "@useStdoutToPython";
|
||||||
import { useNotificationStatus } from "@logics_common";
|
import { useNotificationStatus } from "@logics_common";
|
||||||
@@ -29,6 +32,12 @@ export const useOthers = () => {
|
|||||||
// Speaker2Chatbox
|
// Speaker2Chatbox
|
||||||
// Send Received Message To VRC
|
// Send Received Message To VRC
|
||||||
const { currentEnableSendReceivedMessageToVrc, updateEnableSendReceivedMessageToVrc, pendingEnableSendReceivedMessageToVrc } = useStore_EnableSendReceivedMessageToVrc();
|
const { currentEnableSendReceivedMessageToVrc, updateEnableSendReceivedMessageToVrc, pendingEnableSendReceivedMessageToVrc } = useStore_EnableSendReceivedMessageToVrc();
|
||||||
|
// Message Formats
|
||||||
|
const { currentMessageFormat_ExampleViewFilter, updateMessageFormat_ExampleViewFilter, pendingMessageFormat_ExampleViewFilter } = useStore_MessageFormat_ExampleViewFilter();
|
||||||
|
// Send
|
||||||
|
const { currentSendMessageFormatParts, updateSendMessageFormatParts, pendingSendMessageFormatParts } = useStore_SendMessageFormatParts();
|
||||||
|
// Received
|
||||||
|
const { currentReceivedMessageFormatParts, updateReceivedMessageFormatParts, pendingReceivedMessageFormatParts } = useStore_ReceivedMessageFormatParts();
|
||||||
|
|
||||||
const { showNotification_SaveSuccess } = useNotificationStatus();
|
const { showNotification_SaveSuccess } = useNotificationStatus();
|
||||||
|
|
||||||
@@ -107,6 +116,10 @@ export const useOthers = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getSuccessEnableVrcMicMuteSync = (is_enabled) => {
|
||||||
|
updateEnableVrcMicMuteSync(old => ({ ...old.data, is_enabled: is_enabled }));
|
||||||
|
};
|
||||||
|
|
||||||
const setSuccessEnableVrcMicMuteSync = (is_enabled) => {
|
const setSuccessEnableVrcMicMuteSync = (is_enabled) => {
|
||||||
updateEnableVrcMicMuteSync(old => ({ ...old.data, is_enabled: is_enabled }));
|
updateEnableVrcMicMuteSync(old => ({ ...old.data, is_enabled: is_enabled }));
|
||||||
showNotification_SaveSuccess();
|
showNotification_SaveSuccess();
|
||||||
@@ -174,6 +187,53 @@ export const useOthers = () => {
|
|||||||
showNotification_SaveSuccess();
|
showNotification_SaveSuccess();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Message Formats
|
||||||
|
// Send
|
||||||
|
const getSendMessageFormatParts = () => {
|
||||||
|
pendingSendMessageFormatParts();
|
||||||
|
asyncStdoutToPython("/get/data/send_message_format_parts");
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSendMessageFormatParts = (message_format_parts) => {
|
||||||
|
pendingSendMessageFormatParts();
|
||||||
|
asyncStdoutToPython("/set/data/send_message_format_parts", message_format_parts);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSuccessSendMessageFormatParts = (message_format_parts) => {
|
||||||
|
updateSendMessageFormatParts(message_format_parts);
|
||||||
|
showNotification_SaveSuccess();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Received
|
||||||
|
const getReceivedMessageFormatParts = () => {
|
||||||
|
pendingReceivedMessageFormatParts();
|
||||||
|
asyncStdoutToPython("/get/data/received_message_format_parts");
|
||||||
|
};
|
||||||
|
|
||||||
|
const setReceivedMessageFormatParts = (message_format_parts) => {
|
||||||
|
pendingReceivedMessageFormatParts();
|
||||||
|
asyncStdoutToPython("/set/data/received_message_format_parts", message_format_parts);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSuccessReceivedMessageFormatParts = (message_format_parts) => {
|
||||||
|
updateReceivedMessageFormatParts(message_format_parts);
|
||||||
|
showNotification_SaveSuccess();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const toggleMessageFormat_ExampleViewFilter = (id) => {
|
||||||
|
pendingMessageFormat_ExampleViewFilter();
|
||||||
|
if (["send", "received"].includes(id) === false) return console.error(`id should be small case 'send' or 'received'. got id: ${id}`);
|
||||||
|
|
||||||
|
updateMessageFormat_ExampleViewFilter({
|
||||||
|
...currentMessageFormat_ExampleViewFilter.data,
|
||||||
|
[id]: currentMessageFormat_ExampleViewFilter.data[id] === "Simplified"
|
||||||
|
? "All"
|
||||||
|
: "Simplified"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Auto Clear Message Input Box
|
// Auto Clear Message Input Box
|
||||||
currentEnableAutoClearMessageInputBox,
|
currentEnableAutoClearMessageInputBox,
|
||||||
@@ -199,6 +259,7 @@ export const useOthers = () => {
|
|||||||
// VRC Mic Mute Sync
|
// VRC Mic Mute Sync
|
||||||
currentEnableVrcMicMuteSync,
|
currentEnableVrcMicMuteSync,
|
||||||
getEnableVrcMicMuteSync,
|
getEnableVrcMicMuteSync,
|
||||||
|
getSuccessEnableVrcMicMuteSync,
|
||||||
toggleEnableVrcMicMuteSync,
|
toggleEnableVrcMicMuteSync,
|
||||||
updateEnableVrcMicMuteSync,
|
updateEnableVrcMicMuteSync,
|
||||||
setSuccessEnableVrcMicMuteSync,
|
setSuccessEnableVrcMicMuteSync,
|
||||||
@@ -225,5 +286,22 @@ export const useOthers = () => {
|
|||||||
toggleEnableSendReceivedMessageToVrc,
|
toggleEnableSendReceivedMessageToVrc,
|
||||||
updateEnableSendReceivedMessageToVrc,
|
updateEnableSendReceivedMessageToVrc,
|
||||||
setSuccessEnableSendReceivedMessageToVrc,
|
setSuccessEnableSendReceivedMessageToVrc,
|
||||||
|
|
||||||
|
// Message Formats
|
||||||
|
currentMessageFormat_ExampleViewFilter,
|
||||||
|
toggleMessageFormat_ExampleViewFilter,
|
||||||
|
// Send
|
||||||
|
currentSendMessageFormatParts,
|
||||||
|
updateSendMessageFormatParts,
|
||||||
|
getSendMessageFormatParts,
|
||||||
|
setSendMessageFormatParts,
|
||||||
|
setSuccessSendMessageFormatParts,
|
||||||
|
|
||||||
|
// Received
|
||||||
|
currentReceivedMessageFormatParts,
|
||||||
|
updateReceivedMessageFormatParts,
|
||||||
|
getReceivedMessageFormatParts,
|
||||||
|
setReceivedMessageFormatParts,
|
||||||
|
setSuccessReceivedMessageFormatParts,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -14,6 +14,11 @@ import {
|
|||||||
useStore_SelectedWhisperWeightType,
|
useStore_SelectedWhisperWeightType,
|
||||||
|
|
||||||
useStore_WhisperWeightTypeStatus,
|
useStore_WhisperWeightTypeStatus,
|
||||||
|
|
||||||
|
useStore_MicAvgLogprob,
|
||||||
|
useStore_MicNoSpeechProb,
|
||||||
|
useStore_SpeakerAvgLogprob,
|
||||||
|
useStore_SpeakerNoSpeechProb,
|
||||||
} from "@store";
|
} from "@store";
|
||||||
import { useStdoutToPython } from "@useStdoutToPython";
|
import { useStdoutToPython } from "@useStdoutToPython";
|
||||||
import { transformToIndexedArray } from "@utils";
|
import { transformToIndexedArray } from "@utils";
|
||||||
@@ -41,6 +46,13 @@ export const useTranscription = () => {
|
|||||||
const { currentSelectableWhisperComputeDeviceList, updateSelectableWhisperComputeDeviceList, pendingSelectableWhisperComputeDeviceList } = useStore_SelectableWhisperComputeDeviceList();
|
const { currentSelectableWhisperComputeDeviceList, updateSelectableWhisperComputeDeviceList, pendingSelectableWhisperComputeDeviceList } = useStore_SelectableWhisperComputeDeviceList();
|
||||||
const { currentSelectedWhisperComputeDevice, updateSelectedWhisperComputeDevice, pendingSelectedWhisperComputeDevice } = useStore_SelectedWhisperComputeDevice();
|
const { currentSelectedWhisperComputeDevice, updateSelectedWhisperComputeDevice, pendingSelectedWhisperComputeDevice } = useStore_SelectedWhisperComputeDevice();
|
||||||
|
|
||||||
|
// Advanced Settings
|
||||||
|
const { currentMicAvgLogprob, updateMicAvgLogprob, pendingMicAvgLogprob } = useStore_MicAvgLogprob();
|
||||||
|
const { currentMicNoSpeechProb, updateMicNoSpeechProb, pendingMicNoSpeechProb } = useStore_MicNoSpeechProb();
|
||||||
|
const { currentSpeakerAvgLogprob, updateSpeakerAvgLogprob, pendingSpeakerAvgLogprob } = useStore_SpeakerAvgLogprob();
|
||||||
|
const { currentSpeakerNoSpeechProb, updateSpeakerNoSpeechProb, pendingSpeakerNoSpeechProb } = useStore_SpeakerNoSpeechProb();
|
||||||
|
|
||||||
|
|
||||||
// Mic
|
// Mic
|
||||||
const getMicRecordTimeout = () => {
|
const getMicRecordTimeout = () => {
|
||||||
pendingMicRecordTimeout();
|
pendingMicRecordTimeout();
|
||||||
@@ -97,6 +109,21 @@ export const useTranscription = () => {
|
|||||||
asyncStdoutToPython("/set/data/mic_word_filter", selected_mic_word_filter);
|
asyncStdoutToPython("/set/data/mic_word_filter", selected_mic_word_filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getSuccessMicWordFilterList = (payload) => {
|
||||||
|
updateMicWordFilterList((prev_list) => {
|
||||||
|
const updated_list = [...prev_list.data];
|
||||||
|
for (const value of payload) {
|
||||||
|
const existing_item = updated_list.find(item => item.value === value);
|
||||||
|
if (existing_item) {
|
||||||
|
existing_item.is_redoable = false;
|
||||||
|
} else {
|
||||||
|
updated_list.push({ value, is_redoable: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updated_list;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const setSuccessMicWordFilterList = (payload) => {
|
const setSuccessMicWordFilterList = (payload) => {
|
||||||
updateMicWordFilterList((prev_list) => {
|
updateMicWordFilterList((prev_list) => {
|
||||||
const updated_list = [...prev_list.data];
|
const updated_list = [...prev_list.data];
|
||||||
@@ -261,6 +288,67 @@ export const useTranscription = () => {
|
|||||||
showNotification_SaveSuccess();
|
showNotification_SaveSuccess();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Advanced (Mic Avg Logprob)
|
||||||
|
const getMicAvgLogprob = () => {
|
||||||
|
pendingMicAvgLogprob();
|
||||||
|
asyncStdoutToPython("/get/data/mic_avg_logprob");
|
||||||
|
};
|
||||||
|
|
||||||
|
const setMicAvgLogprob = (selected_mic_avg_logprob) => {
|
||||||
|
pendingMicAvgLogprob();
|
||||||
|
asyncStdoutToPython("/set/data/mic_avg_logprob", selected_mic_avg_logprob);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSuccessMicAvgLogprob = (selected_mic_avg_logprob) => {
|
||||||
|
updateMicAvgLogprob(selected_mic_avg_logprob);
|
||||||
|
showNotification_SaveSuccess();
|
||||||
|
};
|
||||||
|
// Advanced (Mic No Speech Prob)
|
||||||
|
const getMicNoSpeechProb = () => {
|
||||||
|
pendingMicNoSpeechProb();
|
||||||
|
asyncStdoutToPython("/get/data/mic_no_speech_prob");
|
||||||
|
};
|
||||||
|
|
||||||
|
const setMicNoSpeechProb = (selected_mic_no_speech_prob) => {
|
||||||
|
pendingMicNoSpeechProb();
|
||||||
|
asyncStdoutToPython("/set/data/mic_no_speech_prob", selected_mic_no_speech_prob);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSuccessMicNoSpeechProb = (selected_mic_no_speech_prob) => {
|
||||||
|
updateMicNoSpeechProb(selected_mic_no_speech_prob);
|
||||||
|
showNotification_SaveSuccess();
|
||||||
|
};
|
||||||
|
// Advanced (Speaker Avg Logprob)
|
||||||
|
const getSpeakerAvgLogprob = () => {
|
||||||
|
pendingSpeakerAvgLogprob();
|
||||||
|
asyncStdoutToPython("/get/data/speaker_avg_logprob");
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSpeakerAvgLogprob = (selected_speaker_avg_logprob) => {
|
||||||
|
pendingSpeakerAvgLogprob();
|
||||||
|
asyncStdoutToPython("/set/data/speaker_avg_logprob", selected_speaker_avg_logprob);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSuccessSpeakerAvgLogprob = (selected_speaker_avg_logprob) => {
|
||||||
|
updateSpeakerAvgLogprob(selected_speaker_avg_logprob);
|
||||||
|
showNotification_SaveSuccess();
|
||||||
|
};
|
||||||
|
// Advanced (Speaker No Speech Prob)
|
||||||
|
const getSpeakerNoSpeechProb = () => {
|
||||||
|
pendingSpeakerNoSpeechProb();
|
||||||
|
asyncStdoutToPython("/get/data/speaker_no_speech_prob");
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSpeakerNoSpeechProb = (selected_speaker_no_speech_prob) => {
|
||||||
|
pendingSpeakerNoSpeechProb();
|
||||||
|
asyncStdoutToPython("/set/data/speaker_no_speech_prob", selected_speaker_no_speech_prob);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSuccessSpeakerNoSpeechProb = (selected_speaker_no_speech_prob) => {
|
||||||
|
updateSpeakerNoSpeechProb(selected_speaker_no_speech_prob);
|
||||||
|
showNotification_SaveSuccess();
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Mic
|
// Mic
|
||||||
currentMicRecordTimeout,
|
currentMicRecordTimeout,
|
||||||
@@ -283,6 +371,7 @@ export const useTranscription = () => {
|
|||||||
|
|
||||||
currentMicWordFilterList,
|
currentMicWordFilterList,
|
||||||
getMicWordFilterList,
|
getMicWordFilterList,
|
||||||
|
getSuccessMicWordFilterList,
|
||||||
updateMicWordFilterList,
|
updateMicWordFilterList,
|
||||||
setMicWordFilterList,
|
setMicWordFilterList,
|
||||||
setSuccessMicWordFilterList,
|
setSuccessMicWordFilterList,
|
||||||
@@ -337,5 +426,31 @@ export const useTranscription = () => {
|
|||||||
updateSelectedWhisperComputeDevice,
|
updateSelectedWhisperComputeDevice,
|
||||||
setSelectedWhisperComputeDevice,
|
setSelectedWhisperComputeDevice,
|
||||||
setSuccessSelectedWhisperComputeDevice,
|
setSuccessSelectedWhisperComputeDevice,
|
||||||
|
|
||||||
|
// Advanced
|
||||||
|
// Mic Avg Logprob
|
||||||
|
currentMicAvgLogprob,
|
||||||
|
getMicAvgLogprob,
|
||||||
|
updateMicAvgLogprob,
|
||||||
|
setMicAvgLogprob,
|
||||||
|
setSuccessMicAvgLogprob,
|
||||||
|
// Mic No Speech Prob
|
||||||
|
currentMicNoSpeechProb,
|
||||||
|
getMicNoSpeechProb,
|
||||||
|
updateMicNoSpeechProb,
|
||||||
|
setMicNoSpeechProb,
|
||||||
|
setSuccessMicNoSpeechProb,
|
||||||
|
// Speaker Avg Logprob
|
||||||
|
currentSpeakerAvgLogprob,
|
||||||
|
getSpeakerAvgLogprob,
|
||||||
|
updateSpeakerAvgLogprob,
|
||||||
|
setSpeakerAvgLogprob,
|
||||||
|
setSuccessSpeakerAvgLogprob,
|
||||||
|
// Speaker No Speech Prob
|
||||||
|
currentSpeakerNoSpeechProb,
|
||||||
|
getSpeakerNoSpeechProb,
|
||||||
|
updateSpeakerNoSpeechProb,
|
||||||
|
setSpeakerNoSpeechProb,
|
||||||
|
setSuccessSpeakerNoSpeechProb,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -194,7 +194,7 @@ export const ROUTE_META_LIST = [
|
|||||||
{ endpoint: "/get/data/mic_max_phrases", ns: configs, hook_name: "useTranscription", method_name: "updateMicMaxWords" },
|
{ endpoint: "/get/data/mic_max_phrases", ns: configs, hook_name: "useTranscription", method_name: "updateMicMaxWords" },
|
||||||
{ endpoint: "/set/data/mic_max_phrases", ns: configs, hook_name: "useTranscription", method_name: "setSuccessMicMaxWords" },
|
{ endpoint: "/set/data/mic_max_phrases", ns: configs, hook_name: "useTranscription", method_name: "setSuccessMicMaxWords" },
|
||||||
|
|
||||||
{ endpoint: "/get/data/mic_word_filter", ns: configs, hook_name: "useTranscription", method_name: "updateMicWordFilterList" },
|
{ endpoint: "/get/data/mic_word_filter", ns: configs, hook_name: "useTranscription", method_name: "getSuccessMicWordFilterList" },
|
||||||
{ endpoint: "/set/data/mic_word_filter", ns: configs, hook_name: "useTranscription", method_name: "setSuccessMicWordFilterList" },
|
{ endpoint: "/set/data/mic_word_filter", ns: configs, hook_name: "useTranscription", method_name: "setSuccessMicWordFilterList" },
|
||||||
|
|
||||||
// Transcription (Speaker)
|
// Transcription (Speaker)
|
||||||
@@ -224,6 +224,16 @@ export const ROUTE_META_LIST = [
|
|||||||
{ endpoint: "/get/data/selected_transcription_compute_device", ns: configs, hook_name: "useTranscription", method_name: "updateSelectedWhisperComputeDevice" },
|
{ endpoint: "/get/data/selected_transcription_compute_device", ns: configs, hook_name: "useTranscription", method_name: "updateSelectedWhisperComputeDevice" },
|
||||||
{ endpoint: "/set/data/selected_transcription_compute_device", ns: configs, hook_name: "useTranscription", method_name: "setSuccessSelectedWhisperComputeDevice" },
|
{ endpoint: "/set/data/selected_transcription_compute_device", ns: configs, hook_name: "useTranscription", method_name: "setSuccessSelectedWhisperComputeDevice" },
|
||||||
|
|
||||||
|
// Transcription (Advanced)
|
||||||
|
{ endpoint: "/get/data/mic_avg_logprob", ns: configs, hook_name: "useTranscription", method_name: "updateMicAvgLogprob" },
|
||||||
|
{ endpoint: "/set/data/mic_avg_logprob", ns: configs, hook_name: "useTranscription", method_name: "setSuccessMicAvgLogprob" },
|
||||||
|
{ endpoint: "/get/data/mic_no_speech_prob", ns: configs, hook_name: "useTranscription", method_name: "updateMicNoSpeechProb" },
|
||||||
|
{ endpoint: "/set/data/mic_no_speech_prob", ns: configs, hook_name: "useTranscription", method_name: "setSuccessMicNoSpeechProb" },
|
||||||
|
{ endpoint: "/get/data/speaker_avg_logprob", ns: configs, hook_name: "useTranscription", method_name: "updateSpeakerAvgLogprob" },
|
||||||
|
{ endpoint: "/set/data/speaker_avg_logprob", ns: configs, hook_name: "useTranscription", method_name: "setSuccessSpeakerAvgLogprob" },
|
||||||
|
{ endpoint: "/get/data/speaker_no_speech_prob", ns: configs, hook_name: "useTranscription", method_name: "updateSpeakerNoSpeechProb" },
|
||||||
|
{ endpoint: "/set/data/speaker_no_speech_prob", ns: configs, hook_name: "useTranscription", method_name: "setSuccessSpeakerNoSpeechProb" },
|
||||||
|
|
||||||
// VR
|
// VR
|
||||||
{ endpoint: "/get/data/overlay_small_log", ns: configs, hook_name: "useVr", method_name: "updateIsEnabledOverlaySmallLog" },
|
{ endpoint: "/get/data/overlay_small_log", ns: configs, hook_name: "useVr", method_name: "updateIsEnabledOverlaySmallLog" },
|
||||||
{ endpoint: "/set/enable/overlay_small_log", ns: configs, hook_name: "useVr", method_name: "setSuccessIsEnabledOverlaySmallLog" },
|
{ endpoint: "/set/enable/overlay_small_log", ns: configs, hook_name: "useVr", method_name: "setSuccessIsEnabledOverlaySmallLog" },
|
||||||
@@ -259,7 +269,7 @@ export const ROUTE_META_LIST = [
|
|||||||
{ endpoint: "/set/enable/logger_feature", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableAutoExportMessageLogs" },
|
{ endpoint: "/set/enable/logger_feature", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableAutoExportMessageLogs" },
|
||||||
{ endpoint: "/set/disable/logger_feature", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableAutoExportMessageLogs" },
|
{ endpoint: "/set/disable/logger_feature", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableAutoExportMessageLogs" },
|
||||||
|
|
||||||
{ endpoint: "/get/data/vrc_mic_mute_sync", ns: configs, hook_name: "useOthers", method_name: "updateEnableVrcMicMuteSync_FromBackend" },
|
{ endpoint: "/get/data/vrc_mic_mute_sync", ns: configs, hook_name: "useOthers", method_name: "getSuccessEnableVrcMicMuteSync" },
|
||||||
{ endpoint: "/set/enable/vrc_mic_mute_sync", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableVrcMicMuteSync" },
|
{ endpoint: "/set/enable/vrc_mic_mute_sync", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableVrcMicMuteSync" },
|
||||||
{ endpoint: "/set/disable/vrc_mic_mute_sync", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableVrcMicMuteSync" },
|
{ endpoint: "/set/disable/vrc_mic_mute_sync", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableVrcMicMuteSync" },
|
||||||
|
|
||||||
@@ -275,6 +285,12 @@ export const ROUTE_META_LIST = [
|
|||||||
{ endpoint: "/get/data/notification_vrc_sfx", ns: configs, hook_name: "useOthers", method_name: "updateEnableNotificationVrcSfx" },
|
{ endpoint: "/get/data/notification_vrc_sfx", ns: configs, hook_name: "useOthers", method_name: "updateEnableNotificationVrcSfx" },
|
||||||
{ endpoint: "/set/enable/notification_vrc_sfx", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableNotificationVrcSfx" },
|
{ endpoint: "/set/enable/notification_vrc_sfx", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableNotificationVrcSfx" },
|
||||||
{ endpoint: "/set/disable/notification_vrc_sfx", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableNotificationVrcSfx" },
|
{ endpoint: "/set/disable/notification_vrc_sfx", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableNotificationVrcSfx" },
|
||||||
|
{ endpoint: "/set/disable/notification_vrc_sfx", ns: configs, hook_name: "useOthers", method_name: "setSuccessEnableNotificationVrcSfx" },
|
||||||
|
|
||||||
|
{ endpoint: "/get/data/send_message_format_parts", ns: configs, hook_name: "useOthers", method_name: "updateSendMessageFormatParts" },
|
||||||
|
{ endpoint: "/set/data/send_message_format_parts", ns: configs, hook_name: "useOthers", method_name: "setSuccessSendMessageFormatParts" },
|
||||||
|
{ endpoint: "/get/data/received_message_format_parts", ns: configs, hook_name: "useOthers", method_name: "updateReceivedMessageFormatParts" },
|
||||||
|
{ endpoint: "/set/data/received_message_format_parts", ns: configs, hook_name: "useOthers", method_name: "setSuccessReceivedMessageFormatParts" },
|
||||||
|
|
||||||
// Hotkeys
|
// Hotkeys
|
||||||
{ endpoint: "/get/data/hotkeys", ns: configs, hook_name: "useHotkeys", method_name: "updateHotkeys" },
|
{ endpoint: "/get/data/hotkeys", ns: configs, hook_name: "useHotkeys", method_name: "updateHotkeys" },
|
||||||
@@ -334,6 +350,9 @@ export const useReceiveRoutes = () => {
|
|||||||
ROUTE_META_LIST.map(({ endpoint, hook_name, method_name }) => {
|
ROUTE_META_LIST.map(({ endpoint, hook_name, method_name }) => {
|
||||||
const result_obj = hook_results[hook_name] || {};
|
const result_obj = hook_results[hook_name] || {};
|
||||||
const fn = result_obj[method_name];
|
const fn = result_obj[method_name];
|
||||||
|
if (fn === undefined && method_name !== null) {
|
||||||
|
console.error("Method not found.", {endpoint, hook_name, method_name, result_obj, fn});
|
||||||
|
}
|
||||||
return [endpoint, typeof fn === "function" ? fn : noop];
|
return [endpoint, typeof fn === "function" ? fn : noop];
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -238,6 +238,11 @@ export const { atomInstance: Atom_SelectedTranscriptionEngine, useHook: useStore
|
|||||||
export const { atomInstance: Atom_SelectableWhisperComputeDeviceList, useHook: useStore_SelectableWhisperComputeDeviceList } = createAtomWithHook({}, "SelectableWhisperComputeDeviceList");
|
export const { atomInstance: Atom_SelectableWhisperComputeDeviceList, useHook: useStore_SelectableWhisperComputeDeviceList } = createAtomWithHook({}, "SelectableWhisperComputeDeviceList");
|
||||||
export const { atomInstance: Atom_SelectedWhisperComputeDevice, useHook: useStore_SelectedWhisperComputeDevice } = createAtomWithHook("", "SelectedWhisperComputeDevice");
|
export const { atomInstance: Atom_SelectedWhisperComputeDevice, useHook: useStore_SelectedWhisperComputeDevice } = createAtomWithHook("", "SelectedWhisperComputeDevice");
|
||||||
|
|
||||||
|
export const { atomInstance: Atom_MicAvgLogprob, useHook: useStore_MicAvgLogprob } = createAtomWithHook(-0.8, "MicAvgLogprob");
|
||||||
|
export const { atomInstance: Atom_MicNoSpeechProb, useHook: useStore_MicNoSpeechProb } = createAtomWithHook(0.6, "MicNoSpeechProb");
|
||||||
|
export const { atomInstance: Atom_SpeakerAvgLogprob, useHook: useStore_SpeakerAvgLogprob } = createAtomWithHook(-0.8, "SpeakerAvgLogprob");
|
||||||
|
export const { atomInstance: Atom_SpeakerNoSpeechProb, useHook: useStore_SpeakerNoSpeechProb } = createAtomWithHook(0.6, "SpeakerNoSpeechProb");
|
||||||
|
|
||||||
|
|
||||||
// VR
|
// VR
|
||||||
export const { atomInstance: Atom_OverlaySmallLogSettings, useHook: useStore_OverlaySmallLogSettings } = createAtomWithHook({
|
export const { atomInstance: Atom_OverlaySmallLogSettings, useHook: useStore_OverlaySmallLogSettings } = createAtomWithHook({
|
||||||
@@ -274,6 +279,37 @@ export const { atomInstance: Atom_EnableVrcMicMuteSync, useHook: useStore_Enable
|
|||||||
export const { atomInstance: Atom_EnableSendMessageToVrc, useHook: useStore_EnableSendMessageToVrc } = createAtomWithHook(true, "EnableSendMessageToVrc");
|
export const { atomInstance: Atom_EnableSendMessageToVrc, useHook: useStore_EnableSendMessageToVrc } = createAtomWithHook(true, "EnableSendMessageToVrc");
|
||||||
export const { atomInstance: Atom_EnableSendReceivedMessageToVrc, useHook: useStore_EnableSendReceivedMessageToVrc } = createAtomWithHook(false, "EnableSendReceivedMessageToVrc");
|
export const { atomInstance: Atom_EnableSendReceivedMessageToVrc, useHook: useStore_EnableSendReceivedMessageToVrc } = createAtomWithHook(false, "EnableSendReceivedMessageToVrc");
|
||||||
export const { atomInstance: Atom_EnableNotificationVrcSfx, useHook: useStore_EnableNotificationVrcSfx } = createAtomWithHook(true, "EnableNotificationVrcSfx");
|
export const { atomInstance: Atom_EnableNotificationVrcSfx, useHook: useStore_EnableNotificationVrcSfx } = createAtomWithHook(true, "EnableNotificationVrcSfx");
|
||||||
|
export const { atomInstance: Atom_MessageFormat_ExampleViewFilter, useHook: useStore_MessageFormat_ExampleViewFilter } = createAtomWithHook({
|
||||||
|
send: "Simplified",
|
||||||
|
received: "Simplified",
|
||||||
|
}, "MessageFormat_ExampleViewFilter");
|
||||||
|
export const { atomInstance: Atom_SendMessageFormatParts, useHook: useStore_SendMessageFormatParts } = createAtomWithHook({
|
||||||
|
message: {
|
||||||
|
prefix: "",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
separator: "\n",
|
||||||
|
translation: {
|
||||||
|
prefix: "",
|
||||||
|
separator: "\n",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
translation_first: false,
|
||||||
|
}, "SendMessageFormatParts");
|
||||||
|
export const { atomInstance: Atom_ReceivedMessageFormatParts, useHook: useStore_ReceivedMessageFormatParts } = createAtomWithHook({
|
||||||
|
message: {
|
||||||
|
prefix: "",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
separator: "\n",
|
||||||
|
translation: {
|
||||||
|
prefix: "",
|
||||||
|
separator: "\n",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
translation_first: false,
|
||||||
|
}, "ReceivedMessageFormatParts");
|
||||||
|
|
||||||
|
|
||||||
// Hotkeys
|
// Hotkeys
|
||||||
export const { atomInstance: Atom_Hotkeys, useHook: useStore_Hotkeys } = createAtomWithHook({
|
export const { atomInstance: Atom_Hotkeys, useHook: useStore_Hotkeys } = createAtomWithHook({
|
||||||
|
|||||||
@@ -49,6 +49,33 @@ export const ui_configs = {
|
|||||||
tracker: "LeftHand",
|
tracker: "LeftHand",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
send_message_format_parts: {
|
||||||
|
message: {
|
||||||
|
prefix: "",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
separator: "\n",
|
||||||
|
translation: {
|
||||||
|
prefix: "",
|
||||||
|
separator: "\n",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
translation_first: false,
|
||||||
|
},
|
||||||
|
received_message_format_parts: {
|
||||||
|
message: {
|
||||||
|
prefix: "",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
separator: "\n",
|
||||||
|
translation: {
|
||||||
|
prefix: "",
|
||||||
|
separator: "\n",
|
||||||
|
suffix: ""
|
||||||
|
},
|
||||||
|
translation_first: false,
|
||||||
|
},
|
||||||
|
|
||||||
selectable_ui_languages: [
|
selectable_ui_languages: [
|
||||||
{id: "en", label: "English"},
|
{id: "en", label: "English"},
|
||||||
{id: "ja", label: "日本語"},
|
{id: "ja", label: "日本語"},
|
||||||
|
|||||||
Reference in New Issue
Block a user