diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index cc1700ef..a9178174 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,13 +1,13 @@ # These are supported funding model platforms github: [misyaguziya] -patreon: # Replace with a single Patreon username +patreon: vrct_dev open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username +ko_fi: vrct_dev tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry polar: # Replace with a single Polar username -custom: ["https://misyaguziya.booth.pm/", "https://vrct-dev.fanbox.cc/"] +custom: ["https://misyaguziya.booth.pm", "https://vrct-dev.fanbox.cc"] diff --git a/README.ja.md b/README.ja.md index 018f5ead..1d7a8c2a 100644 --- a/README.ja.md +++ b/README.ja.md @@ -1,12 +1,56 @@
-![](docs/vrct_logo.png) + + + + VRCT Logo + + +
+
+ [![GitHub release](https://img.shields.io/github/v/release/misyaguziya/VRCT.svg)](https://github.com/misyaguziya/VRCT/releases) [![Downloads](https://img.shields.io/github/downloads/misyaguziya/VRCT/total)](https://github.com/misyaguziya/VRCT/releases) -[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) +[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) [![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325) [![Github Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-30363D?&logo=GitHub-Sponsors&logoColor=EA4AAA)](https://github.com/sponsors/misyaguziya) -[![PIXIV FANBOX](https://img.shields.io/badge/PIXIV%20FANBOX-30363D?)](https://vrct-dev.fanbox.cc/) + +

+Become a VRCT Supporter on: +

+ + + + + + PIXIV FANBOX + +   + + + + + + Patreon + +   + + + + Ko-fi + +   + +
+ + + + + Supporter Section Border + + +
+
| [English](./README.md) | **日本語** | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) | diff --git a/README.ko.md b/README.ko.md index 824a4c4c..cffa325c 100644 --- a/README.ko.md +++ b/README.ko.md @@ -1,14 +1,58 @@
-![](docs/vrct_logo.png) + + + + VRCT Logo + + +
+
+ [![GitHub release](https://img.shields.io/github/v/release/misyaguziya/VRCT.svg)](https://github.com/misyaguziya/VRCT/releases) [![Downloads](https://img.shields.io/github/downloads/misyaguziya/VRCT/total)](https://github.com/misyaguziya/VRCT/releases) -[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) +[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) [![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325) [![Github Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-30363D?&logo=GitHub-Sponsors&logoColor=EA4AAA)](https://github.com/sponsors/misyaguziya) -[![PIXIV FANBOX](https://img.shields.io/badge/PIXIV%20FANBOX-30363D?)](https://vrct-dev.fanbox.cc/) -| [English](./README.md) | [日本語](./README.ja.md) | **한국어** | +

+Become a VRCT Supporter on: +

+ + + + + + PIXIV FANBOX + +   + + + + + + Patreon + +   + + + + Ko-fi + +   + +
+ + + + + Supporter Section Border + + +
+
+ +| [English](./README.md) | [日本語](./README.ja.md) | **한국어** | [繁體中文](./README.zh-Hant.md) |

VRCT는 음성인식 및 번역 기능을 통해 VRChat의 대화를 지원하는 소프트웨어입니다. diff --git a/README.md b/README.md index 93a7fa5a..13c563a6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,56 @@
-![](docs/vrct_logo.png) + + + + VRCT Logo + + +
+
+ [![GitHub release](https://img.shields.io/github/v/release/misyaguziya/VRCT.svg)](https://github.com/misyaguziya/VRCT/releases) [![Downloads](https://img.shields.io/github/downloads/misyaguziya/VRCT/total)](https://github.com/misyaguziya/VRCT/releases) -[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) +[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) [![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325) [![Github Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-30363D?&logo=GitHub-Sponsors&logoColor=EA4AAA)](https://github.com/sponsors/misyaguziya) -[![PIXIV FANBOX](https://img.shields.io/badge/PIXIV%20FANBOX-30363D?)](https://vrct-dev.fanbox.cc/) + +

+Become a VRCT Supporter on: +

+ + + + + + PIXIV FANBOX + +   + + + + + + Patreon + +   + + + + Ko-fi + +   + +
+ + + + + Supporter Section Border + + +
+
| **English** | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) | diff --git a/README.zh-Hant.md b/README.zh-Hant.md index 4cf5bb36..ea79a1b1 100644 --- a/README.zh-Hant.md +++ b/README.zh-Hant.md @@ -1,12 +1,56 @@
-![](docs/vrct_logo.png) + + + + VRCT Logo + + +
+
+ [![GitHub release](https://img.shields.io/github/v/release/misyaguziya/VRCT.svg)](https://github.com/misyaguziya/VRCT/releases) [![Downloads](https://img.shields.io/github/downloads/misyaguziya/VRCT/total)](https://github.com/misyaguziya/VRCT/releases) -[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) +[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) [![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325) [![Github Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-30363D?&logo=GitHub-Sponsors&logoColor=EA4AAA)](https://github.com/sponsors/misyaguziya) -[![PIXIV FANBOX](https://img.shields.io/badge/PIXIV%20FANBOX-30363D?)](https://vrct-dev.fanbox.cc/) + +

+Become a VRCT Supporter on: +

+ + + + + + PIXIV FANBOX + +   + + + + + + Patreon + +   + + + + Ko-fi + +   + +
+ + + + + Supporter Section Border + + +
+
| [English](./README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | **繁體中文** | diff --git a/docs/kofi_logo.png b/docs/kofi_logo.png new file mode 100644 index 00000000..a5bccdc1 Binary files /dev/null and b/docs/kofi_logo.png differ diff --git a/docs/patreon_logo_black.png b/docs/patreon_logo_black.png new file mode 100644 index 00000000..26ecd6b7 Binary files /dev/null and b/docs/patreon_logo_black.png differ diff --git a/docs/patreon_logo_white.png b/docs/patreon_logo_white.png new file mode 100644 index 00000000..ba7e83c7 Binary files /dev/null and b/docs/patreon_logo_white.png differ diff --git a/docs/pixiv_fanbox_black.png b/docs/pixiv_fanbox_black.png new file mode 100644 index 00000000..fa187faf Binary files /dev/null and b/docs/pixiv_fanbox_black.png differ diff --git a/docs/pixiv_fanbox_white.png b/docs/pixiv_fanbox_white.png new file mode 100644 index 00000000..890ecb96 Binary files /dev/null and b/docs/pixiv_fanbox_white.png differ diff --git a/docs/supporter_section_border_d.png b/docs/supporter_section_border_d.png new file mode 100644 index 00000000..04ab2391 Binary files /dev/null and b/docs/supporter_section_border_d.png differ diff --git a/docs/supporter_section_border_l.png b/docs/supporter_section_border_l.png new file mode 100644 index 00000000..78e8fc79 Binary files /dev/null and b/docs/supporter_section_border_l.png differ diff --git a/docs/vrct_logo_black.png b/docs/vrct_logo_black.png new file mode 100644 index 00000000..7868b38b Binary files /dev/null and b/docs/vrct_logo_black.png differ diff --git a/docs/vrct_logo_white.png b/docs/vrct_logo_white.png new file mode 100644 index 00000000..e3258fb9 Binary files /dev/null and b/docs/vrct_logo_white.png differ diff --git a/locales/en.yml b/locales/en.yml index 85d51180..73ba1ed0 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -1,268 +1,279 @@ -# ================================= -# IMPORTANT: -# Please read 'readme_first.txt' before making any changes. -# ================================= - -common: - go_back_button_label: Go Back - -main_page: - translation: Translation - transcription_send: Voice2Chatbox - transcription_receive: Speaker2Log - foreground: Foreground - language_settings: Language Settings - your_language: Your Language - translate_each_other_label: Translate Each Other - swap_button_label: Swap Languages - target_language: Target Language - translator: Translator - translator_ctranslate2: Internal (Default) - - translator_selector: - is_selected_same_language: |- - Since the same language is selected for both '{{your_language}}' and '{{target_language}}', only '{{translator_ctranslate2}}' is available. - - message_log: - all: All - sent: Sent - received: Received - system: System - - show_resend_button: Show Resend Button - resend_button_on_hover_desc: Press and hold to send - - # textbox_system_message: - # enabled_easter_egg: Whoa! You caught us! There is something...like...easter-egg-ish function has enabled! It'll affect to Overlay(VR) for now;). - # enabled_translation: Translation feature is turned on. - # disabled_translation: Translation feature is turned off. - # enabled_voice2chatbox: Transcription from the microphone has started. - # disabled_voice2chatbox: Transcription from the microphone has been stopped. - # enabled_speaker2log: Transcription from the speaker has started. - # disabled_speaker2log: Transcription from the speaker has been stopped. - # enabled_foreground: The screen is fixed in the foreground. - # disabled_foreground: The foreground fixation has been released. - # auth_key_success: Auth key update completed. - # auth_key_error: Auth Key is incorrect or Usage limit reached. - # no_mic_device_detected_error: No mic device detected. - # no_speaker_device_detected_error: No speaker device detected. - # translation_engine_limit_error: It has automatically changed the translation engine. Access has been temporarily restricted due to an excessive number of requests to the translation engine. If you want to use the same translation engine, please wait for a while, restart VRCT, and try again. - # detected_by_word_filter: The word {{detected_message}} has not been sent due to detection by the word filter. - # selected_your_language: '"Your Language" has set to {{your_language}}.' - # selected_target_language: '"Target Language" has set to {{target_language}}.' - # switched_language_preset_tab: Switched to Language Preset Tab No.{{tab_no}}." - # latest_language_setting: Currently, "Your Language" is set to {{your_language}}, and "Target Language" is set to {{target_language}}. - # opened_web_page_booth: Opened Booth page in your web browser. - # opened_web_page_vrct_documents: |- - # Opened VRCT Documents page in your web browser. - # For any issues, requests, or inquiries, please feel free to contact us through the links at the bottom of the documents page, the "Contact Form," or via X (formerly Twitter)! - - state_text_enabled: Enabled - state_text_disabled: Disabled - - language_selector: - title_your_language: Select Your Language - title_target_language: Select Target Language - - update_available: New version is here! - updating: Now updating... - -update_modal: - cpu_desc: Use CPU only as the compute device. - cuda_desc: Selectable between CPU and NVIDIA GPUs as compute devices. - cuda_compare_cpu_desc: With GPU selection, processing is faster compared to a CPU. - cuda_disk_space_desc: Requires approximately {{size}} of disk space. - close_modal: Close - download_latest_and_restart: |- - The latest version will be downloaded, - and the app will automatically restart. - is_latest_version_already: Already using the latest version - is_current_compute_device: Currently using this version - -config_page: - version: version {{version}} - # config_title: Settings - # compact_mode: Compact Mode - # restart_message: Apply changes with a restart. - # common_error_message: - # invalid_value: Invalid value. - model_download_button_label: Download - side_menu_labels: - device: Device - appearance: Appearance - translation: Translation - transcription: Transcription - vr: VR - others: Others - advanced_settings: Advanced Settings - supporters: Supporters - about_vrct: About VRCT - - device: - check_volume: Check Volume - mic_host_device: - label: Mic Device - label_auto_select: Auto Select - label_host: Host/Driver - label_device: Device - mic_dynamic_energy_threshold: - label_for_automatic: 'Mic Energy Threshold (Current Setting: Automatic)' - desc_for_automatic: Automatically determine microphone input sensitivity. - label_for_manual: 'Mic Energy Threshold (Current Setting: Manual)' - desc_for_manual: Manually determine the microphone input sensitivity using the slider. Press the microphone icon to input your voice and adjust the sensitivity while monitoring the volume. - error_message: You can set it with a value between 0 to {{max}}. - speaker_device: - label: Speaker Device - label_auto_select: Auto Select - label_device: Device - speaker_dynamic_energy_threshold: - label_for_automatic: 'Speaker Energy Threshold (Current Setting: Automatic)' - desc_for_automatic: Automatically determine speaker input sensitivity. - label_for_manual: 'Speaker Energy Threshold (Current Setting: Manual)' - desc_for_manual: Manually determine the speaker input sensitivity using the slider. Press the headphones icon to listen to the audio and adjust the sensitivity while monitoring the volume. - error_message: You can set it with a value between 0 to {{max}}. - no_device_error_message: No speaker device detected. - - appearance: - transparency: - label: Transparency - desc: Change the main window's transparency. - ui_size: - label: UI Size - textbox_ui_size: - label: Message Logs Font Size - desc: You can adjust the font size used in the logs relative to the UI size. - send_message_button_type: - label: Send Message Button - hide: Hide (Use enter key to send) - show: Show - show_and_disable_enter_key: Show and disable to send when pressed enter key - font_family: - label: Font Family - ui_language: - label: UI Language - - translation: - ctranslate2_weight_type: - label: Internal Translation Model - desc: You can choose the translation model to use for the internal translation engine. - small: Basic model ({{capacity}}) - large: High accuracy model ({{capacity}}) - ctranslate2_compute_device: - label: Internal Translation Compute Device - deepl_auth_key: - label: DeepL Auth Key - desc: Please select {{translator}} on the main screen with DeepL_API when using. ※Some languages may not be supported. - save: Save - edit: Edit - open_auth_key_webpage: Open DeepL Account Webpage - auth_key_success: Auth key update completed. - auth_key_error: Auth Key is incorrect or Usage limit reached. - - transcription: - section_label_mic: Mic - section_label_speaker: Speaker - section_label_transcription_engines: Transcription Engines - mic_record_timeout: - label: Mic Record Timeout - desc: Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s)) - error_message: It cannot be greater than '{{mic_phrase_timeout_label}}' with a value of 0 or more. - mic_phrase_timeout: - label: Mic Phrase Timeout - desc: Transcription processing is performed at intervals of the specified number of seconds. - error_message: It cannot be set lower than '{{mic_record_timeout_label}}' with a value of 0 or more. - mic_max_phrase: - label: Mic Max Words - desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs and send to VRChat. - error_message: You can set a number equal to or greater than 0. - mic_word_filter: - label: Mic Word Filter - desc: |- - If a registered word is detected, the text will not be sent. To add multiple words at once, separate them with a "," (comma). - *Duplicate words will not be registered. - add_button_label: Add - count_desc: 'Current registered word count: {{count}}' - speaker_record_timeout: - label: Speaker Record Timeout - desc: Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s)) - error_message: It cannot be greater than '{{speaker_phrase_timeout_label}}' with a value of 0 or more. - speaker_phrase_timeout: - label: Speaker Phrase Timeout - desc: Transcription processing is performed at intervals of the specified number of seconds. - error_message: It cannot be set lower than '{{speaker_record_timeout_label}}' with a value of 0 or more. - speaker_max_phrase: - label: Speaker Max Words - desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs. - error_message: You can set a number equal to or greater than 0. - select_transcription_engine: - label: Transcription Engine - whisper_weight_type: - label: Whisper Model - desc: |- - Larger models tend to have higher accuracy, but they also consume more CPU or GPU resources. - Especially for models larger than medium, it may be difficult or even impossible to use them depending on the performance of your CPU/GPU. - model_template: '{{model_name}} model ({{capacity}})' - recommended_model_template: '{{model_name}} model ({{capacity}}) (Recommended)' - whisper_compute_device: - label: Whisper Compute Device - - vr: - single_line: Single line - multi_lines: Multi lines - overlay_enable: Enable - restore_default_settings: Restore Default Settings - position: Position - rotation: Rotation - x_position: X-axis (left-right) - y_position: Y-axis (up-down) - z_position: Z-axis (front-back) - x_rotation: X-axis rotation - y_rotation: Y-axis rotation - z_rotation: Z-axis rotation - sample_text_button: - start: |- - Send sample texts - to Overlay - stop: Stop Sending - sample_text: Sample text. - opacity: Opacity - ui_scaling: UI Scaling - display_duration: Display duration - fadeout_duration: Fadeout duration - tracker: Tracker - hmd: HMD - left_hand: Left hand - right_hand: Right hand - common_settings: Common Settings - overlay_show_only_translated_messages: - label: Show Only Translated Messages - - others: - auto_clear_the_message_box: - label: Auto Clear The Message Box - send_only_translated_messages: - label: Send Only Translated Messages - auto_export_message_logs: - label: Auto Export Message Logs - desc: Automatically export the conversation messages as a text file. - vrc_mic_mute_sync: - label: VRC Mic Mute Sync - desc: |- - VRCT will not send the message to VRChat while VRChat's mic is muted. - *There is a bit latency and Push-To-Talk is not supported. - send_message_to_vrc: - label: Send Message To VRChat - desc: There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat. - send_received_message_to_vrc: - label: Send Received Message To VRChat - desc: Send the message you received from the speaker's sound to VRChat's chatbox. - - advanced_settings: - osc_ip_address: - label: OSC IP Address - osc_port: - label: OSC Port - open_config_filepath: - label: Open Config File - switch_compute_device: +# ================================= +# IMPORTANT: +# Please read 'readme_first.txt' before making any changes. +# ================================= + +common: + go_back_button_label: Go Back + +main_page: + translation: Translation + transcription_send: Voice2Chatbox + transcription_receive: Speaker2Log + foreground: Foreground + language_settings: Language Settings + your_language: Your Language + translate_each_other_label: Translate Each Other + swap_button_label: Swap Languages + target_language: Target Language + translator: Translator + translator_ctranslate2: Internal (Default) + + translator_selector: + is_selected_same_language: |- + Since the same language is selected for both '{{your_language}}' and '{{target_language}}', only '{{translator_ctranslate2}}' is available. + + message_log: + all: All + sent: Sent + received: Received + system: System + + show_resend_button: Show Resend Button + resend_button_on_hover_desc: Press and hold to send + + # textbox_system_message: + # enabled_easter_egg: Whoa! You caught us! There is something...like...easter-egg-ish function has enabled! It'll affect to Overlay(VR) for now;). + # enabled_translation: Translation feature is turned on. + # disabled_translation: Translation feature is turned off. + # enabled_voice2chatbox: Transcription from the microphone has started. + # disabled_voice2chatbox: Transcription from the microphone has been stopped. + # enabled_speaker2log: Transcription from the speaker has started. + # disabled_speaker2log: Transcription from the speaker has been stopped. + # enabled_foreground: The screen is fixed in the foreground. + # disabled_foreground: The foreground fixation has been released. + # auth_key_success: Auth key update completed. + # auth_key_error: Auth Key is incorrect or Usage limit reached. + # no_mic_device_detected_error: No mic device detected. + # no_speaker_device_detected_error: No speaker device detected. + # translation_engine_limit_error: It has automatically changed the translation engine. Access has been temporarily restricted due to an excessive number of requests to the translation engine. If you want to use the same translation engine, please wait for a while, restart VRCT, and try again. + # detected_by_word_filter: The word {{detected_message}} has not been sent due to detection by the word filter. + # selected_your_language: '"Your Language" has set to {{your_language}}.' + # selected_target_language: '"Target Language" has set to {{target_language}}.' + # switched_language_preset_tab: Switched to Language Preset Tab No.{{tab_no}}." + # latest_language_setting: Currently, "Your Language" is set to {{your_language}}, and "Target Language" is set to {{target_language}}. + # opened_web_page_booth: Opened Booth page in your web browser. + # opened_web_page_vrct_documents: |- + # Opened VRCT Documents page in your web browser. + # For any issues, requests, or inquiries, please feel free to contact us through the links at the bottom of the documents page, the "Contact Form," or via X (formerly Twitter)! + + state_text_enabled: Enabled + state_text_disabled: Disabled + + language_selector: + title_your_language: Select Your Language + title_target_language: Select Target Language + + update_available: New version is here! + updating: Now updating... + +update_modal: + cpu_desc: Use CPU only as the compute device. + cuda_desc: Selectable between CPU and NVIDIA GPUs as compute devices. + cuda_compare_cpu_desc: With GPU selection, processing is faster compared to a CPU. + cuda_disk_space_desc: Requires approximately {{size}} of disk space. + close_modal: Close + download_latest_and_restart: |- + The latest version will be downloaded, + and the app will automatically restart. + is_latest_version_already: Already using the latest version + is_current_compute_device: Currently using this version + +config_page: + version: version {{version}} + # config_title: Settings + # compact_mode: Compact Mode + # restart_message: Apply changes with a restart. + # common_error_message: + # invalid_value: Invalid value. + model_download_button_label: Download + side_menu_labels: + device: Device + appearance: Appearance + translation: Translation + transcription: Transcription + vr: VR + others: Others + hotkeys: Hotkeys + advanced_settings: Advanced Settings + supporters: Supporters + about_vrct: About VRCT + + device: + check_volume: Check Volume + mic_host_device: + label: Mic Device + label_auto_select: Auto Select + label_host: Host/Driver + label_device: Device + mic_dynamic_energy_threshold: + label_for_automatic: 'Mic Energy Threshold (Current Setting: Automatic)' + desc_for_automatic: Automatically determine microphone input sensitivity. + label_for_manual: 'Mic Energy Threshold (Current Setting: Manual)' + desc_for_manual: Manually determine the microphone input sensitivity using the slider. Press the microphone icon to input your voice and adjust the sensitivity while monitoring the volume. + error_message: You can set it with a value between 0 to {{max}}. + speaker_device: + label: Speaker Device + label_auto_select: Auto Select + label_device: Device + speaker_dynamic_energy_threshold: + label_for_automatic: 'Speaker Energy Threshold (Current Setting: Automatic)' + desc_for_automatic: Automatically determine speaker input sensitivity. + label_for_manual: 'Speaker Energy Threshold (Current Setting: Manual)' + desc_for_manual: Manually determine the speaker input sensitivity using the slider. Press the headphones icon to listen to the audio and adjust the sensitivity while monitoring the volume. + error_message: You can set it with a value between 0 to {{max}}. + no_device_error_message: No speaker device detected. + + appearance: + transparency: + label: Transparency + desc: Change the main window's transparency. + ui_size: + label: UI Size + textbox_ui_size: + label: Message Logs Font Size + desc: You can adjust the font size used in the logs relative to the UI size. + send_message_button_type: + label: Send Message Button + hide: Hide (Use enter key to send) + show: Show + show_and_disable_enter_key: Show and disable to send when pressed enter key + font_family: + label: Font Family + ui_language: + label: UI Language + + translation: + ctranslate2_weight_type: + label: Internal Translation Model + desc: You can choose the translation model to use for the internal translation engine. + small: Basic model ({{capacity}}) + large: High accuracy model ({{capacity}}) + ctranslate2_compute_device: + label: Internal Translation Compute Device + deepl_auth_key: + label: DeepL Auth Key + desc: Please select {{translator}} on the main screen with DeepL_API when using. ※Some languages may not be supported. + save: Save + edit: Edit + open_auth_key_webpage: Open DeepL Account Webpage + auth_key_success: Auth key update completed. + auth_key_error: Auth Key is incorrect or Usage limit reached. + + transcription: + section_label_mic: Mic + section_label_speaker: Speaker + section_label_transcription_engines: Transcription Engines + mic_record_timeout: + label: Mic Record Timeout + desc: Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s)) + error_message: It cannot be greater than '{{mic_phrase_timeout_label}}' with a value of 0 or more. + mic_phrase_timeout: + label: Mic Phrase Timeout + desc: Transcription processing is performed at intervals of the specified number of seconds. + error_message: It cannot be set lower than '{{mic_record_timeout_label}}' with a value of 0 or more. + mic_max_phrase: + label: Mic Max Words + desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs and send to VRChat. + error_message: You can set a number equal to or greater than 0. + mic_word_filter: + label: Mic Word Filter + desc: |- + If a registered word is detected, the text will not be sent. To add multiple words at once, separate them with a "," (comma). + *Duplicate words will not be registered. + add_button_label: Add + count_desc: 'Current registered word count: {{count}}' + speaker_record_timeout: + label: Speaker Record Timeout + desc: Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s)) + error_message: It cannot be greater than '{{speaker_phrase_timeout_label}}' with a value of 0 or more. + speaker_phrase_timeout: + label: Speaker Phrase Timeout + desc: Transcription processing is performed at intervals of the specified number of seconds. + error_message: It cannot be set lower than '{{speaker_record_timeout_label}}' with a value of 0 or more. + speaker_max_phrase: + label: Speaker Max Words + desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs. + error_message: You can set a number equal to or greater than 0. + select_transcription_engine: + label: Transcription Engine + whisper_weight_type: + label: Whisper Model + desc: |- + Larger models tend to have higher accuracy, but they also consume more CPU or GPU resources. + Especially for models larger than medium, it may be difficult or even impossible to use them depending on the performance of your CPU/GPU. + model_template: '{{model_name}} model ({{capacity}})' + recommended_model_template: '{{model_name}} model ({{capacity}}) (Recommended)' + whisper_compute_device: + label: Whisper Compute Device + + vr: + single_line: Single line + multi_lines: Multi lines + overlay_enable: Enable + restore_default_settings: Restore Default Settings + position: Position + rotation: Rotation + x_position: X-axis (left-right) + y_position: Y-axis (up-down) + z_position: Z-axis (front-back) + x_rotation: X-axis rotation + y_rotation: Y-axis rotation + z_rotation: Z-axis rotation + sample_text_button: + start: |- + Send sample texts + to Overlay + stop: Stop Sending + sample_text: Sample text. + opacity: Opacity + ui_scaling: UI Scaling + display_duration: Display duration + fadeout_duration: Fadeout duration + tracker: Tracker + hmd: HMD + left_hand: Left hand + right_hand: Right hand + common_settings: Common Settings + overlay_show_only_translated_messages: + label: Show Only Translated Messages + + others: + auto_clear_the_message_box: + label: Auto Clear The Message Box + send_only_translated_messages: + label: Send Only Translated Messages + auto_export_message_logs: + label: Auto Export Message Logs + desc: Automatically export the conversation messages as a text file. + vrc_mic_mute_sync: + label: VRC Mic Mute Sync + desc: |- + VRCT will not send the message to VRChat while VRChat's mic is muted. + *There is a bit latency and Push-To-Talk is not supported. + send_message_to_vrc: + label: Send Message To VRChat + desc: There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat. + send_received_message_to_vrc: + label: Send Received Message To VRChat + desc: Send the message you received from the speaker's sound to VRChat's chatbox. + + hotkeys: + toggle_vrct_visibility: + label: Toggle VRCT Visibility + toggle_translation: + label: Toggle {{translation}} + toggle_transcription_send: + label: Toggle {{transcription_send}} + toggle_transcription_receive: + label: Toggle {{transcription_receive}} + + advanced_settings: + osc_ip_address: + label: OSC IP Address + osc_port: + label: OSC Port + open_config_filepath: + label: Open Config File + switch_compute_device: label: Switch VRCT to CPU/GPU Version \ No newline at end of file diff --git a/locales/ja.yml b/locales/ja.yml index c8fe0069..1218ef08 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -1,266 +1,277 @@ -# ================================= -# IMPORTANT: -# Please read 'readme_first.txt' before making any changes. -# ================================= - -common: - go_back_button_label: 戻る - -main_page: - translation: 翻訳 - transcription_send: 音声認識(マイク) - transcription_receive: 音声認識(スピーカー) - foreground: 最前面表示 - language_settings: 言語設定 - your_language: あなたの言語 - translate_each_other_label: 双方向に翻訳 - swap_button_label: 言語を入れ替え - target_language: 相手の言語 - translator: 翻訳エンジン - translator_ctranslate2: オフライン翻訳 (Default) - - translator_selector: - is_selected_same_language: |- - 「{{your_language}}」と「{{target_language}}」に同じ言語が選択がされているため、「{{translator_ctranslate2}}」のみが使用できます。 - - message_log: - all: 全て - sent: 送信 - received: 受信 - system: システム - - show_resend_button: 再送信ボタンを表示する - resend_button_on_hover_desc: 長押しで送信 - - # textbox_system_message: - # enabled_translation: 翻訳機能をONにしました。 - # disabled_translation: 翻訳機能をOFFしました。 - # enabled_voice2chatbox: マイクからの音声入力、文字起こしを開始します。 - # disabled_voice2chatbox: マイクからの音声入力、文字起こしを終了しました。 - # enabled_speaker2log: スピーカーからの音声聞き取り、文字起こしを開始します。 - # disabled_speaker2log: スピーカーからの音声聞き取り、文字起こしを終了しました。 - # enabled_foreground: 画面を常に最前面へ固定します。 - # disabled_foreground: 最前面への固定を解除しました。 - # auth_key_success: 認証キーの更新が完了しました。 - # auth_key_error: 認証キーが間違っているか、API使用制限が上限に達しています。 - # no_mic_device_detected_error: マイクデバイスが検出されませんでした。 - # no_speaker_device_detected_error: スピーカーデバイスが検出されませんでした。 - # translation_engine_limit_error: 翻訳エンジンを自動的に変更しました。対象翻訳エンジンへのリクエストが多すぎるため、一時的にアクセスが制限されています。同じ翻訳エンジンを使用したい場合はしばらく待ってから、VRCTの再起動をしてもう一度試してみてください。 - # detected_by_word_filter: ワードフィルターに登録されている単語 {{detected_message}} が検出されたため送信しませんでした。 - # selected_your_language: 「あなたの言語」 を {{your_language}} に設定しました。 - # selected_target_language: 「相手の言語」 を {{target_language}} に設定しました。 - # switched_language_preset_tab: 言語プリセット番号 {{tab_no}} に切り替わりました。 - # latest_language_setting: 現在「あなたの言語」は {{your_language}}、「相手の言語」は {{target_language}} に設定されています。 - # opened_web_page_booth: お使いのブラウザで、Boothのページを開きました。 - # opened_web_page_vrct_documents: |- - # お使いのブラウザで、VRCTのドキュメントを開きました。使用方法などはそちらに記載されています。 - # 不具合、ご要望、その他お問い合わせはドキュメント最下部にあるLinks、「お問合せフォーム」もしくはX (元Twitter) にて気軽にご連絡ください! - - state_text_enabled: 有効 - state_text_disabled: 無効 - - language_selector: - title_your_language: あなたの言語 - title_target_language: 相手の言語 - - update_available: 新しいバージョンが出ました! - updating: アップデート中... - -update_modal: - cpu_desc: 処理デバイスとしてCPUのみを使用 - cuda_desc: 処理デバイスとしてCPUとNVIDIA製のGPUを選択可能 - cuda_compare_cpu_desc: GPU選択時、CPUと比べて処理が高速 - cuda_disk_space_desc: 約{{size}}のディスク容量が必要 - close_modal: 閉じる - download_latest_and_restart: |- - 最新版がダウンロードされ、 - アプリは自動的に再起動します。 - is_latest_version_already: すでに最新版を使用中 - is_current_compute_device: 現在使用中のバージョン - -config_page: - version: バージョン {{version}} - # config_title: 設定 - # compact_mode: コンパクトモード - # restart_message: 再起動して変更を適用する。 - # common_error_message: - # invalid_value: 無効な値です。 - model_download_button_label: ダウンロード - side_menu_labels: - device: デバイス - appearance: デザイン - translation: 翻訳 - transcription: 音声認識 - others: その他 - advanced_settings: 高度な設定 - - device: - check_volume: 音量チェック - mic_host_device: - label: マイク (デバイス) - label_auto_select: 自動選択 - label_host: ホスト/ドライバー - label_device: デバイス - mic_dynamic_energy_threshold: - label_for_automatic: 'マイク入力感度の調整 (現在の設定: 自動)' - desc_for_automatic: マイクの入力感度を自動的に調節する。 - label_for_manual: 'マイク入力感度の調整 (現在の設定: 手動)' - desc_for_manual: スライダーを調整して入力感度を手動で決められます。マイクのアイコンを押すと、実際に声を入力し、音量を確認しながら調節できます。 - error_message: 0 から {{max}} までの数値で設定できます。 - speaker_device: - label: スピーカー (デバイス) - label_auto_select: 自動選択 - speaker_dynamic_energy_threshold: - label_for_automatic: 'スピーカー入力感度の調整 (現在の設定: 自動)' - desc_for_automatic: スピーカーの入力感度を自動的に調節する。 - label_for_manual: 'スピーカー入力感度の調整 (現在の設定: 手動)' - desc_for_manual: スライダーを調整して入力感度を手動で決められます。ヘッドフォンのアイコンを押すと、実際に音声を聞き取り、音量を確認しながら調節できます。 - error_message: 0 から {{max}} までの数値で設定できます。 - no_device_error_message: スピーカーデバイスが検出されませんでした。 - - appearance: - transparency: - label: 透明度 - desc: メイン画面の透明度を変更できます。 - ui_size: - label: UIサイズ - textbox_ui_size: - label: ログのフォントサイズ - desc: ログに表示されるフォントのサイズを、UIサイズを基準にして倍率を変えられます。 - send_message_button_type: - label: メッセージ送信ボタン - hide: 非表示 (エンターキーを使って送信) - show: 表示 - show_and_disable_enter_key: 表示し、エンターキーでの送信を無効 - font_family: - label: 使用フォント - ui_language: - label: UIの言語 - - translation: - ctranslate2_weight_type: - label: オフライン翻訳のタイプ - desc: 翻訳エンジン(オフライン翻訳)で翻訳する際に、使用する翻訳モデルを選択できます。 - small: 通常モデル ({{capacity}}) - large: 高精度モデル ({{capacity}}) - ctranslate2_compute_device: - label: オフライン翻訳の処理デバイス - deepl_auth_key: - label: DeepL 認証キー - desc: |- - 使用の際は、メイン画面にある {{translator}} をDeepL_APIに変更してください。 - ※対応していない言語もあります。 - open_auth_key_webpage: DeepLアカウントページを開く - save: 保存 - edit: 編集 - auth_key_success: 認証キーの更新が完了しました。 - auth_key_error: 認証キーが間違っているか、API使用制限が上限に達しています。 - - transcription: - section_label_mic: マイク - section_label_speaker: スピーカー - section_label_transcription_engines: 音声認識エンジン - mic_record_timeout: - label: 入力が終了したとみなす無音時間 - desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。 - error_message: 0 以上で 「{{mic_phrase_timeout_label}}」より大きくすることはできません。 - mic_phrase_timeout: - label: 一度に文字起こしする時間の長さ - desc: 設定された秒数ごとに文字起こし処理が行われます。 - error_message: 0 以上で 「{{mic_record_timeout_label}}」より小さくすることはできません。 - mic_max_phrase: - label: 送信するまでに保持する単語数 - desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をVRChatへ送信し、ログに表示します。 - error_message: 0以上の数値を設定できます。 - mic_word_filter: - label: ワードフィルター - desc: |- - 登録された単語を検出すると、その文章は送信されません。 - 「,」カンマで区切ると、まとめて複数の単語を追加できます。 - ※重複した単語は登録されません。 - add_button_label: 追加 - count_desc: '現在登録されている単語数: {{count}}' - speaker_record_timeout: - label: 入力が終了したとみなす無音時間 - desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。 - error_message: 0 以上で 「{{speaker_phrase_timeout_label}}」より大きくすることはできません。 - speaker_phrase_timeout: - label: 一度に文字起こしする時間の長さ - desc: 設定された秒数ごとに文字起こし処理が行われます。 - error_message: 0 以上で 「{{speaker_record_timeout_label}}」より小さくすることはできません。 - speaker_max_phrase: - label: ログとして表示するまでに保持する単語数 - desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をログに表示します。 - error_message: 0以上の数値を設定できます。 - select_transcription_engine: - label: 音声認識で使用するエンジン - whisper_weight_type: - label: Whisperモデルのタイプ - desc: |- - 容量が大きいモデルほど精度は高いですが、その分CPUやGPUを占有します。 - ※特にmediumより容量の大きいモデルは、CPU/GPUの性能によっては使用すらも困難です。 - model_template: '{{model_name}} モデル ({{capacity}})' - recommended_model_template: '{{model_name}} モデル ({{capacity}}) (推奨)' - whisper_compute_device: - label: Whisperで使用する処理デバイス - - vr: - single_line: 一行 - multi_lines: 複数行 - overlay_enable: 有効にする - restore_default_settings: 初期値に戻す - position: 位置 - rotation: 回転 - x_position: X軸(左右) - y_position: Y軸(上下) - z_position: Z軸(前後) - x_rotation: X軸の回転 - y_rotation: Y軸の回転 - z_rotation: Z軸の回転 - sample_text_button: - start: |- - サンプルテキストを - Overlayに送信する - stop: 送信を停止 - sample_text: サンプルテキスト - opacity: 透明度 - ui_scaling: サイズ - display_duration: 表示時間 - fadeout_duration: フェードアウト時間 - common_settings: 共通設定 - hmd: HMD - left_hand: 左手 - right_hand: 右手 - tracker: 表示するトラッカーの位置 - overlay_show_only_translated_messages: - label: 翻訳後のメッセージのみ表示する - - others: - auto_clear_the_message_box: - label: 送信後はチャットボックスを空にする - send_only_translated_messages: - label: 翻訳後のメッセージのみ送信する - auto_export_message_logs: - label: 会話ログを自動的に保存する - desc: テキストファイルとしてログがlogsフォルダ内に保存されます。 - vrc_mic_mute_sync: - label: VRCマイクミュート同期 - desc: |- - VRChatのマイクがミュートされている間は、メッセージをVRChatに送信しません。 - ※若干の遅延はあります。また、Push-To-Talkは非対応です。 - send_message_to_vrc: - label: VRChatにメッセージを送信する - desc: サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。 - send_received_message_to_vrc: - label: 受信したメッセージをVRChatに送信する - desc: スピーカーから聞き取り、文字起こしされたメッセージをVRChatに送信します。 - - advanced_settings: - osc_ip_address: - label: OSC IP Address - osc_port: - label: OSC Port - open_config_filepath: - label: 設定ファイルを開く - switch_compute_device: +# ================================= +# IMPORTANT: +# Please read 'readme_first.txt' before making any changes. +# ================================= + +common: + go_back_button_label: 戻る + +main_page: + translation: 翻訳 + transcription_send: 音声認識(マイク) + transcription_receive: 音声認識(スピーカー) + foreground: 最前面表示 + language_settings: 言語設定 + your_language: あなたの言語 + translate_each_other_label: 双方向に翻訳 + swap_button_label: 言語を入れ替え + target_language: 相手の言語 + translator: 翻訳エンジン + translator_ctranslate2: オフライン翻訳 (Default) + + translator_selector: + is_selected_same_language: |- + 「{{your_language}}」と「{{target_language}}」に同じ言語が選択がされているため、「{{translator_ctranslate2}}」のみが使用できます。 + + message_log: + all: 全て + sent: 送信 + received: 受信 + system: システム + + show_resend_button: 再送信ボタンを表示する + resend_button_on_hover_desc: 長押しで送信 + + # textbox_system_message: + # enabled_translation: 翻訳機能をONにしました。 + # disabled_translation: 翻訳機能をOFFしました。 + # enabled_voice2chatbox: マイクからの音声入力、文字起こしを開始します。 + # disabled_voice2chatbox: マイクからの音声入力、文字起こしを終了しました。 + # enabled_speaker2log: スピーカーからの音声聞き取り、文字起こしを開始します。 + # disabled_speaker2log: スピーカーからの音声聞き取り、文字起こしを終了しました。 + # enabled_foreground: 画面を常に最前面へ固定します。 + # disabled_foreground: 最前面への固定を解除しました。 + # auth_key_success: 認証キーの更新が完了しました。 + # auth_key_error: 認証キーが間違っているか、API使用制限が上限に達しています。 + # no_mic_device_detected_error: マイクデバイスが検出されませんでした。 + # no_speaker_device_detected_error: スピーカーデバイスが検出されませんでした。 + # translation_engine_limit_error: 翻訳エンジンを自動的に変更しました。対象翻訳エンジンへのリクエストが多すぎるため、一時的にアクセスが制限されています。同じ翻訳エンジンを使用したい場合はしばらく待ってから、VRCTの再起動をしてもう一度試してみてください。 + # detected_by_word_filter: ワードフィルターに登録されている単語 {{detected_message}} が検出されたため送信しませんでした。 + # selected_your_language: 「あなたの言語」 を {{your_language}} に設定しました。 + # selected_target_language: 「相手の言語」 を {{target_language}} に設定しました。 + # switched_language_preset_tab: 言語プリセット番号 {{tab_no}} に切り替わりました。 + # latest_language_setting: 現在「あなたの言語」は {{your_language}}、「相手の言語」は {{target_language}} に設定されています。 + # opened_web_page_booth: お使いのブラウザで、Boothのページを開きました。 + # opened_web_page_vrct_documents: |- + # お使いのブラウザで、VRCTのドキュメントを開きました。使用方法などはそちらに記載されています。 + # 不具合、ご要望、その他お問い合わせはドキュメント最下部にあるLinks、「お問合せフォーム」もしくはX (元Twitter) にて気軽にご連絡ください! + + state_text_enabled: 有効 + state_text_disabled: 無効 + + language_selector: + title_your_language: あなたの言語 + title_target_language: 相手の言語 + + update_available: 新しいバージョンが出ました! + updating: アップデート中... + +update_modal: + cpu_desc: 処理デバイスとしてCPUのみを使用 + cuda_desc: 処理デバイスとしてCPUとNVIDIA製のGPUを選択可能 + cuda_compare_cpu_desc: GPU選択時、CPUと比べて処理が高速 + cuda_disk_space_desc: 約{{size}}のディスク容量が必要 + close_modal: 閉じる + download_latest_and_restart: |- + 最新版がダウンロードされ、 + アプリは自動的に再起動します。 + is_latest_version_already: すでに最新版を使用中 + is_current_compute_device: 現在使用中のバージョン + +config_page: + version: バージョン {{version}} + # config_title: 設定 + # compact_mode: コンパクトモード + # restart_message: 再起動して変更を適用する。 + # common_error_message: + # invalid_value: 無効な値です。 + model_download_button_label: ダウンロード + side_menu_labels: + device: デバイス + appearance: デザイン + translation: 翻訳 + transcription: 音声認識 + others: その他 + hotkeys: ホットキー + advanced_settings: 高度な設定 + + device: + check_volume: 音量チェック + mic_host_device: + label: マイク (デバイス) + label_auto_select: 自動選択 + label_host: ホスト/ドライバー + label_device: デバイス + mic_dynamic_energy_threshold: + label_for_automatic: 'マイク入力感度の調整 (現在の設定: 自動)' + desc_for_automatic: マイクの入力感度を自動的に調節する。 + label_for_manual: 'マイク入力感度の調整 (現在の設定: 手動)' + desc_for_manual: スライダーを調整して入力感度を手動で決められます。マイクのアイコンを押すと、実際に声を入力し、音量を確認しながら調節できます。 + error_message: 0 から {{max}} までの数値で設定できます。 + speaker_device: + label: スピーカー (デバイス) + label_auto_select: 自動選択 + speaker_dynamic_energy_threshold: + label_for_automatic: 'スピーカー入力感度の調整 (現在の設定: 自動)' + desc_for_automatic: スピーカーの入力感度を自動的に調節する。 + label_for_manual: 'スピーカー入力感度の調整 (現在の設定: 手動)' + desc_for_manual: スライダーを調整して入力感度を手動で決められます。ヘッドフォンのアイコンを押すと、実際に音声を聞き取り、音量を確認しながら調節できます。 + error_message: 0 から {{max}} までの数値で設定できます。 + no_device_error_message: スピーカーデバイスが検出されませんでした。 + + appearance: + transparency: + label: 透明度 + desc: メイン画面の透明度を変更できます。 + ui_size: + label: UIサイズ + textbox_ui_size: + label: ログのフォントサイズ + desc: ログに表示されるフォントのサイズを、UIサイズを基準にして倍率を変えられます。 + send_message_button_type: + label: メッセージ送信ボタン + hide: 非表示 (エンターキーを使って送信) + show: 表示 + show_and_disable_enter_key: 表示し、エンターキーでの送信を無効 + font_family: + label: 使用フォント + ui_language: + label: UIの言語 + + translation: + ctranslate2_weight_type: + label: オフライン翻訳のタイプ + desc: 翻訳エンジン(オフライン翻訳)で翻訳する際に、使用する翻訳モデルを選択できます。 + small: 通常モデル ({{capacity}}) + large: 高精度モデル ({{capacity}}) + ctranslate2_compute_device: + label: オフライン翻訳の処理デバイス + deepl_auth_key: + label: DeepL 認証キー + desc: |- + 使用の際は、メイン画面にある {{translator}} をDeepL_APIに変更してください。 + ※対応していない言語もあります。 + open_auth_key_webpage: DeepLアカウントページを開く + save: 保存 + edit: 編集 + auth_key_success: 認証キーの更新が完了しました。 + auth_key_error: 認証キーが間違っているか、API使用制限が上限に達しています。 + + transcription: + section_label_mic: マイク + section_label_speaker: スピーカー + section_label_transcription_engines: 音声認識エンジン + mic_record_timeout: + label: 入力が終了したとみなす無音時間 + desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。 + error_message: 0 以上で 「{{mic_phrase_timeout_label}}」より大きくすることはできません。 + mic_phrase_timeout: + label: 一度に文字起こしする時間の長さ + desc: 設定された秒数ごとに文字起こし処理が行われます。 + error_message: 0 以上で 「{{mic_record_timeout_label}}」より小さくすることはできません。 + mic_max_phrase: + label: 送信するまでに保持する単語数 + desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をVRChatへ送信し、ログに表示します。 + error_message: 0以上の数値を設定できます。 + mic_word_filter: + label: ワードフィルター + desc: |- + 登録された単語を検出すると、その文章は送信されません。 + 「,」カンマで区切ると、まとめて複数の単語を追加できます。 + ※重複した単語は登録されません。 + add_button_label: 追加 + count_desc: '現在登録されている単語数: {{count}}' + speaker_record_timeout: + label: 入力が終了したとみなす無音時間 + desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。 + error_message: 0 以上で 「{{speaker_phrase_timeout_label}}」より大きくすることはできません。 + speaker_phrase_timeout: + label: 一度に文字起こしする時間の長さ + desc: 設定された秒数ごとに文字起こし処理が行われます。 + error_message: 0 以上で 「{{speaker_record_timeout_label}}」より小さくすることはできません。 + speaker_max_phrase: + label: ログとして表示するまでに保持する単語数 + desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をログに表示します。 + error_message: 0以上の数値を設定できます。 + select_transcription_engine: + label: 音声認識で使用するエンジン + whisper_weight_type: + label: Whisperモデルのタイプ + desc: |- + 容量が大きいモデルほど精度は高いですが、その分CPUやGPUを占有します。 + ※特にmediumより容量の大きいモデルは、CPU/GPUの性能によっては使用すらも困難です。 + model_template: '{{model_name}} モデル ({{capacity}})' + recommended_model_template: '{{model_name}} モデル ({{capacity}}) (推奨)' + whisper_compute_device: + label: Whisperで使用する処理デバイス + + vr: + single_line: 一行 + multi_lines: 複数行 + overlay_enable: 有効にする + restore_default_settings: 初期値に戻す + position: 位置 + rotation: 回転 + x_position: X軸(左右) + y_position: Y軸(上下) + z_position: Z軸(前後) + x_rotation: X軸の回転 + y_rotation: Y軸の回転 + z_rotation: Z軸の回転 + sample_text_button: + start: |- + サンプルテキストを + Overlayに送信する + stop: 送信を停止 + sample_text: サンプルテキスト + opacity: 透明度 + ui_scaling: サイズ + display_duration: 表示時間 + fadeout_duration: フェードアウト時間 + common_settings: 共通設定 + hmd: HMD + left_hand: 左手 + right_hand: 右手 + tracker: 表示するトラッカーの位置 + overlay_show_only_translated_messages: + label: 翻訳後のメッセージのみ表示する + + others: + auto_clear_the_message_box: + label: 送信後はチャットボックスを空にする + send_only_translated_messages: + label: 翻訳後のメッセージのみ送信する + auto_export_message_logs: + label: 会話ログを自動的に保存する + desc: テキストファイルとしてログがlogsフォルダ内に保存されます。 + vrc_mic_mute_sync: + label: VRCマイクミュート同期 + desc: |- + VRChatのマイクがミュートされている間は、メッセージをVRChatに送信しません。 + ※若干の遅延はあります。また、Push-To-Talkは非対応です。 + send_message_to_vrc: + label: VRChatにメッセージを送信する + desc: サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。 + send_received_message_to_vrc: + label: 受信したメッセージをVRChatに送信する + desc: スピーカーから聞き取り、文字起こしされたメッセージをVRChatに送信します。 + + hotkeys: + toggle_vrct_visibility: + label: VRCTの最小化/アクティブ化の切り替え + toggle_translation: + label: '{{translation}}機能切り替え' + toggle_transcription_send: + label: '{{transcription_send}}機能切り替え' + toggle_transcription_receive: + label: '{{transcription_receive}}機能切り替え' + + advanced_settings: + osc_ip_address: + label: OSC IP Address + osc_port: + label: OSC Port + open_config_filepath: + label: 設定ファイルを開く + switch_compute_device: label: VRCT CPU/GPUバージョンの切り替え \ No newline at end of file diff --git a/package.json b/package.json index bbd3c011..5cbeaae6 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,9 @@ "dev-ui": "npm-run-all --parallel vite tauri-dev", "build": "npm run build-python && npm run vite-build && npm run tauri build", "build-cuda": "npm run build-python-cuda && npm run vite-build && npm run tauri build", - "build-ui": "npm run vite-build && npm run tauri build", - "release": "python zip.py --zip_name VRCT.zip", - "release-cuda": "python zip.py --zip_name VRCT_cuda.zip", - "release-all": "npm run build && npm run release && npm run build-cuda && npm run release-cuda" + "release": "npm run build && python zip.py --zip_name VRCT.zip", + "release-cuda": "npm run build-cuda && python zip.py --zip_name VRCT_cuda.zip", + "release-all": "npm run release && npm run release-cuda" }, "dependencies": { "@emotion/react": "11.14.0", diff --git a/src-python/config.py b/src-python/config.py index be7ba2fb..6b8433d1 100644 --- a/src-python/config.py +++ b/src-python/config.py @@ -237,6 +237,15 @@ class Config: if isinstance(value, dict): self._SELECTABLE_TRANSLATION_ENGINE_STATUS = value + @property + def SELECTABLE_TRANSCRIPTION_ENGINE_STATUS(self): + return self._SELECTABLE_TRANSCRIPTION_ENGINE_STATUS + + @SELECTABLE_TRANSCRIPTION_ENGINE_STATUS.setter + def SELECTABLE_TRANSCRIPTION_ENGINE_STATUS(self, value): + if isinstance(value, dict): + self._SELECTABLE_TRANSCRIPTION_ENGINE_STATUS = value + # Save Json Data ## Main Window @property @@ -533,6 +542,19 @@ class Config: self._MIC_WORD_FILTER = sorted(set(value), key=value.index) self.saveConfig(inspect.currentframe().f_code.co_name, value) + @property + @json_serializable('HOTKEYS') + def HOTKEYS(self): + return self._HOTKEYS + + @HOTKEYS.setter + def HOTKEYS(self, value): + if isinstance(value, dict) and set(value.keys()) == set(self.HOTKEYS.keys()): + for key, value in value.items(): + if isinstance(value, list) or value is None: + self._HOTKEYS[key] = value + self.saveConfig(inspect.currentframe().f_code.co_name, self.HOTKEYS, immediate_save=True) + @property @json_serializable('MIC_AVG_LOGPROB') def MIC_AVG_LOGPROB(self): @@ -911,7 +933,7 @@ class Config: def init_config(self): # Read Only - self._VERSION = "3.0.1" + self._VERSION = "3.0.2" if getattr(sys, 'frozen', False): self._PATH_LOCAL = os_path.dirname(sys.executable) else: @@ -964,6 +986,9 @@ class Config: self._SELECTABLE_TRANSLATION_ENGINE_STATUS = {} for engine in self.SELECTABLE_TRANSLATION_ENGINE_LIST: self._SELECTABLE_TRANSLATION_ENGINE_STATUS[engine] = False + self._SELECTABLE_TRANSCRIPTION_ENGINE_STATUS = {} + for engine in self.SELECTABLE_TRANSCRIPTION_ENGINE_LIST: + self._SELECTABLE_TRANSCRIPTION_ENGINE_STATUS[engine] = False # Save Json Data ## Main Window @@ -1026,6 +1051,12 @@ class Config: self._MIC_PHRASE_TIMEOUT = 3 self._MIC_MAX_PHRASES = 10 self._MIC_WORD_FILTER = [] + self._HOTKEYS = { + "toggle_vrct_visibility": None, + "toggle_translation": None, + "toggle_transcription_send": None, + "toggle_transcription_receive": None, + } self._MIC_AVG_LOGPROB = -0.8 self._MIC_NO_SPEECH_PROB = 0.6 self._AUTO_SPEAKER_SELECT = True diff --git a/src-python/controller.py b/src-python/controller.py index 43fbe9e3..bd193ff0 100644 --- a/src-python/controller.py +++ b/src-python/controller.py @@ -6,7 +6,7 @@ import re from device_manager import device_manager from config import config from model import model -from utils import removeLog, printLog, errorLogging +from utils import removeLog, printLog, errorLogging, isConnectedNetwork class Controller: def __init__(self) -> None: @@ -25,6 +25,34 @@ class Controller: self.run = run # response functions + def connectedNetwork(self) -> None: + self.run( + 200, + self.run_mapping["connected_network"], + True, + ) + + def disconnectedNetwork(self) -> None: + self.run( + 200, + self.run_mapping["connected_network"], + False, + ) + + def enableAiModels(self) -> None: + self.run( + 200, + self.run_mapping["enable_ai_models"], + True, + ) + + def disableAiModels(self) -> None: + self.run( + 200, + self.run_mapping["enable_ai_models"], + False, + ) + def updateMicHostList(self) -> None: self.run( 200, @@ -148,15 +176,25 @@ class Controller: ) def downloaded(self) -> None: - weight_type_dict = config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT - weight_type_dict[self.weight_type] = True - config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT = weight_type_dict + if model.checkTranslatorCTranslate2ModelWeight(self.weight_type) is True: + weight_type_dict = config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT + weight_type_dict[self.weight_type] = True + config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT = weight_type_dict - self.run( - 200, - self.run_mapping["downloaded_ctranslate2_weight"], - self.weight_type, - ) + self.run( + 200, + self.run_mapping["downloaded_ctranslate2_weight"], + self.weight_type, + ) + else: + self.run( + 400, + self.run_mapping["error_ctranslate2_weight"], + { + "message":"CTranslate2 weight download error", + "data": None + }, + ) class DownloadWhisper: def __init__(self, run_mapping:dict, weight_type:str, run:Callable[[int, str, Any], None]) -> None: @@ -173,15 +211,25 @@ class Controller: ) def downloaded(self) -> None: - weight_type_dict = config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT - weight_type_dict[self.weight_type] = True - config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT = weight_type_dict + if model.checkTranscriptionWhisperModelWeight(self.weight_type) is True: + weight_type_dict = config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT + weight_type_dict[self.weight_type] = True + config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT = weight_type_dict - self.run( - 200, - self.run_mapping["downloaded_whisper_weight"], - self.weight_type, - ) + self.run( + 200, + self.run_mapping["downloaded_whisper_weight"], + self.weight_type, + ) + else: + self.run( + 400, + self.run_mapping["error_whisper_weight"], + { + "message":"Whisper weight download error", + "data": None + }, + ) def micMessage(self, result: dict) -> None: message = result["text"] @@ -494,7 +542,10 @@ class Controller: your_language = config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO]["1"] for target_language in config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO].values(): if your_language["language"] == target_language["language"] and target_language["enable"] is True: - engines = ["CTranslate2"] + if config.SELECTABLE_TRANSLATION_ENGINE_STATUS["CTranslate2"] is True: + engines = ["CTranslate2"] + else: + engines = [] return {"status":200, "result":engines} @@ -541,6 +592,11 @@ class Controller: self.updateTranslationEngineAndEngineList() return {"status":200, "result":config.SELECTED_TARGET_LANGUAGES} + @staticmethod + def getTranscriptionEngines(*args, **kwargs) -> dict: + engines = [key for key, value in config.SELECTABLE_TRANSCRIPTION_ENGINE_STATUS.items() if value is True] + return {"status":200, "result":engines} + @staticmethod def getSelectedTranscriptionEngine(*args, **kwargs) -> dict: return {"status":200, "result":config.SELECTED_TRANSCRIPTION_ENGINE} @@ -996,6 +1052,15 @@ class Controller: response = {"status":200, "result":config.SPEAKER_MAX_PHRASES} return response + @staticmethod + def getHotkeys(*args, **kwargs) -> dict: + return {"status":200, "result":config.HOTKEYS} + + @staticmethod + def setHotkeys(data, *args, **kwargs) -> dict: + config.HOTKEYS = data + return {"status":200, "result":config.HOTKEYS} + @staticmethod def getSpeakerAvgLogprob(*args, **kwargs) -> dict: return {"status":200, "result":config.SPEAKER_AVG_LOGPROB} @@ -1411,6 +1476,7 @@ class Controller: ) else: model.downloadCTranslate2ModelWeight(weight_type, download_ctranslate2.progressBar, download_ctranslate2.downloaded) + model.downloadCTranslate2ModelTokenizer(weight_type) return {"status":200, "result":True} def downloadWhisperWeight(self, data:str, asynchronous:bool=True, *args, **kwargs) -> dict: @@ -1572,10 +1638,22 @@ class Controller: config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT = weight_type_dict def updateTranscriptionEngine(self): - weight_type_dict = config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT weight_type = config.WHISPER_WEIGHT_TYPE - if config.SELECTED_TRANSCRIPTION_ENGINE == "Whisper" and weight_type_dict[weight_type] is False: - config.SELECTED_TRANSCRIPTION_ENGINE = "Google" + weight_type_dict = config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT + weight_available = bool(weight_type_dict.get(weight_type)) + current_engine = config.SELECTED_TRANSCRIPTION_ENGINE + selected_engines = [key for key, value in config.SELECTABLE_TRANSCRIPTION_ENGINE_STATUS.items() if value is True] + + # 選択可能なエンジンがなければ、Whisper に変更 + if current_engine in {"Whisper", "Google"}: + if current_engine not in selected_engines: + if weight_available: + alternate = "Google" if current_engine == "Whisper" else "Whisper" + config.SELECTED_TRANSCRIPTION_ENGINE = alternate if alternate in selected_engines else None + else: + config.SELECTED_TRANSCRIPTION_ENGINE = "Whisper" + else: + config.SELECTED_TRANSCRIPTION_ENGINE = "Whisper" def startCheckMicEnergy(self) -> None: while self.device_access_status is False: @@ -1654,12 +1732,55 @@ class Controller: self.run(200, self.run_mapping["initialization_progress"], progress) def init(self, *args, **kwargs) -> None: - printLog("Start Initialization") removeLog() + printLog("Start Initialization") + connected_network = isConnectedNetwork() + if connected_network is True: + self.connectedNetwork() + else: + self.disconnectedNetwork() + printLog(f"Connected Network: {connected_network}") + + self.initializationProgress(1) + + if connected_network is True: + # download CTranslate2 Model Weight + printLog("Download CTranslate2 Model Weight") + weight_type = config.CTRANSLATE2_WEIGHT_TYPE + th_download_ctranslate2 = None + if model.checkTranslatorCTranslate2ModelWeight(weight_type) is False: + th_download_ctranslate2 = Thread(target=self.downloadCtranslate2Weight, args=(weight_type, False)) + th_download_ctranslate2.daemon = True + th_download_ctranslate2.start() + + # download Whisper Model Weight + printLog("Download Whisper Model Weight") + weight_type = config.WHISPER_WEIGHT_TYPE + th_download_whisper = None + if model.checkTranscriptionWhisperModelWeight(weight_type) is False: + th_download_whisper = Thread(target=self.downloadWhisperWeight, args=(weight_type, False)) + th_download_whisper.daemon = True + th_download_whisper.start() + + if isinstance(th_download_ctranslate2, Thread): + th_download_ctranslate2.join() + if isinstance(th_download_whisper, Thread): + th_download_whisper.join() + + if (model.checkTranslatorCTranslate2ModelWeight(config.CTRANSLATE2_WEIGHT_TYPE) is False or + model.checkTranscriptionWhisperModelWeight(config.WHISPER_WEIGHT_TYPE) is False): + self.disableAiModels() + else: + self.enableAiModels() printLog("Init Translation Engine Status") for engine in config.SELECTABLE_TRANSLATION_ENGINE_LIST: match engine: + case "CTranslate2": + if model.checkTranslatorCTranslate2ModelWeight(config.CTRANSLATE2_WEIGHT_TYPE) is True: + config.SELECTABLE_TRANSLATION_ENGINE_STATUS[engine] = True + else: + config.SELECTABLE_TRANSLATION_ENGINE_STATUS[engine] = False case "DeepL_API": printLog("Start check DeepL API Key") config.SELECTABLE_TRANSLATION_ENGINE_STATUS[engine] = False @@ -1672,33 +1793,23 @@ class Controller: auth_keys[engine] = None config.AUTH_KEYS = auth_keys case _: - config.SELECTABLE_TRANSLATION_ENGINE_STATUS[engine] = True - - self.initializationProgress(1) - - # download CTranslate2 Model Weight - printLog("Download CTranslate2 Model Weight") - weight_type = config.CTRANSLATE2_WEIGHT_TYPE - th_download_ctranslate2 = None - if model.checkTranslatorCTranslate2ModelWeight(weight_type) is False: - th_download_ctranslate2 = Thread(target=self.downloadCtranslate2Weight, args=(weight_type, False)) - th_download_ctranslate2.daemon = True - th_download_ctranslate2.start() - - # download Whisper Model Weight - printLog("Download Whisper Model Weight") - weight_type = config.WHISPER_WEIGHT_TYPE - th_download_whisper = None - if model.checkTranscriptionWhisperModelWeight(weight_type) is False: - th_download_whisper = Thread(target=self.downloadWhisperWeight, args=(weight_type, False)) - th_download_whisper.daemon = True - th_download_whisper.start() - - if isinstance(th_download_ctranslate2, Thread): - th_download_ctranslate2.join() - if isinstance(th_download_whisper, Thread): - th_download_whisper.join() + if connected_network is True: + config.SELECTABLE_TRANSLATION_ENGINE_STATUS[engine] = True + else: + config.SELECTABLE_TRANSLATION_ENGINE_STATUS[engine] = False + for engine in config.SELECTABLE_TRANSCRIPTION_ENGINE_LIST: + match engine: + case "Whisper": + if model.checkTranscriptionWhisperModelWeight(config.WHISPER_WEIGHT_TYPE) is True: + config.SELECTABLE_TRANSCRIPTION_ENGINE_STATUS[engine] = True + else: + config.SELECTABLE_TRANSCRIPTION_ENGINE_STATUS[engine] = False + case _: + if connected_network is True: + config.SELECTABLE_TRANSCRIPTION_ENGINE_STATUS[engine] = True + else: + config.SELECTABLE_TRANSCRIPTION_ENGINE_STATUS[engine] = False self.initializationProgress(2) # set Translation Engine diff --git a/src-python/mainloop.py b/src-python/mainloop.py index c17c9564..e2dabbfc 100644 --- a/src-python/mainloop.py +++ b/src-python/mainloop.py @@ -7,9 +7,10 @@ from queue import Queue from controller import Controller from utils import printLog, printResponse, errorLogging, encodeBase64 -controller = Controller() - run_mapping = { + "connected_network":"/run/connected_network", + "enable_ai_models":"/run/enable_ai_models", + "transcription_mic":"/run/transcription_send_mic_message", "transcription_speaker":"/run/transcription_receive_speaker_message", @@ -22,8 +23,10 @@ run_mapping = { "download_progress_ctranslate2_weight":"/run/download_progress_ctranslate2_weight", "downloaded_ctranslate2_weight":"/run/downloaded_ctranslate2_weight", + "error_ctranslate2_weight":"/run/error_ctranslate2_weight", "download_progress_whisper_weight":"/run/download_progress_whisper_weight", "downloaded_whisper_weight":"/run/downloaded_whisper_weight", + "error_whisper_weight":"/run/error_whisper_weight", "selected_mic_device":"/run/selected_mic_device", "selected_speaker_device":"/run/selected_speaker_device", @@ -41,11 +44,11 @@ run_mapping = { "initialization_complete":"/run/initialization_complete", } -controller.setRunMapping(run_mapping) - def run(status:int, endpoint:str, result:Any) -> None: printResponse(status, endpoint, result) +controller = Controller() +controller.setRunMapping(run_mapping) controller.setRun(run) mapping = { @@ -81,6 +84,7 @@ mapping = { "/get/data/selected_target_languages": {"status": True, "variable":controller.getSelectedTargetLanguages}, "/set/data/selected_target_languages": {"status": True, "variable":controller.setSelectedTargetLanguages}, + "/get/data/transcription_engines": {"status": False, "variable":controller.getTranscriptionEngines}, "/get/data/selected_transcription_engine": {"status": False, "variable":controller.getSelectedTranscriptionEngine}, "/set/data/selected_transcription_engine": {"status": False, "variable":controller.setSelectedTranscriptionEngine}, @@ -183,6 +187,9 @@ mapping = { "/get/data/mic_max_phrases": {"status": True, "variable":controller.getMicMaxPhrases}, "/set/data/mic_max_phrases": {"status": True, "variable":controller.setMicMaxPhrases}, + "/get/data/hotkeys": {"status": True, "variable":controller.getHotkeys}, + "/set/data/hotkeys": {"status": True, "variable":controller.setHotkeys}, + "/get/data/mic_avg_logprob": {"status": True, "variable":controller.getMicAvgLogprob}, "/set/data/mic_avg_logprob": {"status": True, "variable":controller.setMicAvgLogprob}, diff --git a/src-python/model.py b/src-python/model.py index 251d9869..b6a416b4 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -24,7 +24,7 @@ from models.transcription.transcription_recorder import SelectedMicEnergyRecorde from models.transcription.transcription_transcriber import AudioTranscriber from models.translation.translation_languages import translation_lang from models.transcription.transcription_languages import transcription_lang -from models.translation.translation_utils import checkCTranslate2Weight, downloadCTranslate2Weight +from models.translation.translation_utils import checkCTranslate2Weight, downloadCTranslate2Weight, downloadCTranslate2Tokenizer from models.transcription.transcription_whisper import checkWhisperWeight, downloadWhisperWeight from models.overlay.overlay import Overlay from models.overlay.overlay_image import OverlayImage @@ -72,12 +72,15 @@ class Model: self.th_check_device = None self.mic_print_transcript = None self.mic_audio_recorder = None + self.mic_transcriber = None self.mic_energy_recorder = None self.mic_energy_plot_progressbar = None self.speaker_print_transcript = None self.speaker_audio_recorder = None + self.speaker_transcriber = None self.speaker_energy_recorder = None self.speaker_energy_plot_progressbar = None + self.previous_send_message = "" self.previous_receive_message = "" self.translator = Translator() @@ -110,6 +113,9 @@ class Model: def downloadCTranslate2ModelWeight(self, weight_type, callback=None, end_callback=None): return downloadCTranslate2Weight(config.PATH_LOCAL, weight_type, callback, end_callback) + def downloadCTranslate2ModelTokenizer(self, weight_type): + return downloadCTranslate2Tokenizer(config.PATH_LOCAL, weight_type) + def isLoadedCTranslate2Model(self): return self.translator.isLoadedCTranslate2Model() @@ -426,13 +432,14 @@ class Model: selected_your_languages = config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO] languages = [data["language"] for data in selected_your_languages.values() if data["enable"] is True] countries = [data["country"] for data in selected_your_languages.values() if data["enable"] is True] - res = self.mic_transcriber.transcribeAudioQueue( - self.mic_audio_queue, - languages, - countries, - config.MIC_AVG_LOGPROB, - config.MIC_NO_SPEECH_PROB - ) + if isinstance(self.mic_transcriber, AudioTranscriber) is True: + res = self.mic_transcriber.transcribeAudioQueue( + self.mic_audio_queue, + languages, + countries, + config.MIC_AVG_LOGPROB, + config.MIC_NO_SPEECH_PROB + ) if res: result = self.mic_transcriber.getTranscript() fnc(result) @@ -444,7 +451,7 @@ class Model: self.mic_audio_queue.get() # while not self.mic_energy_queue.empty(): # self.mic_energy_queue.get() - del self.mic_transcriber + self.mic_transcriber = None gc.collect() # def sendMicEnergy(): @@ -593,13 +600,14 @@ class Model: selected_target_languages = config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO] languages = [data["language"] for data in selected_target_languages.values() if data["enable"] is True] countries = [data["country"] for data in selected_target_languages.values() if data["enable"] is True] - res = self.speaker_transcriber.transcribeAudioQueue( - speaker_audio_queue, - languages, - countries, - config.SPEAKER_AVG_LOGPROB, - config.SPEAKER_NO_SPEECH_PROB - ) + if isinstance(self.speaker_transcriber, AudioTranscriber) is True: + res = self.speaker_transcriber.transcribeAudioQueue( + speaker_audio_queue, + languages, + countries, + config.SPEAKER_AVG_LOGPROB, + config.SPEAKER_NO_SPEECH_PROB + ) if res: result = self.speaker_transcriber.getTranscript() fnc(result) @@ -611,7 +619,7 @@ class Model: speaker_audio_queue.get() # while not speaker_energy_queue.empty(): # speaker_energy_queue.get() - del self.speaker_transcriber + self.speaker_transcriber = None gc.collect() # def sendSpeakerEnergy(): diff --git a/src-python/models/overlay/overlay_image.py b/src-python/models/overlay/overlay_image.py index f9ddf201..52fd242d 100644 --- a/src-python/models/overlay/overlay_image.py +++ b/src-python/models/overlay/overlay_image.py @@ -68,7 +68,7 @@ class OverlayImage: text_width = draw.textlength(text, font) character_width = text_width // len(text) - character_line_num = (base_width // character_width) - 12 + character_line_num = int((base_width // character_width) - 12) if len(text) > character_line_num: text = "\n".join([text[i:i + character_line_num] for i in range(0, len(text), character_line_num)]) text_height = font_size * (len(text.split("\n")) + 1) + 20 diff --git a/src-python/models/transcription/transcription_whisper.py b/src-python/models/transcription/transcription_whisper.py index 3eb574c7..080054b5 100644 --- a/src-python/models/transcription/transcription_whisper.py +++ b/src-python/models/transcription/transcription_whisper.py @@ -4,6 +4,7 @@ from typing import Callable import huggingface_hub from faster_whisper import WhisperModel import logging +from utils import getBestComputeType logger = logging.getLogger('faster_whisper') logger.setLevel(logging.CRITICAL) @@ -73,7 +74,7 @@ def downloadWhisperWeight(root, weight_type, callback=None, end_callback=None): def getWhisperModel(root, weight_type, device="cpu", device_index=0): path = os_path.join(root, "weights", "whisper", weight_type) - compute_type = "int8" if device == "cpu" else "float16" + compute_type = getBestComputeType(device, device_index) return WhisperModel( path, device=device, diff --git a/src-python/models/translation/translation_translator.py b/src-python/models/translation/translation_translator.py index 44004155..b9031c6c 100644 --- a/src-python/models/translation/translation_translator.py +++ b/src-python/models/translation/translation_translator.py @@ -1,12 +1,17 @@ from os import path as os_path from deepl import Translator as deepl_Translator -from translators import translate_text as other_web_Translator +try: + from translators import translate_text as other_web_Translator + ENABLE_TRANSLATORS = True +except Exception: + ENABLE_TRANSLATORS = False + from .translation_languages import translation_lang from .translation_utils import ctranslate2_weights import ctranslate2 import transformers -from utils import errorLogging +from utils import errorLogging, getBestComputeType import warnings warnings.filterwarnings("ignore") @@ -18,6 +23,7 @@ class Translator(): self.ctranslate2_translator = None self.ctranslate2_tokenizer = None self.is_loaded_ctranslate2_model = False + self.is_enable_translators = ENABLE_TRANSLATORS def authenticationDeepLAuthKey(self, authkey): result = True @@ -37,7 +43,7 @@ class Translator(): weight_path = os_path.join(path, "weights", "ctranslate2", directory_name) tokenizer_path = os_path.join(path, "weights", "ctranslate2", directory_name, "tokenizer") - compute_type = "int8" if device == "cpu" else "float16" + compute_type = getBestComputeType(device, device_index) self.ctranslate2_translator = ctranslate2.Translator( weight_path, device=device, @@ -97,42 +103,47 @@ class Translator(): source_language, target_language = self.getLanguageCode(translator_name, target_country, source_language, target_language) match translator_name: case "DeepL": - result = other_web_Translator( - query_text=message, - translator="deepl", - from_language=source_language, - to_language=target_language, - ) + if self.is_enable_translators is True: + result = other_web_Translator( + query_text=message, + translator="deepl", + from_language=source_language, + to_language=target_language, + ) case "DeepL_API": - if self.deepl_client is None: - result = False - else: - result = self.deepl_client.translate_text( - message, - source_lang=source_language, - target_lang=target_language, - ).text + if self.is_enable_translators is True: + if self.deepl_client is None: + result = False + else: + result = self.deepl_client.translate_text( + message, + source_lang=source_language, + target_lang=target_language, + ).text case "Google": - result = other_web_Translator( - query_text=message, - translator="google", - from_language=source_language, - to_language=target_language, - ) + if self.is_enable_translators is True: + result = other_web_Translator( + query_text=message, + translator="google", + from_language=source_language, + to_language=target_language, + ) case "Bing": - result = other_web_Translator( - query_text=message, - translator="bing", - from_language=source_language, - to_language=target_language, - ) + if self.is_enable_translators is True: + result = other_web_Translator( + query_text=message, + translator="bing", + from_language=source_language, + to_language=target_language, + ) case "Papago": - result = other_web_Translator( - query_text=message, - translator="papago", - from_language=source_language, - to_language=target_language, - ) + if self.is_enable_translators is True: + result = other_web_Translator( + query_text=message, + translator="papago", + from_language=source_language, + to_language=target_language, + ) case "CTranslate2": result = self.translateCTranslate2( message=message, diff --git a/src-python/models/translation/translation_utils.py b/src-python/models/translation/translation_utils.py index 47c53e05..457a65f1 100644 --- a/src-python/models/translation/translation_utils.py +++ b/src-python/models/translation/translation_utils.py @@ -5,6 +5,7 @@ from os import makedirs as os_makedirs from requests import get as requests_get from typing import Callable import hashlib +import transformers from utils import errorLogging ctranslate2_weights = { @@ -86,4 +87,17 @@ def downloadCTranslate2Weight(root, weight_type="small", callback=None, end_call errorLogging() if isinstance(end_callback, Callable): - end_callback() \ No newline at end of file + end_callback() + +def downloadCTranslate2Tokenizer(path, weight_type="small"): + directory_name = ctranslate2_weights[weight_type]["directory_name"] + tokenizer = ctranslate2_weights[weight_type]["tokenizer"] + tokenizer_path = os_path.join(path, "weights", "ctranslate2", directory_name, "tokenizer") + + try: + os_makedirs(tokenizer_path, exist_ok=True) + transformers.AutoTokenizer.from_pretrained(tokenizer, cache_dir=tokenizer_path) + except Exception: + errorLogging() + tokenizer_path = os_path.join("./weights", "ctranslate2", directory_name, "tokenizer") + transformers.AutoTokenizer.from_pretrained(tokenizer, cache_dir=tokenizer_path) \ No newline at end of file diff --git a/src-python/utils.py b/src-python/utils.py index 31d589bd..e31a1f46 100644 --- a/src-python/utils.py +++ b/src-python/utils.py @@ -1,68 +1,28 @@ import base64 from typing import Any import json -import random -from typing import Union -from os import path as os_path, rename as os_rename import traceback import logging -from PIL.Image import open as Image_open +from logging.handlers import RotatingFileHandler -def getImageFile(file_name): - img = Image_open(os_path.join(os_path.dirname(__file__), "img", file_name)) - return img +from ctranslate2 import get_supported_compute_types +import requests -def callFunctionIfCallable(function, *args): - if callable(function) is True: - function(*args) +def isConnectedNetwork(url="http://www.google.com", timeout=3): + try: + response = requests.get(url, timeout=timeout) + return response.status_code == 200 + except requests.RequestException: + return False -def isEven(number): - return number % 2 == 0 +def getBestComputeType(device, device_index) -> str: + compute_types = get_supported_compute_types(device, device_index) + compute_types = set(compute_types) + preferred_types = ["int8_bfloat16", "int8_float16", "int8", "bfloat16", "float16", "int8_float32", "float32"] -def makeEven(number, minus:bool=False): - if minus is True: - return number if isEven(number) else number - 1 - return number if isEven(number) else number + 1 - -def intToPctStr(value:int): - return f"{value}%" - -def floatToPctStr(value:float): - return f"{int(value*100)}%" - -def strPctToInt(value:str): - return int(value.replace("%", "")) - -def isUniqueStrings(unique_strings:Union[str, list], input_string:str, require=False): - import re - if isinstance(unique_strings, str): - unique_strings = [unique_strings] - patterns = [re.escape(s) for s in unique_strings] - - counts = [len(re.findall(pattern, input_string)) for pattern in patterns] - - if require is True: - # If require is True, unique_strings must appear once - return all(count == 1 for count in counts) and counts.count(1) == 2 - else: - # If require is False, check if unique strings are used exactly once - return all(count == 1 for count in counts) - -# path先のweightフォルダがある場合にはそのフォルダ名をweightsに変更する -def renameWeightFolder(path): - weight_path = os_path.join(path, "weight") - if os_path.exists(weight_path): - os_rename(weight_path, os_path.join(path, "weights")) - -def splitList(lst:list, split_count:int, to_shuffle:bool=False): - if to_shuffle is True: - random.shuffle(lst) - - split_lists = [] - for i in range(0, len(lst), split_count): - sub_list = lst[i:i+split_count] - split_lists.append(sub_list) - return split_lists + for preferred_type in preferred_types: + if preferred_type in compute_types: + return preferred_type def encodeBase64(data:str) -> dict: return json.loads(base64.b64decode(data).decode('utf-8')) @@ -80,8 +40,17 @@ def setupLogger(name, log_file, level=logging.INFO): logger.setLevel(level) logger.propagate = False # 親ロガーへの伝播を防ぐ + # filled with 10MB logs + max_log_size = 10 * 1024 * 1024 # 10MB + # ハンドラーを作成 - file_handler = logging.FileHandler(log_file, encoding="utf-8", delay=True) + file_handler = RotatingFileHandler( + log_file, + maxBytes=max_log_size, + backupCount=1, + encoding="utf-8", + delay=True + ) file_handler.setLevel(level) # フォーマッターを設定 diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6291f841..347908d6 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -16,18 +16,18 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "atk" @@ -100,23 +100,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -145,9 +145,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block" @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "brotli" -version = "3.5.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -177,9 +177,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", "serde", @@ -203,9 +203,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.16.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" [[package]] name = "byteorder" @@ -215,9 +215,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cairo-rs" @@ -255,9 +255,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.98" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +dependencies = [ + "shlex", +] [[package]] name = "cesu8" @@ -303,15 +306,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -394,9 +397,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-graphics" @@ -449,9 +452,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -467,18 +470,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -495,9 +498,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" @@ -533,24 +536,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "ctor" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -558,27 +561,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] @@ -593,15 +596,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.94", ] [[package]] @@ -662,6 +665,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + [[package]] name = "dlib" version = "0.5.2" @@ -679,24 +693,24 @@ checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dtoa-short" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" dependencies = [ "dtoa", ] [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dwrote" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da3498378ed373237bdef1eddcc64e7be2d3ba4841f4c22a998e81cadeea83c" +checksum = "70182709525a3632b2ba96b6569225467b18ecb4a77f46d255f713a6bebf05fd" dependencies = [ "lazy_static", "libc", @@ -706,14 +720,14 @@ dependencies = [ [[package]] name = "embed-resource" -version = "2.4.2" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d" +checksum = "b68b6f9f63a0b6a38bc447d4ce84e2b388f3ec95c99c641c8ff0dd3ef89a6379" dependencies = [ "cc", "memchr", "rustc_version", - "toml 0.8.2", + "toml 0.8.19", "vswhom", "winreg", ] @@ -726,9 +740,9 @@ checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -741,25 +755,25 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] @@ -776,21 +790,21 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -802,6 +816,15 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d" +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "fnv" version = "1.0.7" @@ -814,7 +837,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b64b34f4efd515f905952d91bc185039863705592c0c53ae6d979805dd154520" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "byteorder", "core-foundation", "core-graphics 0.23.2", @@ -860,7 +883,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] @@ -907,24 +930,24 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -933,32 +956,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-macro", @@ -1110,9 +1133,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "gio" @@ -1191,21 +1214,21 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] @@ -1282,9 +1305,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -1307,12 +1330,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hex" version = "0.4.3" @@ -1341,7 +1358,7 @@ checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", - "itoa 1.0.11", + "itoa 1.0.14", ] [[package]] @@ -1352,9 +1369,9 @@ checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1383,6 +1400,124 @@ dependencies = [ "png", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1391,25 +1526,36 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", "log", "memchr", - "regex-automata 0.4.6", + "regex-automata 0.4.9", "same-file", "walkdir", "winapi-util", @@ -1440,12 +1586,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "serde", ] @@ -1475,9 +1621,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "javascriptcore-rs" @@ -1524,24 +1670,37 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "json-patch" -version = "1.4.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" +checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" dependencies = [ + "jsonptr", "serde", "serde_json", "thiserror", ] +[[package]] +name = "jsonptr" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627" +dependencies = [ + "fluent-uri", + "serde", + "serde_json", +] + [[package]] name = "kuchikiki" version = "0.8.2" @@ -1557,24 +1716,24 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -1583,22 +1742,23 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", + "redox_syscall", ] -[[package]] -name = "line-wrap" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" - [[package]] name = "linux-raw-sys" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -1611,9 +1771,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "loom" @@ -1676,9 +1836,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -1691,11 +1851,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ - "adler", + "adler2", "simd-adler32", ] @@ -1764,16 +1924,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_enum" version = "0.5.11" @@ -1825,18 +1975,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "open" @@ -1856,12 +2006,12 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "os_pipe" -version = "1.1.5" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1897,9 +2047,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1913,16 +2063,16 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.1", + "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pathfinder_geometry" @@ -2053,7 +2203,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] @@ -2085,9 +2235,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -2097,19 +2247,18 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plist" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ - "base64 0.21.7", - "indexmap 2.2.6", - "line-wrap", + "base64 0.22.1", + "indexmap 2.7.0", "quick-xml", "serde", "time", @@ -2117,9 +2266,9 @@ dependencies = [ [[package]] name = "png" -version = "0.17.13" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -2136,9 +2285,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "precomputed-hash" @@ -2188,27 +2340,27 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -2302,27 +2454,18 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" -dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", @@ -2331,14 +2474,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] @@ -2352,13 +2495,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.5", ] [[package]] @@ -2369,9 +2512,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-demangle" @@ -2381,31 +2524,31 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ryu" @@ -2456,41 +2599,42 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.202" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" dependencies = [ - "indexmap 2.2.6", - "itoa 1.0.11", + "indexmap 2.7.0", + "itoa 1.0.14", + "memchr", "ryu", "serde", ] @@ -2503,29 +2647,29 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] [[package]] name = "serde_with" -version = "3.8.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.7.0", "serde", "serde_derive", "serde_json", @@ -2535,21 +2679,21 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "serialize-to-javascript" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" +checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" dependencies = [ "serde", "serde_json", @@ -2558,13 +2702,13 @@ dependencies = [ [[package]] name = "serialize-to-javascript-impl" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" +checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.94", ] [[package]] @@ -2599,14 +2743,20 @@ dependencies = [ [[package]] name = "shared_child" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +checksum = "09fa9338aed9a1df411814a5b2252f7cd206c55ae9bf2fa763f8de84603aa60c" dependencies = [ "libc", - "winapi", + "windows-sys 0.59.0", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "simd-adler32" version = "0.3.7" @@ -2722,15 +2872,26 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.65" +version = "2.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + [[package]] name = "system-deps" version = "5.0.0" @@ -2753,15 +2914,15 @@ dependencies = [ "cfg-expr 0.15.8", "heck 0.5.0", "pkg-config", - "toml 0.8.2", + "toml 0.8.19", "version-compare 0.2.0", ] [[package]] name = "tao" -version = "0.16.9" +version = "0.16.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575c856fc21e551074869dcfaad8f706412bd5b803dfa0fbf6881c4ff4bfafab" +checksum = "48d298c441a1da46e28e8ad8ec205aab7fd8cd71b9d10e05454224eef422e1ae" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -2806,20 +2967,20 @@ dependencies = [ [[package]] name = "tao-macros" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.94", ] [[package]] name = "tar" -version = "0.4.41" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", @@ -2828,15 +2989,15 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "1.6.8" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77567d2b3b74de4588d544147142d02297f3eaa171a25a065252141d8597a516" +checksum = "1bf327e247698d3f39af8aa99401c9708384290d1f5c544bf5d251d44c2fea22" dependencies = [ "anyhow", "cocoa 0.24.1", @@ -2853,11 +3014,13 @@ dependencies = [ "heck 0.5.0", "http", "ignore", + "log", "objc", "once_cell", "open", "os_pipe", "percent-encoding", + "plist", "rand 0.8.5", "raw-window-handle", "regex", @@ -2885,9 +3048,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "1.5.2" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab30cba12974d0f9b09794f61e72cad6da2142d3ceb81e519321bab86ce53312" +checksum = "586f3e677f940c8bb4f70c52eda05dc59b79e61543f1182de83516810bb8e35d" dependencies = [ "anyhow", "cargo_toml", @@ -2904,9 +3067,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "1.4.3" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a1d90db526a8cdfd54444ad3f34d8d4d58fa5c536463915942393743bd06f8" +checksum = "93a9e3f5cebf779a63bf24903e714ec91196c307d8249a0008b882424328bcda" dependencies = [ "base64 0.21.7", "brotli", @@ -2930,9 +3093,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "1.4.4" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a582d75414250122e4a597b9dd7d3c910a2c77906648fc2ac9353845ff0feec" +checksum = "d1d0e989f54fe06c5ef0875c5e19cf96453d099a0a774d5192ab47e80471cdab" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2944,9 +3107,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7ffddf36d450791018e63a3ddf54979b9581d9644c584a5fb5611e6b5f20b4" +checksum = "f33fda7d213e239077fad52e96c6b734cecedb30c2382118b64f94cb5103ff3a" dependencies = [ "gtk", "http", @@ -2965,9 +3128,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "0.14.8" +version = "0.14.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1989b3b4d611f5428b3414a4abae6fa6df30c7eb8ed33250ca90a5f7e5bb3655" +checksum = "18c447dcd9b0f09c7dc4b752cc33e72788805bfd761fbda5692d30c48289efec" dependencies = [ "cocoa 0.24.1", "gtk", @@ -2985,9 +3148,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "1.5.4" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "450b17a7102e5d46d4bdabae0d1590fd27953e704e691fc081f06c06d2253b35" +checksum = "83a0c939e88d82903a0a7dfb28388b12a3c03504d6bd6086550edaa3b6d8beaa" dependencies = [ "brotli", "ctor", @@ -3025,14 +3188,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom 0.2.15", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3054,22 +3219,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] @@ -3084,12 +3249,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", - "itoa 1.0.11", + "itoa 1.0.14", "num-conv", "powerfmt", "serde", @@ -3105,38 +3270,32 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.37.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", - "num_cpus", "pin-project-lite", ] @@ -3163,21 +3322,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.22.22", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -3188,31 +3347,31 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.22", ] [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3221,20 +3380,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -3253,9 +3412,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -3275,38 +3434,23 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "url" -version = "2.5.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -3321,10 +3465,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] -name = "uuid" -version = "1.8.0" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom 0.2.15", ] @@ -3349,9 +3505,9 @@ checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vswhom" @@ -3397,34 +3553,34 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3432,22 +3588,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.94", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "webkit2gtk" @@ -3552,11 +3708,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3615,7 +3771,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -3664,7 +3820,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -3684,18 +3849,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3710,7 +3875,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -3727,9 +3892,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3751,9 +3916,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3775,15 +3940,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3805,9 +3970,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3829,9 +3994,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3847,9 +4012,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3871,9 +4036,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -3884,6 +4049,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.52.0" @@ -3904,10 +4078,22 @@ dependencies = [ ] [[package]] -name = "wry" -version = "0.24.10" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00711278ed357350d44c749c286786ecac644e044e4da410d466212152383b45" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "wry" +version = "0.24.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55c80b12287eb1ff7c365fc2f7a5037cb6181bd44c9fce81c8d1cf7605ffad6" dependencies = [ "base64 0.13.1", "block", @@ -3983,3 +4169,91 @@ dependencies = [ "once_cell", "pkg-config", ] + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 46da9fa7..06160d79 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -11,12 +11,13 @@ edition = "2021" tauri-build = { version = "1", features = [] } [dependencies] -tauri = { version = "1", features = [ "window-set-size", "window-set-position", "window-unmaximize", "window-close", "window-maximize", "window-minimize", "window-unminimize", "window-start-dragging", "window-set-decorations", "window-set-always-on-top", "shell-sidecar", "shell-open", "devtools"] } +tauri = { version = "1", features = [ "window-hide", "window-set-focus", "global-shortcut-all", "window-set-size", "window-set-position", "window-unmaximize", "window-close", "window-maximize", "window-minimize", "window-unminimize", "window-start-dragging", "window-set-decorations", "window-set-always-on-top", "shell-sidecar", "shell-open", "devtools"] } serde = { version = "1", features = ["derive"] } serde_json = "1" font-kit = "0.14.2" window-shadows = { git = "https://github.com/tauri-apps/window-shadows.git" } + [features] # This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!! custom-protocol = ["tauri/custom-protocol"] diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 66464eff..163cc78a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,9 +1,9 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] -// use tauri::command; use tauri::Manager; use window_shadows::set_shadow; + fn main() { tauri::Builder::default() .setup(|app| { @@ -17,6 +17,11 @@ fn main() { Ok(()) }) + .on_window_event(|event| { // This is for fix the bug that the window scaling issue when dragging between monitors. + if let tauri::WindowEvent::ScaleFactorChanged { new_inner_size, .. } = event.event() { + event.window().set_size(tauri::Size::Physical(*new_inner_size)).unwrap(); + } + }) .invoke_handler(tauri::generate_handler![get_font_list]) .run(tauri::generate_context!()) .expect("error while running tauri application"); @@ -40,4 +45,4 @@ async fn get_font_list() -> Vec { } font_families.into_iter().collect() -} +} \ No newline at end of file diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 040bce33..9b869f1a 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -15,8 +15,10 @@ "window": { "all": false, "setAlwaysOnTop": true, + "setFocus": true, "setDecorations": true, "close": true, + "hide": true, "setPosition": true, "setSize": true, "maximize": true, @@ -24,7 +26,10 @@ "unmaximize": true, "unminimize": true, "startDragging": true - }, + }, + "globalShortcut": { + "all": true + }, "shell": { "all": false, "open": true, diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index 051855e2..86b5430d 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -1,14 +1,9 @@ import { useTranslation } from "react-i18next"; -import { - useWindow, -} from "@logics_common"; - -// import React from "react"; - import { KeyEventController, StartPythonController, + GlobalHotKeyController, UiLanguageController, ConfigPageCloseTriggerController, UiSizeController, @@ -24,9 +19,10 @@ import { UpdatingComponent } from "./updating_component/UpdatingComponent"; import { ModalController } from "./modal_controller/ModalController"; import { SnackbarController } from "./snackbar_controller/SnackbarController"; import styles from "./App.module.scss"; -import { useIsBackendReady, useIsSoftwareUpdating } from "@logics_common"; +import { useIsBackendReady, useIsSoftwareUpdating, useIsVrctAvailable, useWindow } from "@logics_common"; export const App = () => { + const { currentIsVrctAvailable } = useIsVrctAvailable(); const { currentIsBackendReady } = useIsBackendReady(); const { WindowGeometryController } = useWindow(); const { i18n } = useTranslation(); @@ -35,6 +31,7 @@ export const App = () => {
+ @@ -42,10 +39,12 @@ export const App = () => { - {currentIsBackendReady.data === false - ? - : + {(currentIsBackendReady.data === false || currentIsVrctAvailable.data === false) + ? + : } + +
); }; @@ -61,7 +60,6 @@ const Contents = () => { -
: diff --git a/src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx b/src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx index 7705aecc..c04e2a1a 100644 --- a/src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx +++ b/src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx @@ -9,6 +9,8 @@ import { useMainFunction, } from "@logics_main"; +import { useHotkeys } from "@logics_configs"; + import { useStore_MainFunctionsStateMemory } from "@store"; export const ConfigPageCloseTriggerController = () => { @@ -27,6 +29,8 @@ export const ConfigPageCloseTriggerController = () => { volumeCheckStop_Speaker, } = useVolume(); + const { registerShortcuts, unregisterAll } = useHotkeys(); + const memorizeLatestMainFunctionsState = () => { updateMainFunctionsStateMemory({ @@ -43,9 +47,11 @@ export const ConfigPageCloseTriggerController = () => { useEffect(() => { if (currentIsOpenedConfigPage.data === true) { // When config page is opened. memorizeLatestMainFunctionsState(); + unregisterAll(); if (currentTranscriptionSendStatus.data === true) setTranscriptionSend(false); if (currentTranscriptionReceiveStatus.data === true) setTranscriptionReceive(false); } else if (currentIsOpenedConfigPage.data === false) { // When config page is closed. + registerShortcuts(); if (currentMicThresholdCheckStatus.data === true) volumeCheckStop_Mic(); if (currentSpeakerThresholdCheckStatus.data === true) volumeCheckStop_Speaker(); restoreMainFunctionState(); diff --git a/src-ui/app/_app_controllers/GlobalHotKeyController.jsx b/src-ui/app/_app_controllers/GlobalHotKeyController.jsx new file mode 100644 index 00000000..050232cf --- /dev/null +++ b/src-ui/app/_app_controllers/GlobalHotKeyController.jsx @@ -0,0 +1,25 @@ +import { useEffect } from "react"; +import { useHotkeys } from "@logics_configs"; +import { useIsBackendReady, useIsSoftwareUpdating, useIsVrctAvailable } from "@logics_common"; + +export const GlobalHotKeyController = () => { + const { currentIsBackendReady } = useIsBackendReady(); + const { currentIsSoftwareUpdating } = useIsSoftwareUpdating(); + const { registerShortcuts, unregisterAll } = useHotkeys(); + + const { currentIsVrctAvailable } = useIsVrctAvailable(); + + useEffect(() => { + const is_backend_ready = currentIsBackendReady.data; + const is_software_updating = currentIsSoftwareUpdating.data; + const is_vrct_available = currentIsVrctAvailable.data; + + if (is_vrct_available && is_backend_ready && !is_software_updating) { + registerShortcuts(); + } else { + unregisterAll(); + } + }, [currentIsBackendReady.data, currentIsSoftwareUpdating.data, currentIsVrctAvailable.data]); + + return null; +}; \ No newline at end of file diff --git a/src-ui/app/_app_controllers/KeyEventController.jsx b/src-ui/app/_app_controllers/KeyEventController.jsx index 9e8c43a6..57260503 100644 --- a/src-ui/app/_app_controllers/KeyEventController.jsx +++ b/src-ui/app/_app_controllers/KeyEventController.jsx @@ -2,24 +2,29 @@ import { useEffect } from "react"; export const KeyEventController = () => { useEffect(() => { - const handleKeydown = (event) => { - if (event.key === "F5" || (event.ctrlKey && event.key === "r") || - (event.metaKey && event.key === "r")) { + const handleKeydown = (event) => { + if ( + event.key === "F5" || // Page reload + event.key === "F10" || // Focus thw window menu (maybe) + event.key === "F12" || // Open dev tool + (event.ctrlKey && event.key === "r") || + (event.metaKey && event.key === "r") + ) { + event.preventDefault(); + } + }; + + const handleContextmenu = (event) => { event.preventDefault(); - } - }; + }; - const handleContextmenu = (event) => { - event.preventDefault(); - }; + document.addEventListener("keydown", handleKeydown); + document.addEventListener("contextmenu", handleContextmenu); - document.addEventListener("keydown", handleKeydown); - document.addEventListener("contextmenu", handleContextmenu); - - return () => { - document.removeEventListener("keydown", handleKeydown); - document.removeEventListener("contextmenu", handleContextmenu); - }; + return () => { + document.removeEventListener("keydown", handleKeydown); + document.removeEventListener("contextmenu", handleContextmenu); + }; }, []); return null; diff --git a/src-ui/app/_app_controllers/index.js b/src-ui/app/_app_controllers/index.js index abe6f018..547c78f4 100644 --- a/src-ui/app/_app_controllers/index.js +++ b/src-ui/app/_app_controllers/index.js @@ -1,5 +1,6 @@ export { KeyEventController } from "./KeyEventController"; export { StartPythonController } from "./StartPythonController"; +export { GlobalHotKeyController } from "./GlobalHotKeyController"; export { UiLanguageController } from "./UiLanguageController"; export { ConfigPageCloseTriggerController } from "./ConfigPageCloseTriggerController"; export { UiSizeController } from "./UiSizeController"; diff --git a/src-ui/app/_index_css/root.css b/src-ui/app/_index_css/root.css index e2bcc6e7..4d96f38b 100644 --- a/src-ui/app/_index_css/root.css +++ b/src-ui/app/_index_css/root.css @@ -3,7 +3,7 @@ :root { font-size: 62.5%; - color: #F2F2F2; + color: var(--dark_basic_text_color); } * { diff --git a/src-ui/app/_index_css/variables.css b/src-ui/app/_index_css/variables.css index 2d38f67a..d212b415 100644 --- a/src-ui/app/_index_css/variables.css +++ b/src-ui/app/_index_css/variables.css @@ -20,6 +20,10 @@ --sent_400_color: #6197b4; --received_300_color: #a861b4; + --error_bc_color: #bb4448; + --error_bc_active_color: #9c3938; + --success_bc_color: #368777; + --waring_color: #cb944f; --dark_basic_text_color: #f2f2f2; --dark_100_color: #f5f7fb; @@ -48,8 +52,11 @@ --dark_975_color: #1a1b1d; --dark_1000_color: #151517; - --dark_825_color_cc: #434447cc; --dark_550_color_22: #94959922; + --dark_825_color_cc: #434447cc; + --dark_1000_color_66: #15151766; + --dark_1000_color_aa: #151517aa; + --dark_1000_color_dd: #151517dd; --title_bar_height: 2rem; diff --git a/src-ui/app/config_page/ConfigPage.jsx b/src-ui/app/config_page/ConfigPage.jsx index 6eb33644..7c71a5fd 100644 --- a/src-ui/app/config_page/ConfigPage.jsx +++ b/src-ui/app/config_page/ConfigPage.jsx @@ -3,22 +3,9 @@ import styles from "./ConfigPage.module.scss"; import { Topbar } from "./topbar/Topbar.jsx"; import { SidebarSection } from "./sidebar_section/SidebarSection.jsx"; import { SettingSection } from "./setting_section/SettingSection.jsx"; - -import { useSoftwareVersion } from "@logics_configs"; -import { useComputeMode } from "@logics_common"; -import { useTranslation } from "react-i18next"; +import { VersionLabel } from "./version_label/VersionLabel.jsx"; export const ConfigPage = () => { - const { t } = useTranslation(); - const { currentSoftwareVersion } = useSoftwareVersion(); - const { currentComputeMode } = useComputeMode(); - - const version_label = currentComputeMode.data === "cpu" - ? t("config_page.version", { version: currentSoftwareVersion.data }) - : currentComputeMode.data === "cuda" - ? t("config_page.version", { version: currentSoftwareVersion.data }) + " CUDA" - : t("config_page.version", { version: currentSoftwareVersion.data }); - return (
@@ -27,7 +14,7 @@ export const ConfigPage = () => {
-

{version_label}

+
); diff --git a/src-ui/app/config_page/ConfigPage.module.scss b/src-ui/app/config_page/ConfigPage.module.scss index 28d2fd0e..2eb9bab6 100644 --- a/src-ui/app/config_page/ConfigPage.module.scss +++ b/src-ui/app/config_page/ConfigPage.module.scss @@ -23,12 +23,4 @@ height: 100%; display: flex; padding-top: var(--config_page_topbar_height); -} - -.software_version { - position: absolute; - bottom: 0.8rem; - left: 1.2rem; - font-size: 1.2rem; - color: var(--dark_400_color); } \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/SettingSection.module.scss b/src-ui/app/config_page/setting_section/SettingSection.module.scss index 2ed9e9e6..fd35a3e2 100644 --- a/src-ui/app/config_page/setting_section/SettingSection.module.scss +++ b/src-ui/app/config_page/setting_section/SettingSection.module.scss @@ -1,6 +1,6 @@ .scroll_container { width: 100%; - overflow-y: auto; + overflow-y: scroll; overflow-x: hidden; } diff --git a/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx b/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx index eba09ff7..e61067a7 100644 --- a/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx @@ -8,6 +8,7 @@ import { Others, AdvancedSettings, Vr, + Hotkeys, Supporters, AboutVrct, } from "@setting_box"; @@ -27,6 +28,8 @@ export const SettingBox = () => { return ; case "vr": return ; + case "hotkeys": + return ; case "advanced_settings": return ; case "supporters": diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx index e8bba371..d9b0d4cb 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx @@ -8,23 +8,36 @@ const _Entry = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); + }, + blur: () => { + inputRef.current.blur(); } })); const input_class_names = clsx(styles.entry_input_area, { - [styles.is_disabled]: props.is_disabled + [styles.is_disabled]: props.is_disabled, + }); + const input_wrapper_class_names = clsx(styles.entry_wrapper, { + [styles.is_activated]: props.is_activated, }); return (
props.onChange(e)} + onChange={(e) => props.onChange?.(e)} + onFocus={(e) => props.onFocus?.(e)} + onBlur={(e) => props.onBlur?.(e)} + onKeyDown={(e) => props.onKeyDown?.(e)} + onKeyUp={(e) => props.onKeyUp?.(e)} + readOnly={props.readOnly === true ? true : false} />
diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss index c9744de6..7fc4a388 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss @@ -9,6 +9,9 @@ background-color: var(--dark_875_color); border: 0.1rem solid var(--dark_750_color); border-radius: 0.4rem; + &.is_activated { + border: 0.1rem solid var(--primary_400_color); + } } .entry_input_area { @@ -16,7 +19,6 @@ height: 100%; font-size: 1.4rem; resize: none; - color: var(--dark_basic_text_color); &.is_disabled { color: var(--dark_500_color); pointer-events: none; diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss index 915f300c..1f5a530e 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss @@ -22,11 +22,11 @@ bottom: 0; left: 0; border-radius: 0.4rem; - background-color: (#00000044); + background-color: var(--dark_1000_color_66); backdrop-filter: blur(4rem); border: solid 0.1rem var(--dark_700_color); &:hover { - background-color: (#00000088); + background-color: var(--dark_1000_color_aa); } &:active { backdrop-filter: blur(1.4rem); @@ -35,7 +35,6 @@ .edit_button { padding: 0.8rem 1.2rem; - color: var(--dark_basic_text_color); height: 100%; width: 100%; font-size: 1.4rem; @@ -62,7 +61,6 @@ } .save_button_label { - color: var(--dark_basic_text_color); font-size: 1.4rem; } @@ -91,7 +89,6 @@ .open_webpage_text { font-size: 1.2rem; - color: var(--dark_basic_text_color); } .external_link_svg { diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.jsx index 6ec51fb1..b1f2360b 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.jsx @@ -1,12 +1,10 @@ -import { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; -import clsx from "clsx"; import CircularProgress from "@mui/material/CircularProgress"; import styles from "./DownloadModels.module.scss"; import { RadioButton, - // DownloadModels, } from "../index"; + export const DownloadModels = (props) => { const options = props.options.map(item => ({ ...item, @@ -25,25 +23,11 @@ export const DownloadModels = (props) => { downloadStartFunction={props.downloadStartFunction} /> - //
- // {props.models.map((option) => ( - // - // ))} - //
); }; const ModelSelector = ({option, ...props}) => { const { t } = useTranslation(); - const [circular_color, setCircularColor] = useState(""); - const [circular_color_2, setCircularColor2] = useState(""); - useEffect(() => { - const circular_color = getComputedStyle(document.documentElement).getPropertyValue("--dark_600_color"); - setCircularColor(circular_color.trim()); - const circular_color_2 = getComputedStyle(document.documentElement).getPropertyValue("--primary_300_color"); - setCircularColor2(circular_color_2.trim()); - }, []); - const renderContent = () => { const circular_progress = Math.floor(option.progress / 10) * 10; @@ -56,13 +40,13 @@ const ModelSelector = ({option, ...props}) => { variant={(option.progress === 100) ? "indeterminate" : "determinate"} value={circular_progress} size="3rem" - sx={{ color: circular_color_2 }} + sx={{ color: "var(--primary_300_color)" }} />

{`${Math.round(option.progress)}%`}

); case option.is_pending: - return ; + return ; case !option.is_downloaded: return ( +

+ ); +}; diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/hotkeys_entry/HotkeysEntry.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/hotkeys_entry/HotkeysEntry.module.scss new file mode 100644 index 00000000..017f4085 --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/_components/hotkeys_entry/HotkeysEntry.module.scss @@ -0,0 +1,41 @@ +@import "@scss_mixins"; + +.container { + display: flex; + justify-content: center; + align-items: center; + gap: 1rem; + position: relative; +} + +.delete_button { + padding: 0.4rem; + font-size: 1.4rem; + // background-color: var(--dark_800_color); + flex-shrink: 0; + display: flex; + justify-content: center; + align-items: center; + border-radius: 0.2rem; + &:hover { + background-color: var(--dark_850_color); + } + &:active { + background-color: var(--dark_900_color); + } + &.is_pending { + pointer-events: none; + & .delete_svg { + color: var(--dark_600_color); + } + } +} + +.delete_svg { + width: 2.2rem; + color: var(--error_bc_color); +} + +.loader { + @include loader(2rem, 0.2rem, left, -2.2rem); +} \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/index.js b/src-ui/app/config_page/setting_section/setting_box/_components/index.js index 20cc6fe1..3a295d3c 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/index.js +++ b/src-ui/app/config_page/setting_section/setting_box/_components/index.js @@ -3,6 +3,7 @@ export { ComputeDevice } from "./compute_device/ComputeDevice"; export { DeeplAuthKey, OpenWebpage_DeeplAuthKey } from "./deepl_auth_key/DeeplAuthKey"; export { DropdownMenu } from "./dropdown_menu/DropdownMenu"; export { Entry } from "./entry/Entry"; +export { HotkeysEntry } from "./hotkeys_entry/HotkeysEntry"; export { LabelComponent } from "./label_component/LabelComponent"; export { RadioButton } from "./radio_button/RadioButton"; export { SectionLabelComponent } from "./section_label_component/SectionLabelComponent"; diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss index c49055a8..a2b6e999 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss @@ -8,7 +8,6 @@ .label { font-size: 1.6rem; font-weight: 400; - color: var(--dark_basic_text_color); white-space: nowrap; width: max-content; } diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx index 3e896a59..07c70ff2 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx @@ -31,13 +31,6 @@ export const Slider = (props) => { backgroundColor: "var(--dark_800_color)", padding: "0.6rem 1rem", lineHeight: "1.15", - // top: "-1.4rem", - // "&::before": { - // left: "30%", - // width: "1rem", - // height: "1rem", - // clipPath: "polygon(50% 0, 100% 100%, 0 100%)", - // }, }, }, "& .MuiSlider-markLabel": { diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss index 929f8975..19d8d9ee 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss @@ -16,7 +16,6 @@ height: 100%; font-size: 1.4rem; resize: none; - color: var(--dark_basic_text_color); &.is_disable { color: var(--dark_500_color); pointer-events: none; diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/volume_check_button/VolumeCheckButton.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/volume_check_button/VolumeCheckButton.module.scss index 302ab71e..a7c6dcde 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/volume_check_button/VolumeCheckButton.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/volume_check_button/VolumeCheckButton.module.scss @@ -41,5 +41,4 @@ .button_text { font-size: 1.2rem; - color: var(--dark_basic_text_color); } \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/word_filter/WordFilter.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/word_filter/WordFilter.module.scss index 74e42ef5..b32edc26 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/word_filter/WordFilter.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/word_filter/WordFilter.module.scss @@ -32,7 +32,6 @@ .item_text { font-size: 1.4rem; font-weight: 300; - color: var(--dark_basic_text_color); &.is_redoable { text-decoration: line-through; } @@ -56,7 +55,7 @@ .delete_svg { width: 2.4rem; - color: #bb4448; + color: var(--error_bc_color); } .redo_svg { @@ -77,7 +76,6 @@ .add_button { padding: 0.8rem 1.2rem; background-color: var(--primary_600_color); - color: var(--dark_basic_text_color); font-size: 1.4rem; border-radius: 0.4rem; text-align: center; diff --git a/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.jsx b/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.jsx index 0afb017b..716a15c9 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.jsx @@ -8,6 +8,7 @@ import { Slider, SwitchBox, Entry, + HotkeysEntry, RadioButton, OpenWebpage_DeeplAuthKey, DeeplAuthKey, @@ -75,6 +76,10 @@ export const EntryContainer = (props) => ( ); +export const HotkeysEntryContainer = (props) => ( + +); + export const RadioButtonContainer = (props) => ( ); diff --git a/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.jsx b/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.jsx index 5a8d49b3..e36a39f5 100644 --- a/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.jsx @@ -3,10 +3,20 @@ import dev_section_title from "@images/about_vrct/dev_section_title.png"; import dev_misya from "@images/about_vrct/dev_misya.png"; import dev_shiina from "@images/about_vrct/dev_shiina.png"; import vrct_logo_for_about_vrct from "@images/about_vrct/vrct_logo_for_about_vrct.png"; + import contributors_section_title from "@images/about_vrct/contributors_section_title.png"; -import contributors_members from "@images/about_vrct/contributors_members.png"; +import contributor_done from "@images/about_vrct/contributor_done.png"; +import contributor_iya from "@images/about_vrct/contributor_iya.png"; +import contributor_rera from "@images/about_vrct/contributor_rera.png"; +import contributor_poposuke from "@images/about_vrct/contributor_poposuke.png"; +import contributor_kumaguma from "@images/about_vrct/contributor_kumaguma.png"; + import localization_section_title from "@images/about_vrct/localization_section_title.png"; -import localization_members from "@images/about_vrct/localization_members.png"; +import localization_1 from "@images/about_vrct/localization_1.png"; +import localization_2 from "@images/about_vrct/localization_2.png"; +import localization_3 from "@images/about_vrct/localization_3.png"; +import localization_4 from "@images/about_vrct/localization_4.png"; +import localization_5 from "@images/about_vrct/localization_5.png"; import special_thanks_section_title from "@images/about_vrct/special_thanks_section_title.png"; import special_thanks_members from "@images/about_vrct/special_thanks_members.png"; @@ -15,8 +25,6 @@ import special_thanks_message_ja from "@images/about_vrct/special_thanks_message import poster_showcase_section_title from "@images/about_vrct/poster_showcase_section_title.png"; -import vrchat_disclaimer from "@images/about_vrct/vrchat_disclaimer.png"; - import clsx from "clsx"; import { useTranslation } from "react-i18next"; import { useStore_UiLanguage } from "@store"; @@ -43,7 +51,9 @@ export const AboutVrct = () => {
- +
+ +
@@ -55,19 +65,46 @@ export const AboutVrct = () => {
- - - - - - - +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + +
- +
+
+ + +
+
+ + +
+
+ + {/* */} +
+
@@ -87,7 +124,7 @@ export const AboutVrct = () => {
- +

VRCT is not endorsed by VRChat and does not reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat properties. VRChat and all associated properties are trademarks or registered trademarks of VRChat Inc. VRChat © VRChat Inc.

diff --git a/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.module.scss b/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.module.scss index 741b2934..a4d06e2e 100644 --- a/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/about_vrct/AboutVrct.module.scss @@ -1,9 +1,11 @@ .container { display: flex; gap: 2.2rem; + justify-content: center; + align-items: center; flex-direction: column; - width: 72rem; - // background-color: gray; + max-width: 72rem; + margin: auto; } .section_title { @@ -30,20 +32,23 @@ } .dev_section_wrapper { display: flex; - justify-content: space-between; + gap: 2rem; + flex-wrap: wrap; + width: 100%; + justify-content: center; } .dev_card_wrapper { - width: 34.6rem; position: relative; + // width: 100%; } .dev_card_img { - width: 100%; + width: 34.6rem; } @mixin dev_sns_styles($right) { position: absolute; right: $right; - bottom: 1.2rem; + bottom: 0.6rem; width: 2.8rem; padding: 0.4rem; border-radius: 0.4rem; @@ -69,8 +74,16 @@ display: flex; flex-direction: row; justify-content: space-between; - text-align: center; padding: 0 5.5rem; + flex-wrap: wrap; + gap: 1rem; +} +.about_vrct_logo_wrapper { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + padding: 2rem 0; } .about_vrct_logo { width: 20rem; @@ -78,7 +91,7 @@ } .project_links_wrapper { display: flex; - flex-direction: column; + flex-wrap: wrap; gap: 0.2rem; align-items: start; } @@ -87,6 +100,7 @@ height: 2.6rem; padding: 0.4rem 1rem; border-radius: 0.4rem; + flex-shrink: 0; &:hover { background-color: var(--dark_850_color); } @@ -96,19 +110,27 @@ } .contributors_img_wrapper { + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: center; + align-items: center; +} +.contributor_card_wrapper { position: relative; } .contributors_img { - width: 100%; + width: 22rem; } -@mixin contributors_sns_styles($top, $left) { +@mixin contributors_sns_styles($bottom, $left) { position: absolute; left: $left; - top: $top; + bottom: $bottom; width: 2.4rem; padding: 0.4rem; border-radius: 0.4rem; + transform: translate(50%, 50%); &:hover { background-color: var(--dark_825_color); } @@ -117,34 +139,51 @@ } } -$first_line_top: 6.2rem; +$bottom_pos: 16%; +$sns_left_pos: 0.8rem; .contributors_done_san_x { - @include contributors_sns_styles($first_line_top, 2rem); + @include contributors_sns_styles($bottom_pos, $sns_left_pos); } .contributors_iya_x { - @include contributors_sns_styles($first_line_top, 27.6rem); + @include contributors_sns_styles($bottom_pos, $sns_left_pos); } .contributors_rera_x { - @include contributors_sns_styles($first_line_top, 52.2rem); + @include contributors_sns_styles($bottom_pos, calc($sns_left_pos - 1.4rem)); } .contributors_rera_github { - @include contributors_sns_styles($first_line_top, 55rem); + @include contributors_sns_styles($bottom_pos, calc($sns_left_pos + 1.4rem)); } -$second_line_top: 16.6rem; .contributors_poposuke_x { - @include contributors_sns_styles($second_line_top, 14.8rem); + @include contributors_sns_styles($bottom_pos, $sns_left_pos); } .contributors_kumaguma_x { - @include contributors_sns_styles($second_line_top, 40.8rem); + @include contributors_sns_styles($bottom_pos, $sns_left_pos); } .localization_section { display: flex; flex-direction: column; + width: 100%; + gap: 0.6rem; +} +.localization_members_wrapper { + display: flex; + justify-content: center; + align-items: start; + column-gap: 6rem; + row-gap: 1rem; + flex-wrap: wrap; +} +.localization_members_row_wrapper { + display: flex; + flex-direction: column; + justify-content: center; + align-items: start; + gap: 0.2rem; } .localization_members_img { - width: 100%; + height: 2.2rem; } .special_thanks_section { @@ -163,9 +202,11 @@ $second_line_top: 16.6rem; .poster_showcase_section { display: flex; flex-direction: column; + width: 100%; } .vrchat_disclaimer { - width: 100%; + font-size: 1.2rem; margin-top: 8rem; + color: var(--dark_600_color); } \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.module.scss b/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.module.scss index c7b760b7..6d94b14a 100644 --- a/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.module.scss @@ -1,6 +1,7 @@ .container { display: flex; - justify-content: space-between; + justify-content: center; align-items: start; gap: 2rem; + flex-wrap: wrap; } \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.module.scss b/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.module.scss index fa819d64..28d4dcf5 100644 --- a/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.module.scss @@ -1,9 +1,10 @@ .container { display: flex; flex-direction: column; - flex: 1; + // flex: 1; gap: 1rem; justify-content: space-between; + width: 42rem; } $image_height: 2.8rem; $y_padding: 0.4rem; @@ -32,6 +33,7 @@ $image_height_gap: 0.4rem; } .poster_showcase_world_img { height: $image_height; + flex-shrink: 0; } .pagination_container { diff --git a/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.module.scss b/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.module.scss index 739fe78d..e7c453a5 100644 --- a/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.module.scss @@ -3,6 +3,7 @@ flex-direction: column; justify-content: center; align-items: center; + flex-shrink: 0; } .poster_pagination_wrapper { display: flex; diff --git a/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss b/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss index 65fab80a..5497b661 100644 --- a/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss @@ -61,7 +61,6 @@ .device_label { font-size: 1.8rem; - color: var(--dark_basic_text_color); } .device_contents { @@ -76,6 +75,8 @@ display: flex; flex-direction: column; gap: 1.2rem; + justify-content: center; + align-items: center; } .device_dropdown_wrapper { @@ -97,6 +98,7 @@ .device_secondary_label { padding-left: 0.2rem; + padding-right: 0.4rem; font-size: 1.4rem; color: var(--dark_500_color); white-space: nowrap; diff --git a/src-ui/app/config_page/setting_section/setting_box/hotkeys/Hotkeys.jsx b/src-ui/app/config_page/setting_section/setting_box/hotkeys/Hotkeys.jsx new file mode 100644 index 00000000..33d57923 --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/hotkeys/Hotkeys.jsx @@ -0,0 +1,49 @@ +import { useHotkeys } from "@logics_configs"; +import styles from "./Hotkeys.module.scss"; +import { HotkeysEntryContainer } from "../_templates/Templates"; +import { useTranslation } from "react-i18next"; +export const Hotkeys = () => { + return ( +
+ +
+ ); +}; + +const HotkeysBoxContainer = () => { + const { t } = useTranslation(); + const { currentHotkeys, setHotkeys } = useHotkeys(); + + return ( +
+ + + + +
+ ); +}; diff --git a/src-ui/app/config_page/setting_section/setting_box/hotkeys/Hotkeys.module.scss b/src-ui/app/config_page/setting_section/setting_box/hotkeys/Hotkeys.module.scss new file mode 100644 index 00000000..dad10feb --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/hotkeys/Hotkeys.module.scss @@ -0,0 +1,5 @@ +.container { + display: flex; + // gap: 6.4rem; + flex-direction: column; +} \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/index.js b/src-ui/app/config_page/setting_section/setting_box/index.js index 489f63ca..dc5798c3 100644 --- a/src-ui/app/config_page/setting_section/setting_box/index.js +++ b/src-ui/app/config_page/setting_section/setting_box/index.js @@ -5,5 +5,6 @@ export { Transcription } from "./transcription/Transcription"; export { Others, VrcMicMuteSyncContainer } from "./others/Others"; export { AdvancedSettings } from "./advanced_settings/AdvancedSettings"; export { Vr } from "./vr/Vr"; +export { Hotkeys } from "./hotkeys/Hotkeys"; export { AboutVrct } from "./about_vrct/AboutVrct"; export { Supporters } from "./supporters/Supporters"; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.jsx b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.jsx index 1d64b9c5..30c65b9d 100644 --- a/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.jsx @@ -1,224 +1,22 @@ -import { useState, useEffect } from "react"; import styles from "./Supporters.module.scss"; -import clsx from "clsx"; -import { useTranslation } from "react-i18next"; - -import { - useSettingBoxScrollPosition, -} from "@logics_configs" - -const supporter_images = import.meta.glob("@images/supporters/supporters_images/*.{png,jpg,jpeg,svg}", { eager: true }); -const chato_expression_images = import.meta.glob("@images/supporters/chato_expressions/*.{png,jpg,jpeg,svg}", { eager: true }); -import fanbox_img from "@images/supporters/c_fanbox_1620x580.png"; -import vrct_supporters_title from "@images/supporters/vrct_supporters_title.png"; -import fanbox_button from "@images/supporters/fanbox_button.png"; -import kofi_preparing from "@images/supporters/kofi_preparing.png"; - -import ExternalLink from "@images/external_link.svg?react"; - -const mogu_count = 8; -const mochi_count = 3; -const fuwa_count = 4; -const basic_count = 5; -const former_count = 2; -const and_you_count = 1; -const default_icon_numbers = ["05", "06", "07", "11"]; - -const supporters_filenames = Array.from({ length: 23 }, (_, index) => `supporter_${String(index + 1).padStart(2, "0")}`); -const chato_expressions_filenames = Array.from({ length: 7 }, (_, index) => `chato_expression_${String(index + 1).padStart(2, "0")}`); - -const SHUFFLE_INTERVAL_TIME = 20000; -const shuffleArray = (array) => { - return array - .map((value) => ({ value, sort: Math.random() })) - .sort((a, b) => a.sort - b.sort) - .map(({ value }) => value); -}; +import { SupportUsContainer } from "./support_us_container/SupportUsContainer"; +import { SupportersContainer } from "./supporters_container/SupportersContainer"; +import { useSupporters } from "@logics_configs"; +import { useEffect } from "react"; export const Supporters = () => { + const { asyncFetchSupportersData } = useSupporters(); + + useEffect(() => { + asyncFetchSupportersData(); + }, []); + return (
- -
- ); -}; - -const SupportUsContainer = () => { - return ( -
- -
-
- - - -

日本語 / Mainly Japanese

-
-
- -

Mainly English

-
+
+
); -}; - -const getRandomImage = (images) => { - const random_index = Math.floor(Math.random() * images.length); - return images[random_index]; -}; - -export const SupportersContainer = () => { - - return ( -
- -

{`VRCT3.0のアップデートに向けて、めちゃ大変な開発を支えてくれた "Early Supporters" です。\nThey are the 'Early Supporters' who supported us through the incredibly challenging development toward the VRCT3.0 update.`}

- - - -

{`みなさんのおかげで、みしゃ社長は布団で寝ることを許され(in開発室) しいなは喜び庭駆け回っています!!!ふわもちもぐもぐです!ありがとうございます。これからもまだまだ進化するVRCTをどうかよろしくお願いします!\nThanks to everyone, Misha has been granted the privilege of sleeping in a proper bed (in the development room), and Shiina is so happy, running around the yard! Fuwa-mochi-mogu-mogu! Thank you so much! We hope you'll continue to support the ever-evolving VRCT!`}

-
- ); -}; - -const ProgressBar = () => { - const [is_active, setIsActive] = useState(false); - - useEffect(() => { - setIsActive(true); - const interval = setInterval(() => { - setIsActive(false); - setTimeout(() => setIsActive(true), 50); - }, SHUFFLE_INTERVAL_TIME); - - return () => clearInterval(interval); - }, []); - - return ( -
- ); -}; - -const SupportsWrapper = () => { - const { saveScrollPosition, restoreScrollPosition } = useSettingBoxScrollPosition(); - const [imagesState, setImagesState] = useState({ - mogu_images: [], - mochi_images: [], - fuwa_images: [], - basic_images: [], - former_images: [], - and_you_images: [], - chato_images: [], - }); - - const shuffleImages = () => { - saveScrollPosition(); - const getCategoryImages = (start, count) => { - const category_images = supporters_filenames.slice(start, start + count); - return shuffleArray(category_images); - }; - - const randomChatoImages = shuffleArray( - Array.from({ length: mogu_count + mochi_count + fuwa_count + basic_count + former_count }, () => - getRandomImage(chato_expressions_filenames) - ) - ); - - setImagesState({ - mogu_images: getCategoryImages(0, mogu_count), - mochi_images: getCategoryImages(mogu_count, mochi_count), - fuwa_images: getCategoryImages(mogu_count + mochi_count, fuwa_count), - basic_images: getCategoryImages(mogu_count + mochi_count + fuwa_count, basic_count), - former_images: getCategoryImages(mogu_count + mochi_count + fuwa_count + basic_count, former_count), - and_you_images: getCategoryImages(mogu_count + mochi_count + fuwa_count + basic_count + former_count, and_you_count), - chato_images: randomChatoImages, - }); - setTimeout(() => restoreScrollPosition(), 0); - }; - - useEffect(() => { - shuffleImages(); - const interval = setInterval(() => { - shuffleImages(); - }, SHUFFLE_INTERVAL_TIME); - - return () => clearInterval(interval); - }, []); - - - const getSupportersImageByFileName = (file_name) => { - const image_path = Object.keys(supporter_images).find((path) => path.endsWith(file_name + ".png")); - return image_path ? supporter_images[image_path]?.default : null; - }; - - const getChatoImageByFileName = (file_name) => { - const image_path = Object.keys(chato_expression_images).find((path) => path.endsWith(file_name + ".png")); - return image_path ? chato_expression_images[image_path]?.default : null; - }; - - const getRandomDelay = (min, max) => { - const random_value = Math.random() * (max - min) + min; - return `${random_value.toFixed(1)}s`; - }; - - - const renderImages = (image_list, chato_list, options = {}) => { - return image_list.map((file_name, index) => { - const img_src = getSupportersImageByFileName(file_name); - const is_default_icon = default_icon_numbers.some((element) => file_name.endsWith(element)); - const chato_expression_src = is_default_icon ? getChatoImageByFileName(chato_list[index]) : null; - const random_delay = getRandomDelay(0.1, 6); - - return img_src ? ( -
- - {chato_expression_src && ( - - )} - {options.is_and_you_icon ? : null} -
- ) : null; - }); - }; - - return ( -
- {renderImages(imagesState.mogu_images, imagesState.chato_images, { class_name: styles.mogu_image })} - {renderImages(imagesState.mochi_images, imagesState.chato_images)} - {renderImages(imagesState.fuwa_images, imagesState.chato_images)} - {renderImages(imagesState.basic_images, imagesState.chato_images)} - {renderImages(imagesState.former_images, imagesState.chato_images)} - - {renderImages(imagesState.and_you_images, imagesState.chato_images, { is_and_you_icon: true, class_name: styles.and_you_image })} - -
- ); -}; - -const AndYouIcon = () => { - return ( - <> -
-
-
-
-

- FANBOX - -

- - ); }; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.module.scss b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.module.scss index 4288b653..3c678046 100644 --- a/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.module.scss @@ -1,205 +1,21 @@ .container { display: flex; - gap: 1.2rem; + gap: 3.2rem; flex-direction: column; justify-content: center; align-items: center; width: 100%; - // background-color: gray; +} +.supportersWrapper { + opacity: 0; + animation: fadeIn 0.8s ease-in-out 1.6s forwards; } -.support_us_container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 2rem; - width: 100%; - -} -.fanbox_img { - width: 60vw; -} - -.support_us_button_wrapper { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - gap: 4.8rem; -} -.fanbox_wrapper, .kofi_wrapper { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 1rem; -} -.fanbox_button { - width: 14rem; - transition: all 0.3s ease; - &:hover { - width: 16rem; +@keyframes fadeIn { + from { + opacity: 0; } -} -.kofi_preparing { - width: 6rem; -} - -.mainly_japanese, .mainly_english { - font-size: 1.2rem; - color: var(--dark_400_color); -} - - -.supporters_container { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - gap: 1rem; -} -.vrct_supporters_title { - height: 6rem; -} -.vrct_supporters_desc { - font-size: 1.4rem; - text-align: start; -} - -.supporters_wrapper { - display: flex; - justify-content: center; - align-items: center; - align-content: start; - flex-wrap: wrap; - column-gap: 1.4rem; - row-gap: 0.8rem; -} - -.supporter_image_wrapper { - position: relative; - width: 18rem; - overflow: hidden; -} - -.supporter_image { - width: 100%; -} - -.mogu_image { - position: relative; - &::after { - content: ""; - position: absolute; - top: -200%; - left: -200%; - width: 300%; - height: 300%; - background: linear-gradient(45deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.7) 50%, rgba(255, 255, 255, 0) 70%); - transform: rotate(90deg); - animation: shine 2.5s infinite; - filter: blur(0.4rem); - animation-delay: var(--delay, 0s); - } - -} - -@keyframes shine { - 0% { - top: -200%; - left: -200%; - } - 50% { - top: 50%; - left: 50%; - opacity: 0.7; - } - 100% { - top: 200%; - left: 200%; - } -} - -.default_chato_expression_image { - position: absolute; - top: 50%; - left: 2.9rem; - width: 2.8rem; - transform: translate(-50%, -50%) rotate(10deg); - opacity: 0.8; -} - -.and_you_container { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - transition: all 0.3s ease; -} - -.and_you_1, .and_you_2 { - width: 2.2rem; - height: 0.2rem; - border-radius: 50%; - background-color: var(--dark_400_color); -} - -.and_you_2 { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%) rotate(90deg); -} - -.supporter_image_wrapper { - &:hover .and_you_container { - top: 40%; - transform: translate(-50%, -50%) rotate(180deg); - } - &:hover .and_you_fanbox_link_text { - top: 70%; + to { opacity: 1; } -} - -.supporter_image_wrapper.and_you_image { - cursor: pointer; - &:active { - opacity: 0.6; - } -} - -.and_you_fanbox_link_text { - font-size: 1.2rem; - color: var(--dark_400_color); - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - transition: all 0.3s ease; - opacity: 0; -} - -.external_link_svg { - color: var(--dark_200_color); - width: 1.2rem; - margin-left: 0.6rem; - padding-bottom: 0.2rem; -} - -.vrct_supporters_desc_end { - font-size: 1.4rem; - margin-top: 2rem; - color: var(--dark_300_color); -} - -.progress_bar { - height: 0.2rem; - width: 0%; - &.progress_bar_active { - transition: width 20000ms linear; - background-color: var(--primary_400_color); - width: 100%; - } } \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/support_us_container/SupportUsContainer.jsx b/src-ui/app/config_page/setting_section/setting_box/supporters/support_us_container/SupportUsContainer.jsx new file mode 100644 index 00000000..7c357a9f --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/support_us_container/SupportUsContainer.jsx @@ -0,0 +1,48 @@ +import top_img from "@images/supporters/patreon_1600x400px.png"; +import fanbox_logo from "@images/supporters/fanbox_logo.png"; +import kofi_logo from "@images/supporters/kofi_logo.png"; +import patreon_logo from "@images/supporters/patreon_logo.png"; +import styles from "./SupportUsContainer.module.scss"; +import { clsx } from "clsx"; + +export const SupportUsContainer = () => { + return ( +
+ +
+ +
+
+
+
+
+
+
+
+ ); +}; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/support_us_container/SupportUsContainer.module.scss b/src-ui/app/config_page/setting_section/setting_box/supporters/support_us_container/SupportUsContainer.module.scss new file mode 100644 index 00000000..47ea8636 --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/support_us_container/SupportUsContainer.module.scss @@ -0,0 +1,219 @@ +$progress_ease: cubic-bezier(0, 1, 0.75, 1); + +@keyframes revealTopImg { + 0% { + clip-path: inset(0 50% 0 50%); + opacity: 0; + } + 100% { + clip-path: inset(0 0 0 0); + opacity: 1; + } +} + +@keyframes bounceIn { + 0% { + transform: translateY(100%); + opacity: 0; + } + 60% { + transform: translateY(-10%); + opacity: 1; + } + 80% { + transform: translateY(10%); + opacity: 1; + } + 100% { + transform: translateY(0); + opacity: 1; + } +} + +@keyframes expandWidth { + 0% { + transform: scaleX(0); + } + 100% { + transform: scaleX(1); + } +} + +.support_us_container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 1.4rem; + width: 100%; +} + +.support_buttons_wrapper { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 1.2rem; +} + +.top_img { + width: 100%; + animation: revealTopImg 0.8s ease forwards; +} + +.lines_container { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + gap: 3.6rem; +} + +.line_basic, +.line_fuwa, +.line_mochi, +.line_mogu { + width: 8.6rem; + height: 0.2rem; + transform: scaleX(0); + transform-origin: left center; +} + +.line_basic { + background-color: var(--dark_800_color); + animation: expandWidth 1s $progress_ease 0.4s forwards; +} + +.line_fuwa { + background-color: #5788a2; + animation: expandWidth 1s $progress_ease 0.6s forwards; +} + +.line_mochi { + background-color: var(--received_300_color); + animation: expandWidth 1s $progress_ease 0.8s forwards; +} + +.line_mogu { + background-color: var(--dark_basic_text_color); + animation: expandWidth 1s $progress_ease 1s forwards; +} + +.support_us_button_wrapper { + display: flex; + justify-content: center; + align-items: center; + column-gap: 3.6rem; + flex-wrap: wrap; +} + +.support_button { + position: relative; + padding: 1.2rem 1.6rem; + opacity: 0; + transform: translateY(100%); +} + +.support_button:nth-child(1) { + animation: bounceIn 0.4s ease-out 1.2s forwards; +} +.support_button:nth-child(2) { + animation: bounceIn 0.4s ease-out 1.4s forwards; +} +.support_button:nth-child(3) { + animation: bounceIn 0.4s ease-out 1.6s forwards; +} + + +.support_img { + &.fanbox_logo { + height: 1.8rem; + } + &.kofi_logo, &.patreon_logo { + height: 2.2rem; + } +} + + +.spiral_top::before, +.spiral_top::after, +.spiral_bottom::before, +.spiral_bottom::after { + content: ""; + position: absolute; + transition-duration: 0.3s; +} + +.spiral_top::before { + background: var(--dark_800_color); + box-shadow: 0 0 0.4rem 0 var(--dark_800_color); +} +.spiral_top::after { + background: #5788a2; + box-shadow: 0 0 0.4rem 0 #5788a2; +} +.spiral_bottom::before { + background: var(--received_300_color); + box-shadow: 0 0 0.4rem 0 var(--received_300_color); +} +.spiral_bottom::after { + background: var(--dark_basic_text_color); + box-shadow: 0 0 0.4rem 0 var(--dark_basic_text_color); +} + +.spiral_top::before { + top: 0; + left: 0; + width: 0.1rem; + height: 0; +} +.spiral_top::after { + top: 0; + right: 0; + width: 0; + height: 0.1rem; +} +.spiral_bottom::before { + bottom: 0; + left: 0; + width: 0; + height: 0.1rem; +} +.spiral_bottom::after { + bottom: 0; + right: 0; + width: 0.1rem; + height: 0; +} + + +.support_button:hover .spiral_top::before { + height: 100%; +} +.support_button:hover .spiral_top::after { + width: 100%; +} +.support_button:hover .spiral_bottom::before { + width: 100%; +} +.support_button:hover .spiral_bottom::after { + height: 100%; +} + + +.supporters_container { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 1rem; +} + +.vrct_supporters_title { + height: 6rem; +} + +.vrct_supporters_desc { + font-size: 1.4rem; + text-align: start; +} diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/SupportersContainer.jsx b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/SupportersContainer.jsx new file mode 100644 index 00000000..7fba643c --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/SupportersContainer.jsx @@ -0,0 +1,30 @@ +import styles from "./SupportersContainer.module.scss"; +import { SupportersWrapper } from "./supporters_wrapper/SupportersWrapper"; +import { useSupporters } from "@logics_configs"; +import { supporters_images_url } from "@ui_configs"; +import vrct_supporters_title from "@images/supporters/vrct_supporters_title.png"; + +export const SupportersContainer = () => { + const { currentSupportersData } = useSupporters(); + + if (currentSupportersData.state === "error") + return
Failed to retrieve data.
; + + if (currentSupportersData.state === "pending" || currentSupportersData.data === null) + return
Loading...
; + + const supporters_settings = currentSupportersData.data.supporters_settings; + const last_updated_local_date = new Date(supporters_settings.last_updated_utc_date).toLocaleString(); + + return ( +
+
+ + +

{`Last updated date: ${last_updated_local_date}`}

+
+ +

{`みなさんのおかげで、みしゃ社長は布団で寝ることを許され(in開発室) しいなは喜び庭駆け回っています!!!ふわもちもぐもぐです!ありがとうございます。これからもまだまだ進化するVRCTをどうかよろしくお願いします!\nThanks to everyone, Misha has been granted the privilege of sleeping in a proper bed (in the development room), and Shiina is so happy, running around the yard! Fuwa-mochi-mogu-mogu! Thank you so much! We hope you'll continue to support the ever-evolving VRCT!`}

+
+ ); +}; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/SupportersContainer.module.scss b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/SupportersContainer.module.scss new file mode 100644 index 00000000..19546afc --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/SupportersContainer.module.scss @@ -0,0 +1,34 @@ +.supporters_container { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 1rem; +} + +.vrct_supporters_title_wrapper { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 0.2rem; + width: 100%; +} +.vrct_supporters_title { + height: 4.2rem; +} +.calc_period { + height: 1.6rem; +} +.last_updated_local_date { + font-size: 1.2rem; + color: var(--dark_600_color); + width: 100%; + text-align: end; +} + +.vrct_supporters_desc_end { + font-size: 1.4rem; + margin-top: 2rem; + color: var(--dark_300_color); +} \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/supporters_wrapper/SupportersWrapper.jsx b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/supporters_wrapper/SupportersWrapper.jsx new file mode 100644 index 00000000..c6397255 --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/supporters_wrapper/SupportersWrapper.jsx @@ -0,0 +1,316 @@ +import React, { useState, useCallback, useEffect } from "react"; +import clsx from "clsx"; +import ArrowLeftSvg from "@images/arrow_left.svg?react"; +import styles from "./SupportersWrapper.module.scss"; +import { shuffleArray, randomIntMinMax, randomMinMax } from "@utils"; + +import { + useSettingBoxScrollPosition, + useSupporters, +} from "@logics_configs"; + +import { supporters_images_url } from "@ui_configs"; + +const SHUFFLE_INTERVAL_TIME = 20000; + +const and_you_data = { + supporter_id: "and_you", +}; + + +const image_sets = { + supporter_cards: `${supporters_images_url}/supporter_cards/`, + chato_expressions: `${supporters_images_url}/chato_expressions/`, + supporters_labels: `${supporters_images_url}/supporters_labels/`, + supporters_icons: `${supporters_images_url}/supporters_icons/`, +}; + +const getSupporterCard = (plan_name) => { + const card_map = { + "mogu_2000": "mogu_card", + "mochi_1000": "mochi_card", + "fuwa_500": "fuwa_card", + "basic_300": "basic_card", + }; + if (!card_map[plan_name]) return `${image_sets.supporter_cards}basic_card.png`; + + return `${image_sets.supporter_cards}${card_map[plan_name]}.png`; +}; + +const getChatoExpressionsPath = (file_name) => `${image_sets.chato_expressions}${file_name}.png`; +const getSupportersLabelsPath = (file_name) => `${image_sets.supporters_labels}${file_name}.png`; +const getSupportersIconsPath = (file_name) => `${image_sets.supporters_icons}${file_name}.png`; + + +export const SupportersWrapper = () => { + const { saveScrollPosition, restoreScrollPosition } = useSettingBoxScrollPosition(); + const { currentSupportersData } = useSupporters(); + + const [json_data, setJsonData] = useState(); + const [supportersData, setSupportersData] = useState([]); + const [chatoExpressions, setChatoExpressions] = useState([]); + + useEffect(() => { + setJsonData(currentSupportersData.data); + }, [currentSupportersData.data]); + + const supporters_settings = currentSupportersData.data.supporters_settings; + const calc_support_period = supporters_settings.calc_support_period; + const chato_ex_count = supporters_settings.chato_ex_count; + + const recalcAndUpdateSupporters = useCallback(() => { + if (!json_data) return; + + const grouped_data = { + mogu_2000: [], + mochi_1000: [], + fuwa_500: [], + basic_300: [], + former_supporter: [], + and_you: [], + }; + + json_data.supporters_data.forEach((supporter) => { + const value = supporter.highest_plan_during_the_period || "former_supporter"; + if (grouped_data[value]) { + grouped_data[value].push(supporter); + } else { + grouped_data["former_supporter"].push(supporter); + } + }); + + const newSupportersData = [ + ...shuffleArray(grouped_data["mogu_2000"]), + ...shuffleArray(grouped_data["mochi_1000"]), + ...shuffleArray(grouped_data["fuwa_500"]), + ...shuffleArray(grouped_data["basic_300"]), + ...shuffleArray(grouped_data["former_supporter"]), + and_you_data, + ]; + + setSupportersData(newSupportersData); + + setChatoExpressions( + newSupportersData.map(() => + getChatoExpressionsPath( + `chato_expression_${randomIntMinMax(1, chato_ex_count)}` + ) + ) + ); + }, [json_data]); + + useEffect(() => { + recalcAndUpdateSupporters(); + }, [json_data, recalcAndUpdateSupporters]); + + const shuffleSupporters = useCallback(() => { + if (!json_data) return; + saveScrollPosition(); + recalcAndUpdateSupporters(); + setTimeout(() => restoreScrollPosition(), 0); + }, [json_data, recalcAndUpdateSupporters, saveScrollPosition, restoreScrollPosition]); + + useEffect(() => { + const interval = setInterval(() => { + shuffleSupporters(); + }, SHUFFLE_INTERVAL_TIME); + + return () => clearInterval(interval); + }, [shuffleSupporters]); + + return ( +
+ +
+ +
+ +
+ ); +}; + +const AndYouIcon = () => { + return ( + <> +
+
+
+
+

+ FANBOX Ko-fi Patreon +

+ + + ); +}; + +const SupporterCardsComponent = ({ supportersData, chatoExpressions, calc_support_period }) => { + return supportersData.map((item, index) => { + const target_plan = item.highest_plan_during_the_period; + + const img_src = getSupporterCard(target_plan); + + const is_and_you = item.supporter_id === "and_you"; + + const random_delay = `${randomMinMax(0.1, 6).toFixed(1)}s`; + + const supporter_image_wrapper_classname = clsx( + styles.supporter_image_wrapper, + { + [styles.mogu_image]: target_plan === "mogu_2000", + } + ); + + return is_and_you ? ( + +
+
+ supporter + + +
+
+
+ ) : img_src ? ( +
+
+ supporter + +
+ +
+ ) : null; + }); +}; + +const SupporterLabelComponent = ({ item, target_plan, chato_src }) => { + const is_icon_plan = ["mogu_2000", "mochi_1000"].includes( + target_plan + ); + + const supporter_label_component_classname = clsx( + styles.supporter_label_component, + { + [styles.is_icon_plan]: is_icon_plan, + } + ); + + const is_and_you = item.supporter_id === "and_you"; + const is_default_icon = item.supporter_icon_id === ""; + + const file_name = is_and_you ? "and_you" : `supporter_${item.supporter_id}`; + const label_img_src = getSupportersLabelsPath(file_name); + const icon_img_src = getSupportersIconsPath( + `supporter_icon_${item.supporter_icon_id}` + ); + + return ( +
+ {is_icon_plan && ( +
+ {is_default_icon ? ( + chato expression + ) : ( + supporter icon + )} +
+ )} + supporter label +
+ ); +}; + +const SupporterPeriodContainer = ({ settings, calc_support_period }) => { + const period_data = extractKeys(settings, calc_support_period); + return ( +
+ {Object.entries(period_data).map(([key, item], index) => { + if (item === "") return null; + const class_name = clsx(styles.period_box, { + [styles.mogu_bar]: item === "mogu_2000", + [styles.mochi_bar]: item === "mochi_1000", + [styles.fuwa_bar]: item === "fuwa_500", + [styles.basic_bar]: item === "basic_300", + }); + + return
; + })} +
+ ); +}; + +const extractKeys = (data, keys_to_extract) => { + const result = {}; + for (const key of keys_to_extract) { + if (key in data) { + result[key] = data[key]; + } + } + return result; +}; + + +const ProgressBar = () => { + const [is_active, setIsActive] = useState(false); + useEffect(() => { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + setIsActive(true); + }); + }); + + const interval = setInterval(() => { + setIsActive(false); + setTimeout(() => setIsActive(true), 50); + }, SHUFFLE_INTERVAL_TIME); + + return () => clearInterval(interval); + }, []); + + return ( +
+ ); +}; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/supporters_wrapper/SupportersWrapper.module.scss b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/supporters_wrapper/SupportersWrapper.module.scss new file mode 100644 index 00000000..19cbb0ac --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/supporters/supporters_container/supporters_wrapper/SupportersWrapper.module.scss @@ -0,0 +1,240 @@ +.container { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 2rem; +} + +.supporters_wrapper { + display: flex; + justify-content: center; + align-items: center; + align-content: start; + flex-wrap: wrap; + column-gap: 1.8rem; + row-gap: 1rem; +} + +.supporter_image_container { + position: relative; + width: 18rem; + display: flex; + flex-direction: column; + gap: 0.3rem; +} + +.supporter_image_wrapper { + position: relative; + overflow: hidden; +} + +.supporter_image { + position: relative; + width: 100%; +} + +.supporter_label_component { + position: absolute; + left: 0.6rem; + &.is_icon_plan { + top: 50%; + transform: translateY(-50%); + } + top: 0.4rem; + display: flex; + justify-content: center; + gap: 0.4rem; +} + +.supporter_label_image { + height: 2rem; + // margin-top: 0.2rem; + &.small { + height: 1.4rem; + } +} + +.supporter_icon_wrapper { + height: 4rem; + aspect-ratio: 1 /1; + border-radius: 50%; + background-color: #ffffff; + overflow: hidden; + position: relative; +} + +.supporter_icon { + aspect-ratio: 1 / 1; + height: 100%; + width: 100%; +} + +.default_chato_expression_image { + position: absolute; + top: 52%; + left: 50%; + transform: translate(-50%, -50%) rotate(10deg); + width: 2.8rem; + opacity: 0.8; +} + +.mogu_image { + position: relative; + &::after { + content: ""; + position: absolute; + top: -200%; + left: -200%; + width: 300%; + height: 300%; + background: linear-gradient(45deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.7) 50%, rgba(255, 255, 255, 0) 70%); + transform: rotate(90deg); + animation: shine 2.5s infinite; + filter: blur(0.4rem); + animation-delay: var(--delay, 0s); + } + +} + +@keyframes shine { + 0% { + top: -200%; + left: -200%; + } + 50% { + top: 50%; + left: 50%; + opacity: 0.7; + } + 100% { + top: 200%; + left: 200%; + } +} + + + +.and_you_container { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + transition: all 0.3s ease; +} + +.and_you_1, .and_you_2 { + width: 2.2rem; + height: 0.2rem; + border-radius: 50%; + background-color: var(--dark_400_color); +} + +.and_you_2 { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%) rotate(90deg); +} + +.supporter_image_container { + &:hover .and_you_container { + top: 36%; + transform: translate(-50%, -50%) rotate(180deg); + animation: disappear 0.3s forwards; + } + &:hover .and_you_fanbox_link_text { + top: 74%; + opacity: 1; + } + &:hover .arrow_left_svg { + opacity: 0; + animation: arrow_up_down 0.3s forwards; + animation-delay: 0.3s; + } +} + +.supporter_image_container.and_you_image { + cursor: pointer; + &:active { + opacity: 0.6; + } +} + +.and_you_fanbox_link_text { + font-size: 1.2rem; + color: var(--dark_400_color); + position: absolute; + top: 50%; + left: 50%; + width: 100%; + text-align: center; + transform: translate(-50%, -50%); + transition: all 0.3s ease; + opacity: 0; +} + +.arrow_left_svg { + position: absolute; + top: 60%; + left: 50%; + transform: translate(-50%, -50%) rotate(90deg); + color: var(--dark_400_color); + width: 2rem; + opacity: 0; +} + +@keyframes arrow_up_down { + 0% { + top: 60%; + } + 100% { + top: 36%; + opacity: 1; + } +} + +@keyframes disappear { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + + +.supporter_period_container { + display: flex; + gap: 0.2rem; + padding-left: 0.4rem; +} + +.period_box { + width: 1.8rem; + height: 0.3rem; + border-radius: 0.3rem; + &.mogu_bar { + background-color: var(--dark_basic_text_color); + } + &.mochi_bar { + background-color: var(--received_300_color); + } + &.fuwa_bar { + background-color: #5788a2; + } + &.basic_bar { + background-color: var(--dark_800_color); + } +} + + +.progress_bar { + height: 0.2rem; + width: 0%; + &.progress_bar_active { + transition: width 20000ms linear; + background-color: var(--primary_400_color); + width: 100%; + } +} \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss b/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss index 83dec71d..35798530 100644 --- a/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss @@ -39,7 +39,7 @@ background-color: var(--dark_850_color); } &.is_selected .controller_switcher_label { - color: var(--dark_basic_text_color); + color: var(--dark_200_color); } } .controller_switcher_label { @@ -92,7 +92,6 @@ transform: translateX(10%) rotate(90deg); } .sample_text_button_label { - color: var(--dark_basic_text_color); position: absolute; left: 50%; top: 110%; @@ -281,7 +280,6 @@ } .restore_default_settings_button { - color: var(--dark_basic_text_color); font-size: 1.2rem; margin-top: 6rem; padding: 0.8rem; diff --git a/src-ui/app/config_page/sidebar_section/SidebarSection.jsx b/src-ui/app/config_page/sidebar_section/SidebarSection.jsx index 2b109910..6938f97f 100644 --- a/src-ui/app/config_page/sidebar_section/SidebarSection.jsx +++ b/src-ui/app/config_page/sidebar_section/SidebarSection.jsx @@ -3,18 +3,21 @@ import styles from "./SidebarSection.module.scss"; export const SidebarSection = () => { return (
-
- - - - - - - -
-
- - +
+
+ + + + + + + + +
+
+ + +
); diff --git a/src-ui/app/config_page/sidebar_section/SidebarSection.module.scss b/src-ui/app/config_page/sidebar_section/SidebarSection.module.scss index 6051cff6..383ef8cb 100644 --- a/src-ui/app/config_page/sidebar_section/SidebarSection.module.scss +++ b/src-ui/app/config_page/sidebar_section/SidebarSection.module.scss @@ -1,10 +1,15 @@ .container { width: var(--config_page_sidebar_width); flex-shrink: 0; + padding: 0rem 0rem 5.8rem 1.2rem; +} + +.scroll_container { display: flex; flex-direction: column; justify-content: space-between; - padding: 0rem 0rem 5.8rem 1.2rem; + overflow-y: auto; + height: 100%; max-height: 60rem; } @@ -22,7 +27,6 @@ display: flex; justify-content: left; align-items: center; - color: var(--dark_basic_text_color); padding: 0.8rem 0 0.8rem 1rem; cursor: pointer; &:hover { diff --git a/src-ui/app/config_page/version_label/VersionLabel.jsx b/src-ui/app/config_page/version_label/VersionLabel.jsx new file mode 100644 index 00000000..f6325165 --- /dev/null +++ b/src-ui/app/config_page/version_label/VersionLabel.jsx @@ -0,0 +1,49 @@ +import { useTranslation } from "react-i18next"; +import { useState } from "react"; +import { clsx } from "clsx"; +import styles from "./VersionLabel.module.scss"; + +import { useSoftwareVersion } from "@logics_configs"; +import { useComputeMode } from "@logics_common"; +import CopySvg from "@images/copy.svg?react"; +import CheckMarkSvg from "@images/check_mark.svg?react"; + +export const VersionLabel = () => { + const [is_copied, setIsCopied] = useState(false); + + const { t } = useTranslation(); + const { currentSoftwareVersion } = useSoftwareVersion(); + const { currentComputeMode } = useComputeMode(); + + const version_label = currentComputeMode.data === "cpu" + ? t("config_page.version", { version: currentSoftwareVersion.data }) + : currentComputeMode.data === "cuda" + ? t("config_page.version", { version: currentSoftwareVersion.data }) + " CUDA" + : t("config_page.version", { version: currentSoftwareVersion.data }); + + const is_cpu = currentComputeMode.data === "cpu"; + + const copyToClipboard = async () => { + if (is_copied) return; + const copy_text = is_cpu ? `${currentSoftwareVersion.data}` : `${currentSoftwareVersion.data} CUDA`; + await navigator.clipboard.writeText(copy_text); + setIsCopied(true); + + setTimeout(() => { + setIsCopied(false); + }, 1000); + }; + + + return ( +
+
+

{version_label}

+ {is_copied + ? + : + } +
+
+ ); +}; \ No newline at end of file diff --git a/src-ui/app/config_page/version_label/VersionLabel.module.scss b/src-ui/app/config_page/version_label/VersionLabel.module.scss new file mode 100644 index 00000000..78edf79c --- /dev/null +++ b/src-ui/app/config_page/version_label/VersionLabel.module.scss @@ -0,0 +1,33 @@ +.container { + position: absolute; + bottom: 1.2rem; + left: 1.4rem; + font-size: 1.2rem; + color: var(--dark_400_color); +} + +.wrapper { + position: relative; + display: flex; + align-items: center; + gap: 0.6rem; + cursor: pointer; + &.is_copied { + cursor: default; + } +} + +.version_label { + font-size: 1.2rem; + color: var(--dark_400_color); +} + +.copy_svg { + width: 1.4rem; + color: var(--dark_500_color); +} + +.check_mark_svg { + width: 1.4rem; + color: var(--primary_300_color); +} \ No newline at end of file diff --git a/src-ui/app/main_page/MainPage.module.scss b/src-ui/app/main_page/MainPage.module.scss index 50fbe594..da3e7880 100644 --- a/src-ui/app/main_page/MainPage.module.scss +++ b/src-ui/app/main_page/MainPage.module.scss @@ -25,40 +25,4 @@ justify-content: space-between; background-color: var(--dark_888_color); position: relative; -} - -.main_page_cover { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background-color: (#000000cc); - display: flex; - flex-direction: column; - gap: 2rem; - justify-content: center; - align-items: center; - backdrop-filter: blur(0.8rem); - color: var(--dark_basic_text_color); -} - -.cover_message { - font-size: 2rem; - font-weight: 300; -} - -.close_settings_window_button { - font-size: 1.6rem; - font-weight: 300; - padding: 1rem 1.4rem; - border-radius: 0.4rem; - background-color: var(--dark_888_color); - cursor: pointer; - &:hover { - background-color: var(--dark_825_color); - } - &:active { - background-color: var(--dark_925_color); - } } \ No newline at end of file diff --git a/src-ui/app/main_page/main_section/language_selector/LanguageSelector.module.scss b/src-ui/app/main_page/main_section/language_selector/LanguageSelector.module.scss index 4a9fd247..64bd1b53 100644 --- a/src-ui/app/main_page/main_section/language_selector/LanguageSelector.module.scss +++ b/src-ui/app/main_page/main_section/language_selector/LanguageSelector.module.scss @@ -46,5 +46,4 @@ .language_label { font-size: 1.4rem; - color: var(--dark_basic_text_color); } \ No newline at end of file diff --git a/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx b/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx index dbc5c100..be95b1c0 100644 --- a/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx +++ b/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx @@ -1,99 +1,67 @@ import { useResizable } from "react-resizable-layout"; -import { useRef, useEffect, useState } from "react"; +import { useRef, useEffect, useState, forwardRef } from "react"; import styles from "./MessageContainer.module.scss"; -import { appWindow } from "@tauri-apps/api/window"; import { LogBox } from "./log_box/LogBox"; import { MessageLogSettingsContainer } from "./message_log_settings_container/MessageLogSettingsContainer"; import { MessageInputBox } from "./message_input_box/MessageInputBox"; import { useMessageInputBoxRatio } from "@logics_main"; -import { useUiScaling } from "@logics_configs"; -import { useStore_IsAppliedInitMessageBoxHeight } from "@store"; export const MessageContainer = () => { const { currentMessageInputBoxRatio, asyncSetMessageInputBoxRatio } = useMessageInputBoxRatio(); - const { currentUiScaling } = useUiScaling(); + const [ui_message_box_ratio, setUiMessageBoxRatio] = useState(false); const [is_hovered, setIsHovered] = useState(false); - const [message_box_height_in_rem, setMessageBoxHeightInRem] = useState(10); - const FONT_SIZE_STANDARD = 10 * currentUiScaling.data / 100; // 10px = 1rem - const { currentIsAppliedInitMessageBoxHeight, updateIsAppliedInitMessageBoxHeight } = useStore_IsAppliedInitMessageBoxHeight(); const container_ref = useRef(null); + const separator_ref = useRef(null); const log_box_ref = useRef(null); - const message_box_wrapper_ref = useRef(null); + const message_input_box_wrapper_ref = useRef(null); - const asyncSetMessageBoxHeightInRem = async (data) => { - const minimized = await appWindow.isMinimized(); - if (minimized) return; // don't save while the window is minimized. - setMessageBoxHeightInRem(data); + const calculateMessageInputBoxRatio = (position) => { + if (log_box_ref.current && message_input_box_wrapper_ref.current && separator_ref.current && container_ref.current) { + const container_padding_bottom = parseFloat( + window.getComputedStyle(container_ref.current).paddingBottom + ); + const total_height = + log_box_ref.current.offsetHeight + + separator_ref.current.offsetHeight * 2 + + message_input_box_wrapper_ref.current.offsetHeight; + const adjusted_position = position - container_padding_bottom; + const message_box_ratio = (adjusted_position / total_height) * 100; + return message_box_ratio; + } + console.warn("References not ready for calculation"); + return 10; // Default initial height percentage }; - const calculateMessageBoxRatioAndHeight = () => { - if (!currentIsAppliedInitMessageBoxHeight.data) { - asyncSetMessageInputBoxRatio(currentMessageInputBoxRatio.data); - asyncSetMessageBoxHeightInRem(convertRatioToRem(currentMessageInputBoxRatio.data)); - return; - } - - if (log_box_ref.current && message_box_wrapper_ref.current && container_ref.current) { - const container_height = container_ref.current.offsetHeight; - const container_padding_bottom = parseFloat(window.getComputedStyle(container_ref.current).paddingBottom); - const total_height = container_height - container_padding_bottom; - - const message_box_height = message_box_wrapper_ref.current.offsetHeight; - const message_box_ratio = (message_box_height / total_height) * 100; - - asyncSetMessageInputBoxRatio(message_box_ratio); - asyncSetMessageBoxHeightInRem(convertRatioToRem(message_box_ratio)); - } else { - console.warn("References not ready for calculation"); + const asyncSaveRatio = (position) => { + if (position > 0) { + asyncSetMessageInputBoxRatio(calculateMessageInputBoxRatio(position)); } }; const { position, separatorProps } = useResizable({ axis: "y", reverse: true, - onResizeEnd: calculateMessageBoxRatioAndHeight, }); useEffect(() => { - asyncSetMessageBoxHeightInRem((position / FONT_SIZE_STANDARD) - 1.4); + if (position > 0) { + setUiMessageBoxRatio(calculateMessageInputBoxRatio(position)); + const timeout = setTimeout(() => { + asyncSaveRatio(position); + }, 200); + return () => clearTimeout(timeout); + } }, [position]); useEffect(() => { - asyncSetMessageBoxHeightInRem(convertRatioToRem(currentMessageInputBoxRatio.data)); - }, [currentMessageInputBoxRatio.data]); - - const convertRatioToRem = (ratio) => { - if (!container_ref.current) return 0; - const container_height = container_ref.current.offsetHeight; - const container_padding_bottom = parseFloat(window.getComputedStyle(container_ref.current).paddingBottom); - const total_height = container_height - container_padding_bottom; - return total_height === 0 ? 0 : ((ratio / 100) * total_height / FONT_SIZE_STANDARD); - }; - - useEffect(() => { - calculateMessageBoxRatioAndHeight(); - updateIsAppliedInitMessageBoxHeight(true); // Ensure this happens after initial calculation - }, []); - - useEffect(() => { - let resizeTimeout; - - const unlisten = appWindow.onResized(() => { - clearTimeout(resizeTimeout); - resizeTimeout = setTimeout(() => { - calculateMessageBoxRatioAndHeight(); - }, 200); - }); - - return () => { - unlisten.then((dispose) => dispose()); - }; - }, []); + setUiMessageBoxRatio(currentMessageInputBoxRatio.data); + }, [currentMessageInputBoxRatio]); return (
-
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} @@ -101,11 +69,11 @@ export const MessageContainer = () => {
- +
@@ -113,8 +81,8 @@ export const MessageContainer = () => { ); }; -const Separator = ({ onDragStart, ...props }) => ( -
+const Separator = forwardRef((props, ref) => ( +
-); +)); diff --git a/src-ui/app/main_page/main_section/message_container/MessageContainer.module.scss b/src-ui/app/main_page/main_section/message_container/MessageContainer.module.scss index e1886dfe..55b8a8be 100644 --- a/src-ui/app/main_page/main_section/message_container/MessageContainer.module.scss +++ b/src-ui/app/main_page/main_section/message_container/MessageContainer.module.scss @@ -36,7 +36,7 @@ } .message_box_resize_wrapper { - height: 10rem; + height: 10%; min-height: 3.8rem; max-height: 90%; } \ No newline at end of file diff --git a/src-ui/app/main_page/main_section/message_container/log_box/LogBox.jsx b/src-ui/app/main_page/main_section/message_container/log_box/LogBox.jsx index 4f9ef5a0..8aa8d2ec 100644 --- a/src-ui/app/main_page/main_section/message_container/log_box/LogBox.jsx +++ b/src-ui/app/main_page/main_section/message_container/log_box/LogBox.jsx @@ -1,50 +1,26 @@ -import { useEffect, useLayoutEffect, useRef, useState } from "react"; +import React, { useRef, useLayoutEffect, useEffect } from "react"; import styles from "./LogBox.module.scss"; -import { store } from "@store"; import { MessageContainer } from "./message_container/MessageContainer"; -import { scrollToBottom } from "@utils"; import { useMessage } from "@logics_common"; +import { useMessageLogScroll } from "@logics_main"; +import { store } from "@store"; export const LogBox = () => { const { currentMessageLogs } = useMessage(); - const log_container_ref = useRef(null); - const [is_scrolling, setIsScrolling] = useState(false); - + const { scrollToBottom, isScrolling } = useMessageLogScroll(); + const logContainerRef = useRef(null); useLayoutEffect(() => { - store.log_box_ref = log_container_ref; - if (!is_scrolling) { - scrollToBottom(store.log_box_ref); - // scrollToBottom(store.log_box_ref, true); [Fix me] + store.log_box_ref = logContainerRef; + if (!isScrolling) { + scrollToBottom(); } - }, [currentMessageLogs.data]); - - useEffect(() => { - const handleScroll = () => { - const element = log_container_ref.current; - if (!element) return; - const currentScrollTop = element.scrollTop; - const at_bottom = element.scrollHeight - currentScrollTop === element.clientHeight; - - if (at_bottom) { - setIsScrolling(false); - } else { - setIsScrolling(true); - } - }; - - const element = log_container_ref.current; - element.addEventListener("scroll", handleScroll); - - return () => { - element.removeEventListener("scroll", handleScroll); - }; - }, []); + }, [currentMessageLogs.data, isScrolling]); return ( -
+
- {currentMessageLogs.data.map(message_data => ( + {currentMessageLogs.data.map((message_data) => ( ))}
diff --git a/src-ui/app/main_page/main_section/message_container/log_box/message_container/MessageContainer.module.scss b/src-ui/app/main_page/main_section/message_container/log_box/message_container/MessageContainer.module.scss index 309da7f8..ea82b297 100644 --- a/src-ui/app/main_page/main_section/message_container/log_box/message_container/MessageContainer.module.scss +++ b/src-ui/app/main_page/main_section/message_container/log_box/message_container/MessageContainer.module.scss @@ -72,18 +72,21 @@ display: flex; flex-direction: column; &.sent_message { + width: 100%; align-items: end; text-align: end; } &.received_message { + width: 100%; align-items: start; } } .message_main { - color: var(--dark_basic_text_color); user-select: text; font-size: 1.4em; + overflow-wrap: break-word; + max-width: 100%; } .message_second { diff --git a/src-ui/app/main_page/main_section/message_container/log_box/message_container/message_sub_menu_container/MessageSubMenuContainer.module.scss b/src-ui/app/main_page/main_section/message_container/log_box/message_container/message_sub_menu_container/MessageSubMenuContainer.module.scss index 30b436b1..0fff2f3b 100644 --- a/src-ui/app/main_page/main_section/message_container/log_box/message_container/message_sub_menu_container/MessageSubMenuContainer.module.scss +++ b/src-ui/app/main_page/main_section/message_container/log_box/message_container/message_sub_menu_container/MessageSubMenuContainer.module.scss @@ -30,7 +30,7 @@ .tooltip_title { font-size: 1.2rem; - color: var(--dark_basic_text_color); + color: var(--dark_200_color); } .hold_progress_bar { diff --git a/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx b/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx index 88ee0605..a8be8e2e 100644 --- a/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx +++ b/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx @@ -1,10 +1,11 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useLayoutEffect, useRef } from "react"; import styles from "./MessageInputBox.module.scss"; import SendMessageSvg from "@images/send_message.svg?react"; import { useMessage } from "@logics_common"; import { useSendMessageButtonType, useEnableAutoClearMessageInputBox } from "@logics_configs"; +import { useMessageLogScroll } from "@logics_main"; import { store } from "@store"; -import { scrollToBottom } from "@utils"; +import { appWindow } from "@tauri-apps/api/window"; export const MessageInputBox = () => { const [message_history, setMessageHistory] = useState([]); @@ -21,6 +22,14 @@ export const MessageInputBox = () => { const { currentEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox(); const { currentSendMessageButtonType } = useSendMessageButtonType(); + const { scrollToBottom } = useMessageLogScroll(); + + const log_box_ref = useRef(null); + + useLayoutEffect(() => { + store.text_area_ref = log_box_ref; + }, []); + useEffect(() => { if (currentMessageLogs.data) { const sentMessages = currentMessageLogs.data @@ -32,6 +41,7 @@ export const MessageInputBox = () => { const onSubmitFunction = (e) => { e.preventDefault(); + // appWindow.minimize(); if (!currentMessageInputValue.data.trim()) return updateMessageInputValue(""); @@ -40,7 +50,7 @@ export const MessageInputBox = () => { if (currentEnableAutoClearMessageInputBox.data) updateMessageInputValue(""); setTimeout(() => { - scrollToBottom(store.log_box_ref); + scrollToBottom(); }, 10); setHistoryIndex(-1); @@ -69,7 +79,7 @@ export const MessageInputBox = () => { if (history_index > -1) { const new_index = history_index - 1; setHistoryIndex(new_index); - setInputValue( + updateMessageInputValue( new_index >= 0 ? message_history[message_history.length - 1 - new_index] : "" @@ -89,6 +99,7 @@ export const MessageInputBox = () => {