Merge branch 'develop' into plugins_system

# Conflicts:
#	src-tauri/tauri.conf.json
This commit is contained in:
Sakamoto Shiina
2025-04-24 02:20:00 +09:00
42 changed files with 716 additions and 589 deletions

116
README.md
View File

@@ -1,116 +0,0 @@
<div align="center">
<picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture>
<br>
<br>
[![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)
[![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)
<h3>
Become a VRCT Supporter on:
</h3>
<a href="https://vrct-dev.fanbox.cc">
<picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture>
</a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev">
<picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px">
</picture>
</a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev">
<picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px">
</picture>
</a>&emsp;&nbsp;
<br>
<picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border">
</picture>
<br>
<br>
| **English** | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) |
<h3>
VRCT is software that supports VRChat conversations with translation and transcription.
</h3>
![](docs/main_window.png)
<div align="left">
# Download & Install
Download from anywhere you like.
- [Github.com](https://github.com/misyaguziya/VRCT/releases/)
- [BOOTH.pm](https://misyaguziya.booth.pm/items/5155325)
Just download and run the exe.
# What is VRCT?
VRCT is software that supports conversations between people who speak different languages by providing chat or voice translation.
These features are designed for use within VRChat.
*Although not supported, it is also used for other purposes such as watching movies.
VRCT supports your conversations with
- 💬 **Send chat to VRChat**
- 🌐 **Translation**
- 🎙 **Transcription of audio from microphone**
- 🔈 **Transcription of audio from Speaker**
# Documents
Initial setup, basic functions, and other features are also described.
- [Documents Link](https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246?pvs=4)
# How to Use (YouTube)
<div align="center">
[![](https://img.youtube.com/vi/rUTad037n8Q/0.jpg)](https://www.youtube.com/watch?v=rUTad037n8Q)
<div align="left">
# If you want to run it in python
1. Install the following version of python.
`python version 3.11.5`
2. Install package and run main.py.
```bash
./install.bat
python main.py
```
## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (Main Development)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI multilingual support)
- [レラ](https://github.com/soumt-r) (Technical Support)
- [どね](https://twitter.com/done_vrc) (Logo Design)
## Thanks to our contributors
<a href="https://github.com/misyaguziya/VRCT/graphs/contributors" target="_blank">
<img src="https://contrib.rocks/image?repo=misyaguziya/VRCT" />
</a>
---
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.

1
README.md Symbolic link
View File

@@ -0,0 +1 @@
docs/readmes/README.en.md

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 182 B

View File

Before

Width:  |  Height:  |  Size: 186 B

After

Width:  |  Height:  |  Size: 186 B

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

107
docs/readmes/README.en.md Normal file
View File

@@ -0,0 +1,107 @@
<div align="center">
<picture>
<source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture>
<br>
<br>
[![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)
[![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)
<h3>
Become a VRCT Supporter on:
</h3>
<a href="https://vrct-dev.fanbox.cc">
<picture>
<source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture>
</a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev">
<picture>
<source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture>
</a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev">
<picture>
<img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture>
</a>&emsp;&nbsp;
<br>
<picture>
<source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture>
<br>
<br>
| **English** | [日本語](/docs/readmes/README.ja.md) | [한국어](/docs/readmes/README.ko.md) | [繁體中文](/docs/readmes/README.zh-Hant.md) |
<h3>
VRCT is software that supports VRChat conversations with translation and transcription.
</h3>
![](/docs/img/main_window.png)
<div align="left">
# Download & Install
Download from anywhere you like.
- [Github.com](https://github.com/misyaguziya/VRCT/releases/)
- [BOOTH.pm](https://misyaguziya.booth.pm/items/5155325)
Just download and run the exe.
# What is VRCT?
VRCT is software that supports conversations between people who speak different languages by providing chat or voice translation.
These features are designed for use within VRChat.
*Although not supported, it is also used for other purposes such as watching movies.
VRCT supports your conversations with
- 💬 **Send chat to VRChat**
- 🌐 **Translation**
- 🎙 **Transcription of audio from microphone**
- 🔈 **Transcription of audio from Speaker**
# Documents
Initial setup, basic functions, and other features are also described.
- [Documents Link](https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246?pvs=4)
# How to Use (YouTube)
<div align="center">
[![](https://img.youtube.com/vi/rUTad037n8Q/0.jpg)](https://www.youtube.com/watch?v=rUTad037n8Q)
<div align="left">
## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (Main Development)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI multilingual support)
- [レラ](https://github.com/soumt-r) (Technical Support)
- [どね](https://twitter.com/done_vrc) (Logo Design)
## Thanks to our contributors
<a href="https://github.com/misyaguziya/VRCT/graphs/contributors" target="_blank">
<img src="https://contrib.rocks/image?repo=misyaguziya/VRCT" />
</a>
---
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.

View File

@@ -1,9 +1,9 @@
<div align="center"> <div align="center">
<picture> <picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%"> <source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%"> <source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%"> <img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture> </picture>
<br> <br>
@@ -21,44 +21,44 @@ Become a VRCT Supporter on:
<a href="https://vrct-dev.fanbox.cc"> <a href="https://vrct-dev.fanbox.cc">
<picture> <picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px"> <source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px"> <source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px"> <img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev"> <a href="https://patreon.com/vrct_dev">
<picture> <picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px"> <source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px"> <source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px"> <img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev"> <a href="https://ko-fi.com/vrct_dev">
<picture> <picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px"> <img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<br> <br>
<picture> <picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)"> <source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)"> <source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border"> <img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture> </picture>
<br> <br>
<br> <br>
| [English](./README.md) | **日本語** | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) | | [English](/docs/readmes/README.en.md) | **日本語** | [한국어](/docs/readmes/README.ko.md) | [繁體中文](/docs/readmes/README.zh-Hant.md) |
<h3> <h3>
VRCTは翻訳や文字起こしでVRChatの会話をサポートするソフトウェアです。 VRCTは翻訳や文字起こしでVRChatの会話をサポートするソフトウェアです。
</h3> </h3>
![](docs/main_window.png) ![](/docs/img/main_window.png)
<div align="left"> <div align="left">
@@ -91,15 +91,6 @@ VRCTはあなたの会話を以下でサポートをします。
<div align="left"> <div align="left">
# pythonで実行したい場合
1. 以下のバージョンのpythonをインストールしてください。
`python version 3.11.5`
2. packageのインストールとmain.pyを起動してください。
```bash
./install.bat
python main.py
```
## Author ## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (メイン開発) - [みしゃ(misyaguzi)](https://github.com/misyaguziya) (メイン開発)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI多言語対応) - [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI多言語対応)

View File

@@ -1,9 +1,9 @@
<div align="center"> <div align="center">
<picture> <picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%"> <source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%"> <source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%"> <img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture> </picture>
<br> <br>
@@ -21,44 +21,44 @@ Become a VRCT Supporter on:
<a href="https://vrct-dev.fanbox.cc"> <a href="https://vrct-dev.fanbox.cc">
<picture> <picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px"> <source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px"> <source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px"> <img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev"> <a href="https://patreon.com/vrct_dev">
<picture> <picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px"> <source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px"> <source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px"> <img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev"> <a href="https://ko-fi.com/vrct_dev">
<picture> <picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px"> <img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<br> <br>
<picture> <picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)"> <source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)"> <source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border"> <img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture> </picture>
<br> <br>
<br> <br>
| [English](./README.md) | [日本語](./README.ja.md) | **한국어** | [繁體中文](./README.zh-Hant.md) | | [English](/docs/readmes/README.en.md) | [日本語](/docs/readmes/README.ja.md) | **한국어** | [繁體中文](/docs/readmes/README.zh-Hant.md) |
<h3> <h3>
VRCT는 음성인식 및 번역 기능을 통해 VRChat의 대화를 지원하는 소프트웨어입니다. VRCT는 음성인식 및 번역 기능을 통해 VRChat의 대화를 지원하는 소프트웨어입니다.
</h3> </h3>
![](docs/main_window.png) ![](/docs/img/main_window.png)
<div align="left"> <div align="left">
@@ -91,15 +91,6 @@ VRCT는 다음과 같이 당신의 대화를 도와드려요.
<div align="left"> <div align="left">
# python으로 실행하고 싶은 경우
1. 다음 버전의 python을 설치합니다.
`python version 3.11.5`
2. 패키지를 설치하고 main.py를 실행합니다.
```bash
./install.bat
python main.py
```
## Author ## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (주요 개발) - [みしゃ(misyaguzi)](https://github.com/misyaguziya) (주요 개발)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI 다국어 지원) - [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI 다국어 지원)

View File

@@ -1,9 +1,9 @@
<div align="center"> <div align="center">
<picture> <picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%"> <source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%"> <source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%"> <img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture> </picture>
<br> <br>
@@ -21,44 +21,44 @@ Become a VRCT Supporter on:
<a href="https://vrct-dev.fanbox.cc"> <a href="https://vrct-dev.fanbox.cc">
<picture> <picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px"> <source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px"> <source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px"> <img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev"> <a href="https://patreon.com/vrct_dev">
<picture> <picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px"> <source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px"> <source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px"> <img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev"> <a href="https://ko-fi.com/vrct_dev">
<picture> <picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px"> <img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture> </picture>
</a>&emsp;&nbsp; </a>&emsp;&nbsp;
<br> <br>
<picture> <picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)"> <source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)"> <source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border"> <img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture> </picture>
<br> <br>
<br> <br>
| [English](./README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | **繁體中文** | | [English](/docs/readmes/README.en.md) | [日本語](/docs/readmes/README.ja.md) | [한국어](/docs/readmes/README.ko.md) | **繁體中文** |
<h3> <h3>
VRCT 是一個支援 VRChat 對話翻譯和紀錄的軟體。 VRCT 是一個支援 VRChat 對話翻譯和紀錄的軟體。
</h3> </h3>
![](docs/main_window.png) ![](/docs/img/main_window.png)
<div align="left"> <div align="left">
@@ -90,15 +90,6 @@ VRCT 可以:
<div align="left"> <div align="left">
# 原始碼啟動
1. 安裝此版本的 Python。
`python version 3.11.5`
2. 安裝 package 並啟動 main.py。
```bash
./install.bat
python main.py
```
## 作者 ## 作者
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (主要開發) - [みしゃ(misyaguzi)](https://github.com/misyaguziya) (主要開發)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI 多語系支援) - [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI 多語系支援)

View File

@@ -8,13 +8,13 @@ common:
common_error: common_error:
no_device_mic: "No mic device detected." no_device_mic: "No mic device detected."
no_device_speaker: "No Speaker device detected." no_device_speaker: "No speaker device detected."
threshold_invalid_value: "You can set it with a value between {{min}} to {{max}}." threshold_invalid_value: "You can set it with a value between {{min}} to {{max}}."
failed_download_weight_ctranslate2: "CTranslate2 weight download error." failed_download_weight_ctranslate2: "CTranslate2 weight download error."
failed_download_weight_whisper: "Whisper weight download error." failed_download_weight_whisper: "Whisper weight download error."
translation_limit: "Translation engine limit error." translation_limit: "Translation engine limit reached or temporarily restricted."
deepl_auth_key_invalid_length: "DeepL auth key length is not correct." deepl_auth_key_invalid_length: "DeepL auth key length is not correct."
deepl_auth_key_failed_authentication: "Auth Key is incorrect or Usage limit reached." deepl_auth_key_failed_authentication: "Auth key is incorrect or API usage limit reached."
invalid_value_mic_record_timeout: "It cannot be greater than '{{mic_phrase_timeout_label}}' with a value of 0 or more." invalid_value_mic_record_timeout: "It cannot be greater than '{{mic_phrase_timeout_label}}' with a value of 0 or more."
invalid_value_mic_phrase_timeout: "It cannot be set lower than '{{mic_record_timeout_label}}' with a value of 0 or more." invalid_value_mic_phrase_timeout: "It cannot be set lower than '{{mic_record_timeout_label}}' with a value of 0 or more."
@@ -28,18 +28,18 @@ main_page:
translation: "Translation" translation: "Translation"
transcription_send: "Voice2Chatbox" transcription_send: "Voice2Chatbox"
transcription_receive: "Speaker2Log" transcription_receive: "Speaker2Log"
foreground: "Foreground" foreground: "Set To Stay On Top"
language_settings: "Language Settings" language_settings: "Language Settings"
your_language: "Your Language" your_language: "Your Language"
translate_each_other_label: "Translate Each Other" translate_each_other_label: "Translate Both Languages"
swap_button_label: "Swap Languages" swap_button_label: "Switch Languages"
target_language: "Target Language" target_language: "Target Language"
translator: "Translator" translator: "Translator"
translator_label_default: "Default" translator_label_default: "Default"
translator_selector: translator_selector:
is_selected_same_language: "Since the same language is selected for both '{{your_language}}' and '{{target_language}}', only '{{ctranslate2}}' is available." is_selected_same_language: "You are selecting the same language for '{{your_language}}' and '{{target_language}}' so only '{{ctranslate2}}' is available."
message_log: message_log:
all: "All" all: "All"
@@ -48,7 +48,7 @@ main_page:
system: "System" system: "System"
show_resend_button: "Show Resend Button" show_resend_button: "Show Resend Button"
resend_button_on_hover_desc: "Press and hold to send" resend_button_on_hover_desc: "Press And Hold To Send"
state_text_enabled: "Enabled" state_text_enabled: "Enabled"
state_text_disabled: "Disabled" state_text_disabled: "Disabled"
@@ -57,28 +57,28 @@ main_page:
title_your_language: "Select Your Language" title_your_language: "Select Your Language"
title_target_language: "Select Target Language" title_target_language: "Select Target Language"
update_available: "New version is here!" update_available: "New version is ready!"
updating: "Now updating..." updating: "Now updating..."
update_modal: update_modal:
cpu_desc: "Use CPU only as the compute device." cpu_desc: "Use CPU only as the compute device."
cuda_desc: "Selectable between CPU and NVIDIA GPUs as compute devices." 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_compare_cpu_desc: "GPUs offer faster processing than CPUs."
cuda_disk_space_desc: "Requires approximately {{size}} of disk space." cuda_disk_space_desc: "Requires approximately {{size}} of disk space."
close_modal: "Close" close_modal: "Close"
download_latest_and_restart: "The latest version will be downloaded,\nand the app will automatically restart." download_latest_and_restart: "The latest version will be downloaded,\nand the app will automatically restart."
is_latest_version_already: "Already using the latest version" is_latest_version_already: "Already using the latest version"
is_current_compute_device: "Currently using this version" is_current_compute_device: "The version currently in use"
config_page: config_page:
version: "version {{version}}" version: "Version {{version}}"
model_download_button_label: "Download" model_download_button_label: "Download"
side_menu_labels: side_menu_labels:
device: "Device" device: "Device"
appearance: "Appearance" appearance: "Appearance"
translation: "Translation" translation: "Translation"
transcription: "Transcription" transcription: "Transcription"
others: "Others" others: "Other"
hotkeys: "Hotkeys" hotkeys: "Hotkeys"
advanced_settings: "Advanced Settings" advanced_settings: "Advanced Settings"
@@ -90,17 +90,17 @@ config_page:
mic_host_device: mic_host_device:
label: "Mic Device" label: "Mic Device"
mic_dynamic_energy_threshold: mic_dynamic_energy_threshold:
label_for_automatic: "Mic Energy Threshold (Current Setting: Automatic)" label_for_automatic: "Mic Sensitivity Settings (Current Setting: Automatic)"
desc_for_automatic: "Automatically determine microphone input sensitivity." desc_for_automatic: "Automatically control mic input sensitivity."
label_for_manual: "Mic Energy Threshold (Current Setting: Manual)" label_for_manual: "Mic Sensitivity Settings (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." desc_for_manual: "Input sensitivity can be manually adjusted using the slider. Click the mic icon to test your voice input and adjust the level while monitoring the volume."
speaker_device: speaker_device:
label: "Speaker Device" label: "Speaker Device"
speaker_dynamic_energy_threshold: speaker_dynamic_energy_threshold:
label_for_automatic: "Speaker Energy Threshold (Current Setting: Automatic)" label_for_automatic: "Speaker Input Sensitivity Adjustment (Current Setting: Automatic)"
desc_for_automatic: "Automatically determine speaker input sensitivity." desc_for_automatic: "Automatically control speaker input sensitivity."
label_for_manual: "Speaker Energy Threshold (Current Setting: Manual)" label_for_manual: "Speaker Input Sensitivity Adjustment (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." desc_for_manual: "Input sensitivity can be manually adjusted using the slider. Click the headphone icon to listen to the audio and adjust the level while checking the volume."
appearance: appearance:
transparency: transparency:
@@ -110,12 +110,12 @@ config_page:
label: "UI Size" label: "UI Size"
textbox_ui_size: textbox_ui_size:
label: "Message Logs Font Size" label: "Message Logs Font Size"
desc: "You can adjust the font size used in the logs relative to the UI size." desc: "You can adjust the log font size by changing the scaling factor relative to the UI size."
send_message_button_type: send_message_button_type:
label: "Send Message Button" label: "Send Message Button"
hide: "Hide (Use enter key to send)" hide: "Hide (Use Enter key to send)"
show: "Show" show: "Show"
show_and_disable_enter_key: "Show and disable to send when pressed enter key" show_and_disable_enter_key: "Show and disable sending using the Enter key."
font_family: font_family:
label: "Font Family" label: "Font Family"
ui_language: ui_language:
@@ -124,14 +124,14 @@ config_page:
translation: translation:
ctranslate2_weight_type: ctranslate2_weight_type:
label: "{{ctranslate2}} Model" label: "{{ctranslate2}} Model"
desc: "You can choose the translation model to use for the internal translation engine." desc: "You can choose the translation model when using the {{ctranslate2}} translation engine."
small: "Basic model ({{capacity}})" small: "Basic Model ({{capacity}})"
large: "High accuracy model ({{capacity}})" large: "High Accuracy Model ({{capacity}})"
ctranslate2_compute_device: ctranslate2_compute_device:
label: "{{ctranslate2}} Compute Device" label: "Processing device for AI translation {{ctranslate2}}"
deepl_auth_key: deepl_auth_key:
label: "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." desc: "When using it, please change {{translator}} on the main screen to DeepL_API. ※Some languages may not be supported."
open_auth_key_webpage: "Open DeepL Account Webpage" open_auth_key_webpage: "Open DeepL Account Webpage"
save: "Save" save: "Save"
edit: "Edit" edit: "Edit"
@@ -143,7 +143,7 @@ config_page:
section_label_transcription_engines: "Transcription Engines" section_label_transcription_engines: "Transcription Engines"
mic_record_timeout: mic_record_timeout:
label: "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))" desc: "Detects silence and, when the specified number of seconds passes, the system considers the voice input to have ended. (Second(s))"
mic_phrase_timeout: mic_phrase_timeout:
label: "Mic Phrase Timeout" label: "Mic Phrase Timeout"
desc: "Transcription processing is performed at intervals of the specified number of seconds." desc: "Transcription processing is performed at intervals of the specified number of seconds."
@@ -152,9 +152,9 @@ config_page:
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." 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."
mic_word_filter: mic_word_filter:
label: "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).\n*Duplicate words will not be registered." desc: "If a registered word is detected, the message will not be sent. To add multiple words at once, separate them with ',' (comma).\n*Duplicate words will not be registered."
add_button_label: "Add" add_button_label: "Add"
count_desc: "Current registered word count: {{count}}" count_desc: "Words Currently Registered: {{count}}"
speaker_record_timeout: speaker_record_timeout:
label: "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))" desc: "Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s))"
@@ -165,20 +165,20 @@ config_page:
label: "Speaker Max Words" 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." 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."
select_transcription_engine: select_transcription_engine:
label: "Transcription Engine" label: "Transcription Engine Used For Speech Recognition"
whisper_weight_type: whisper_weight_type:
label: "Whisper Model" label: "Whisper Model"
desc: "Larger models tend to have higher accuracy, but they also consume more CPU or GPU resources.\nEspecially for models larger than medium, it may be difficult or even impossible to use them depending on the performance of your CPU/GPU." desc: "Larger models have higher accuracy, but they also consume more CPU or GPU resources.\nEspecially 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}})" model_template: "{{model_name}} model ({{capacity}})"
recommended_model_template: "{{model_name}} model ({{capacity}}) (Recommended)" recommended_model_template: "{{model_name}} model ({{capacity}}) (Recommended)"
whisper_compute_device: whisper_compute_device:
label: "Whisper Compute Device" label: "Processing Device Used For Whisper"
vr: vr:
single_line: "Single line" single_line: "Single line"
multi_lines: "Multi lines" multi_lines: "Multiple Lines"
overlay_enable: "Enable" overlay_enable: "Enable"
restore_default_settings: "Restore Default Settings" restore_default_settings: "Reset to Default Settings"
position: "Position" position: "Position"
rotation: "Rotation" rotation: "Rotation"
x_position: "X-axis (left-right)" x_position: "X-axis (left-right)"
@@ -188,46 +188,46 @@ config_page:
y_rotation: "Y-axis rotation" y_rotation: "Y-axis rotation"
z_rotation: "Z-axis rotation" z_rotation: "Z-axis rotation"
sample_text_button: sample_text_button:
start: "Send sample texts\nto Overlay" start: "Send Sample Texts\nTo Overlay"
stop: "Stop Sending" stop: "Stop Sending"
sample_text: "Sample text." sample_text: "Sample Text."
opacity: "Opacity" opacity: "Opacity"
ui_scaling: "UI Scaling" ui_scaling: "UI Scaling"
display_duration: "Display duration" display_duration: "Display Duration"
fadeout_duration: "Fadeout duration" fadeout_duration: "Fadeout Duration"
common_settings: "Common Settings" common_settings: "Common Settings"
tracker: "Tracker" tracker: "Tracker"
hmd: "HMD" hmd: "HMD"
left_hand: "Left hand" left_hand: "Left Hand"
right_hand: "Right hand" right_hand: "Right Hand"
overlay_show_only_translated_messages: overlay_show_only_translated_messages:
label: "Show Only Translated Messages" label: "Show Only Translated Messages"
others: others:
section_label_sounds: "Sounds" section_label_sounds: "Sounds"
auto_clear_the_message_box: auto_clear_the_message_box:
label: "Auto Clear The Message Box" label: "Auto Clear Message box"
send_only_translated_messages: send_only_translated_messages:
label: "Send Only Translated Messages" label: "Send Only Translated Messages"
auto_export_message_logs: auto_export_message_logs:
label: "Auto Export Message Logs" label: "Auto Save Message Logs"
desc: "Automatically export the conversation messages as a text file." desc: "Automatically saves the conversation messages as text files."
vrc_mic_mute_sync: vrc_mic_mute_sync:
label: "VRC Mic Mute Sync" label: "VRC Mic Mute Sync"
desc: "VRCT will not send the message to VRChat while VRChat's mic is muted.\n*There is a bit latency and Push-To-Talk is not supported." desc: "Messages will not be sent to VRCT while VRChat's mic is muted.\n*There may be a slight delay. Push-To-Talk is not supported."
send_message_to_vrc: send_message_to_vrc:
label: "Send Message To VRChat" 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." desc: "This feature is not supported, but there is a way to use it without sending messages to VRChat. Make sure to enable this feature when you wish to send messages to VRChat."
notification_vrc_sfx: notification_vrc_sfx:
label: "Enable Notification Sound When Sending Chat" label: "Enable Notification Sound When Sending Chat"
desc: "Disabling this feature will send chats quietly without playing a notification sound that others can hear." desc: "When this feature is disabled, messages will be sent silently without playing the chatbox notification sound that others can hear."
send_received_message_to_vrc: send_received_message_to_vrc:
label: "Send Received Message To VRChat" label: "Send Received Message To VRChat"
desc: "Send the message you received from the speaker's sound to VRChat's chatbox." desc: "Send the message you received from the speaker's voice to VRChat's chatbox."
hotkeys: hotkeys:
toggle_vrct_visibility: toggle_vrct_visibility:
label: "Toggle VRCT Visibility" label: "Toggle VRCT visibility"
toggle_translation: toggle_translation:
label: "Toggle {{translation}}" label: "Toggle {{translation}}"
toggle_transcription_send: toggle_transcription_send:
@@ -243,4 +243,4 @@ config_page:
open_config_filepath: open_config_filepath:
label: "Open Config File" label: "Open Config File"
switch_compute_device: switch_compute_device:
label: "Switch VRCT to CPU/GPU Version" label: "Switch VRCT To CPU/GPU Version"

View File

@@ -956,7 +956,7 @@ class Config:
def init_config(self): def init_config(self):
# Read Only # Read Only
self._VERSION = "3.0.4" self._VERSION = "3.0.5"
if getattr(sys, 'frozen', False): if getattr(sys, 'frozen', False):
self._PATH_LOCAL = os_path.dirname(sys.executable) self._PATH_LOCAL = os_path.dirname(sys.executable)
else: else:

View File

@@ -6,7 +6,7 @@ import re
from device_manager import device_manager from device_manager import device_manager
from config import config from config import config
from model import model from model import model
from utils import removeLog, printLog, errorLogging, isConnectedNetwork from utils import removeLog, printLog, errorLogging, isConnectedNetwork, isValidIpAddress
class Controller: class Controller:
def __init__(self) -> None: def __init__(self) -> None:
@@ -150,7 +150,7 @@ class Controller:
400, 400,
self.run_mapping["error_device"], self.run_mapping["error_device"],
{ {
"message":"No Speaker device detected", "message":"No speaker device detected",
"data": None "data": None
}, },
) )
@@ -1094,9 +1094,29 @@ class Controller:
@staticmethod @staticmethod
def setOscIpAddress(data, *args, **kwargs) -> dict: def setOscIpAddress(data, *args, **kwargs) -> dict:
if isValidIpAddress(data) is False:
response = {
"status":400,
"result":{
"message":"Invalid IP address",
"data": config.OSC_IP_ADDRESS
}
}
else:
try:
model.setOscIpAddress(data)
config.OSC_IP_ADDRESS = data config.OSC_IP_ADDRESS = data
response = {"status":200, "result":config.OSC_IP_ADDRESS}
except Exception:
model.setOscIpAddress(config.OSC_IP_ADDRESS) model.setOscIpAddress(config.OSC_IP_ADDRESS)
return {"status":200, "result":config.OSC_IP_ADDRESS} response = {
"status":400,
"result":{
"message":"Cannot set IP address",
"data": config.OSC_IP_ADDRESS
}
}
return response
@staticmethod @staticmethod
def getOscPort(*args, **kwargs) -> dict: def getOscPort(*args, **kwargs) -> dict:

View File

@@ -400,9 +400,9 @@ class Model:
mic_device_list = device_manager.getMicDevices().get(mic_host_name, [{"name": "NoDevice"}]) mic_device_list = device_manager.getMicDevices().get(mic_host_name, [{"name": "NoDevice"}])
selected_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name] selected_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name]
if len(selected_mic_device) == 0: if len(selected_mic_device) == 0 or mic_device_name == "NoDevice":
return False fnc({"text": False, "language": None})
else:
self.mic_audio_queue = Queue() self.mic_audio_queue = Queue()
# self.mic_energy_queue = Queue() # self.mic_energy_queue = Queue()
@@ -535,9 +535,9 @@ class Model:
mic_device_list = device_manager.getMicDevices().get(mic_host_name, [{"name": "NoDevice"}]) mic_device_list = device_manager.getMicDevices().get(mic_host_name, [{"name": "NoDevice"}])
selected_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name] selected_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name]
if len(selected_mic_device) == 0: if len(selected_mic_device) == 0 or mic_device_name == "NoDevice":
return False self.check_mic_energy_fnc(False)
else:
def sendMicEnergy(): def sendMicEnergy():
if mic_energy_queue.empty() is False: if mic_energy_queue.empty() is False:
energy = mic_energy_queue.get() energy = mic_energy_queue.get()
@@ -566,12 +566,14 @@ class Model:
self.mic_energy_recorder = None self.mic_energy_recorder = None
def startSpeakerTranscript(self, fnc): def startSpeakerTranscript(self, fnc):
speaker_device_name = config.SELECTED_SPEAKER_DEVICE
speaker_device_list = device_manager.getSpeakerDevices() speaker_device_list = device_manager.getSpeakerDevices()
selected_speaker_device = [device for device in speaker_device_list if device["name"] == config.SELECTED_SPEAKER_DEVICE] selected_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name]
if len(selected_speaker_device) == 0:
return False
if len(selected_speaker_device) == 0 or speaker_device_name == "NoDevice":
fnc({"text": False, "language": None})
else:
speaker_audio_queue = Queue() speaker_audio_queue = Queue()
# speaker_energy_queue = Queue() # speaker_energy_queue = Queue()
speaker_device = selected_speaker_device[0] speaker_device = selected_speaker_device[0]
@@ -660,12 +662,13 @@ class Model:
if isinstance(fnc, Callable): if isinstance(fnc, Callable):
self.check_speaker_energy_fnc = fnc self.check_speaker_energy_fnc = fnc
speaker_device_name = config.SELECTED_SPEAKER_DEVICE
speaker_device_list = device_manager.getSpeakerDevices() speaker_device_list = device_manager.getSpeakerDevices()
selected_speaker_device = [device for device in speaker_device_list if device["name"] == config.SELECTED_SPEAKER_DEVICE] selected_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name]
if len(selected_speaker_device) == 0:
return False
if len(selected_speaker_device) == 0 or speaker_device_name == "NoDevice":
self.check_speaker_energy_fnc(False)
else:
def sendSpeakerEnergy(): def sendSpeakerEnergy():
if speaker_energy_queue.empty() is False: if speaker_energy_queue.empty() is False:
energy = speaker_energy_queue.get() energy = speaker_energy_queue.get()

View File

@@ -17,6 +17,8 @@ _MODELS = {
"large-v1": "Systran/faster-whisper-large-v1", "large-v1": "Systran/faster-whisper-large-v1",
"large-v2": "Systran/faster-whisper-large-v2", "large-v2": "Systran/faster-whisper-large-v2",
"large-v3": "Systran/faster-whisper-large-v3", "large-v3": "Systran/faster-whisper-large-v3",
"large-v3-turbo-int8": "Zoont/faster-whisper-large-v3-turbo-int8-ct2", #794MB
"large-v3-turbo": "deepdml/faster-whisper-large-v3-turbo-ct2", #1.58GB
} }
_FILENAMES = [ _FILENAMES = [

View File

@@ -7,14 +7,22 @@ from logging.handlers import RotatingFileHandler
from ctranslate2 import get_supported_compute_types from ctranslate2 import get_supported_compute_types
import requests import requests
import ipaddress
def isConnectedNetwork(url="http://www.google.com", timeout=3): def isConnectedNetwork(url="http://www.google.com", timeout=3) -> bool:
try: try:
response = requests.get(url, timeout=timeout) response = requests.get(url, timeout=timeout)
return response.status_code == 200 return response.status_code == 200
except requests.RequestException: except requests.RequestException:
return False return False
def isValidIpAddress(ip_address: str) -> bool:
try:
ipaddress.ip_address(ip_address)
return True
except ValueError:
return False
def getBestComputeType(device, device_index) -> str: def getBestComputeType(device, device_index) -> str:
compute_types = get_supported_compute_types(device, device_index) compute_types = get_supported_compute_types(device, device_index)
compute_types = set(compute_types) compute_types = set(compute_types)

View File

@@ -53,14 +53,11 @@
"open": true, "open": true,
"sidecar": true, "sidecar": true,
"scope": [ "scope": [
{ { "name": "bin/VRCT-sidecar", "sidecar": true, "args": true }
"name": "bin/VRCT-sidecar", "sidecar": true,"args": true
}
] ]
} }
}, },
"windows": [ "windows": [{
{
"title": "VRCT", "title": "VRCT",
"center": true, "center": true,
"width": 450, "width": 450,
@@ -69,11 +66,8 @@
"minHeight": 200, "minHeight": 200,
"transparent": true, "transparent": true,
"decorations": false "decorations": false
} }],
], "security": { "csp": null },
"security": {
"csp": null
},
"bundle": { "bundle": {
"active": true, "active": true,
"targets": "nsis", "targets": "nsis",
@@ -91,7 +85,7 @@
"externalBin": [ "externalBin": [
"bin/VRCT-sidecar" "bin/VRCT-sidecar"
], ],
"resources":{ "resources": {
"bin/_internal": "_internal", "bin/_internal": "_internal",
"plugins": "plugins" "plugins": "plugins"
}, },

View File

@@ -24,7 +24,7 @@ const _Entry = forwardRef((props, ref) => {
<div className={styles.entry_container}> <div className={styles.entry_container}>
<div <div
className={input_wrapper_class_names} className={input_wrapper_class_names}
style={{width: props.width }} style={{width: props.width || "20rem" }}
> >
<input <input
ref={inputRef} ref={inputRef}

View File

@@ -0,0 +1,32 @@
import styles from "./EntryWithSaveButton.module.scss";
import { _Entry } from "../_atoms/_entry/_Entry";
import CircularProgress from "@mui/material/CircularProgress";
import { useTranslation } from "react-i18next";
import { clsx } from "clsx";
export const EntryWithSaveButton = (props) => {
const { t } = useTranslation();
const onChangeFunction = (e) => {
props.onChangeFunction?.(e.target.value);
};
const saveFunction = () => {
props.saveFunction();
};
const is_disabled = props.state === "pending";
const save_button_class_names = clsx(styles.save_button, {
[styles.is_disabled]: is_disabled
});
return (
<div className={styles.container}>
<_Entry width={props.width} onChange={onChangeFunction} ui_variable={props.variable} is_disabled={is_disabled}/>
<button className={save_button_class_names} onClick={saveFunction}>
{is_disabled
? <CircularProgress size="1.4rem" sx={{ color: "var(--dark_basic_text_color)" }}/>
: <p className={styles.save_button_label}>{t("config_page.translation.deepl_auth_key.save")}</p>
}
</button>
</div>
);
};

View File

@@ -0,0 +1,30 @@
.container {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
flex-shrink: 0;
}
.save_button {
padding: 0.8rem 1.2rem;
background-color: var(--primary_600_color);
border-radius: 0.4rem;
text-align: center;
flex-shrink: 0;
min-width: 5.4rem;
&:hover {
background-color: var(--primary_500_color);
}
&:active {
background-color: var(--primary_700_color);
}
&.is_disabled {
pointer-events: none;
background-color: var(--primary_800_color);
}
}
.save_button_label {
font-size: 1.4rem;
}

View File

@@ -3,6 +3,7 @@ export { ComputeDevice } from "./compute_device/ComputeDevice";
export { DeeplAuthKey, OpenWebpage_DeeplAuthKey } from "./deepl_auth_key/DeeplAuthKey"; export { DeeplAuthKey, OpenWebpage_DeeplAuthKey } from "./deepl_auth_key/DeeplAuthKey";
export { DropdownMenu } from "./dropdown_menu/DropdownMenu"; export { DropdownMenu } from "./dropdown_menu/DropdownMenu";
export { Entry } from "./entry/Entry"; export { Entry } from "./entry/Entry";
export { EntryWithSaveButton } from "./entry_with_save_button/EntryWithSaveButton";
export { HotkeysEntry } from "./hotkeys_entry/HotkeysEntry"; export { HotkeysEntry } from "./hotkeys_entry/HotkeysEntry";
export { LabelComponent } from "./label_component/LabelComponent"; export { LabelComponent } from "./label_component/LabelComponent";
export { RadioButton } from "./radio_button/RadioButton"; export { RadioButton } from "./radio_button/RadioButton";

View File

@@ -8,6 +8,7 @@ import {
Slider, Slider,
SwitchBox, SwitchBox,
Entry, Entry,
EntryWithSaveButton,
HotkeysEntry, HotkeysEntry,
RadioButton, RadioButton,
OpenWebpage_DeeplAuthKey, OpenWebpage_DeeplAuthKey,
@@ -75,6 +76,9 @@ export const SwitchBoxContainer = (props) => (
export const EntryContainer = (props) => ( export const EntryContainer = (props) => (
<CommonContainer Component={Entry} {...props} add_break_point={false} /> <CommonContainer Component={Entry} {...props} add_break_point={false} />
); );
export const EntryWithSaveButtonContainer = (props) => (
<CommonContainer Component={EntryWithSaveButton} {...props} add_break_point={false} />
);
export const HotkeysEntryContainer = (props) => ( export const HotkeysEntryContainer = (props) => (
<CommonContainer Component={HotkeysEntry} {...props} /> <CommonContainer Component={HotkeysEntry} {...props} />

View File

@@ -10,6 +10,7 @@ import contributor_iya from "@images/about_vrct/contributor_iya.png";
import contributor_rera from "@images/about_vrct/contributor_rera.png"; import contributor_rera from "@images/about_vrct/contributor_rera.png";
import contributor_poposuke from "@images/about_vrct/contributor_poposuke.png"; import contributor_poposuke from "@images/about_vrct/contributor_poposuke.png";
import contributor_kumaguma from "@images/about_vrct/contributor_kumaguma.png"; import contributor_kumaguma from "@images/about_vrct/contributor_kumaguma.png";
import contributor_riku from "@images/about_vrct/contributor_riku.png";
import localization_section_title from "@images/about_vrct/localization_section_title.png"; import localization_section_title from "@images/about_vrct/localization_section_title.png";
import localization_1 from "@images/about_vrct/localization_1.png"; import localization_1 from "@images/about_vrct/localization_1.png";
@@ -86,6 +87,10 @@ export const AboutVrct = () => {
<img src={contributor_kumaguma} className={clsx(styles.contributors_img, styles.contributors)} /> <img src={contributor_kumaguma} className={clsx(styles.contributors_img, styles.contributors)} />
<OpenLinkContainer className={styles.contributors_kumaguma_x} href_id="contributors_kumaguma_x" /> <OpenLinkContainer className={styles.contributors_kumaguma_x} href_id="contributors_kumaguma_x" />
</div> </div>
<div className={styles.contributor_card_wrapper}>
<img src={contributor_riku} className={clsx(styles.contributors_img, styles.contributors)} />
<OpenLinkContainer className={styles.contributors_riku_x} href_id="contributors_riku_x" />
</div>
</div> </div>
</div> </div>
@@ -158,6 +163,7 @@ const about_vrct_links = {
contributors_rera_github: { img: contributors_github_icon, href: "https://github.com/soumt-r" }, contributors_rera_github: { img: contributors_github_icon, href: "https://github.com/soumt-r" },
contributors_poposuke_x: { img: contributors_x_icon, href: "https://twitter.com/sig_popo" }, contributors_poposuke_x: { img: contributors_x_icon, href: "https://twitter.com/sig_popo" },
contributors_kumaguma_x: { img: contributors_x_icon, href: "https://twitter.com/K_kumaguma_A" }, contributors_kumaguma_x: { img: contributors_x_icon, href: "https://twitter.com/K_kumaguma_A" },
contributors_riku_x: { img: contributors_x_icon, href: "https://twitter.com/Riku7302" },
}; };
const OpenLinkContainer = ({className, href_id}) => { const OpenLinkContainer = ({className, href_id}) => {

View File

@@ -160,6 +160,9 @@ $sns_left_pos: 0.8rem;
.contributors_kumaguma_x { .contributors_kumaguma_x {
@include contributors_sns_styles($bottom_pos, $sns_left_pos); @include contributors_sns_styles($bottom_pos, $sns_left_pos);
} }
.contributors_riku_x {
@include contributors_sns_styles($bottom_pos, $sns_left_pos);
}
.localization_section { .localization_section {
display: flex; display: flex;

View File

@@ -11,6 +11,7 @@ import {
import { import {
ActionButtonContainer, ActionButtonContainer,
EntryContainer, EntryContainer,
EntryWithSaveButtonContainer,
} from "../_templates/Templates"; } from "../_templates/Templates";
@@ -30,54 +31,59 @@ export const AdvancedSettings = () => {
const OscIpAddressContainer = () => { const OscIpAddressContainer = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentOscIpAddress, setOscIpAddress } = useOscIpAddress(); const { currentOscIpAddress, setOscIpAddress } = useOscIpAddress();
const onChangeFunction = (e) => { const [input_value, setInputValue] = useState(currentOscIpAddress.data);
const value = e.currentTarget.value;
if (value === "") { const onChangeFunction = (value) => {
setUiVariable(""); setInputValue(value);
} else { };
setUiVariable(value);
setOscIpAddress(value); const saveFunction = () => {
} setOscIpAddress(input_value);
}; };
useEffect(()=> { useEffect(()=> {
setUiVariable(currentOscIpAddress.data); setInputValue(currentOscIpAddress.data);
}, [currentOscIpAddress]); }, [currentOscIpAddress]);
return ( return (
<EntryContainer <EntryWithSaveButtonContainer
label={t("config_page.advanced_settings.osc_ip_address.label")} label={t("config_page.advanced_settings.osc_ip_address.label")}
ui_variable={ui_variable} variable={input_value}
onChange={onChangeFunction} saveFunction={saveFunction}
onChangeFunction={onChangeFunction}
state={currentOscIpAddress.state}
width="14rem"
/> />
); );
}; };
const OscPortContainer = () => { const OscPortContainer = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentOscPort, setOscPort } = useOscPort(); const { currentOscPort, setOscPort } = useOscPort();
const onChangeFunction = (e) => { const [input_value, setInputValue] = useState(currentOscPort.data);
const value = e.currentTarget.value;
if (value === "") { const onChangeFunction = (value) => {
setUiVariable(""); value = value.replace(/[^0-9]/g, "");
} else { setInputValue(value);
setUiVariable(value); };
setOscPort(value);
} const saveFunction = () => {
setOscPort(input_value);
}; };
useEffect(()=> { useEffect(()=> {
setUiVariable(currentOscPort.data); setInputValue(currentOscPort.data);
}, [currentOscPort]); }, [currentOscPort]);
return ( return (
<EntryContainer <EntryWithSaveButtonContainer
label={t("config_page.advanced_settings.osc_port.label")} label={t("config_page.advanced_settings.osc_port.label")}
ui_variable={ui_variable} variable={input_value}
onChange={onChangeFunction} saveFunction={saveFunction}
onChangeFunction={onChangeFunction}
state={currentOscPort.state}
width="10rem"
/> />
); );
}; };

View File

@@ -260,6 +260,8 @@ const WhisperWeightType_Box = () => {
{ id: "large-v1", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v1", capacity: "2.87GB"}) }, { id: "large-v1", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v1", capacity: "2.87GB"}) },
{ id: "large-v2", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v2", capacity: "2.87GB"}) }, { id: "large-v2", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v2", capacity: "2.87GB"}) },
{ id: "large-v3", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v3", capacity: "2.87GB"}) }, { id: "large-v3", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v3", capacity: "2.87GB"}) },
{ id: "large-v3-turbo-int8", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v3-turbo-int8", capacity: "794MB"}) },
{ id: "large-v3-turbo", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v3-turbo", capacity: "1.58GB"}) },
]; ];
const whisper_weight_types = updateLabelsById(currentWhisperWeightTypeStatus.data, new_labels); const whisper_weight_types = updateLabelsById(currentWhisperWeightTypeStatus.data, new_labels);

View File

@@ -62,7 +62,7 @@ const CTranslate2WeightType_Box = () => {
)} )}
desc={t( desc={t(
"config_page.translation.ctranslate2_weight_type.desc", "config_page.translation.ctranslate2_weight_type.desc",
{translator: t("main_page.translator")} {ctranslate2: "CTranslate2"}
)} )}
name="ctransalte2_weight_type" name="ctransalte2_weight_type"
options={c_translate2_weight_types} options={c_translate2_weight_types}

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -14,6 +14,8 @@ import {
useSpeakerMaxWords, useSpeakerMaxWords,
useDeepLAuthKey, useDeepLAuthKey,
useOscIpAddress,
} from "@logics_configs"; } from "@logics_configs";
import { ui_configs } from "../ui_configs"; import { ui_configs } from "../ui_configs";
@@ -29,14 +31,16 @@ export const _useBackendErrorHandling = () => {
const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout(); const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
const { updateSpeakerMaxWords } = useSpeakerMaxWords(); const { updateSpeakerMaxWords } = useSpeakerMaxWords();
const { updateDeepLAuthKey } = useDeepLAuthKey(); const { updateDeepLAuthKey, saveErrorDeepLAuthKey } = useDeepLAuthKey();
const errorHandling_Backend = ({message, data, endpoint}) => { const { updateOscIpAddress } = useOscIpAddress();
const errorHandling_Backend = ({message, data, endpoint, _result}) => {
switch (message) { switch (message) {
case "No mic device detected": case "No mic device detected":
showNotification_Error(t("common_error.no_device_mic")); showNotification_Error(t("common_error.no_device_mic"));
break; break;
case "No Speaker device detected": case "No speaker device detected":
showNotification_Error(t("common_error.no_device_speaker")); showNotification_Error(t("common_error.no_device_speaker"));
break; break;
@@ -110,10 +114,23 @@ export const _useBackendErrorHandling = () => {
showNotification_Error(t("common_error.invalid_value_speaker_max_phrase")); showNotification_Error(t("common_error.invalid_value_speaker_max_phrase"));
break; break;
default:
if (endpoint === "/set/data/deepl_auth_key") updateDeepLAuthKey(data); // Advanced Settings, error messages are set by Backend (EN only)
case "Invalid IP address":
updateOscIpAddress(data);
showNotification_Error(message); showNotification_Error(message);
break; break;
case "Cannot set IP address":
updateOscIpAddress(data);
showNotification_Error(message);
break;
default:
// determine by endpoint, not message.
if (endpoint === "/set/data/deepl_auth_key") saveErrorDeepLAuthKey({message, data, endpoint, _result});
break;
} }
} }

View File

@@ -1,7 +1,9 @@
import { useStore_OscPort } from "@store"; import { useStore_OscPort } from "@store";
import { useStdoutToPython } from "@logics/useStdoutToPython"; import { useStdoutToPython } from "@logics/useStdoutToPython";
import { useNotificationStatus } from "@logics_common";
export const useOscPort = () => { export const useOscPort = () => {
const { showNotification_Error } = useNotificationStatus();
const { asyncStdoutToPython } = useStdoutToPython(); const { asyncStdoutToPython } = useStdoutToPython();
const { currentOscPort, updateOscPort, pendingOscPort } = useStore_OscPort(); const { currentOscPort, updateOscPort, pendingOscPort } = useStore_OscPort();
@@ -15,10 +17,17 @@ export const useOscPort = () => {
asyncStdoutToPython("/set/data/osc_port", osc_port); asyncStdoutToPython("/set/data/osc_port", osc_port);
}; };
const saveErrorOscPort = ({data, message, _result}) => {
updateOscPort(d => d.data);
showNotification_Error(_result);
};
return { return {
currentOscPort, currentOscPort,
getOscPort, getOscPort,
updateOscPort, updateOscPort,
setOscPort, setOscPort,
saveErrorOscPort,
}; };
}; };

View File

@@ -18,22 +18,30 @@ export const useDeepLAuthKey = () => {
pendingDeepLAuthKey(); pendingDeepLAuthKey();
asyncStdoutToPython("/set/data/deepl_auth_key", selected_deepl_auth_key); asyncStdoutToPython("/set/data/deepl_auth_key", selected_deepl_auth_key);
}; };
const saveSuccessDeepLAuthKey = (saved_deepl_auth_key) => {
updateDeepLAuthKey(saved_deepl_auth_key);
showNotification_Success(t("config_page.translation.deepl_auth_key.auth_key_success"));
};
const deleteDeepLAuthKey = () => { const deleteDeepLAuthKey = () => {
pendingDeepLAuthKey(); pendingDeepLAuthKey();
asyncStdoutToPython("/delete/data/deepl_auth_key"); asyncStdoutToPython("/delete/data/deepl_auth_key");
}; };
const savedDeepLAuthKey = (data) => {
updateDeepLAuthKey(data);
showNotification_Success(t("config_page.translation.deepl_auth_key.auth_key_success"));
};
const saveErrorDeepLAuthKey = ({data, message}) => {
updateDeepLAuthKey(data);
showNotification_Error(message);
};
return { return {
currentDeepLAuthKey, currentDeepLAuthKey,
getDeepLAuthKey, getDeepLAuthKey,
updateDeepLAuthKey, updateDeepLAuthKey,
setDeepLAuthKey, setDeepLAuthKey,
saveSuccessDeepLAuthKey,
deleteDeepLAuthKey, deleteDeepLAuthKey,
saveErrorDeepLAuthKey,
savedDeepLAuthKey,
}; };
}; };

View File

@@ -148,7 +148,7 @@ export const useReceiveRoutes = () => {
const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout(); const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
const { updateSpeakerMaxWords } = useSpeakerMaxWords(); const { updateSpeakerMaxWords } = useSpeakerMaxWords();
const { updateDeepLAuthKey, saveSuccessDeepLAuthKey } = useDeepLAuthKey(); const { updateDeepLAuthKey, savedDeepLAuthKey } = useDeepLAuthKey();
const { updateSelectedCTranslate2WeightType } = useSelectedCTranslate2WeightType(); const { updateSelectedCTranslate2WeightType } = useSelectedCTranslate2WeightType();
const { const {
updateDownloadedCTranslate2WeightTypeStatus, updateDownloadedCTranslate2WeightTypeStatus,
@@ -353,7 +353,7 @@ export const useReceiveRoutes = () => {
// Translation // Translation
"/get/data/deepl_auth_key": updateDeepLAuthKey, "/get/data/deepl_auth_key": updateDeepLAuthKey,
"/set/data/deepl_auth_key": saveSuccessDeepLAuthKey, "/set/data/deepl_auth_key": savedDeepLAuthKey,
"/delete/data/deepl_auth_key": () => updateDeepLAuthKey(""), "/delete/data/deepl_auth_key": () => updateDeepLAuthKey(""),
"/get/data/ctranslate2_weight_type": updateSelectedCTranslate2WeightType, "/get/data/ctranslate2_weight_type": updateSelectedCTranslate2WeightType,
@@ -528,6 +528,8 @@ export const useReceiveRoutes = () => {
"/set/data/speaker_record_timeout": errorHandling_Backend, "/set/data/speaker_record_timeout": errorHandling_Backend,
"/set/data/speaker_phrase_timeout": errorHandling_Backend, "/set/data/speaker_phrase_timeout": errorHandling_Backend,
"/set/data/speaker_max_phrases": errorHandling_Backend, "/set/data/speaker_max_phrases": errorHandling_Backend,
"/set/data/osc_ip_address": errorHandling_Backend,
}; };
@@ -566,11 +568,16 @@ export const useReceiveRoutes = () => {
message: parsed_data.result.message, message: parsed_data.result.message,
data: parsed_data.result.data, data: parsed_data.result.data,
endpoint: parsed_data.endpoint, endpoint: parsed_data.endpoint,
_result: parsed_data.result,
}); });
} else { } else {
handleInvalidEndpoint(parsed_data); handleInvalidEndpoint(parsed_data);
} }
break; break;
case 500:
showNotification_Error(
`An error occurred. Please restart VRCT or contact the developers. ${JSON.stringify(parsed_data.result)}`, { hide_duration: null });
break;
case 348: case 348:
// console.log(`from backend: %c ${JSON.stringify(parsed_data)}`, style_348); // console.log(`from backend: %c ${JSON.stringify(parsed_data)}`, style_348);

