Merge branch 'develop'
This commit is contained in:
92
.github/workflows/release.yml
vendored
Normal file
92
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
name: Release VRCT
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # タグが 'v' で始まる場合にトリガー (例: v1.0.0)
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Build VRCT
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22.15.0'
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Set up Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Setup Python environment
|
||||
run: npm run setup-python
|
||||
|
||||
- name: Install Python script dependencies
|
||||
run: pip install tqdm
|
||||
|
||||
- name: Build and package
|
||||
run: npm run release-all
|
||||
|
||||
- name: Get version from tag
|
||||
id: get_version
|
||||
shell: pwsh
|
||||
run: |
|
||||
$TAG_WITH_V = $env:GITHUB_REF -replace "^refs/tags/", ""
|
||||
$VERSION_NUM = $TAG_WITH_V -replace "^v", ""
|
||||
echo "VERSION=$VERSION_NUM" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
- name: Upload to Hugging Face Hub
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
||||
shell: pwsh # Explicitly use PowerShell for file operations
|
||||
run: |
|
||||
pip install huggingface_hub
|
||||
|
||||
$UPLOAD_DIR = "./hf_upload_temp"
|
||||
New-Item -ItemType Directory -Force -Path $UPLOAD_DIR
|
||||
Copy-Item -Path ./VRCT.zip -Destination "$UPLOAD_DIR/VRCT.zip"
|
||||
Copy-Item -Path ./VRCT_cuda.zip -Destination "$UPLOAD_DIR/VRCT_cuda.zip"
|
||||
|
||||
huggingface-cli upload ms-software/VRCT $UPLOAD_DIR . --repo-type model --commit-message "👍️[Update] ${{ env.VERSION }} Release"
|
||||
|
||||
huggingface-cli tag ms-software/VRCT ${{ github.ref_name }} --repo-type model --message "Release ${{ github.ref_name }}"
|
||||
|
||||
Remove-Item -Recurse -Force $UPLOAD_DIR
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ env.VERSION }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload Release Asset (NSIS Installer)
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./src-tauri/target/release/bundle/nsis/VRCT_${{ env.VERSION }}_x64-setup.exe
|
||||
asset_name: VRCT_${{ env.VERSION }}_x64-setup.exe
|
||||
asset_content_type: application/octet-stream
|
||||
@@ -50,7 +50,6 @@ main_page:
|
||||
received: "Received"
|
||||
system: "System"
|
||||
|
||||
show_resend_button: "Show Resend Button"
|
||||
resend_button_on_hover_desc: "Press And Hold To Send"
|
||||
|
||||
state_text_enabled: "Enabled"
|
||||
@@ -120,6 +119,9 @@ config_page:
|
||||
hide: "Hide (Use Enter key to send)"
|
||||
show: "Show"
|
||||
show_and_disable_enter_key: "Show and disable sending using the Enter key."
|
||||
show_resend_button:
|
||||
label: "Show Resend Button"
|
||||
desc: "When hovering over a sent message log, the resend button appears. Click to edit, long press to resend."
|
||||
font_family:
|
||||
label: "Font Family"
|
||||
ui_language:
|
||||
@@ -267,6 +269,9 @@ config_page:
|
||||
websocket_port:
|
||||
label: "WebSocket Port"
|
||||
|
||||
notifications:
|
||||
save_success: "Settings have been saved."
|
||||
|
||||
plugin_notifications:
|
||||
downloading: Downloading the plugin.
|
||||
downloaded_success: Downloaded successfully.
|
||||
@@ -277,6 +282,7 @@ plugin_notifications:
|
||||
updated_error: Update failed.
|
||||
|
||||
disabled_out_of_support: The plugin has been disabled. It's not supported on this VRCT version.
|
||||
disabled_due_to_an_error: "An error was detected while running the plugin. Please report this to the plugin developer."
|
||||
|
||||
is_enabled: The plugin has enabled.
|
||||
is_disabled: The plugin has disabled.
|
||||
@@ -50,7 +50,6 @@ main_page:
|
||||
received: "受信"
|
||||
system: "システム"
|
||||
|
||||
show_resend_button: "再送信ボタンを表示する"
|
||||
resend_button_on_hover_desc: "長押しで送信"
|
||||
|
||||
state_text_enabled: "有効"
|
||||
@@ -120,6 +119,9 @@ config_page:
|
||||
hide: "非表示 (エンターキーを使って送信)"
|
||||
show: "表示"
|
||||
show_and_disable_enter_key: "表示し、エンターキーでの送信を無効"
|
||||
show_resend_button:
|
||||
label: "再送信ボタンを表示する"
|
||||
desc: "送信済メッセージログにマウスホバーすると、再送信ボタンが表示されます。クリックで編集モード、長押しで再送信します。"
|
||||
font_family:
|
||||
label: "使用フォント"
|
||||
ui_language:
|
||||
@@ -267,6 +269,9 @@ config_page:
|
||||
websocket_port:
|
||||
label: "WebSocket Port"
|
||||
|
||||
notifications:
|
||||
save_success: "設定を保存しました。"
|
||||
|
||||
plugin_notifications:
|
||||
downloading: プラグインをダウンロード中。
|
||||
downloaded_success: プラグインのダウンロードが完了しました。
|
||||
@@ -277,6 +282,7 @@ plugin_notifications:
|
||||
updated_error: プラグインのアップデートに失敗しました。
|
||||
|
||||
disabled_out_of_support: 現在のバージョンとの互換性がありません。プラグインを無効にしました。
|
||||
disabled_due_to_an_error: プラグイン実行中にエラーを検知しました。プラグイン開発者に報告してください。
|
||||
|
||||
is_enabled: プラグインを有効にしました。
|
||||
is_disabled: プラグインを無効にしました。
|
||||
@@ -47,7 +47,6 @@ main_page:
|
||||
received: "수신"
|
||||
system: "시스템"
|
||||
|
||||
show_resend_button:
|
||||
resend_button_on_hover_desc:
|
||||
|
||||
state_text_enabled: "Enabled"
|
||||
|
||||
11
locales/useI18n.js
Normal file
11
locales/useI18n.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// To avoid a name conflict with our own `useTranslation` function,
|
||||
// rename the one from `react-i18next` to `useI18n`.
|
||||
// This is aliased via `vite.config.js`, so it can be imported using `@useI18n`.
|
||||
// Example:
|
||||
// import { useI18n } from "@useI18n";
|
||||
//
|
||||
// export const useTranslation = () => {
|
||||
// const { t } = useI18n();
|
||||
// ...
|
||||
// };
|
||||
export { useTranslation as useI18n } from "react-i18next";
|
||||
@@ -47,7 +47,6 @@ main_page:
|
||||
received: "接受"
|
||||
system: "系统"
|
||||
|
||||
show_resend_button:
|
||||
resend_button_on_hover_desc:
|
||||
|
||||
state_text_enabled: "启用"
|
||||
|
||||
@@ -47,7 +47,6 @@ main_page:
|
||||
received: "已接收"
|
||||
system: "系統"
|
||||
|
||||
show_resend_button:
|
||||
resend_button_on_hover_desc:
|
||||
|
||||
state_text_enabled: "啟用"
|
||||
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -28,6 +28,7 @@
|
||||
"react-error-boundary": "5.0.0",
|
||||
"react-i18next": "15.5.1",
|
||||
"react-resizable-layout": "0.7.2",
|
||||
"react-toastify": "11.0.5",
|
||||
"sass": "1.79.4",
|
||||
"semver": "7.7.1"
|
||||
},
|
||||
@@ -5534,6 +5535,19 @@
|
||||
"react-dom": ">=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-toastify": {
|
||||
"version": "11.0.5",
|
||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz",
|
||||
"integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18 || ^19",
|
||||
"react-dom": "^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"react-error-boundary": "5.0.0",
|
||||
"react-i18next": "15.5.1",
|
||||
"react-resizable-layout": "0.7.2",
|
||||
"react-toastify": "11.0.5",
|
||||
"sass": "1.79.4",
|
||||
"semver": "7.7.1"
|
||||
},
|
||||
|
||||
@@ -407,6 +407,29 @@ class Config:
|
||||
self._MESSAGE_BOX_RATIO = value
|
||||
self.saveConfig(inspect.currentframe().f_code.co_name, value, immediate_save=True)
|
||||
|
||||
@property
|
||||
@json_serializable('SEND_MESSAGE_BUTTON_TYPE')
|
||||
def SEND_MESSAGE_BUTTON_TYPE(self):
|
||||
return self._SEND_MESSAGE_BUTTON_TYPE
|
||||
|
||||
@SEND_MESSAGE_BUTTON_TYPE.setter
|
||||
def SEND_MESSAGE_BUTTON_TYPE(self, value):
|
||||
if isinstance(value, str):
|
||||
if value in self.SEND_MESSAGE_BUTTON_TYPE_LIST:
|
||||
self._SEND_MESSAGE_BUTTON_TYPE = value
|
||||
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
||||
|
||||
@property
|
||||
@json_serializable('SHOW_RESEND_BUTTON')
|
||||
def SHOW_RESEND_BUTTON(self):
|
||||
return self._SHOW_RESEND_BUTTON
|
||||
|
||||
@SHOW_RESEND_BUTTON.setter
|
||||
def SHOW_RESEND_BUTTON(self, value):
|
||||
if isinstance(value, bool):
|
||||
self._SHOW_RESEND_BUTTON = value
|
||||
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
||||
|
||||
@property
|
||||
@json_serializable('FONT_FAMILY')
|
||||
def FONT_FAMILY(self):
|
||||
@@ -804,18 +827,6 @@ class Config:
|
||||
self._SEND_ONLY_TRANSLATED_MESSAGES = value
|
||||
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
||||
|
||||
@property
|
||||
@json_serializable('SEND_MESSAGE_BUTTON_TYPE')
|
||||
def SEND_MESSAGE_BUTTON_TYPE(self):
|
||||
return self._SEND_MESSAGE_BUTTON_TYPE
|
||||
|
||||
@SEND_MESSAGE_BUTTON_TYPE.setter
|
||||
def SEND_MESSAGE_BUTTON_TYPE(self, value):
|
||||
if isinstance(value, str):
|
||||
if value in self.SEND_MESSAGE_BUTTON_TYPE_LIST:
|
||||
self._SEND_MESSAGE_BUTTON_TYPE = value
|
||||
self.saveConfig(inspect.currentframe().f_code.co_name, value)
|
||||
|
||||
@property
|
||||
@json_serializable('OVERLAY_SMALL_LOG')
|
||||
def OVERLAY_SMALL_LOG(self):
|
||||
@@ -989,7 +1000,7 @@ class Config:
|
||||
|
||||
def init_config(self):
|
||||
# Read Only
|
||||
self._VERSION = "3.2.0"
|
||||
self._VERSION = "3.2.1"
|
||||
if getattr(sys, 'frozen', False):
|
||||
self._PATH_LOCAL = os_path.dirname(sys.executable)
|
||||
else:
|
||||
@@ -1090,6 +1101,8 @@ class Config:
|
||||
self._UI_SCALING = 100
|
||||
self._TEXTBOX_UI_SCALING = 100
|
||||
self._MESSAGE_BOX_RATIO = 10
|
||||
self._SEND_MESSAGE_BUTTON_TYPE = "show"
|
||||
self._SHOW_RESEND_BUTTON = False
|
||||
self._FONT_FAMILY = "Yu Gothic UI"
|
||||
self._UI_LANGUAGE = "en"
|
||||
self._MAIN_WINDOW_GEOMETRY = {
|
||||
@@ -1137,7 +1150,6 @@ class Config:
|
||||
self._WHISPER_WEIGHT_TYPE = "base"
|
||||
self._AUTO_CLEAR_MESSAGE_BOX = True
|
||||
self._SEND_ONLY_TRANSLATED_MESSAGES = False
|
||||
self._SEND_MESSAGE_BUTTON_TYPE = "show"
|
||||
self._OVERLAY_SMALL_LOG = False
|
||||
self._OVERLAY_SMALL_LOG_SETTINGS = {
|
||||
"x_pos": 0.0,
|
||||
|
||||
@@ -259,17 +259,44 @@ class Controller:
|
||||
elif config.ENABLE_TRANSLATION is False:
|
||||
pass
|
||||
else:
|
||||
translation, success = model.getInputTranslate(message, source_language=language)
|
||||
if all(success) is not True:
|
||||
self.changeToCTranslate2Process()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_engine"],
|
||||
{
|
||||
"message":"Translation engine limit error",
|
||||
"data": None
|
||||
},
|
||||
)
|
||||
try:
|
||||
translation, success = model.getInputTranslate(message, source_language=language)
|
||||
if all(success) is not True:
|
||||
self.changeToCTranslate2Process()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_engine"],
|
||||
{
|
||||
"message":"Translation engine limit error",
|
||||
"data": None
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
# VRAM不足エラーの検出
|
||||
is_vram_error, error_message = model.detectVRAMError(e)
|
||||
if is_vram_error:
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_mic_vram_overflow"],
|
||||
{
|
||||
"message":"VRAM out of memory during translation of mic",
|
||||
"data": error_message
|
||||
},
|
||||
)
|
||||
# 翻訳機能をOFFにする
|
||||
self.setDisableTranslation()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["enable_translation"],
|
||||
{
|
||||
"message":"Translation disabled due to VRAM overflow",
|
||||
"data": False
|
||||
},
|
||||
)
|
||||
return
|
||||
else:
|
||||
# その他のエラーは通常通り処理
|
||||
raise
|
||||
|
||||
if config.CONVERT_MESSAGE_TO_ROMAJI is True or config.CONVERT_MESSAGE_TO_HIRAGANA is True:
|
||||
if config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"] == "Japanese":
|
||||
@@ -295,6 +322,27 @@ class Controller:
|
||||
"transliteration":transliteration
|
||||
})
|
||||
|
||||
if config.OVERLAY_LARGE_LOG is True and model.overlay.initialized is True:
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True:
|
||||
if len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageLargeLog(
|
||||
"send",
|
||||
None,
|
||||
None,
|
||||
translation,
|
||||
config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO]
|
||||
)
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
else:
|
||||
overlay_image = model.createOverlayImageLargeLog(
|
||||
"send",
|
||||
message,
|
||||
config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"],
|
||||
translation,
|
||||
config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO]
|
||||
)
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
|
||||
if model.checkWebSocketServerAlive() is True:
|
||||
model.websocketSendMessage(
|
||||
{
|
||||
@@ -308,16 +356,8 @@ class Controller:
|
||||
)
|
||||
|
||||
if config.LOGGER_FEATURE is True:
|
||||
if len(translation) > 0:
|
||||
translation = " (" + "/".join(translation) + ")"
|
||||
model.logger.info(f"[SENT] {message}{translation}")
|
||||
|
||||
if config.OVERLAY_LARGE_LOG is True and model.overlay.initialized is True:
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True and len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageLargeLog("send", translation[0], "")
|
||||
else:
|
||||
overlay_image = model.createOverlayImageLargeLog("send", message, translation[0] if len(translation) > 0 else "")
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
translation_text = f" ({'/'.join(translation)})" if translation else ""
|
||||
model.logger.info(f"[SENT] {message}{translation_text}")
|
||||
|
||||
def speakerMessage(self, result:dict) -> None:
|
||||
message = result["text"]
|
||||
@@ -346,17 +386,44 @@ class Controller:
|
||||
elif config.ENABLE_TRANSLATION is False:
|
||||
pass
|
||||
else:
|
||||
translation, success = model.getOutputTranslate(message, source_language=language)
|
||||
if all(success) is not True:
|
||||
self.changeToCTranslate2Process()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_engine"],
|
||||
{
|
||||
"message":"Translation engine limit error",
|
||||
"data": None
|
||||
},
|
||||
)
|
||||
try:
|
||||
translation, success = model.getOutputTranslate(message, source_language=language)
|
||||
if all(success) is not True:
|
||||
self.changeToCTranslate2Process()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_engine"],
|
||||
{
|
||||
"message":"Translation engine limit error",
|
||||
"data": None
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
# VRAM不足エラーの検出
|
||||
is_vram_error, error_message = model.detectVRAMError(e)
|
||||
if is_vram_error:
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_speaker_vram_overflow"],
|
||||
{
|
||||
"message":"VRAM out of memory during translation of speaker",
|
||||
"data": error_message
|
||||
},
|
||||
)
|
||||
# 翻訳機能をOFFにする
|
||||
self.setDisableTranslation()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["enable_translation"],
|
||||
{
|
||||
"message":"Translation disabled due to VRAM overflow",
|
||||
"data": False
|
||||
},
|
||||
)
|
||||
return
|
||||
else:
|
||||
# その他のエラーは通常通り処理
|
||||
raise
|
||||
|
||||
if config.CONVERT_MESSAGE_TO_ROMAJI is True or config.CONVERT_MESSAGE_TO_HIRAGANA is True:
|
||||
if config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"] == "Japanese":
|
||||
@@ -364,18 +431,43 @@ class Controller:
|
||||
|
||||
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
|
||||
if config.OVERLAY_SMALL_LOG is True and model.overlay.initialized is True:
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True and len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageSmallLog(translation[0], "")
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True:
|
||||
if len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageSmallLog(
|
||||
None,
|
||||
None,
|
||||
translation,
|
||||
config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO],
|
||||
)
|
||||
model.updateOverlaySmallLog(overlay_image)
|
||||
else:
|
||||
overlay_image = model.createOverlayImageSmallLog(message, translation[0] if len(translation) > 0 else "")
|
||||
model.updateOverlaySmallLog(overlay_image)
|
||||
overlay_image = model.createOverlayImageSmallLog(
|
||||
message,
|
||||
language,
|
||||
translation,
|
||||
config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO],
|
||||
)
|
||||
model.updateOverlaySmallLog(overlay_image)
|
||||
|
||||
if config.OVERLAY_LARGE_LOG is True and model.overlay.initialized is True:
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True and len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageLargeLog("receive", translation[0], "")
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True:
|
||||
if len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageLargeLog(
|
||||
"receive",
|
||||
None,
|
||||
None,
|
||||
translation,
|
||||
)
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
else:
|
||||
overlay_image = model.createOverlayImageLargeLog("receive", message, translation[0] if len(translation) > 0 else "")
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
overlay_image = model.createOverlayImageLargeLog(
|
||||
"receive",
|
||||
message,
|
||||
language,
|
||||
translation,
|
||||
config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO]
|
||||
)
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
|
||||
if config.SEND_RECEIVED_MESSAGE_TO_VRC is True:
|
||||
osc_message = self.messageFormatter("RECEIVED", translation, [message])
|
||||
@@ -404,9 +496,8 @@ class Controller:
|
||||
)
|
||||
|
||||
if config.LOGGER_FEATURE is True:
|
||||
if len(translation) > 0:
|
||||
translation = " (" + "/".join(translation) + ")"
|
||||
model.logger.info(f"[RECEIVED] {message}{translation}")
|
||||
translation_text = f" ({'/'.join(translation)})" if translation else ""
|
||||
model.logger.info(f"[RECEIVED] {message}{translation_text}")
|
||||
|
||||
def chatMessage(self, data) -> None:
|
||||
id = data["id"]
|
||||
@@ -417,26 +508,62 @@ class Controller:
|
||||
if config.ENABLE_TRANSLATION is False:
|
||||
pass
|
||||
else:
|
||||
if config.USE_EXCLUDE_WORDS is True:
|
||||
replacement_message, replacement_dict = self.replaceExclamationsWithRandom(message)
|
||||
translation, success = model.getInputTranslate(replacement_message)
|
||||
try:
|
||||
if config.USE_EXCLUDE_WORDS is True:
|
||||
replacement_message, replacement_dict = self.replaceExclamationsWithRandom(message)
|
||||
translation, success = model.getInputTranslate(replacement_message)
|
||||
|
||||
message = self.removeExclamations(message)
|
||||
for i in range(len(translation)):
|
||||
translation[i] = self.restoreText(translation[i], replacement_dict)
|
||||
else:
|
||||
translation, success = model.getInputTranslate(message)
|
||||
message = self.removeExclamations(message)
|
||||
for i in range(len(translation)):
|
||||
translation[i] = self.restoreText(translation[i], replacement_dict)
|
||||
else:
|
||||
translation, success = model.getInputTranslate(message)
|
||||
|
||||
if all(success) is not True:
|
||||
self.changeToCTranslate2Process()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_engine"],
|
||||
{
|
||||
"message":"Translation engine limit error",
|
||||
"data": None
|
||||
},
|
||||
)
|
||||
if all(success) is not True:
|
||||
self.changeToCTranslate2Process()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_engine"],
|
||||
{
|
||||
"message":"Translation engine limit error",
|
||||
"data": None
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
# VRAM不足エラーの検出
|
||||
is_vram_error, error_message = model.detectVRAMError(e)
|
||||
if is_vram_error:
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_translation_chat_vram_overflow"],
|
||||
{
|
||||
"message":"VRAM out of memory during translation of chat",
|
||||
"data": error_message
|
||||
},
|
||||
)
|
||||
# 翻訳機能をOFFにする
|
||||
self.setDisableTranslation()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["enable_translation"],
|
||||
{
|
||||
"message":"Translation disabled due to VRAM overflow",
|
||||
"data": False
|
||||
},
|
||||
)
|
||||
# エラー時は翻訳なしで返す
|
||||
return {"status":200,
|
||||
"result":
|
||||
{
|
||||
"id":id,
|
||||
"message":message,
|
||||
"translation":[],
|
||||
"transliteration":[],
|
||||
},
|
||||
}
|
||||
else:
|
||||
# その他のエラーは通常通り処理
|
||||
raise
|
||||
|
||||
if config.CONVERT_MESSAGE_TO_ROMAJI is True or config.CONVERT_MESSAGE_TO_HIRAGANA is True:
|
||||
if config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"] == "Japanese":
|
||||
@@ -454,11 +581,25 @@ class Controller:
|
||||
model.oscSendMessage(osc_message)
|
||||
|
||||
if config.OVERLAY_LARGE_LOG is True:
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True and len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageLargeLog("send", translation[0], "")
|
||||
if config.OVERLAY_SHOW_ONLY_TRANSLATED_MESSAGES is True:
|
||||
if len(translation) > 0:
|
||||
overlay_image = model.createOverlayImageLargeLog(
|
||||
"send",
|
||||
None,
|
||||
None,
|
||||
translation,
|
||||
config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO],
|
||||
)
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
else:
|
||||
overlay_image = model.createOverlayImageLargeLog("send", message, translation[0] if len(translation) > 0 else "")
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
overlay_image = model.createOverlayImageLargeLog(
|
||||
"send",
|
||||
message,
|
||||
config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"],
|
||||
translation,
|
||||
config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO],
|
||||
)
|
||||
model.updateOverlayLargeLog(overlay_image)
|
||||
|
||||
if model.checkWebSocketServerAlive() is True:
|
||||
model.websocketSendMessage(
|
||||
@@ -472,10 +613,8 @@ class Controller:
|
||||
}
|
||||
)
|
||||
|
||||
# update textbox message log (Chat)
|
||||
if config.LOGGER_FEATURE is True:
|
||||
if len(translation) > 0:
|
||||
translation_text = " (" + "/".join(translation) + ")"
|
||||
translation_text = f" ({'/'.join(translation)})" if translation else ""
|
||||
model.logger.info(f"[CHAT] {message}{translation_text}")
|
||||
|
||||
return {"status":200,
|
||||
@@ -514,8 +653,21 @@ class Controller:
|
||||
@staticmethod
|
||||
def setSelectedTranslationComputeDevice(device:str, *args, **kwargs) -> dict:
|
||||
printLog("setSelectedTranslationComputeDevice", device)
|
||||
pre_device = config.SELECTED_TRANSLATION_COMPUTE_DEVICE
|
||||
config.SELECTED_TRANSLATION_COMPUTE_DEVICE = device
|
||||
model.changeTranslatorCTranslate2Model()
|
||||
try:
|
||||
model.changeTranslatorCTranslate2Model()
|
||||
except Exception as e:
|
||||
# VRAM不足エラーの検出(デバイス切り替え時)
|
||||
is_vram_error, error_message = model.detectVRAMError(e)
|
||||
if is_vram_error:
|
||||
# 前のデバイス設定に戻す
|
||||
printLog("VRAM error detected, reverting device setting")
|
||||
config.SELECTED_TRANSLATION_COMPUTE_DEVICE = pre_device
|
||||
model.changeTranslatorCTranslate2Model()
|
||||
else:
|
||||
# その他のエラーは通常通り処理
|
||||
errorLogging()
|
||||
return {"status":200,"result":config.SELECTED_TRANSLATION_COMPUTE_DEVICE}
|
||||
|
||||
@staticmethod
|
||||
@@ -729,6 +881,29 @@ class Controller:
|
||||
config.MESSAGE_BOX_RATIO = data
|
||||
return {"status":200, "result":config.MESSAGE_BOX_RATIO}
|
||||
|
||||
@staticmethod
|
||||
def getSendMessageButtonType(*args, **kwargs) -> dict:
|
||||
return {"status":200, "result":config.SEND_MESSAGE_BUTTON_TYPE}
|
||||
|
||||
@staticmethod
|
||||
def setSendMessageButtonType(data, *args, **kwargs) -> dict:
|
||||
config.SEND_MESSAGE_BUTTON_TYPE = data
|
||||
return {"status":200, "result":config.SEND_MESSAGE_BUTTON_TYPE}
|
||||
|
||||
@staticmethod
|
||||
def getShowResendButton(*args, **kwargs) -> dict:
|
||||
return {"status":200, "result":config.SHOW_RESEND_BUTTON}
|
||||
|
||||
@staticmethod
|
||||
def setEnableShowResendButton(*args, **kwargs) -> dict:
|
||||
config.SHOW_RESEND_BUTTON = True
|
||||
return {"status":200, "result":config.SHOW_RESEND_BUTTON}
|
||||
|
||||
@staticmethod
|
||||
def setDisableShowResendButton(*args, **kwargs) -> dict:
|
||||
config.SHOW_RESEND_BUTTON = False
|
||||
return {"status":200, "result":config.SHOW_RESEND_BUTTON}
|
||||
|
||||
@staticmethod
|
||||
def getFontFamily(*args, **kwargs) -> dict:
|
||||
return {"status":200, "result":config.FONT_FAMILY}
|
||||
@@ -1153,8 +1328,12 @@ class Controller:
|
||||
if model.getIsOscQueryEnabled() is True:
|
||||
self.enableOscQuery()
|
||||
else:
|
||||
self.setDisableVrcMicMuteSync()
|
||||
self.disableOscQuery()
|
||||
mute_sync_info_flag = False
|
||||
if config.VRC_MIC_MUTE_SYNC is True:
|
||||
self.setDisableVrcMicMuteSync()
|
||||
mute_sync_info_flag = True
|
||||
self.disableOscQuery(mute_sync_info=mute_sync_info_flag)
|
||||
|
||||
response = {"status":200, "result":config.OSC_IP_ADDRESS}
|
||||
except Exception:
|
||||
model.setOscIpAddress(config.OSC_IP_ADDRESS)
|
||||
@@ -1299,15 +1478,6 @@ class Controller:
|
||||
config.SEND_ONLY_TRANSLATED_MESSAGES = False
|
||||
return {"status":200, "result":config.SEND_ONLY_TRANSLATED_MESSAGES}
|
||||
|
||||
@staticmethod
|
||||
def getSendMessageButtonType(*args, **kwargs) -> dict:
|
||||
return {"status":200, "result":config.SEND_MESSAGE_BUTTON_TYPE}
|
||||
|
||||
@staticmethod
|
||||
def setSendMessageButtonType(data, *args, **kwargs) -> dict:
|
||||
config.SEND_MESSAGE_BUTTON_TYPE = data
|
||||
return {"status":200, "result":config.SEND_MESSAGE_BUTTON_TYPE}
|
||||
|
||||
@staticmethod
|
||||
def getOverlaySmallLog(*args, **kwargs) -> dict:
|
||||
return {"status":200, "result":config.OVERLAY_SMALL_LOG}
|
||||
@@ -1628,8 +1798,35 @@ class Controller:
|
||||
while self.device_access_status is False:
|
||||
sleep(1)
|
||||
self.device_access_status = False
|
||||
model.startMicTranscript(self.micMessage)
|
||||
self.device_access_status = True
|
||||
try:
|
||||
model.startMicTranscript(self.micMessage)
|
||||
except Exception as e:
|
||||
# VRAM不足エラーの検出
|
||||
is_vram_error, error_message = model.detectVRAMError(e)
|
||||
if is_vram_error:
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_transcription_mic_vram_overflow"],
|
||||
{
|
||||
"message":"VRAM out of memory during mic transcription",
|
||||
"data": error_message
|
||||
},
|
||||
)
|
||||
# ここでマイクの音声認識を停止
|
||||
self.stopTranscriptionSendMessage()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["enable_transcription_send"],
|
||||
{
|
||||
"message":"Transcription send disabled due to VRAM overflow",
|
||||
"data": False
|
||||
},
|
||||
)
|
||||
else:
|
||||
# その他のエラーは通常通り処理
|
||||
errorLogging()
|
||||
finally:
|
||||
self.device_access_status = True
|
||||
|
||||
@staticmethod
|
||||
def stopTranscriptionSendMessage() -> None:
|
||||
@@ -1650,8 +1847,35 @@ class Controller:
|
||||
while self.device_access_status is False:
|
||||
sleep(1)
|
||||
self.device_access_status = False
|
||||
model.startSpeakerTranscript(self.speakerMessage)
|
||||
self.device_access_status = True
|
||||
try:
|
||||
model.startSpeakerTranscript(self.speakerMessage)
|
||||
except Exception as e:
|
||||
# VRAM不足エラーの検出
|
||||
is_vram_error, error_message = model.detectVRAMError(e)
|
||||
if is_vram_error:
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["error_transcription_speaker_vram_overflow"],
|
||||
{
|
||||
"message":"VRAM out of memory during speaker transcription",
|
||||
"data": error_message
|
||||
},
|
||||
)
|
||||
# ここでスピーカーの音声認識を停止
|
||||
self.stopTranscriptionReceiveMessage()
|
||||
self.run(
|
||||
400,
|
||||
self.run_mapping["enable_transcription_receive"],
|
||||
{
|
||||
"message":"Transcription receive disabled due to VRAM overflow",
|
||||
"data": False
|
||||
},
|
||||
)
|
||||
else:
|
||||
# その他のエラーは通常通り処理
|
||||
errorLogging()
|
||||
finally:
|
||||
self.device_access_status = True
|
||||
|
||||
@staticmethod
|
||||
def stopTranscriptionReceiveMessage() -> None:
|
||||
@@ -1933,12 +2157,13 @@ class Controller:
|
||||
}
|
||||
)
|
||||
|
||||
def disableOscQuery(self):
|
||||
def disableOscQuery(self, mute_sync_info:bool=False):
|
||||
disabled_functions = []
|
||||
if mute_sync_info is True:
|
||||
disabled_functions.append("vrc_mic_mute_sync")
|
||||
self.run(200, self.run_mapping["enable_osc_query"], {
|
||||
"data": False,
|
||||
"disabled_functions": [
|
||||
"vrc_mic_mute_sync",
|
||||
]
|
||||
"disabled_functions": disabled_functions
|
||||
})
|
||||
|
||||
def init(self, *args, **kwargs) -> None:
|
||||
@@ -2055,13 +2280,15 @@ class Controller:
|
||||
osc_query_enabled = model.getIsOscQueryEnabled()
|
||||
if osc_query_enabled is True:
|
||||
self.enableOscQuery()
|
||||
if config.VRC_MIC_MUTE_SYNC is True:
|
||||
self.setEnableVrcMicMuteSync()
|
||||
else:
|
||||
# OSC Query is disabled, so disable VRC some features
|
||||
config.VRC_MIC_MUTE_SYNC = False
|
||||
self.disableOscQuery()
|
||||
|
||||
if config.VRC_MIC_MUTE_SYNC is True:
|
||||
self.setEnableVrcMicMuteSync()
|
||||
mute_sync_info_flag = False
|
||||
if config.VRC_MIC_MUTE_SYNC is True:
|
||||
self.setDisableVrcMicMuteSync()
|
||||
mute_sync_info_flag = True
|
||||
self.disableOscQuery(mute_sync_info=mute_sync_info_flag)
|
||||
|
||||
# init Auto device selection
|
||||
printLog("Init Device Manager")
|
||||
|
||||
@@ -11,6 +11,10 @@ from utils import printLog, printResponse, errorLogging, encodeBase64 # noqa: E4
|
||||
logging.getLogger("huggingface_hub").setLevel(logging.ERROR)
|
||||
|
||||
run_mapping = {
|
||||
"enable_translation":"/run/enable_translation",
|
||||
"enable_transcription_send":"/run/enable_transcription_send",
|
||||
"enable_transcription_receive":"/run/enable_transcription_receive",
|
||||
|
||||
"connected_network":"/run/connected_network",
|
||||
"enable_ai_models":"/run/enable_ai_models",
|
||||
|
||||
@@ -22,6 +26,13 @@ run_mapping = {
|
||||
|
||||
"error_device":"/run/error_device",
|
||||
"error_translation_engine":"/run/error_translation_engine",
|
||||
|
||||
"error_translation_chat_vram_overflow":"/run/error_translation_chat_vram_overflow",
|
||||
"error_translation_mic_vram_overflow":"/run/error_translation_mic_vram_overflow",
|
||||
"error_translation_speaker_vram_overflow":"/run/error_translation_speaker_vram_overflow",
|
||||
"error_transcription_mic_vram_overflow":"/run/error_transcription_mic_vram_overflow",
|
||||
"error_transcription_speaker_vram_overflow":"/run/error_transcription_speaker_vram_overflow",
|
||||
|
||||
"word_filter":"/run/word_filter",
|
||||
|
||||
"download_progress_ctranslate2_weight":"/run/download_progress_ctranslate2_weight",
|
||||
@@ -120,6 +131,13 @@ mapping = {
|
||||
"/get/data/message_box_ratio": {"status": True, "variable":controller.getMessageBoxRatio},
|
||||
"/set/data/message_box_ratio": {"status": True, "variable":controller.setMessageBoxRatio},
|
||||
|
||||
"/get/data/send_message_button_type": {"status": True, "variable":controller.getSendMessageButtonType},
|
||||
"/set/data/send_message_button_type": {"status": True, "variable":controller.setSendMessageButtonType},
|
||||
|
||||
"/get/data/show_resend_button": {"status": True, "variable":controller.getShowResendButton},
|
||||
"/set/enable/show_resend_button": {"status": True, "variable":controller.setEnableShowResendButton},
|
||||
"/set/disable/show_resend_button": {"status": True, "variable":controller.setDisableShowResendButton},
|
||||
|
||||
"/get/data/font_family": {"status": True, "variable":controller.getFontFamily},
|
||||
"/set/data/font_family": {"status": True, "variable":controller.setFontFamily},
|
||||
|
||||
@@ -275,9 +293,6 @@ mapping = {
|
||||
"/set/enable/send_only_translated_messages": {"status": True, "variable":controller.setEnableSendOnlyTranslatedMessages},
|
||||
"/set/disable/send_only_translated_messages": {"status": True, "variable":controller.setDisableSendOnlyTranslatedMessages},
|
||||
|
||||
"/get/data/send_message_button_type": {"status": True, "variable":controller.getSendMessageButtonType},
|
||||
"/set/data/send_message_button_type": {"status": True, "variable":controller.setSendMessageButtonType},
|
||||
|
||||
"/get/data/logger_feature": {"status": True, "variable":controller.getLoggerFeature},
|
||||
"/set/enable/logger_feature": {"status": True, "variable":controller.setEnableLoggerFeature},
|
||||
"/set/disable/logger_feature": {"status": True, "variable":controller.setDisableLoggerFeature},
|
||||
@@ -524,6 +539,8 @@ if __name__ == "__main__":
|
||||
data = 1.5
|
||||
case "/set/data/message_box_ratio":
|
||||
data = 0.5
|
||||
case "/set/data/send_message_button_type":
|
||||
data = "show"
|
||||
case "/set/data/font_family":
|
||||
data = "Yu Gothic UI"
|
||||
case "/set/data/ui_language":
|
||||
@@ -544,7 +561,7 @@ if __name__ == "__main__":
|
||||
data = 5
|
||||
case "/set/data/mic_max_phrases":
|
||||
data = 5
|
||||
case "/set//data/mic_word_filter":
|
||||
case "/set/data/mic_word_filter":
|
||||
data = "test0, test1, test2"
|
||||
case "/set/data/selected_speaker_device":
|
||||
data = "スピーカー (Realtek High Definition Audio)"
|
||||
@@ -574,8 +591,6 @@ if __name__ == "__main__":
|
||||
"display_duration": 5,
|
||||
"fadeout_duration": 0.5,
|
||||
}
|
||||
case "/set/data/send_message_button_type":
|
||||
data = "show"
|
||||
case "/set/data/send_message_format":
|
||||
data = "[message]"
|
||||
case "/set/data/send_message_format_with_t":
|
||||
|
||||
@@ -96,7 +96,7 @@ class Model:
|
||||
"large": overlay_large_log_settings,
|
||||
}
|
||||
self.overlay = Overlay(overlay_settings)
|
||||
self.overlay_image = OverlayImage()
|
||||
self.overlay_image = OverlayImage(config.PATH_LOCAL)
|
||||
self.mic_audio_queue = None
|
||||
self.mic_mute_status = None
|
||||
self.kks = kakasi()
|
||||
@@ -452,9 +452,9 @@ class Model:
|
||||
config.MIC_AVG_LOGPROB,
|
||||
config.MIC_NO_SPEECH_PROB
|
||||
)
|
||||
if res:
|
||||
result = self.mic_transcriber.getTranscript()
|
||||
fnc(result)
|
||||
if res:
|
||||
result = self.mic_transcriber.getTranscript()
|
||||
fnc(result)
|
||||
except Exception:
|
||||
errorLogging()
|
||||
|
||||
@@ -509,6 +509,15 @@ class Model:
|
||||
if isinstance(self.mic_audio_recorder, SelectedMicEnergyAndAudioRecorder):
|
||||
self.mic_audio_recorder.pause()
|
||||
|
||||
# VRAM 不足エラーを検出するメソッドを追加
|
||||
def detectVRAMError(self, error):
|
||||
error_str = str(error)
|
||||
if isinstance(error, ValueError) and len(error.args) > 0 and error.args[0] == "VRAM_OUT_OF_MEMORY":
|
||||
return True, error.args[1] if len(error.args) > 1 else "VRAM out of memory"
|
||||
if "CUDA out of memory" in error_str or "CUBLAS_STATUS_ALLOC_FAILED" in error_str:
|
||||
return True, error_str
|
||||
return False, None
|
||||
|
||||
def changeMicTranscriptStatus(self):
|
||||
if config.VRC_MIC_MUTE_SYNC is True:
|
||||
match self.mic_mute_status:
|
||||
@@ -626,9 +635,9 @@ class Model:
|
||||
config.SPEAKER_AVG_LOGPROB,
|
||||
config.SPEAKER_NO_SPEECH_PROB
|
||||
)
|
||||
if res:
|
||||
result = self.speaker_transcriber.getTranscript()
|
||||
fnc(result)
|
||||
if res:
|
||||
result = self.speaker_transcriber.getTranscript()
|
||||
fnc(result)
|
||||
except Exception:
|
||||
errorLogging()
|
||||
|
||||
@@ -708,21 +717,20 @@ class Model:
|
||||
self.speaker_energy_recorder.stop()
|
||||
self.speaker_energy_recorder = None
|
||||
|
||||
def createOverlayImageSmallLog(self, message, translation):
|
||||
your_language = config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"]
|
||||
target_language = config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"]
|
||||
def createOverlayImageSmallLog(self, message:str, your_language:str, translation:list, target_language:dict):
|
||||
target_language = [data["language"] for data in target_language.values() if data["enable"] is True]
|
||||
return self.overlay_image.createOverlayImageSmallLog(message, your_language, translation, target_language)
|
||||
|
||||
def createOverlayImageSmallMessage(self, message):
|
||||
ui_language = config.UI_LANGUAGE
|
||||
convert_languages = {
|
||||
"en": "Japanese",
|
||||
"en": "Default",
|
||||
"jp": "Japanese",
|
||||
"ko":"Korean",
|
||||
"zh-Hans":"Chinese Simplified",
|
||||
"zh-Hant":"Chinese Traditional",
|
||||
}
|
||||
language = convert_languages.get(ui_language, "Japanese")
|
||||
language = convert_languages.get(ui_language, "Default")
|
||||
return self.overlay_image.createOverlayImageSmallLog(message, language)
|
||||
|
||||
def clearOverlayImageSmallLog(self):
|
||||
@@ -760,22 +768,21 @@ class Model:
|
||||
if (self.overlay.settings[size]["ui_scaling"] != config.OVERLAY_SMALL_LOG_SETTINGS["ui_scaling"]):
|
||||
self.overlay.updateUiScaling(config.OVERLAY_SMALL_LOG_SETTINGS["ui_scaling"], size)
|
||||
|
||||
def createOverlayImageLargeLog(self, message_type:str, message:str, translation:str):
|
||||
your_language = config.SELECTED_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"]
|
||||
target_language = config.SELECTED_YOUR_LANGUAGES[config.SELECTED_TAB_NO]["1"]["language"]
|
||||
def createOverlayImageLargeLog(self, message_type:str, message:str, your_language:str, translation:list, target_language:dict):
|
||||
target_language = [data["language"] for data in target_language.values() if data["enable"] is True]
|
||||
return self.overlay_image.createOverlayImageLargeLog(message_type, message, your_language, translation, target_language)
|
||||
|
||||
def createOverlayImageLargeMessage(self, message):
|
||||
ui_language = config.UI_LANGUAGE
|
||||
convert_languages = {
|
||||
"en": "Japanese",
|
||||
"en": "Default",
|
||||
"jp": "Japanese",
|
||||
"ko":"Korean",
|
||||
"zh-Hans":"Chinese Simplified",
|
||||
"zh-Hant":"Chinese Traditional",
|
||||
}
|
||||
language = convert_languages.get(ui_language, "Japanese")
|
||||
overlay_image = OverlayImage()
|
||||
language = convert_languages.get(ui_language, "Default")
|
||||
overlay_image = OverlayImage(config.PATH_LOCAL)
|
||||
|
||||
for _ in range(2):
|
||||
overlay_image.createOverlayImageLargeLog("send", message, language)
|
||||
|
||||
@@ -90,8 +90,10 @@ class OSCHandler:
|
||||
# エラー発生時にbrowserをリセットして次回再初期化
|
||||
if self.browser is not None:
|
||||
try:
|
||||
self.browser.zc.close()
|
||||
self.browser.browser.cancel()
|
||||
if hasattr(self.browser, 'zc') and self.browser.zc is not None:
|
||||
self.browser.zc.close()
|
||||
if hasattr(self.browser, 'browser') and self.browser.browser is not None:
|
||||
self.browser.browser.cancel()
|
||||
except Exception:
|
||||
pass
|
||||
self.browser = None
|
||||
@@ -140,8 +142,10 @@ class OSCHandler:
|
||||
# browserがある場合はクリーンアップ
|
||||
if self.browser is not None:
|
||||
try:
|
||||
self.browser.zc.close()
|
||||
self.browser.browser.cancel()
|
||||
if hasattr(self.browser, 'zc') and self.browser.zc is not None:
|
||||
self.browser.zc.close()
|
||||
if hasattr(self.browser, 'browser') and self.browser.browser is not None:
|
||||
self.browser.browser.cancel()
|
||||
except Exception:
|
||||
pass
|
||||
self.browser = None
|
||||
|
||||
@@ -11,14 +11,19 @@ except ImportError:
|
||||
|
||||
class OverlayImage:
|
||||
LANGUAGES = {
|
||||
"Japanese": "NotoSansJP-Regular",
|
||||
"Korean": "NotoSansKR-Regular",
|
||||
"Chinese Simplified": "NotoSansSC-Regular",
|
||||
"Chinese Traditional": "NotoSansTC-Regular",
|
||||
"Default": "NotoSansJP-Regular.ttf",
|
||||
"Japanese": "NotoSansJP-Regular.ttf",
|
||||
"Korean": "NotoSansKR-Regular.ttf",
|
||||
"Chinese Simplified": "NotoSansSC-Regular.ttf",
|
||||
"Chinese Traditional": "NotoSansTC-Regular.ttf",
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, root_path: str=None):
|
||||
self.message_log = []
|
||||
if root_path is None:
|
||||
self.root_path = os_path.join(os_path.dirname(__file__), "..", "..", "..", "fonts")
|
||||
else:
|
||||
self.root_path = os_path.join(root_path, "_internal", "fonts")
|
||||
|
||||
@staticmethod
|
||||
def concatenateImagesVertically(img1: Image, img2: Image, margin: int = 0) -> Image:
|
||||
@@ -54,16 +59,16 @@ class OverlayImage:
|
||||
return colors
|
||||
|
||||
def createTextboxSmallLog(self, text:str, language:str, text_color:tuple, base_width:int, base_height:int, font_size:int) -> Image:
|
||||
font_family = self.LANGUAGES.get(language, "NotoSansJP-Regular")
|
||||
font_family = self.LANGUAGES.get(language, self.LANGUAGES["Default"])
|
||||
img = Image.new("RGBA", (base_width, base_height), (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
try:
|
||||
font_path = os_path.join(os_path.dirname(os_path.dirname(os_path.dirname(__file__))), "fonts", f"{font_family}.ttf")
|
||||
font_path = os_path.join(self.root_path, font_family)
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
except Exception:
|
||||
errorLogging()
|
||||
font_path = os_path.join(os_path.dirname(__file__), "..", "..", "..", "fonts", f"{font_family}.ttf")
|
||||
font_path = os_path.join(os_path.dirname(__file__), "..", "..", "..", "fonts", font_family)
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
|
||||
text_width = draw.textlength(text, font)
|
||||
@@ -80,7 +85,8 @@ class OverlayImage:
|
||||
draw.text((text_x, text_y), text, text_color, anchor="mm", stroke_width=0, font=font, align="center")
|
||||
return img
|
||||
|
||||
def createOverlayImageSmallLog(self, message:str, your_language:str, translation:str="", target_language:str=None) -> Image:
|
||||
def createOverlayImageSmallLog(self, message: str, your_language: str, translation: list = [], target_language: list = []) -> Image:
|
||||
# UI設定を取得
|
||||
ui_size = self.getUiSizeSmallLog()
|
||||
width, height, font_size = ui_size["width"], ui_size["height"], ui_size["font_size"]
|
||||
|
||||
@@ -89,16 +95,41 @@ class OverlayImage:
|
||||
background_color = ui_colors["background_color"]
|
||||
background_outline_color = ui_colors["background_outline_color"]
|
||||
|
||||
img = self.createTextboxSmallLog(message, your_language, text_color, width, height, font_size)
|
||||
if translation and target_language:
|
||||
translation_img = self.createTextboxSmallLog(translation, target_language, text_color, width, height, font_size)
|
||||
img = self.concatenateImagesVertically(img, translation_img)
|
||||
# テキストボックス画像のリストを作成
|
||||
textbox_images = []
|
||||
|
||||
# 翻訳がある場合
|
||||
if translation and target_language:
|
||||
# 元のメッセージがある場合は追加
|
||||
if message:
|
||||
textbox_images.append(
|
||||
self.createTextboxSmallLog(message, your_language, text_color, width, height, font_size)
|
||||
)
|
||||
|
||||
# 翻訳をすべて追加
|
||||
for trans, lang in zip(translation, target_language):
|
||||
textbox_images.append(
|
||||
self.createTextboxSmallLog(trans, lang, text_color, width, height, font_size)
|
||||
)
|
||||
else:
|
||||
# 翻訳がない場合は元のメッセージのみ
|
||||
textbox_images.append(
|
||||
self.createTextboxSmallLog(message, your_language, text_color, width, height, font_size)
|
||||
)
|
||||
|
||||
# すべてのテキストボックスを縦に結合
|
||||
img = textbox_images[0]
|
||||
for textbox_img in textbox_images[1:]:
|
||||
img = self.concatenateImagesVertically(img, textbox_img)
|
||||
|
||||
# 角丸背景を作成
|
||||
background = Image.new("RGBA", img.size, (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(background)
|
||||
draw.rounded_rectangle([(0, 0), img.size], radius=50, fill=background_color, outline=background_outline_color, width=5)
|
||||
|
||||
return Image.alpha_composite(background, img)
|
||||
# 背景とテキストを合成
|
||||
img = Image.alpha_composite(background, img)
|
||||
return img
|
||||
|
||||
@staticmethod
|
||||
def getUiSizeLargeLog() -> dict:
|
||||
@@ -131,17 +162,17 @@ class OverlayImage:
|
||||
anchor = "lm" if message_type == "receive" else "rm"
|
||||
text_x = 0 if message_type == "receive" else ui_size["width"]
|
||||
align = "left" if message_type == "receive" else "right"
|
||||
font_family = self.LANGUAGES.get(language, "NotoSansJP-Regular")
|
||||
font_family = self.LANGUAGES.get(language, self.LANGUAGES["Default"])
|
||||
|
||||
img = Image.new("RGBA", (0, 0), (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
try:
|
||||
font_path = os_path.join(os_path.dirname(os_path.dirname(os_path.dirname(__file__))), "fonts", f"{font_family}.ttf")
|
||||
font_path = os_path.join(self.root_path, font_family)
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
except Exception:
|
||||
errorLogging()
|
||||
font_path = os_path.join(os_path.dirname(__file__), "..", "..", "..", "fonts", f"{font_family}.ttf")
|
||||
font_path = os_path.join(os_path.dirname(__file__), "..", "..", "..", "fonts", font_family)
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
|
||||
text_width = draw.textlength(text, font)
|
||||
@@ -172,11 +203,11 @@ class OverlayImage:
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
try:
|
||||
font_path = os_path.join(os_path.dirname(os_path.dirname(os_path.dirname(__file__))), "fonts", "NotoSansJP-Regular.ttf")
|
||||
font_path = os_path.join(self.root_path, self.LANGUAGES["Default"])
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
except Exception:
|
||||
errorLogging()
|
||||
font_path = os_path.join(os_path.dirname(__file__), "..", "..", "..", "fonts", "NotoSansJP-Regular.ttf")
|
||||
font_path = os_path.join(os_path.dirname(__file__), "..", "..", "..", "fonts", self.LANGUAGES["Default"])
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
|
||||
text_height = font_size + ui_padding
|
||||
@@ -191,17 +222,37 @@ class OverlayImage:
|
||||
draw.text((text_x, text_y), text, text_color, anchor=anchor, stroke_width=0, font=font)
|
||||
return img
|
||||
|
||||
def createTextboxLargeLog(self, message_type:str, message:str, your_language:str, translation:str, target_language:str, date_time:str) -> Image:
|
||||
message_type_img = self.createTextImageMessageType(message_type, date_time)
|
||||
if translation and target_language:
|
||||
img = self.createTextImageLargeLog(message_type, "small", message, your_language)
|
||||
translation_img = self.createTextImageLargeLog(message_type, "large", translation, target_language)
|
||||
img = self.concatenateImagesVertically(img, translation_img)
|
||||
else:
|
||||
img = self.createTextImageLargeLog(message_type, "large", message, your_language)
|
||||
return self.concatenateImagesVertically(message_type_img, img)
|
||||
def createTextboxLargeLog(self, message_type: str, message: str = None, your_language: str = None, translation: list = [], target_language: list = [], date_time: str = None) -> Image:
|
||||
# テキスト画像のリストを作成
|
||||
images = [self.createTextImageMessageType(message_type, date_time)]
|
||||
|
||||
def createOverlayImageLargeLog(self, message_type:str, message:str, your_language:str, translation:str="", target_language:str=None) -> Image:
|
||||
# 翻訳がある場合
|
||||
if translation and target_language:
|
||||
# 元のメッセージがある場合は小さいサイズで追加
|
||||
if message is not None:
|
||||
images.append(
|
||||
self.createTextImageLargeLog(message_type, "small", message, your_language)
|
||||
)
|
||||
|
||||
# 翻訳をすべて大きいサイズで追加
|
||||
for trans, lang in zip(translation, target_language):
|
||||
images.append(
|
||||
self.createTextImageLargeLog(message_type, "large", trans, lang)
|
||||
)
|
||||
else:
|
||||
# 翻訳がない場合は元のメッセージのみ
|
||||
images.append(
|
||||
self.createTextImageLargeLog(message_type, "large", message, your_language)
|
||||
)
|
||||
|
||||
# すべてのテキスト画像を縦に結合
|
||||
combined_img = images[0]
|
||||
for img in images[1:]:
|
||||
combined_img = self.concatenateImagesVertically(combined_img, img)
|
||||
|
||||
return combined_img
|
||||
|
||||
def createOverlayImageLargeLog(self, message_type:str, message:str=None, your_language:str=None, translation:list=[], target_language:list=[]) -> Image:
|
||||
ui_color = self.getUiColorLargeLog()
|
||||
background_color = ui_color["background_color"]
|
||||
background_outline_color = ui_color["background_outline_color"]
|
||||
@@ -242,7 +293,8 @@ class OverlayImage:
|
||||
background = Image.new("RGBA", (width, height), (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(background)
|
||||
draw.rounded_rectangle([(0, 0), (width, height)], radius=ui_radius, fill=background_color, outline=background_outline_color, width=5)
|
||||
return Image.alpha_composite(background, img)
|
||||
img = Image.alpha_composite(background, img)
|
||||
return img
|
||||
|
||||
if __name__ == "__main__":
|
||||
overlay = OverlayImage()
|
||||
|
||||
@@ -77,15 +77,24 @@ 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 = getBestComputeType(device, device_index)
|
||||
return WhisperModel(
|
||||
path,
|
||||
device=device,
|
||||
device_index=device_index,
|
||||
compute_type=compute_type,
|
||||
cpu_threads=4,
|
||||
num_workers=1,
|
||||
local_files_only=True,
|
||||
)
|
||||
try:
|
||||
model = WhisperModel(
|
||||
path,
|
||||
device=device,
|
||||
device_index=device_index,
|
||||
compute_type=compute_type,
|
||||
cpu_threads=4,
|
||||
num_workers=1,
|
||||
local_files_only=True,
|
||||
)
|
||||
return model
|
||||
except RuntimeError as e:
|
||||
# VRAM不足エラーの検出
|
||||
error_message = str(e)
|
||||
if "CUDA out of memory" in error_message or "CUBLAS_STATUS_ALLOC_FAILED" in error_message:
|
||||
raise ValueError("VRAM_OUT_OF_MEMORY", error_message)
|
||||
# その他のエラーは通常通り再送出
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
def callback(value):
|
||||
|
||||
@@ -138,7 +138,8 @@ class WebSocketServer:
|
||||
finally:
|
||||
# 停止指示が出たらすべての接続を閉じ、イベントループを終了
|
||||
self._loop.run_until_complete(self._shutdown())
|
||||
self._loop.close()
|
||||
if self._loop is not None:
|
||||
self._loop.close()
|
||||
|
||||
async def _shutdown(self):
|
||||
"""
|
||||
|
||||
@@ -115,9 +115,24 @@ def printResponse(status:int, endpoint:str, result:Any=None) -> None:
|
||||
"endpoint": endpoint,
|
||||
"result": result,
|
||||
}
|
||||
process_logger.info(response)
|
||||
response = json.dumps(response)
|
||||
print(response, flush=True)
|
||||
process_logger.info(response) # Log the unserialized response
|
||||
|
||||
try:
|
||||
serialized_response = json.dumps(response)
|
||||
except OSError as e:
|
||||
errorLogging() # Log the full traceback of the OSError
|
||||
process_logger.error(f"Problematic response object before json.dumps: {response}")
|
||||
process_logger.error(f"OSError during json.dumps: {e}")
|
||||
# Optionally, print a generic error JSON to stdout if needed, or re-raise
|
||||
# For now, we'll print a simple error message to stdout as a fallback
|
||||
error_json = json.dumps({
|
||||
"status": 500,
|
||||
"endpoint": endpoint,
|
||||
"result": {"error": "Failed to serialize response due to OSError", "details": str(e)}
|
||||
})
|
||||
print(error_json, flush=True)
|
||||
else:
|
||||
print(serialized_response, flush=True)
|
||||
|
||||
error_logger = None
|
||||
def errorLogging() -> None:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "VRCT",
|
||||
"version": "3.0.0",
|
||||
"version": "3.2.1",
|
||||
"identifier": "com.vrct.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const generateTestData = (num) => {
|
||||
export const generateTestConversationData = (num) => {
|
||||
const testDataArray = [];
|
||||
const messagesJa = [
|
||||
"今日はとてもいい天気ですね。",
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
import {
|
||||
KeyEventController,
|
||||
@@ -11,23 +11,28 @@ import {
|
||||
TransparencyController,
|
||||
CornerRadiusController,
|
||||
PluginsController,
|
||||
} from "./_app_controllers/index.js";
|
||||
} from "./_app_controllers";
|
||||
|
||||
import styles from "./App.module.scss";
|
||||
|
||||
import { WindowTitleBar } from "./window_title_bar/WindowTitleBar";
|
||||
import { MainPage } from "./main_page/MainPage";
|
||||
import { ConfigPage } from "./config_page/ConfigPage";
|
||||
import { SplashComponent } from "./splash_component/SplashComponent";
|
||||
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 {
|
||||
WindowTitleBar,
|
||||
SplashComponent,
|
||||
UpdatingComponent,
|
||||
ModalController,
|
||||
SnackbarController,
|
||||
AppErrorBoundary,
|
||||
} from "./others";
|
||||
|
||||
import { useIsBackendReady, useIsSoftwareUpdating, useIsVrctAvailable, useWindow } from "@logics_common";
|
||||
import { AppErrorBoundary } from "./error_boundary/AppErrorBoundary";
|
||||
|
||||
export const App = () => {
|
||||
const { currentIsVrctAvailable } = useIsVrctAvailable();
|
||||
const { currentIsBackendReady } = useIsBackendReady();
|
||||
const { i18n } = useTranslation();
|
||||
const { i18n } = useI18n();
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useEffect } from "react";
|
||||
import { useSelectedFontFamily } from "@logics_configs";
|
||||
import { useAppearance } from "@logics_configs";
|
||||
|
||||
export const FontFamilyController = () => {
|
||||
const { currentSelectedFontFamily } = useSelectedFontFamily();
|
||||
const { currentSelectedFontFamily } = useAppearance();
|
||||
useEffect(() => {
|
||||
document.documentElement.style.setProperty("--font_family", currentSelectedFontFamily.data);
|
||||
}, [currentSelectedFontFamily.data]);
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { Command } from "@tauri-apps/plugin-shell";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useStartPython } from "@logics/useStartPython";
|
||||
import { useStdoutToPython } from "@logics/useStdoutToPython";
|
||||
|
||||
import { useStore_SelectableFontFamilyList } from "@store";
|
||||
import { useStdoutToPython } from "@useStdoutToPython";
|
||||
import { useReceiveRoutes } from "@useReceiveRoutes";
|
||||
import { store, useStore_SelectableFontFamilyList } from "@store";
|
||||
import { arrayToObject } from "@utils";
|
||||
|
||||
import {
|
||||
useNotificationStatus,
|
||||
} from "@logics_common";
|
||||
|
||||
export const StartPythonController = () => {
|
||||
const { asyncStartPython } = useStartPython();
|
||||
const hasRunRef = useRef(false);
|
||||
@@ -26,6 +31,34 @@ export const StartPythonController = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const useStartPython = () => {
|
||||
const { receiveRoutes } = useReceiveRoutes();
|
||||
const { showNotification_Success, showNotification_Error } = useNotificationStatus();
|
||||
|
||||
const asyncStartPython = async () => {
|
||||
const command = Command.sidecar("bin/VRCT-sidecar");
|
||||
command.on("error", error => console.error(`error: "${error}"`));
|
||||
command.stdout.on("data", (line) => {
|
||||
let parsed_data = "";
|
||||
try {
|
||||
parsed_data = JSON.parse(line);
|
||||
receiveRoutes(parsed_data);
|
||||
} catch (error) {
|
||||
console.log(error, 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();
|
||||
store.backend_subprocess = backend_subprocess;
|
||||
};
|
||||
|
||||
return { asyncStartPython };
|
||||
};
|
||||
|
||||
const useAsyncFetchFonts = () => {
|
||||
const { updateSelectableFontFamilyList } = useStore_SelectableFontFamilyList();
|
||||
const asyncFetchFonts = async () => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useEffect } from "react";
|
||||
import { useTransparency } from "@logics_configs";
|
||||
import { useAppearance } from "@logics_configs";
|
||||
|
||||
export const TransparencyController = () => {
|
||||
const { currentTransparency } = useTransparency();
|
||||
const { currentTransparency } = useAppearance();
|
||||
useEffect(() => {
|
||||
document.documentElement.style.setProperty("opacity", `${currentTransparency.data / 100}`);
|
||||
}, [currentTransparency.data]);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useUiLanguage } from "@logics_configs";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { useAppearance } from "@logics_configs";
|
||||
|
||||
export const UiLanguageController = () => {
|
||||
const { currentUiLanguage } = useUiLanguage();
|
||||
const { i18n } = useTranslation();
|
||||
const { currentUiLanguage } = useAppearance();
|
||||
const { i18n } = useI18n();
|
||||
|
||||
useEffect(() => {
|
||||
i18n.changeLanguage(currentUiLanguage.data);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useEffect } from "react";
|
||||
import { useUiScaling } from "@logics_configs";
|
||||
import { useAppearance } from "@logics_configs";
|
||||
|
||||
export const UiSizeController = () => {
|
||||
const { currentUiScaling } = useUiScaling();
|
||||
const { currentUiScaling } = useAppearance();
|
||||
const font_size = 62.5 * currentUiScaling.data / 100;
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { store } from "@store";
|
||||
import { usePlugins } from "@logics_configs";
|
||||
import { useSoftwareVersion } from "@logics_common";
|
||||
import { useNotificationStatus } from "@logics_common";
|
||||
|
||||
export const MergePluginsController = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const {
|
||||
currentLoadedPlugins,
|
||||
updatePluginsData,
|
||||
|
||||
@@ -18,14 +18,15 @@
|
||||
|
||||
--primary_600_color_44: #36877744;
|
||||
|
||||
/* primary_300_color 61b4a7 as standard */
|
||||
--sent_400_color: #6197b4;
|
||||
--sent_300_color: #6197b4;
|
||||
--received_300_color: #a861b4;
|
||||
|
||||
--error_bc_color: #bb4448;
|
||||
--error_bc_active_color: #9c3938;
|
||||
--success_bc_color: #368777;
|
||||
--waring_color: #cb944f;
|
||||
--waring_bc_color: #cf7b1b;
|
||||
--success_bc_color: var(--primary_600_color);
|
||||
--warning_color: #cb944f;
|
||||
--warning_bc_color: #cf7b1b;
|
||||
|
||||
--dark_basic_text_color: #f2f2f2;
|
||||
--dark_100_color: #f5f7fb;
|
||||
@@ -60,6 +61,8 @@
|
||||
--dark_1000_color_aa: #151517aa;
|
||||
--dark_1000_color_dd: #151517dd;
|
||||
|
||||
/*sent_400_color + #000 10% = */
|
||||
--supporters_color_fuwa: #5788a2;
|
||||
|
||||
--title_bar_height: 2rem;
|
||||
--main_page_topbar_height: 4.8rem;
|
||||
@@ -68,4 +71,5 @@
|
||||
|
||||
--font_family: "Yu Gothic UI";
|
||||
}
|
||||
/* https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors */
|
||||
/* https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors */
|
||||
/* https://meyerweb.com/eric/tools/color-blend/#::1:hex */
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import styles from "./_DownloadButton.module.scss";
|
||||
|
||||
export const _DownloadButton = ({option, ...props}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const renderContent = () => {
|
||||
const circular_progress = Math.floor(option.progress / 10) * 10;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import styles from "./DeeplAuthKey.module.scss";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import ExternalLink from "@images/external_link.svg?react";
|
||||
@@ -8,7 +8,7 @@ import { useState, useRef } from "react";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export const DeeplAuthKey = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const [is_editable, seIsEditable] = useState(false);
|
||||
const entryRef = useRef(null);
|
||||
|
||||
@@ -60,7 +60,7 @@ export const DeeplAuthKey = (props) => {
|
||||
|
||||
|
||||
export const OpenWebpage_DeeplAuthKey = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div className={styles.open_webpage_button_wrapper}>
|
||||
<a className={styles.open_webpage_button} href="https://www.deepl.com/ja/your-account/keys" target="_blank" rel="noreferrer" >
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import styles from "./EntryWithSaveButton.module.scss";
|
||||
import { _Entry } from "../_atoms/_entry/_Entry";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { clsx } from "clsx";
|
||||
|
||||
export const EntryWithSaveButton = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const onChangeFunction = (e) => {
|
||||
props.onChangeFunction?.(e.target.value);
|
||||
};
|
||||
|
||||
@@ -12,5 +12,4 @@ export { Slider } from "./slider/Slider";
|
||||
export { SwitchBox } from "./switch_box/SwitchBox";
|
||||
export { ThresholdComponent } from "./threshold_component/ThresholdComponent";
|
||||
export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter";
|
||||
export { DownloadModels } from "./download_models/DownloadModels";
|
||||
export { PluginsControlComponent } from "./plugins_control_component/PluginsControlComponent";
|
||||
export { DownloadModels } from "./download_models/DownloadModels";
|
||||
@@ -7,8 +7,7 @@ import { useVolume } from "@logics_common";
|
||||
import MicSvg from "@images/mic.svg?react";
|
||||
import HeadphonesSvg from "@images/headphones.svg?react";
|
||||
import {
|
||||
useMicThreshold,
|
||||
useSpeakerThreshold,
|
||||
useDevice,
|
||||
} from "@logics_configs";
|
||||
|
||||
export const ThresholdComponent = (props) => {
|
||||
@@ -27,7 +26,7 @@ const MicComponent = (props) => {
|
||||
currentMicThreshold,
|
||||
setMicThreshold,
|
||||
currentEnableAutomaticMicThreshold,
|
||||
} = useMicThreshold();
|
||||
} = useDevice();
|
||||
const [ui_threshold, setUiThreshold] = useState(currentMicThreshold.data);
|
||||
const {
|
||||
volumeCheckStart_Mic,
|
||||
@@ -84,7 +83,7 @@ const SpeakerComponent = (props) => {
|
||||
currentSpeakerThreshold,
|
||||
setSpeakerThreshold,
|
||||
currentEnableAutomaticSpeakerThreshold,
|
||||
} = useSpeakerThreshold();
|
||||
} = useDevice();
|
||||
const [ui_threshold, setUiThreshold] = useState(currentSpeakerThreshold.data);
|
||||
const {
|
||||
volumeCheckStart_Speaker,
|
||||
|
||||
@@ -4,8 +4,7 @@ import {
|
||||
useStore_SpeakerVolume,
|
||||
} from "@store";
|
||||
import {
|
||||
useMicThreshold,
|
||||
useSpeakerThreshold,
|
||||
useDevice,
|
||||
} from "@logics_configs";
|
||||
|
||||
export const SliderAndMeter = (props) => {
|
||||
@@ -24,7 +23,7 @@ export const SliderAndMeter = (props) => {
|
||||
const ThresholdVolumeMeter_Mic = (props) => {
|
||||
const { currentMicVolume } = useStore_MicVolume();
|
||||
|
||||
const { currentEnableAutomaticMicThreshold } = useMicThreshold();
|
||||
const { currentEnableAutomaticMicThreshold } = useDevice();
|
||||
|
||||
const currentVolumeVariable = Math.min(currentMicVolume.data, props.max);
|
||||
const volume_width_percentage = (currentVolumeVariable / props.max) * 100;
|
||||
@@ -50,7 +49,7 @@ const ThresholdVolumeMeter_Mic = (props) => {
|
||||
const ThresholdVolumeMeter_Speaker = (props) => {
|
||||
const { currentSpeakerVolume } = useStore_SpeakerVolume();
|
||||
|
||||
const { currentEnableAutomaticSpeakerThreshold } = useSpeakerThreshold();
|
||||
const { currentEnableAutomaticSpeakerThreshold } = useDevice();
|
||||
|
||||
const currentVolumeVariable = Math.min(currentSpeakerVolume.data, props.max);
|
||||
const volume_width_percentage = (currentVolumeVariable / props.max) * 100;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
import styles from "./VolumeCheckButton.module.scss";
|
||||
|
||||
export const VolumeCheckButton = React.memo((props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const getClassNames = (baseClass) => clsx(baseClass, {
|
||||
[styles.is_active]: (props.isChecking?.data === true),
|
||||
[styles.is_pending]: (props.isChecking.state === "pending"),
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./WordFilter.module.scss";
|
||||
import { _Entry } from "../_atoms/_entry/_Entry";
|
||||
import { useState } from "react";
|
||||
import { useStore_IsOpenedMicWordFilterList } from "@store";
|
||||
import { useMicWordFilterList } from "@logics_configs";
|
||||
import { useTranscription } from "@logics_configs";
|
||||
|
||||
export const WordFilter = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const [input_value, setInputValue] = useState("");
|
||||
const { currentMicWordFilterList, updateMicWordFilterList, setMicWordFilterList } = useMicWordFilterList();
|
||||
const { currentMicWordFilterList, updateMicWordFilterList, setMicWordFilterList } = useTranscription();
|
||||
const { currentIsOpenedMicWordFilterList, updateIsOpenedMicWordFilterList } = useStore_IsOpenedMicWordFilterList();
|
||||
|
||||
const extractRedoableFalseItem = (updated_list) => {
|
||||
@@ -126,9 +126,9 @@ const WordFilterItem = (props) => {
|
||||
|
||||
import ArrowLeftSvg from "@images/arrow_left.svg?react";
|
||||
export const WordFilterListToggleComponent = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentIsOpenedMicWordFilterList, updateIsOpenedMicWordFilterList } = useStore_IsOpenedMicWordFilterList();
|
||||
const { currentMicWordFilterList } = useMicWordFilterList();
|
||||
const { currentMicWordFilterList } = useTranscription();
|
||||
|
||||
|
||||
const svg_class_names = clsx(styles["arrow_left_svg"], {
|
||||
|
||||
@@ -27,12 +27,12 @@ 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 clsx from "clsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { useStore_UiLanguage } from "@store";
|
||||
import { PosterShowcaseContents } from "./poster_showcase_contents/PosterShowcaseContents";
|
||||
|
||||
export const AboutVrct = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentUiLanguage } = useStore_UiLanguage();
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./AdvancedSettings.module.scss";
|
||||
|
||||
import { useOpenFolder } from "@logics_common";
|
||||
import {
|
||||
useOscIpAddress,
|
||||
useOscPort,
|
||||
useWebsocket,
|
||||
useAdvancedSettings,
|
||||
} from "@logics_configs";
|
||||
|
||||
import {
|
||||
@@ -37,8 +35,8 @@ export const AdvancedSettings = () => {
|
||||
};
|
||||
|
||||
const OscIpAddressContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentOscIpAddress, setOscIpAddress } = useOscIpAddress();
|
||||
const { t } = useI18n();
|
||||
const { currentOscIpAddress, setOscIpAddress } = useAdvancedSettings();
|
||||
const [input_value, setInputValue] = useState(currentOscIpAddress.data);
|
||||
|
||||
const onChangeFunction = (value) => {
|
||||
@@ -50,6 +48,7 @@ const OscIpAddressContainer = () => {
|
||||
};
|
||||
|
||||
useEffect(()=> {
|
||||
if (currentOscIpAddress.state === "pending") return;
|
||||
setInputValue(currentOscIpAddress.data);
|
||||
}, [currentOscIpAddress]);
|
||||
|
||||
@@ -66,8 +65,8 @@ const OscIpAddressContainer = () => {
|
||||
};
|
||||
|
||||
const OscPortContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentOscPort, setOscPort } = useOscPort();
|
||||
const { t } = useI18n();
|
||||
const { currentOscPort, setOscPort } = useAdvancedSettings();
|
||||
const [input_value, setInputValue] = useState(currentOscPort.data);
|
||||
|
||||
const onChangeFunction = (value) => {
|
||||
@@ -80,6 +79,7 @@ const OscPortContainer = () => {
|
||||
};
|
||||
|
||||
useEffect(()=> {
|
||||
if (currentOscPort.state === "pending") return;
|
||||
setInputValue(currentOscPort.data);
|
||||
}, [currentOscPort]);
|
||||
|
||||
@@ -96,7 +96,7 @@ const OscPortContainer = () => {
|
||||
};
|
||||
|
||||
const OpenConfigFolderContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { openFolder_ConfigFile } = useOpenFolder();
|
||||
|
||||
return (
|
||||
@@ -113,7 +113,7 @@ const OpenConfigFolderContainer = () => {
|
||||
// Duplicate
|
||||
import { useStore_OpenedQuickSetting } from "@store";
|
||||
const OpenSwitchComputeDeviceModalContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||
const onClickFunction = () => {
|
||||
updateOpenedQuickSetting("update_software");
|
||||
@@ -143,8 +143,8 @@ const WebsocketContainer = () => {
|
||||
};
|
||||
|
||||
const EnableWebsocketContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableWebsocket, toggleEnableWebsocket } = useWebsocket();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableWebsocket, toggleEnableWebsocket } = useAdvancedSettings();
|
||||
|
||||
return (
|
||||
<CheckboxContainer
|
||||
@@ -156,8 +156,8 @@ const EnableWebsocketContainer = () => {
|
||||
};
|
||||
|
||||
const WebsocketHostContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentWebsocketHost, setWebsocketHost } = useWebsocket();
|
||||
const { t } = useI18n();
|
||||
const { currentWebsocketHost, setWebsocketHost } = useAdvancedSettings();
|
||||
const [input_value, setInputValue] = useState(currentWebsocketHost.data);
|
||||
|
||||
const onChangeFunction = (value) => {
|
||||
@@ -169,6 +169,7 @@ const WebsocketHostContainer = () => {
|
||||
};
|
||||
|
||||
useEffect(()=> {
|
||||
if (currentWebsocketHost.state === "pending") return;
|
||||
setInputValue(currentWebsocketHost.data);
|
||||
}, [currentWebsocketHost]);
|
||||
|
||||
@@ -185,8 +186,8 @@ const WebsocketHostContainer = () => {
|
||||
};
|
||||
|
||||
const WebsocketPortContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentWebsocketPort, setWebsocketPort } = useWebsocket();
|
||||
const { t } = useI18n();
|
||||
const { currentWebsocketPort, setWebsocketPort } = useAdvancedSettings();
|
||||
const [input_value, setInputValue] = useState(currentWebsocketPort.data);
|
||||
|
||||
const onChangeFunction = (value) => {
|
||||
@@ -199,6 +200,7 @@ const WebsocketPortContainer = () => {
|
||||
};
|
||||
|
||||
useEffect(()=> {
|
||||
if (currentWebsocketPort.state === "pending") return;
|
||||
setInputValue(currentWebsocketPort.data);
|
||||
}, [currentWebsocketPort]);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./Appearance.module.scss";
|
||||
import { ui_configs } from "@ui_configs";
|
||||
import { useStore_SelectableFontFamilyList } from "@store";
|
||||
@@ -10,18 +10,14 @@ import {
|
||||
} from "@logics_common";
|
||||
|
||||
import {
|
||||
useUiLanguage,
|
||||
useUiScaling,
|
||||
useMessageLogUiScaling,
|
||||
useSendMessageButtonType,
|
||||
useSelectedFontFamily,
|
||||
useTransparency,
|
||||
useAppearance,
|
||||
} from "@logics_configs";
|
||||
|
||||
import {
|
||||
SliderContainer,
|
||||
DropdownMenuContainer,
|
||||
RadioButtonContainer,
|
||||
CheckboxContainer,
|
||||
} from "../_templates/Templates";
|
||||
|
||||
export const Appearance = () => {
|
||||
@@ -31,6 +27,7 @@ export const Appearance = () => {
|
||||
<UiScalingContainer />
|
||||
<MessageLogUiScalingContainer />
|
||||
<SendMessageButtonTypeContainer />
|
||||
<ShowResendButtonContainer />
|
||||
<FontFamilyContainer />
|
||||
<TransparencyContainer />
|
||||
</>
|
||||
@@ -38,8 +35,8 @@ export const Appearance = () => {
|
||||
};
|
||||
|
||||
const UiLanguageContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentUiLanguage, setUiLanguage } = useUiLanguage();
|
||||
const { t } = useI18n();
|
||||
const { currentUiLanguage, setUiLanguage } = useAppearance();
|
||||
|
||||
const is_not_en_lang = currentUiLanguage.data !== "en" && currentUiLanguage.data !== undefined;
|
||||
return (
|
||||
@@ -55,8 +52,8 @@ const UiLanguageContainer = () => {
|
||||
};
|
||||
|
||||
const UiScalingContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentUiScaling, setUiScaling } = useUiScaling();
|
||||
const { t } = useI18n();
|
||||
const { currentUiScaling, setUiScaling } = useAppearance();
|
||||
const { asyncUpdateBreakPoint } = useWindow();
|
||||
|
||||
const [ui_ui_scaling, setUiUiScaling] = useState(currentUiScaling.data);
|
||||
@@ -100,8 +97,8 @@ const UiScalingContainer = () => {
|
||||
|
||||
|
||||
export const MessageLogUiScalingContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentMessageLogUiScaling, setMessageLogUiScaling } = useMessageLogUiScaling();
|
||||
const { t } = useI18n();
|
||||
const { currentMessageLogUiScaling, setMessageLogUiScaling } = useAppearance();
|
||||
const [ui_message_log_ui_scaling, setUiMessageLogUiScaling] = useState(currentMessageLogUiScaling.data);
|
||||
|
||||
const onchangeFunction = (value) => {
|
||||
@@ -141,8 +138,8 @@ export const MessageLogUiScalingContainer = () => {
|
||||
};
|
||||
|
||||
const SendMessageButtonTypeContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSendMessageButtonType, setSendMessageButtonType } = useSendMessageButtonType();
|
||||
const { t } = useI18n();
|
||||
const { currentSendMessageButtonType, setSendMessageButtonType } = useAppearance();
|
||||
|
||||
return (
|
||||
<RadioButtonContainer
|
||||
@@ -160,9 +157,23 @@ const SendMessageButtonTypeContainer = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const ShowResendButtonContainer = () => {
|
||||
const { t } = useI18n();
|
||||
const { currentShowResendButton, toggleShowResendButton } = useAppearance();
|
||||
|
||||
return (
|
||||
<CheckboxContainer
|
||||
label={t("config_page.appearance.show_resend_button.label")}
|
||||
desc={t("config_page.appearance.show_resend_button.desc")}
|
||||
variable={currentShowResendButton}
|
||||
toggleFunction={toggleShowResendButton}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const FontFamilyContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSelectedFontFamily, setSelectedFontFamily } = useSelectedFontFamily();
|
||||
const { t } = useI18n();
|
||||
const { currentSelectedFontFamily, setSelectedFontFamily } = useAppearance();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setSelectedFontFamily(selected_data.selected_id);
|
||||
@@ -182,8 +193,8 @@ const FontFamilyContainer = () => {
|
||||
};
|
||||
|
||||
const TransparencyContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentTransparency, setTransparency } = useTransparency();
|
||||
const { t } = useI18n();
|
||||
const { currentTransparency, setTransparency } = useAppearance();
|
||||
const [ui_message_log_ui_scaling, setUiTransparency] = useState(currentTransparency.data);
|
||||
|
||||
const onchangeFunction = (value) => {
|
||||
|
||||
@@ -1,19 +1,10 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./Device.module.scss";
|
||||
import clsx from "clsx";
|
||||
import { useStore_IsBreakPoint } from "@store";
|
||||
import { ui_configs } from "@ui_configs";
|
||||
import {
|
||||
useEnableAutoMicSelect,
|
||||
useMicHostList,
|
||||
useSelectedMicHost,
|
||||
useMicDeviceList,
|
||||
useSelectedMicDevice,
|
||||
useMicThreshold,
|
||||
useEnableAutoSpeakerSelect,
|
||||
useSpeakerDeviceList,
|
||||
useSelectedSpeakerDevice,
|
||||
useSpeakerThreshold,
|
||||
useDevice,
|
||||
} from "@logics_configs";
|
||||
|
||||
import {
|
||||
@@ -37,14 +28,22 @@ export const Device = () => {
|
||||
};
|
||||
|
||||
const Mic_Container = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableAutoMicSelect, toggleEnableAutoMicSelect } = useEnableAutoMicSelect();
|
||||
const { currentSelectedMicHost, setSelectedMicHost } = useSelectedMicHost();
|
||||
const { currentMicHostList } = useMicHostList();
|
||||
const { currentSelectedMicDevice, setSelectedMicDevice } = useSelectedMicDevice();
|
||||
const { currentMicDeviceList } = useMicDeviceList();
|
||||
const { t } = useI18n();
|
||||
const {
|
||||
currentEnableAutoMicSelect,
|
||||
toggleEnableAutoMicSelect,
|
||||
currentMicDeviceList,
|
||||
currentMicHostList,
|
||||
|
||||
currentSelectedMicHost,
|
||||
setSelectedMicHost,
|
||||
currentSelectedMicDevice,
|
||||
setSelectedMicDevice,
|
||||
|
||||
currentEnableAutomaticMicThreshold,
|
||||
toggleEnableAutomaticMicThreshold,
|
||||
} = useDevice();
|
||||
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
|
||||
const { currentEnableAutomaticMicThreshold, toggleEnableAutomaticMicThreshold } = useMicThreshold();
|
||||
|
||||
const selectFunction_host = (selected_data) => {
|
||||
setSelectedMicHost(selected_data.selected_id);
|
||||
@@ -138,12 +137,17 @@ const Mic_Container = () => {
|
||||
};
|
||||
|
||||
const Speaker_Container = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableAutoSpeakerSelect, toggleEnableAutoSpeakerSelect } = useEnableAutoSpeakerSelect();
|
||||
const { currentSelectedSpeakerDevice, setSelectedSpeakerDevice } = useSelectedSpeakerDevice();
|
||||
const { currentSpeakerDeviceList } = useSpeakerDeviceList();
|
||||
const { t } = useI18n();
|
||||
const {
|
||||
currentEnableAutoSpeakerSelect,
|
||||
toggleEnableAutoSpeakerSelect,
|
||||
currentSpeakerDeviceList,
|
||||
currentSelectedSpeakerDevice,
|
||||
setSelectedSpeakerDevice,
|
||||
currentEnableAutomaticSpeakerThreshold,
|
||||
toggleEnableAutomaticSpeakerThreshold,
|
||||
} = useDevice();
|
||||
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
|
||||
const { currentEnableAutomaticSpeakerThreshold, toggleEnableAutomaticSpeakerThreshold } = useSpeakerThreshold();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setSelectedSpeakerDevice(selected_data.selected_id);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useHotkeys } from "@logics_configs";
|
||||
import styles from "./Hotkeys.module.scss";
|
||||
import { HotkeysEntryContainer } from "../_templates/Templates";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
export const Hotkeys = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@@ -11,7 +11,7 @@ export const Hotkeys = () => {
|
||||
};
|
||||
|
||||
const HotkeysBoxContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentHotkeys, setHotkeys } = useHotkeys();
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./Others.module.scss";
|
||||
|
||||
import { useOpenFolder } from "@logics_common";
|
||||
import {
|
||||
useEnableAutoClearMessageInputBox,
|
||||
useEnableSendOnlyTranslatedMessages,
|
||||
useEnableAutoExportMessageLogs,
|
||||
useEnableVrcMicMuteSync,
|
||||
useEnableSendMessageToVrc,
|
||||
useEnableSendReceivedMessageToVrc,
|
||||
useEnableNotificationVrcSfx,
|
||||
useOthers,
|
||||
} from "@logics_configs";
|
||||
|
||||
import {
|
||||
@@ -26,7 +20,7 @@ import { Checkbox } from "@common_components";
|
||||
import OpenFolderSvg from "@images/open_folder.svg?react";
|
||||
|
||||
export const Others = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@@ -50,8 +44,8 @@ export const Others = () => {
|
||||
};
|
||||
|
||||
const AutoClearMessageInputBoxContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableAutoClearMessageInputBox, toggleEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableAutoClearMessageInputBox, toggleEnableAutoClearMessageInputBox } = useOthers();
|
||||
|
||||
return (
|
||||
<CheckboxContainer
|
||||
@@ -62,8 +56,8 @@ const AutoClearMessageInputBoxContainer = () => {
|
||||
);
|
||||
};
|
||||
const SendOnlyTranslatedMessagesContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableSendOnlyTranslatedMessages, toggleEnableSendOnlyTranslatedMessages } = useEnableSendOnlyTranslatedMessages();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableSendOnlyTranslatedMessages, toggleEnableSendOnlyTranslatedMessages } = useOthers();
|
||||
|
||||
return (
|
||||
<CheckboxContainer
|
||||
@@ -74,8 +68,8 @@ const SendOnlyTranslatedMessagesContainer = () => {
|
||||
);
|
||||
};
|
||||
const AutoExportMessageLogsContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableAutoExportMessageLogs, toggleEnableAutoExportMessageLogs } = useEnableAutoExportMessageLogs();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableAutoExportMessageLogs, toggleEnableAutoExportMessageLogs } = useOthers();
|
||||
const { openFolder_MessageLogs } = useOpenFolder();
|
||||
|
||||
return (
|
||||
@@ -98,8 +92,8 @@ const AutoExportMessageLogsContainer = () => {
|
||||
);
|
||||
};
|
||||
export const VrcMicMuteSyncContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableVrcMicMuteSync, toggleEnableVrcMicMuteSync } = useEnableVrcMicMuteSync();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableVrcMicMuteSync, toggleEnableVrcMicMuteSync } = useOthers();
|
||||
|
||||
const variable = {
|
||||
state: currentEnableVrcMicMuteSync.state,
|
||||
@@ -117,8 +111,8 @@ export const VrcMicMuteSyncContainer = () => {
|
||||
);
|
||||
};
|
||||
const SendMessageToVrcContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableSendMessageToVrc, toggleEnableSendMessageToVrc } = useEnableSendMessageToVrc();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableSendMessageToVrc, toggleEnableSendMessageToVrc } = useOthers();
|
||||
|
||||
return (
|
||||
<CheckboxContainer
|
||||
@@ -132,8 +126,8 @@ const SendMessageToVrcContainer = () => {
|
||||
|
||||
|
||||
const EnableNotificationVrcSfxContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableNotificationVrcSfx, toggleEnableNotificationVrcSfx } = useEnableNotificationVrcSfx();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableNotificationVrcSfx, toggleEnableNotificationVrcSfx } = useOthers();
|
||||
|
||||
return (
|
||||
<CheckboxContainer
|
||||
@@ -146,8 +140,8 @@ const EnableNotificationVrcSfxContainer = () => {
|
||||
};
|
||||
|
||||
const SendReceivedMessageToVrcContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentEnableSendReceivedMessageToVrc, toggleEnableSendReceivedMessageToVrc } = useEnableSendReceivedMessageToVrc();
|
||||
const { t } = useI18n();
|
||||
const { currentEnableSendReceivedMessageToVrc, toggleEnableSendReceivedMessageToVrc } = useOthers();
|
||||
|
||||
return (
|
||||
<CheckboxContainer
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useEffect, useRef, useState, useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { usePlugins } from "@logics_configs";
|
||||
import styles from "./Plugins.module.scss";
|
||||
import { PluginsControlComponent } from "../_components/plugins_control_component/PluginsControlComponent";
|
||||
import { PluginsControlComponent } from "./plugins_control_component/PluginsControlComponent";
|
||||
import { useNotificationStatus } from "@logics_common";
|
||||
import ExternalLink from "@images/external_link.svg?react";
|
||||
|
||||
@@ -27,7 +27,7 @@ export const Plugins = () => {
|
||||
};
|
||||
|
||||
const PluginDownloadContainer = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { t, i18n } = useI18n();
|
||||
const {
|
||||
downloadAndExtractPlugin,
|
||||
currentPluginsData,
|
||||
@@ -105,7 +105,12 @@ const PluginDownloadContainer = () => {
|
||||
</div>
|
||||
<div className={styles.plugin_info_wrapper}>
|
||||
{plugin.is_error ? (
|
||||
<p style={{ color: "red" }}>Error: {plugin.error_message}</p>
|
||||
<div>
|
||||
<p style={{ color: "red" }}>{t(`plugin_notifications.${plugin.error_message_type}`)}</p>
|
||||
<p style={{ color: "red" }}>plugin_version: {plugin.downloaded_plugin_info.plugin_version}</p>
|
||||
<p style={{ color: "red" }}>min_supported_vrct_version: {plugin.downloaded_plugin_info.min_supported_vrct_version}</p>
|
||||
<p style={{ color: "red" }}>max_supported_vrct_version: {plugin.downloaded_plugin_info.max_supported_vrct_version}</p>
|
||||
</div>
|
||||
) : (
|
||||
<PluginsControlComponent
|
||||
variable_state={variable_state}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
max-width: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.plugin_info_wrapper {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React from "react";
|
||||
import { SwitchBox } from "../index";
|
||||
import { _DownloadButton } from "../_atoms/_download_button/_DownloadButton";
|
||||
import { SwitchBox } from "../../_components";
|
||||
import { _DownloadButton } from "../../_components/_atoms/_download_button/_DownloadButton";
|
||||
import styles from "./PluginsControlComponent.module.scss";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
export const PluginsControlComponent = ({
|
||||
variable_state,
|
||||
@@ -10,7 +9,7 @@ export const PluginsControlComponent = ({
|
||||
toggleFunction,
|
||||
downloadStartFunction,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const option = {
|
||||
id: plugin_status.plugin_id,
|
||||
@@ -65,7 +64,7 @@ const DownloadedPluginControl = ({
|
||||
downloaded_version_label,
|
||||
latest_version_label,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const togglePlugin = () => {
|
||||
toggleFunction(plugin_status.plugin_id);
|
||||
@@ -129,7 +128,7 @@ const NotDownloadedPluginControl = ({
|
||||
downloaded_version_label,
|
||||
latest_version_label,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
if (plugin_status.is_latest_version_available) {
|
||||
return (
|
||||
@@ -86,7 +86,7 @@ $progress_ease: cubic-bezier(0, 1, 0.75, 1);
|
||||
}
|
||||
|
||||
.line_fuwa {
|
||||
background-color: #5788a2;
|
||||
background-color: var(--supporters_color_fuwa);
|
||||
animation: expandWidth 1s $progress_ease 0.6s forwards;
|
||||
}
|
||||
|
||||
@@ -150,8 +150,8 @@ $progress_ease: cubic-bezier(0, 1, 0.75, 1);
|
||||
box-shadow: 0 0 0.4rem 0 var(--dark_800_color);
|
||||
}
|
||||
.spiral_top::after {
|
||||
background: #5788a2;
|
||||
box-shadow: 0 0 0.4rem 0 #5788a2;
|
||||
background: var(--supporters_color_fuwa);
|
||||
box-shadow: 0 0 0.4rem 0 var(--supporters_color_fuwa);
|
||||
}
|
||||
.spiral_bottom::before {
|
||||
background: var(--received_300_color);
|
||||
|
||||
@@ -62,7 +62,7 @@ $progress_ease: cubic-bezier(0, 1, 0.75, 1);
|
||||
height: 4rem;
|
||||
aspect-ratio: 1 /1;
|
||||
border-radius: 50%;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--dark_basic_text_color);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
transition: transform 0.6s $progress_ease;
|
||||
@@ -236,7 +236,7 @@ $progress_ease: cubic-bezier(0, 1, 0.75, 1);
|
||||
background-color: var(--received_300_color);
|
||||
}
|
||||
&.fuwa_bar {
|
||||
background-color: #5788a2;
|
||||
background-color: var(--supporters_color_fuwa);
|
||||
}
|
||||
&.basic_bar {
|
||||
background-color: var(--dark_800_color);
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./Transcription.module.scss";
|
||||
import { updateLabelsById, genNumObjArray } from "@utils";
|
||||
|
||||
import {
|
||||
useMicRecordTimeout,
|
||||
useMicPhraseTimeout,
|
||||
useMicMaxWords,
|
||||
|
||||
useSpeakerRecordTimeout,
|
||||
useSpeakerPhraseTimeout,
|
||||
useSpeakerMaxWords,
|
||||
|
||||
useSelectedTranscriptionEngine,
|
||||
useWhisperWeightTypeStatus,
|
||||
useSelectedWhisperWeightType,
|
||||
|
||||
useSelectedWhisperComputeDevice,
|
||||
useSelectableWhisperComputeDeviceList,
|
||||
useTranscription,
|
||||
} from "@logics_configs";
|
||||
|
||||
import {
|
||||
@@ -43,7 +30,7 @@ export const Transcription = () => {
|
||||
|
||||
|
||||
const Mic_Container = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div>
|
||||
<SectionLabelComponent label={t("config_page.transcription.section_label_mic")} />
|
||||
@@ -56,8 +43,8 @@ const Mic_Container = () => {
|
||||
};
|
||||
|
||||
const MicRecordTimeout_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentMicRecordTimeout, setMicRecordTimeout } = useMicRecordTimeout();
|
||||
const { t } = useI18n();
|
||||
const { currentMicRecordTimeout, setMicRecordTimeout } = useTranscription();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setMicRecordTimeout(selected_data.selected_id);
|
||||
@@ -76,8 +63,8 @@ const MicRecordTimeout_Box = () => {
|
||||
);
|
||||
};
|
||||
const MicPhraseTimeout_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentMicPhraseTimeout, setMicPhraseTimeout } = useMicPhraseTimeout();
|
||||
const { t } = useI18n();
|
||||
const { currentMicPhraseTimeout, setMicPhraseTimeout } = useTranscription();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setMicPhraseTimeout(selected_data.selected_id);
|
||||
@@ -96,8 +83,8 @@ const MicPhraseTimeout_Box = () => {
|
||||
);
|
||||
};
|
||||
const MicMaxWords_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentMicMaxWords, setMicMaxWords } = useMicMaxWords();
|
||||
const { t } = useI18n();
|
||||
const { currentMicMaxWords, setMicMaxWords } = useTranscription();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setMicMaxWords(selected_data.selected_id);
|
||||
@@ -117,7 +104,7 @@ const MicMaxWords_Box = () => {
|
||||
};
|
||||
|
||||
const MicWordFilter_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
return (
|
||||
<WordFilterContainer
|
||||
@@ -131,7 +118,7 @@ const MicWordFilter_Box = () => {
|
||||
|
||||
|
||||
const Speaker_Container = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div>
|
||||
<SectionLabelComponent label={t("config_page.transcription.section_label_speaker")} />
|
||||
@@ -143,8 +130,8 @@ const Speaker_Container = () => {
|
||||
};
|
||||
|
||||
const SpeakerRecordTimeout_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSpeakerRecordTimeout, setSpeakerRecordTimeout } = useSpeakerRecordTimeout();
|
||||
const { t } = useI18n();
|
||||
const { currentSpeakerRecordTimeout, setSpeakerRecordTimeout } = useTranscription();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setSpeakerRecordTimeout(selected_data.selected_id);
|
||||
@@ -163,8 +150,8 @@ const SpeakerRecordTimeout_Box = () => {
|
||||
);
|
||||
};
|
||||
const SpeakerPhraseTimeout_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSpeakerPhraseTimeout, setSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
|
||||
const { t } = useI18n();
|
||||
const { currentSpeakerPhraseTimeout, setSpeakerPhraseTimeout } = useTranscription();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setSpeakerPhraseTimeout(selected_data.selected_id);
|
||||
@@ -182,8 +169,8 @@ const SpeakerPhraseTimeout_Box = () => {
|
||||
);
|
||||
};
|
||||
const SpeakerMaxWords_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSpeakerMaxWords, setSpeakerMaxWords } = useSpeakerMaxWords();
|
||||
const { t } = useI18n();
|
||||
const { currentSpeakerMaxWords, setSpeakerMaxWords } = useTranscription();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
setSpeakerMaxWords(selected_data.selected_id);
|
||||
@@ -205,7 +192,7 @@ const SpeakerMaxWords_Box = () => {
|
||||
|
||||
|
||||
const TranscriptionEngine_Container = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div>
|
||||
<SectionLabelComponent label={t("config_page.transcription.section_label_transcription_engines")} />
|
||||
@@ -217,8 +204,8 @@ const TranscriptionEngine_Container = () => {
|
||||
};
|
||||
|
||||
const TranscriptionEngine_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSelectedTranscriptionEngine, setSelectedTranscriptionEngine } = useSelectedTranscriptionEngine();
|
||||
const { t } = useI18n();
|
||||
const { currentSelectedTranscriptionEngine, setSelectedTranscriptionEngine } = useTranscription();
|
||||
|
||||
return (
|
||||
<RadioButtonContainer
|
||||
@@ -235,13 +222,13 @@ const TranscriptionEngine_Box = () => {
|
||||
};
|
||||
|
||||
const WhisperWeightType_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const {
|
||||
currentWhisperWeightTypeStatus,
|
||||
pendingWhisperWeightType,
|
||||
downloadWhisperWeight,
|
||||
} = useWhisperWeightTypeStatus();
|
||||
const { currentSelectedWhisperWeightType, setSelectedWhisperWeightType } = useSelectedWhisperWeightType();
|
||||
} = useTranscription();
|
||||
const { currentSelectedWhisperWeightType, setSelectedWhisperWeightType } = useTranscription();
|
||||
|
||||
const selectFunction = (id) => {
|
||||
setSelectedWhisperWeightType(id);
|
||||
@@ -288,9 +275,9 @@ const WhisperWeightType_Box = () => {
|
||||
// Duplicate
|
||||
import { useComputeMode } from "@logics_common";
|
||||
const WhisperComputeDevice_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSelectedWhisperComputeDevice, setSelectedWhisperComputeDevice } = useSelectedWhisperComputeDevice();
|
||||
const { currentSelectableWhisperComputeDeviceList } = useSelectableWhisperComputeDeviceList();
|
||||
const { t } = useI18n();
|
||||
const { currentSelectedWhisperComputeDevice, setSelectedWhisperComputeDevice } = useTranscription();
|
||||
const { currentSelectableWhisperComputeDeviceList } = useTranscription();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
const target_obj = currentSelectableWhisperComputeDeviceList.data[selected_data.selected_id];
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./Translation.module.scss";
|
||||
import { updateLabelsById } from "@utils";
|
||||
|
||||
import {
|
||||
useDeepLAuthKey,
|
||||
useCTranslate2WeightTypeStatus,
|
||||
useSelectedCTranslate2WeightType,
|
||||
useSelectedCTranslate2ComputeDevice,
|
||||
useSelectableCTranslate2ComputeDeviceList,
|
||||
useTranslation,
|
||||
} from "@logics_configs";
|
||||
|
||||
import {
|
||||
@@ -29,13 +25,15 @@ export const Translation = () => {
|
||||
};
|
||||
|
||||
const CTranslate2WeightType_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const {
|
||||
currentCTranslate2WeightTypeStatus,
|
||||
pendingCTranslate2WeightType,
|
||||
downloadCTranslate2Weight,
|
||||
} = useCTranslate2WeightTypeStatus();
|
||||
const { currentSelectedCTranslate2WeightType, setSelectedCTranslate2WeightType } = useSelectedCTranslate2WeightType();
|
||||
|
||||
currentSelectedCTranslate2WeightType,
|
||||
setSelectedCTranslate2WeightType,
|
||||
} = useTranslation();
|
||||
|
||||
const selectFunction = (id) => {
|
||||
setSelectedCTranslate2WeightType(id);
|
||||
@@ -77,9 +75,9 @@ const CTranslate2WeightType_Box = () => {
|
||||
// Duplicate
|
||||
import { useComputeMode } from "@logics_common";
|
||||
const CTranslation2ComputeDevice_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSelectedCTranslate2ComputeDevice, setSelectedCTranslate2ComputeDevice } = useSelectedCTranslate2ComputeDevice();
|
||||
const { currentSelectableCTranslate2ComputeDeviceList } = useSelectableCTranslate2ComputeDeviceList();
|
||||
const { t } = useI18n();
|
||||
const { currentSelectedCTranslate2ComputeDevice, setSelectedCTranslate2ComputeDevice } = useTranslation();
|
||||
const { currentSelectableCTranslate2ComputeDeviceList } = useTranslation();
|
||||
|
||||
const selectFunction = (selected_data) => {
|
||||
const target_obj = currentSelectableCTranslate2ComputeDeviceList.data[selected_data.selected_id];
|
||||
@@ -120,8 +118,8 @@ const CTranslation2ComputeDevice_Box = () => {
|
||||
};
|
||||
|
||||
const DeeplAuthKey_Box = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentDeepLAuthKey, setDeepLAuthKey, deleteDeepLAuthKey } = useDeepLAuthKey();
|
||||
const { t } = useI18n();
|
||||
const { currentDeepLAuthKey, setDeepLAuthKey, deleteDeepLAuthKey } = useTranslation();
|
||||
const [input_value, seInputValue] = useState(currentDeepLAuthKey.data);
|
||||
|
||||
const onChangeFunction = (value) => {
|
||||
@@ -134,6 +132,7 @@ const DeeplAuthKey_Box = () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (currentDeepLAuthKey.state === "pending") return;
|
||||
seInputValue(currentDeepLAuthKey.data);
|
||||
}, [currentDeepLAuthKey]);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
import styles from "./Vr.module.scss";
|
||||
import { ui_configs } from "@ui_configs";
|
||||
@@ -15,12 +15,7 @@ import {
|
||||
} from "../_components/";
|
||||
|
||||
import {
|
||||
useIsEnabledOverlaySmallLog,
|
||||
useOverlaySmallLogSettings,
|
||||
useIsEnabledOverlayLargeLog,
|
||||
useOverlayLargeLogSettings,
|
||||
useOverlayShowOnlyTranslatedMessages,
|
||||
useSendTextToOverlay,
|
||||
useVr,
|
||||
} from "@logics_configs";
|
||||
|
||||
import RedoSvg from "@images/redo.svg?react";
|
||||
@@ -30,17 +25,23 @@ import TriangleSvg from "@images/triangle.svg?react";
|
||||
import { randomIntMinMax } from "@utils";
|
||||
|
||||
export const Vr = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const [is_opened_small_settings, setIsOpenedSmallSettings] = useState(true);
|
||||
const toggleIsOpenedSmallSettings = () => {
|
||||
setIsOpenedSmallSettings(!is_opened_small_settings);
|
||||
};
|
||||
|
||||
const { currentOverlaySmallLogSettings, setOverlaySmallLogSettings } = useOverlaySmallLogSettings();
|
||||
const { currentIsEnabledOverlaySmallLog, toggleIsEnabledOverlaySmallLog } = useIsEnabledOverlaySmallLog();
|
||||
const {
|
||||
currentIsEnabledOverlayLargeLog,
|
||||
toggleIsEnabledOverlayLargeLog,
|
||||
currentIsEnabledOverlaySmallLog,
|
||||
toggleIsEnabledOverlaySmallLog,
|
||||
currentOverlayLargeLogSettings,
|
||||
setOverlayLargeLogSettings,
|
||||
currentOverlaySmallLogSettings,
|
||||
setOverlaySmallLogSettings,
|
||||
} = useVr();
|
||||
|
||||
const { currentOverlayLargeLogSettings, setOverlayLargeLogSettings } = useOverlayLargeLogSettings();
|
||||
const { currentIsEnabledOverlayLargeLog, toggleIsEnabledOverlayLargeLog } = useIsEnabledOverlayLargeLog();
|
||||
|
||||
const restoreDefaultSettings = () => {
|
||||
setOverlaySmallLogSettings(ui_configs.overlay_small_log_default_settings);
|
||||
@@ -99,7 +100,7 @@ const OverlaySettingsContainer = ({
|
||||
id
|
||||
}) => {
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
useEffect(() => {
|
||||
setSettings(current_overlay_settings);
|
||||
}, [current_overlay_settings]);
|
||||
@@ -193,7 +194,7 @@ const PageSwitcherContainer = (props) => {
|
||||
|
||||
|
||||
export const PositionControls = ({ settings, onchangeFunction, selectFunction, ui_configs, default_ui_configs }) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const {
|
||||
variable_display: x_variable_display,
|
||||
@@ -302,7 +303,7 @@ export const PositionControls = ({ settings, onchangeFunction, selectFunction, u
|
||||
};
|
||||
|
||||
export const RotationControls = ({ settings, onchangeFunction, selectFunction, ui_configs, default_ui_configs }) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const {
|
||||
variable_display: x_variable_display,
|
||||
@@ -443,7 +444,7 @@ const AdjustButtonContainer = ({ wrapper_class_name, is_max, is_min, countUp, co
|
||||
|
||||
|
||||
const OtherControls = ({settings, onchangeFunction, ui_configs}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const ui_variable_opacity = (settings.opacity * 100).toFixed(0);
|
||||
const ui_variable_ui_scaling = (settings.ui_scaling * 100).toFixed(0);
|
||||
@@ -512,8 +513,8 @@ const OtherControls = ({settings, onchangeFunction, ui_configs}) => {
|
||||
|
||||
|
||||
const CommonSettingsContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentOverlayShowOnlyTranslatedMessages, toggleOverlayShowOnlyTranslatedMessages } = useOverlayShowOnlyTranslatedMessages();
|
||||
const { t } = useI18n();
|
||||
const { currentOverlayShowOnlyTranslatedMessages, toggleOverlayShowOnlyTranslatedMessages } = useVr();
|
||||
|
||||
return (
|
||||
<div className={styles.common_container}>
|
||||
@@ -536,8 +537,8 @@ const ResetButton = ({onClickFunction}) => {
|
||||
};
|
||||
|
||||
const SendSampleTextToggleButton = () => {
|
||||
const { t } = useTranslation();
|
||||
const { sendTextToOverlay } = useSendTextToOverlay();
|
||||
const { t } = useI18n();
|
||||
const { sendTextToOverlay } = useVr();
|
||||
const [is_started, setIsStarted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -26,11 +26,11 @@ export const SidebarSection = () => {
|
||||
|
||||
|
||||
import clsx from "clsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { useStore_SelectedConfigTabId } from "@store";
|
||||
|
||||
const Tab = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateSelectedConfigTabId, currentSelectedConfigTabId } = useStore_SelectedConfigTabId();
|
||||
const onclickFunction = () => {
|
||||
updateSelectedConfigTabId(props.tab_id);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
|
||||
import styles from "./Topbar.module.scss";
|
||||
@@ -10,7 +10,7 @@ import { SectionTitleBox } from "./section_title_box/SectionTitleBox";
|
||||
import { CompactSwitchBox } from "./compact_switch_box/CompactSwitchBox";
|
||||
|
||||
export const Topbar = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentIsOpenedConfigPage, setIsOpenedConfigPage } = useIsOpenedConfigPage();
|
||||
const closeConfigPage = () => {
|
||||
setIsOpenedConfigPage(false);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
import styles from "./CompactSwitchBox.module.scss";
|
||||
|
||||
export const CompactSwitchBox = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<p>{t("config_page.compact_mode")}</p>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./SectionTitleBox.module.scss";
|
||||
import { useStore_SelectedConfigTabId } from "@store";
|
||||
|
||||
export const SectionTitleBox = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentSelectedConfigTabId } = useStore_SelectedConfigTabId();
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
import styles from "./TitleBox.module.scss";
|
||||
import chato_img from "@images/chato_white.png";
|
||||
|
||||
export const TitleBox = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<img src={chato_img} className={styles.logo_chato} alt="VRCT logo chato" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import styles from "./VersionLabel.module.scss";
|
||||
@@ -10,7 +10,7 @@ import CheckMarkSvg from "@images/check_mark.svg?react";
|
||||
export const VersionLabel = () => {
|
||||
const [is_copied, setIsCopied] = useState(false);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentSoftwareVersion } = useSoftwareVersion();
|
||||
const { currentComputeMode } = useComputeMode();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./MainSection.module.scss";
|
||||
|
||||
import { TopBar } from "./top_bar/TopBar";
|
||||
@@ -37,7 +37,7 @@ export const MainSection = () => {
|
||||
|
||||
|
||||
const HandleLanguageSelector = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentIsOpenedLanguageSelector, updateIsOpenedLanguageSelector } = useStore_IsOpenedLanguageSelector();
|
||||
const {
|
||||
currentSelectedPresetTabNumber,
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
import React from "react";
|
||||
import { usePlugins } from "@logics_configs";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
|
||||
export const PluginHost = ({render_components}) => {
|
||||
export const PluginHost = ({ render_components }) => {
|
||||
const { setErrorPlugin } = usePlugins();
|
||||
|
||||
return (
|
||||
<>
|
||||
{render_components
|
||||
.map((plugin, index) => {
|
||||
const PluginComponent = plugin.component;
|
||||
return PluginComponent ? <PluginComponent key={index} /> : null;
|
||||
})}
|
||||
{render_components.map((plugin, index) => {
|
||||
const PluginComponent = plugin.component;
|
||||
const plugin_id = plugin.plugin_id;
|
||||
|
||||
return PluginComponent ? (
|
||||
<ErrorBoundary
|
||||
key={plugin_id || index}
|
||||
fallbackRender={() => null}
|
||||
onError={(_error, _info) => {
|
||||
// Disable the plugin on error
|
||||
setErrorPlugin(plugin_id, "disabled_due_to_an_error");
|
||||
}}
|
||||
>
|
||||
<PluginComponent />
|
||||
</ErrorBoundary>
|
||||
) : null;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
import { useSelectableLanguageList } from "@logics_main";
|
||||
import { useLanguageSettings } from "@logics_main";
|
||||
import styles from "./LanguageSelector.module.scss";
|
||||
|
||||
import { LanguageSelectorTopBar } from "./language_selector_top_bar/LanguageSelectorTopBar";
|
||||
export const LanguageSelector = ({ title, onClickFunction }) => {
|
||||
const { t } = useTranslation();
|
||||
const { currentSelectableLanguageList } = useSelectableLanguageList();
|
||||
const { t } = useI18n();
|
||||
const { currentSelectableLanguageList } = useLanguageSettings();
|
||||
|
||||
const groupLanguagesByFirstLetter = (languages) => {
|
||||
return languages.reduce((acc, { language, country }) => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./LanguageSelectorTopBar.module.scss";
|
||||
import { useStore_IsOpenedLanguageSelector } from "@store";
|
||||
|
||||
export const LanguageSelectorTopBar = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateIsOpenedLanguageSelector } = useStore_IsOpenedLanguageSelector();
|
||||
const closeLanguageSelector = () => {
|
||||
updateIsOpenedLanguageSelector({
|
||||
|
||||
@@ -27,9 +27,9 @@ export const LogBox = () => {
|
||||
);
|
||||
};
|
||||
|
||||
import { useMessageLogUiScaling } from "@logics_configs";
|
||||
import { useAppearance } from "@logics_configs";
|
||||
const MessageLogUiSizeController = () => {
|
||||
const { currentMessageLogUiScaling } = useMessageLogUiScaling();
|
||||
const { currentMessageLogUiScaling } = useAppearance();
|
||||
const font_size = currentMessageLogUiScaling.data / 100;
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
import styles from "./MessageContainer.module.scss";
|
||||
import { MessageSubMenuContainer } from "./message_sub_menu_container/MessageSubMenuContainer";
|
||||
import { useMessage } from "@logics_common";
|
||||
import { useIsVisibleResendButton } from "@logics_main";
|
||||
import { useAppearance } from "@logics_configs";
|
||||
|
||||
export const MessageContainer = ({ messages, status, category, created_at }) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const {
|
||||
sendMessage,
|
||||
updateMessageInputValue,
|
||||
} = useMessage();
|
||||
const { currentIsVisibleResendButton } = useIsVisibleResendButton();
|
||||
const { currentShowResendButton } = useAppearance();
|
||||
const [is_hovered, setIsHovered] = useState(false);
|
||||
const [is_locked, setIsLocked] = useState(false);
|
||||
|
||||
@@ -77,7 +77,7 @@ export const MessageContainer = ({ messages, status, category, created_at }) =>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{currentIsVisibleResendButton.data && is_sent_message && is_hovered ? (
|
||||
{currentShowResendButton.data && is_sent_message && is_hovered ? (
|
||||
<MessageSubMenuContainer
|
||||
setIsHovered={lockHoverState}
|
||||
resendFunction={resendFunction}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';
|
||||
import styles from "./MessageSubMenuContainer.module.scss";
|
||||
import SendMessageSvg from "@images/send_message.svg?react";
|
||||
@@ -68,6 +68,6 @@ export const MessageSubMenuContainer = (props) => {
|
||||
};
|
||||
|
||||
const Title_p = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
return <p className={styles.tooltip_title}>{t("main_page.message_log.resend_button_on_hover_desc")}</p>;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 { useAppearance, useOthers } from "@logics_configs";
|
||||
import { useMessageLogScroll } from "@logics_main";
|
||||
import { store } from "@store";
|
||||
|
||||
@@ -18,8 +18,8 @@ export const MessageInputBox = () => {
|
||||
stopTyping,
|
||||
} = useMessage();
|
||||
|
||||
const { currentEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox();
|
||||
const { currentSendMessageButtonType } = useSendMessageButtonType();
|
||||
const { currentEnableAutoClearMessageInputBox } = useOthers();
|
||||
const { currentSendMessageButtonType } = useAppearance();
|
||||
|
||||
const { scrollToBottom } = useMessageLogScroll();
|
||||
|
||||
|
||||
@@ -1,30 +1,22 @@
|
||||
import { useState } from "react";
|
||||
import styles from "./MessageLogSettingsContainer.module.scss";
|
||||
import clsx from "clsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
import { useIsVisibleResendButton } from "@logics_main";
|
||||
import { MessageLogUiScalingContainer } from "@setting_box";
|
||||
import { Checkbox } from "@common_components";
|
||||
import ConfigSvg from "@images/configuration.svg?react";
|
||||
|
||||
export const MessageLogSettingsContainer = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const [is_opened, setIsOpened] = useState(false);
|
||||
const [is_hovered, setIsHovered] = useState(false);
|
||||
|
||||
const { currentIsVisibleResendButton, toggleIsVisibleResendButton } = useIsVisibleResendButton();
|
||||
|
||||
const container_class_name = clsx(styles.container, {
|
||||
[styles.to_visible_toggle_bar]: props.to_visible_toggle_bar,
|
||||
[styles.is_hovered]: is_hovered,
|
||||
[styles.is_opened]: is_opened
|
||||
});
|
||||
|
||||
const toggleVisibleResendButton = () => {
|
||||
toggleIsVisibleResendButton();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={container_class_name}
|
||||
onMouseOver={() => setIsHovered(true)}
|
||||
@@ -38,15 +30,6 @@ export const MessageLogSettingsContainer = (props) => {
|
||||
</div>
|
||||
<MessageLogUiScalingContainer />
|
||||
<div className={styles.others_wrapper}>
|
||||
<div className={styles.resend_checkbox_toggle} onClick={toggleVisibleResendButton}>
|
||||
<p className={styles.resend_checkbox_label}>{t("main_page.message_log.show_resend_button")}</p>
|
||||
<Checkbox
|
||||
id="visible_resend_button"
|
||||
variable={currentIsVisibleResendButton}
|
||||
size="2rem"
|
||||
padding="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./RightSideComponents.module.scss";
|
||||
import RefreshSvg from "@images/refresh.svg?react";
|
||||
import HelpSvg from "@images/help.svg?react";
|
||||
|
||||
import { useStore_OpenedQuickSetting } from "@store";
|
||||
import { useSoftwareVersion } from "@logics_common";
|
||||
import { useIsEnabledOverlaySmallLog, useIsEnabledOverlayLargeLog, useEnableVrcMicMuteSync } from "@logics_configs";
|
||||
import { useVr, useOthers } from "@logics_configs";
|
||||
import { OpenQuickSettingButton } from "./_buttons/OpenQuickSettingButton";
|
||||
|
||||
export const RightSideComponents = () => {
|
||||
@@ -30,10 +30,12 @@ export const RightSideComponents = () => {
|
||||
};
|
||||
|
||||
const OpenOverlayQuickSetting = () => {
|
||||
// const { t } = useTranslation();
|
||||
// const { t } = useI18n();
|
||||
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||
const { currentIsEnabledOverlaySmallLog } = useIsEnabledOverlaySmallLog();
|
||||
const { currentIsEnabledOverlayLargeLog } = useIsEnabledOverlayLargeLog();
|
||||
const {
|
||||
currentIsEnabledOverlaySmallLog,
|
||||
currentIsEnabledOverlayLargeLog,
|
||||
} = useVr();
|
||||
|
||||
const onClickFunction = () => {
|
||||
updateOpenedQuickSetting("overlay");
|
||||
@@ -50,7 +52,7 @@ const OpenOverlayQuickSetting = () => {
|
||||
);
|
||||
};
|
||||
const PluginsQuickSetting = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||
|
||||
const onClickFunction = () => {
|
||||
@@ -66,9 +68,9 @@ const PluginsQuickSetting = () => {
|
||||
};
|
||||
|
||||
const OpenVrcMicMuteSyncQuickSetting = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||
const { currentEnableVrcMicMuteSync } = useEnableVrcMicMuteSync();
|
||||
const { currentEnableVrcMicMuteSync } = useOthers();
|
||||
|
||||
const onClickFunction = () => {
|
||||
updateOpenedQuickSetting("vrc_mic_mute_sync");
|
||||
@@ -85,7 +87,7 @@ const OpenVrcMicMuteSyncQuickSetting = () => {
|
||||
|
||||
const SoftwareUpdateAvailableButton = () => {
|
||||
const { currentLatestSoftwareVersionInfo } = useSoftwareVersion();
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
if (currentLatestSoftwareVersionInfo.data.is_update_available === false) return null;
|
||||
|
||||
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
import styles from "./OpenQuickSettingButton.module.scss";
|
||||
|
||||
export const OpenQuickSettingButton = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const variable = (typeof props.variable === "boolean") ? props.variable : null;
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import styles from "./LanguageSettings.module.scss";
|
||||
import { PresetTabSelector } from "./preset_tab_selector/PresetTabSelector";
|
||||
import { LanguageSelectorOpenButton } from "./language_selector_open_button/LanguageSelectorOpenButton";
|
||||
@@ -8,7 +8,7 @@ import { AddRemoveTargetLanguageButtons } from "./add_remove_target_language_but
|
||||
import { useStore_IsOpenedTranslatorSelector } from "@store";
|
||||
|
||||
export const LanguageSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateIsOpenedTranslatorSelector } = useStore_IsOpenedTranslatorSelector();
|
||||
const closeTranslatorSelector = () => updateIsOpenedTranslatorSelector(false);
|
||||
|
||||
@@ -26,7 +26,7 @@ import HeadphonesSvg from "@images/headphones.svg?react";
|
||||
import { useMainFunction } from "@logics_main";
|
||||
|
||||
const PresetContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { currentTranscriptionSendStatus, currentTranscriptionReceiveStatus } = useMainFunction();
|
||||
|
||||
const yourLanguageSettings = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
import styles from "./LanguageSelectorOpenButton.module.scss";
|
||||
import ArrowLeftSvg from "@images/arrow_left.svg?react";
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "@logics_main";
|
||||
|
||||
export const LanguageSelectorOpenButton = ({ TurnedOnSvgComponent, is_turned_on, selector_key, target_key }) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateIsOpenedLanguageSelector, currentIsOpenedLanguageSelector } = useStore_IsOpenedLanguageSelector();
|
||||
|
||||
const {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
import styles from "./LanguageSwapButton.module.scss";
|
||||
|
||||
@@ -9,8 +9,8 @@ import { useLanguageSettings } from "@logics_main";
|
||||
|
||||
export const LanguageSwapButton = () => {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const { runLanguageSwap } = useLanguageSettings();
|
||||
const { t } = useI18n();
|
||||
const { swapSelectedLanguages } = useLanguageSettings();
|
||||
|
||||
const label = isHovered
|
||||
? t("main_page.swap_button_label")
|
||||
@@ -29,7 +29,7 @@ export const LanguageSwapButton = () => {
|
||||
className={styles.swap_button_wrapper}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
onClick={runLanguageSwap}
|
||||
onClick={swapSelectedLanguages}
|
||||
>
|
||||
<NarrowArrowDownSvg className={clsx(styles.narrow_arrow_down_svg, styles.reverse)} />
|
||||
<p className={labelClassName}>{label}</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { updateLabelsById } from "@utils";
|
||||
import styles from "./TranslatorSelectorOpenButton.module.scss";
|
||||
import { TranslatorSelector } from "./translator_selector/TranslatorSelector";
|
||||
@@ -7,7 +7,7 @@ import { useLanguageSettings } from "@logics_main";
|
||||
import WarningSvg from "@images/warning.svg?react";
|
||||
|
||||
export const TranslatorSelectorOpenButton = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const {
|
||||
currentSelectedYourLanguages,
|
||||
currentSelectedTargetLanguages,
|
||||
|
||||
@@ -31,5 +31,5 @@
|
||||
margin-left: 0.2rem;
|
||||
padding-bottom: 0.2rem;
|
||||
width: 1.8rem;
|
||||
color: var(--waring_color);
|
||||
color: var(--warning_color);
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import clsx from "clsx";
|
||||
import styles from "./TranslatorSelector.module.scss";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
|
||||
import { chunkArray } from "@utils";
|
||||
import { useStore_IsOpenedTranslatorSelector } from "@store";
|
||||
import { useLanguageSettings } from "@logics_main";
|
||||
|
||||
export const TranslatorSelector = ({selected_id, translation_engines, is_selected_same_language}) => { const { t } = useTranslation();
|
||||
export const TranslatorSelector = ({selected_id, translation_engines, is_selected_same_language}) => {
|
||||
const { t } = useI18n();
|
||||
const columns = chunkArray(translation_engines, 2);
|
||||
|
||||
return (
|
||||
@@ -46,7 +47,7 @@ export const TranslatorSelector = ({selected_id, translation_engines, is_selecte
|
||||
};
|
||||
|
||||
const TranslatorBox = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { setSelectedTranslationEngines} = useLanguageSettings();
|
||||
const { updateIsOpenedTranslatorSelector} = useStore_IsOpenedTranslatorSelector();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import clsx from "clsx";
|
||||
import styles from "./MainFunctionSwitch.module.scss";
|
||||
import TranslationSvg from "@images/translation.svg?react";
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from "@logics_main";
|
||||
|
||||
export const MainFunctionSwitch = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
const {
|
||||
toggleTranslation, currentTranslationStatus,
|
||||
|
||||
@@ -65,6 +65,7 @@ const ErrorContainer = ({error}) => {
|
||||
);
|
||||
};
|
||||
|
||||
// Duplicated
|
||||
const CloseButtonContainer = () => {
|
||||
const { asyncCloseApp } = useWindow();
|
||||
return (
|
||||
@@ -72,6 +72,7 @@
|
||||
|
||||
|
||||
|
||||
// Duplicated
|
||||
.close_button_wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
6
src-ui/app/others/index.js
Normal file
6
src-ui/app/others/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export { WindowTitleBar } from "./window_title_bar/WindowTitleBar.jsx";
|
||||
export { SplashComponent } from "./splash_component/SplashComponent.jsx";
|
||||
export { UpdatingComponent } from "./updating_component/UpdatingComponent.jsx";
|
||||
export { ModalController } from "./modal_controller/ModalController.jsx";
|
||||
export { SnackbarController } from "./snackbar_controller/SnackbarController.jsx";
|
||||
export { AppErrorBoundary } from "./error_boundary/AppErrorBoundary.jsx";
|
||||
@@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import styles from "./UpdateModal.module.scss";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import { useStore_OpenedQuickSetting } from "@store";
|
||||
import { usePlugins } from "@logics_configs";
|
||||
import {
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { PluginCompatibilityList } from "./plugins_compatibility_list/PluginCompatibilityList";
|
||||
|
||||
export const UpdateModal = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||
const { updateSoftware, updateSoftware_CUDA } = useUpdateSoftware();
|
||||
const { updateIsSoftwareUpdating } = useIsSoftwareUpdating();
|
||||
@@ -91,7 +91,7 @@ const VersionDescComponent = (props) => {
|
||||
};
|
||||
|
||||
const CurrentVersionLabel = (props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
if (props.is_latest_version_already) {
|
||||
return <p className={clsx(styles.current_version_label, {[styles.is_cuda]: props.is_cuda})}>{t("update_modal.is_latest_version_already")}</p>;
|
||||
@@ -54,7 +54,7 @@
|
||||
.warning_svg {
|
||||
padding-bottom: 0.4rem;
|
||||
width: 2.4rem;
|
||||
color: var(--waring_color);
|
||||
color: var(--warning_color);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
:root {
|
||||
--toastify-color-light: #fff;
|
||||
--toastify-color-dark: var(--dark_950_color);
|
||||
--toastify-color-info: var(--sent_400_color);
|
||||
--toastify-color-success: var(--primary_400_color);
|
||||
--toastify-color-warning: var(--warning_bc_color);
|
||||
--toastify-color-error: var(--error_bc_color);
|
||||
--toastify-color-transparent: rgba(255, 255, 255, 0.7);
|
||||
|
||||
--toastify-icon-color-info: var(--toastify-color-info);
|
||||
--toastify-icon-color-success: var(--toastify-color-success);
|
||||
--toastify-icon-color-warning: var(--toastify-color-warning);
|
||||
--toastify-icon-color-error: var(--toastify-color-error);
|
||||
|
||||
--toastify-container-width: fit-content;
|
||||
--toastify-toast-width: 32rem;
|
||||
--toastify-toast-offset: 1.6rem;
|
||||
--toastify-toast-top: max(var(--toastify-toast-offset), env(safe-area-inset-top));
|
||||
--toastify-toast-right: max(var(--toastify-toast-offset), env(safe-area-inset-right));
|
||||
--toastify-toast-left: max(var(--toastify-toast-offset), env(safe-area-inset-left));
|
||||
--toastify-toast-bottom: max(var(--toastify-toast-offset), env(safe-area-inset-bottom));
|
||||
--toastify-toast-background: #fff;
|
||||
--toastify-toast-padding: 1.4rem;
|
||||
--toastify-toast-min-height: 6.4rem;
|
||||
--toastify-toast-max-height: 80rem;
|
||||
--toastify-toast-bd-radius: 0.6rem;
|
||||
--toastify-toast-shadow: .0 0.4rem 1.2rem rgba(0, 0, 0, 0.1);
|
||||
--toastify-font-family: var(--font_family);
|
||||
--toastify-z-index: 9999;
|
||||
--toastify-text-color-light: #757575;
|
||||
--toastify-text-color-dark: var(--dark_basic_text_color);
|
||||
|
||||
/* Used only for colored theme */
|
||||
--toastify-text-color-info: var(--dark_basic_text_color);
|
||||
--toastify-text-color-success: var(--dark_basic_text_color);
|
||||
--toastify-text-color-warning: var(--dark_basic_text_color);
|
||||
--toastify-text-color-error: var(--dark_basic_text_color);
|
||||
|
||||
--toastify-spinner-color: #616161;
|
||||
--toastify-spinner-color-empty-area: #e0e0e0;
|
||||
--toastify-color-progress-light: linear-gradient(to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55);
|
||||
--toastify-color-progress-dark: #bb86fc;
|
||||
--toastify-color-progress-info: var(--toastify-color-info);
|
||||
--toastify-color-progress-success: var(--toastify-color-success);
|
||||
--toastify-color-progress-warning: var(--toastify-color-warning);
|
||||
--toastify-color-progress-error: var(--toastify-color-error);
|
||||
/* used to control the opacity of the progress trail */
|
||||
--toastify-color-progress-bgo: 0.2;
|
||||
}
|
||||
|
||||
|
||||
.Toastify__toast {
|
||||
// --------------------------------------------------------
|
||||
// Default Settings
|
||||
// --------------------------------------------------------
|
||||
position: relative;
|
||||
touch-action: none;
|
||||
// width: var(--toastify-toast-width);
|
||||
min-height: var(--toastify-toast-min-height);
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 1rem;
|
||||
// padding: var(--toastify-toast-padding);
|
||||
border-radius: 0.6rem;
|
||||
box-shadow: none;
|
||||
max-height: var(--toastify-toast-max-height);
|
||||
// font-family: "Yu Gothic UI";
|
||||
// font-family: var(--toastify-font-family);
|
||||
// z-index: 0;
|
||||
// display: flex;
|
||||
// flex: 1 auto;
|
||||
// align-items: center;
|
||||
word-break: break-word;
|
||||
// --------------------------------------------------------
|
||||
// --------------------------------------------------------
|
||||
|
||||
|
||||
// Comment out above and override. Commented out is just for memorization.
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
font-size: 1.4rem;
|
||||
width: fit-content;
|
||||
max-width: 70vw;
|
||||
padding-right: 4rem;
|
||||
background-color: var(--dark_950_color);
|
||||
gap: 0.6rem;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.Toastify__progress-bar--wrp {
|
||||
height: 0.4rem;
|
||||
}
|
||||
.Toastify__progress-bar--success {
|
||||
background: var(--success_bc_color);
|
||||
}
|
||||
|
||||
.Toastify__progress-bar--warning {
|
||||
background: var(--warning_bc_color);
|
||||
}
|
||||
|
||||
.Toastify__progress-bar--error {
|
||||
background: var(--error_bc_color);
|
||||
}
|
||||
|
||||
|
||||
.Toastify__toast-icon {
|
||||
width: fit-content;
|
||||
max-width: 2.8rem;
|
||||
min-width: 2.8rem;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@keyframes fade_in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes fade_out {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.fade_in {
|
||||
opacity: 0;
|
||||
animation-name: fade_in;
|
||||
animation-duration: 0.1s;
|
||||
animation-timing-function: ease-out;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
.fade_out {
|
||||
opacity: 1;
|
||||
animation-name: fade_out;
|
||||
animation-duration: 0.1s;
|
||||
animation-timing-function: ease-in;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
115
src-ui/app/others/snackbar_controller/SnackbarController.jsx
Normal file
115
src-ui/app/others/snackbar_controller/SnackbarController.jsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { ToastContainer, toast, cssTransition } from "react-toastify";
|
||||
import clsx from "clsx";
|
||||
|
||||
import "./ReactToastifyOverrideClass.scss";
|
||||
import styles from "./SnackbarController.module.scss";
|
||||
|
||||
import XMarkSvg from "@images/cancel.svg?react";
|
||||
import WarningSvg from "@images/warning.svg?react";
|
||||
import MegaphoneSvg from "@images/megaphone.svg?react";
|
||||
import CheckMarkSvg from "@images/check_mark.svg?react";
|
||||
import ErrorSvg from "@images/error.svg?react";
|
||||
|
||||
import { useNotificationStatus } from "@logics_common";
|
||||
|
||||
const CustomTransition = cssTransition({
|
||||
enter: "fade_in",
|
||||
exit: "fade_out",
|
||||
collapse: false,
|
||||
});
|
||||
|
||||
|
||||
export const SnackbarController = () => {
|
||||
const { currentNotificationStatus, closeNotification } = useNotificationStatus();
|
||||
const [containerKey, setContainerKey] = useState(0);
|
||||
|
||||
const settings = currentNotificationStatus.data;
|
||||
|
||||
const snackbar_classname = clsx(
|
||||
styles.snackbar_content,
|
||||
{
|
||||
[styles.is_success]: settings.status === "success",
|
||||
[styles.is_warning]: settings.status === "warning",
|
||||
[styles.is_error]: settings.status === "error",
|
||||
}
|
||||
);
|
||||
|
||||
let hide_duration = 5000;
|
||||
if (settings.options?.hide_duration === null) {
|
||||
hide_duration = false;
|
||||
} else if (Number(settings.options?.hide_duration)) {
|
||||
hide_duration = Number(settings.options?.hide_duration);
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!settings.is_open) return;
|
||||
|
||||
const message_text = settings.message;
|
||||
const category_id = settings.category_id ? settings.category_id : message_text;
|
||||
|
||||
const to_hide_progress_bar = (settings.options?.to_hide_progress_bar === true) ? true : false;
|
||||
|
||||
const asyncShowNotification = async () => {
|
||||
setTimeout(() => {
|
||||
toast(message_text, {
|
||||
toastId: category_id,
|
||||
type: settings.status,
|
||||
autoClose: hide_duration,
|
||||
transition: CustomTransition,
|
||||
toastClassName: snackbar_classname,
|
||||
hideProgressBar: to_hide_progress_bar,
|
||||
progressClassName: styles.toast_progress,
|
||||
closeButton: <CloseButtonContainer />,
|
||||
onClose: () => {
|
||||
closeNotification();
|
||||
},
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// setContainerKey(prevKey => prevKey + 1);
|
||||
asyncShowNotification();
|
||||
|
||||
}, [settings]);
|
||||
|
||||
return (
|
||||
<ToastContainer
|
||||
// key={containerKey}
|
||||
position="bottom-left"
|
||||
transition={CustomTransition}
|
||||
hideProgressBar={false}
|
||||
newestOnTop={false}
|
||||
closeOnClick={false}
|
||||
pauseOnFocusLoss={false}
|
||||
draggable={false}
|
||||
pauseOnHover={true}
|
||||
theme="dark"
|
||||
icon={({ type }) => {
|
||||
switch (type) {
|
||||
case "info":
|
||||
return <MegaphoneSvg className={styles.megaphone_svg} />;
|
||||
case "error":
|
||||
return <ErrorSvg className={styles.error_svg} />;
|
||||
case "success":
|
||||
return <CheckMarkSvg className={styles.check_mark_svg} />;
|
||||
case "warning":
|
||||
return <WarningSvg className={styles.warning_svg} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const CloseButtonContainer = ({ closeToast }) => {
|
||||
return (
|
||||
<button className={styles.close_button_wrapper} onClick={closeToast}>
|
||||
<div className={styles.close_button}>
|
||||
<XMarkSvg className={styles.x_mark_svg} />
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
.snackbar_content {
|
||||
position: relative;
|
||||
padding: 1.2rem 1.6rem;
|
||||
border-radius: 0.8rem;
|
||||
font-size: 1.4rem;
|
||||
box-shadow: 0 0.2rem 0.8rem rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
// .is_success {
|
||||
// background-color: var(--success_bc_color);
|
||||
// }
|
||||
|
||||
// .is_warning {
|
||||
// background-color: var(--warning_bc_color);
|
||||
// }
|
||||
|
||||
// .is_error {
|
||||
// background-color: var(--error_bc_color);
|
||||
// }
|
||||
|
||||
|
||||
.megaphone_svg {
|
||||
color: var(--dark_200_color);
|
||||
width: 2.4rem;
|
||||
}
|
||||
.error_svg {
|
||||
color: var(--error_bc_color);
|
||||
width: 2.4rem;
|
||||
}
|
||||
.check_mark_svg {
|
||||
color: var(--primary_400_color);
|
||||
width: 2rem;
|
||||
}
|
||||
.warning_svg {
|
||||
color: var(--warning_color);
|
||||
width: 2.4rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Duplicated (Customized)
|
||||
.close_button_wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: end;
|
||||
width: 5.6rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
&:hover {
|
||||
background-color: var(--error_bc_color);
|
||||
& .x_mark_svg {
|
||||
color: var(--dark_200_color);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
background-color: var(--error_bc_active_color);
|
||||
}
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
|
||||
.close_button {
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
}
|
||||
|
||||
.x_mark_svg {
|
||||
width: 2rem;
|
||||
transform: rotate(-45deg);
|
||||
color: var(--dark_700_color);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import styles from "./SplashComponent.module.scss";
|
||||
import { StartUpProgressContainer } from "./start_up_progress_container/StartUpProgressContainer/";
|
||||
import { DownloadModelsContainer } from "./download_models_container/DownloadModelsContainer/";
|
||||
import { StartUpProgressContainer } from "./start_up_progress_container/StartUpProgressContainer";
|
||||
import { DownloadModelsContainer } from "./download_models_container/DownloadModelsContainer";
|
||||
import MegaphoneSvg from "@images/megaphone.svg?react";
|
||||
import XMarkSvg from "@images/cancel.svg?react";
|
||||
import { useWindow } from "@logics_common";
|
||||
@@ -71,7 +71,7 @@ const AnnouncementsContainer = () => {
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Duplicated
|
||||
const CloseButtonContainer = () => {
|
||||
const { asyncCloseApp } = useWindow();
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Duplicated
|
||||
.close_button_wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -3,13 +3,13 @@ import vrct_logo_for_dark_mode from "@images/vrct_logo_for_dark_mode.png";
|
||||
import vrct_now_downloading from "@images/VRCT_now_downloading.png";
|
||||
|
||||
import {
|
||||
useCTranslate2WeightTypeStatus,
|
||||
useWhisperWeightTypeStatus,
|
||||
useTranslation,
|
||||
useTranscription,
|
||||
} from "@logics_configs";
|
||||
|
||||
export const DownloadModelsContainer = () => {
|
||||
const { currentCTranslate2WeightTypeStatus } = useCTranslate2WeightTypeStatus();
|
||||
const { currentWhisperWeightTypeStatus } = useWhisperWeightTypeStatus();
|
||||
const { currentCTranslate2WeightTypeStatus } = useTranslation();
|
||||
const { currentWhisperWeightTypeStatus } = useTranscription();
|
||||
|
||||
const c_translate_2 = currentCTranslate2WeightTypeStatus.data.find(d => d.id === "small");
|
||||
const whisper = currentWhisperWeightTypeStatus.data.find(d => d.id === "base");
|
||||
@@ -1,10 +1,10 @@
|
||||
import styles from "./UpdatingComponent.module.scss";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useI18n } from "@useI18n";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import chat_white_square from "@images/chato_white_square.png";
|
||||
|
||||
export const UpdatingComponent = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useI18n();
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@@ -1,46 +0,0 @@
|
||||
import clsx from "clsx";
|
||||
import Snackbar from "@mui/material/Snackbar";
|
||||
import Slide from "@mui/material/Slide";
|
||||
|
||||
import styles from "./SnackbarController.module.scss";
|
||||
import { useNotificationStatus } from "@logics_common";
|
||||
|
||||
export const SnackbarController = () => {
|
||||
const { currentNotificationStatus, closeNotification } = useNotificationStatus();
|
||||
|
||||
const handleClose = (event, reason) => {
|
||||
closeNotification(event, reason);
|
||||
};
|
||||
|
||||
const snackbar_classname = clsx(styles.snackbar_content, {
|
||||
[styles.is_success]: currentNotificationStatus.data.status === "success",
|
||||
[styles.is_warning]: currentNotificationStatus.data.status === "warning",
|
||||
[styles.is_error]: currentNotificationStatus.data.status === "error",
|
||||
});
|
||||
|
||||
const settings = currentNotificationStatus.data;
|
||||
|
||||
let hide_duration = 5000;
|
||||
if (settings.options?.hide_duration === null) hide_duration = null;
|
||||
if (Number(settings.options?.hide_duration)) hide_duration = settings.options.hide_duration;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Snackbar
|
||||
open={settings.is_open}
|
||||
onClose={handleClose}
|
||||
TransitionComponent={SlideTransition}
|
||||
key={settings.key}
|
||||
autoHideDuration={hide_duration}
|
||||
>
|
||||
<div className={snackbar_classname}>
|
||||
<p className={styles.snackbar_message}>{settings.message}</p>
|
||||
</div>
|
||||
</Snackbar>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const SlideTransition = (props) => {
|
||||
return <Slide {...props} direction="up" />;
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user