View File

@@ -1,8 +1,13 @@
import { Command } from "@tauri-apps/api/shell"; import { Command } from "@tauri-apps/api/shell";
import { store } from "@store"; import { store } from "@store";
import { useReceiveRoutes } from "./useReceiveRoutes"; import { useReceiveRoutes } from "./useReceiveRoutes";
import {
useNotificationStatus,
} from "@logics_common";
export const useStartPython = () => { export const useStartPython = () => {
const { receiveRoutes } = useReceiveRoutes(); const { receiveRoutes } = useReceiveRoutes();
const { showNotification_Success, showNotification_Error } = useNotificationStatus();
const asyncStartPython = async () => { const asyncStartPython = async () => {
const command = Command.sidecar("bin/VRCT-sidecar"); const command = Command.sidecar("bin/VRCT-sidecar");
@@ -16,7 +21,11 @@ export const useStartPython = () => {
console.log(error, line); console.log(error, line);
} }
}); });
command.stderr.on("data", line => console.error("stderr:", line)); command.stderr.on("data", line => {
showNotification_Error(
`An error occurred. Please restart VRCT or contact the developers. The last line:${JSON.stringify(line)}`, { hide_duration: null });
console.error("stderr", line)
});
const backend_subprocess = await command.spawn(); const backend_subprocess = await command.spawn();
store.backend_subprocess = backend_subprocess; store.backend_subprocess = backend_subprocess;
}; };

View File

@@ -132,37 +132,38 @@ export const { atomInstance: Atom_NotificationStatus, useHook: useStore_Notifica
}, "NotificationStatus"); }, "NotificationStatus");
// Main Page // Main Page
// Functions // Common
export const { atomInstance: Atom_IsMainPageCompactMode, useHook: useStore_IsMainPageCompactMode } = createAtomWithHook(false, "IsMainPageCompactMode");
// Sidebar Section
export const { atomInstance: Atom_TranslationStatus, useHook: useStore_TranslationStatus } = createAtomWithHook(false, "TranslationStatus", {is_state_ok: true}); export const { atomInstance: Atom_TranslationStatus, useHook: useStore_TranslationStatus } = createAtomWithHook(false, "TranslationStatus", {is_state_ok: true});
export const { atomInstance: Atom_TranscriptionSendStatus, useHook: useStore_TranscriptionSendStatus } = createAtomWithHook(false, "TranscriptionSendStatus", {is_state_ok: true}); export const { atomInstance: Atom_TranscriptionSendStatus, useHook: useStore_TranscriptionSendStatus } = createAtomWithHook(false, "TranscriptionSendStatus", {is_state_ok: true});
export const { atomInstance: Atom_TranscriptionReceiveStatus, useHook: useStore_TranscriptionReceiveStatus } = createAtomWithHook(false, "TranscriptionReceiveStatus", {is_state_ok: true}); export const { atomInstance: Atom_TranscriptionReceiveStatus, useHook: useStore_TranscriptionReceiveStatus } = createAtomWithHook(false, "TranscriptionReceiveStatus", {is_state_ok: true});
export const { atomInstance: Atom_ForegroundStatus, useHook: useStore_ForegroundStatus } = createAtomWithHook(false, "ForegroundStatus", {is_state_ok: true}); export const { atomInstance: Atom_ForegroundStatus, useHook: useStore_ForegroundStatus } = createAtomWithHook(false, "ForegroundStatus", {is_state_ok: true});
export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook([], "MessageLogs");
// export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook(generateTestData(20), "MessageLogs"); // For testing
export const { atomInstance: Atom_MessageInputValue, useHook: useStore_MessageInputValue } = createAtomWithHook("", "MessageInputValue");
export const { atomInstance: Atom_IsVisibleResendButton, useHook: useStore_IsVisibleResendButton } = createAtomWithHook(false, "IsVisibleResendButton", {is_state_ok: true});
export const { atomInstance: Atom_IsAppliedInitMessageBoxHeight, useHook: useStore_IsAppliedInitMessageBoxHeight } = createAtomWithHook(false, "IsAppliedInitMessageBoxHeight");
export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList");
export const { atomInstance: Atom_SelectedPresetTabNumber, useHook: useStore_SelectedPresetTabNumber } = createAtomWithHook("1", "SelectedPresetTabNumber"); export const { atomInstance: Atom_SelectedPresetTabNumber, useHook: useStore_SelectedPresetTabNumber } = createAtomWithHook("1", "SelectedPresetTabNumber");
export const { atomInstance: Atom_EnableMultiTranslation, useHook: useStore_EnableMultiTranslation } = createAtomWithHook(false, "EnableMultiTranslation"); export const { atomInstance: Atom_EnableMultiTranslation, useHook: useStore_EnableMultiTranslation } = createAtomWithHook(false, "EnableMultiTranslation");
export const { atomInstance: Atom_SelectedYourLanguages, useHook: useStore_SelectedYourLanguages } = createAtomWithHook({}, "SelectedYourLanguages"); export const { atomInstance: Atom_SelectedYourLanguages, useHook: useStore_SelectedYourLanguages } = createAtomWithHook({}, "SelectedYourLanguages");
export const { atomInstance: Atom_SelectedTargetLanguages, useHook: useStore_SelectedTargetLanguages } = createAtomWithHook({}, "SelectedTargetLanguages"); export const { atomInstance: Atom_SelectedTargetLanguages, useHook: useStore_SelectedTargetLanguages } = createAtomWithHook({}, "SelectedTargetLanguages");
export const { atomInstance: Atom_TranslationEngines, useHook: useStore_TranslationEngines } = createAtomWithHook(translator_status, "TranslationEngines"); export const { atomInstance: Atom_TranslationEngines, useHook: useStore_TranslationEngines } = createAtomWithHook(translator_status, "TranslationEngines");
export const { atomInstance: Atom_SelectedTranslationEngines, useHook: useStore_SelectedTranslationEngines } = createAtomWithHook({1:"", 2:"", 3:""}, "SelectedTranslationEngines"); export const { atomInstance: Atom_SelectedTranslationEngines, useHook: useStore_SelectedTranslationEngines } = createAtomWithHook({1:"", 2:"", 3:""}, "SelectedTranslationEngines");
export const { atomInstance: Atom_IsOpenedTranslatorSelector, useHook: useStore_IsOpenedTranslatorSelector } = createAtomWithHook(false, "IsOpenedTranslatorSelector");
// Language Selector
// Designs
export const { atomInstance: Atom_IsMainPageCompactMode, useHook: useStore_IsMainPageCompactMode } = createAtomWithHook(false, "IsMainPageCompactMode");
export const { atomInstance: Atom_MessageInputBoxRatio, useHook: useStore_MessageInputBoxRatio } = createAtomWithHook(20, "MessageInputBoxRatio");
export const { atomInstance: Atom_IsOpenedLanguageSelector, useHook: useStore_IsOpenedLanguageSelector } = createAtomWithHook( export const { atomInstance: Atom_IsOpenedLanguageSelector, useHook: useStore_IsOpenedLanguageSelector } = createAtomWithHook(
{ your_language: false, target_language: false, target_key: "1" }, { your_language: false, target_language: false, target_key: "1" },
"IsOpenedLanguageSelector" "IsOpenedLanguageSelector"
); );
export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList");
// Message Container
export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook([], "MessageLogs");
// export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook(generateTestData(20), "MessageLogs"); // For testing
export const { atomInstance: Atom_MessageInputBoxRatio, useHook: useStore_MessageInputBoxRatio } = createAtomWithHook(20, "MessageInputBoxRatio");
export const { atomInstance: Atom_MessageInputValue, useHook: useStore_MessageInputValue } = createAtomWithHook("", "MessageInputValue");
export const { atomInstance: Atom_IsVisibleResendButton, useHook: useStore_IsVisibleResendButton } = createAtomWithHook(false, "IsVisibleResendButton", {is_state_ok: true});
// Config Page // Config Page
@@ -170,8 +171,6 @@ export const { atomInstance: Atom_IsOpenedLanguageSelector, useHook: useStore_Is
export const { atomInstance: Atom_SoftwareVersion, useHook: useStore_SoftwareVersion } = createAtomWithHook("-", "SoftwareVersion"); export const { atomInstance: Atom_SoftwareVersion, useHook: useStore_SoftwareVersion } = createAtomWithHook("-", "SoftwareVersion");
export const { atomInstance: Atom_SelectedConfigTabId, useHook: useStore_SelectedConfigTabId } = createAtomWithHook("device", "SelectedConfigTabId"); export const { atomInstance: Atom_SelectedConfigTabId, useHook: useStore_SelectedConfigTabId } = createAtomWithHook("device", "SelectedConfigTabId");
export const { atomInstance: Atom_SettingBoxScrollPosition, useHook: useStore_SettingBoxScrollPosition } = createAtomWithHook(0, "SettingBoxScrollPosition"); export const { atomInstance: Atom_SettingBoxScrollPosition, useHook: useStore_SettingBoxScrollPosition } = createAtomWithHook(0, "SettingBoxScrollPosition");
// Designs
export const { atomInstance: Atom_IsOpenedDropdownMenu, useHook: useStore_IsOpenedDropdownMenu } = createAtomWithHook("", "IsOpenedDropdownMenu"); export const { atomInstance: Atom_IsOpenedDropdownMenu, useHook: useStore_IsOpenedDropdownMenu } = createAtomWithHook("", "IsOpenedDropdownMenu");
// Device // Device
@@ -292,9 +291,9 @@ export const { atomInstance: Atom_OscPort, useHook: useStore_OscPort } = createA
export const { atomInstance: Atom_IsOpenedTranslatorSelector, useHook: useStore_IsOpenedTranslatorSelector } = createAtomWithHook(false, "IsOpenedTranslatorSelector"); // Supporters
export const { atomInstance: Atom_SupportersData, useHook: useStore_SupportersData } = createAtomWithHook(null, "SupportersData", {is_state_ok: true}); export const { atomInstance: Atom_SupportersData, useHook: useStore_SupportersData } = createAtomWithHook(null, "SupportersData", {is_state_ok: true});
// About VRCT
export const { atomInstance: Atom_VrctPosterIndex, useHook: useStore_VrctPosterIndex } = createAtomWithHook(0, "VrctPosterIndex"); export const { atomInstance: Atom_VrctPosterIndex, useHook: useStore_VrctPosterIndex } = createAtomWithHook(0, "VrctPosterIndex");
export const { atomInstance: Atom_PosterShowcaseWorldPageIndex, useHook: useStore_PosterShowcaseWorldPageIndex } = createAtomWithHook(0, "PosterShowcaseWorldPageIndex"); export const { atomInstance: Atom_PosterShowcaseWorldPageIndex, useHook: useStore_PosterShowcaseWorldPageIndex } = createAtomWithHook(0, "PosterShowcaseWorldPageIndex");

View File

@@ -89,6 +89,8 @@ export const whisper_weight_type_status = [
{ id: "large-v1", label: "large-v1", is_downloaded: false, progress: null }, { id: "large-v1", label: "large-v1", is_downloaded: false, progress: null },
{ id: "large-v2", label: "large-v2", is_downloaded: false, progress: null }, { id: "large-v2", label: "large-v2", is_downloaded: false, progress: null },
{ id: "large-v3", label: "large-v3", is_downloaded: false, progress: null }, { id: "large-v3", label: "large-v3", is_downloaded: false, progress: null },
{ id: "large-v3-turbo-int8", label: "large-v3-turbo-int8", is_downloaded: false, progress: null },
{ id: "large-v3-turbo", label: "large-v3-turbo", is_downloaded: false, progress: null },
]; ];
export const supporters_data_url = "https://shiinasakamoto.github.io/vrct_supporters/assets/supporters/data.json"; export const supporters_data_url = "https://shiinasakamoto.github.io/vrct_supporters/assets/supporters/data.json";