Merge branch 'develop' into plugins_system

This commit is contained in:
Sakamoto Shiina
2025-03-19 09:46:33 +09:00
24 changed files with 704 additions and 312 deletions

View File

@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import styles from "./WordFilter.module.scss";
import { _Entry } from "../_atoms/_entry/_Entry";
import { useState } from "react";
@@ -5,6 +6,8 @@ import { useStore_IsOpenedMicWordFilterList } from "@store";
import { useMicWordFilterList } from "@logics_configs";
export const WordFilter = () => {
const { t } = useTranslation();
const [input_value, setInputValue] = useState("");
const { currentMicWordFilterList, updateMicWordFilterList, setMicWordFilterList } = useMicWordFilterList();
const { currentIsOpenedMicWordFilterList, updateIsOpenedMicWordFilterList } = useStore_IsOpenedMicWordFilterList();
@@ -82,7 +85,7 @@ export const WordFilter = () => {
}
<div className={styles.entry_section_wrapper}>
<_Entry width="30rem" onChange={onChangeEntry} ui_variable={input_value}/>
<button className={styles.add_button} onClick={addWords}>Add</button>
<button className={styles.add_button} onClick={addWords}>{t("config_page.transcription.mic_word_filter.add_button_label")}</button>
</div>
</div>
);
@@ -121,8 +124,6 @@ const WordFilterItem = (props) => {
);
};
import { useTranslation } from "react-i18next";
import ArrowLeftSvg from "@images/arrow_left.svg?react";
export const WordFilterListToggleComponent = (props) => {
const { t } = useTranslation();

View File

@@ -82,7 +82,7 @@ const Mic_Container = () => {
<div className={styles.device_contents}>
<div className={styles.device_auto_select_wrapper}>
<p className={styles.device_secondary_label}>{t("config_page.device.mic_host_device.label_auto_select")}</p>
<p className={styles.device_secondary_label}>{t("config_page.device.label_auto_select")}</p>
<SwitchBox
variable={currentEnableAutoMicSelect}
toggleFunction={toggleEnableAutoMicSelect}
@@ -91,7 +91,7 @@ const Mic_Container = () => {
<div className={styles.device_dropdown_wrapper}>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.device.mic_host_device.label_host")}</p>
<p className={styles.device_secondary_label}>{t("config_page.device.label_host")}</p>
<DropdownMenu
dropdown_id="mic_host"
selected_id={currentSelectedMicHost.data}
@@ -104,7 +104,7 @@ const Mic_Container = () => {
</div>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.device.mic_host_device.label_device")}</p>
<p className={styles.device_secondary_label}>{t("config_page.device.label_device")}</p>
<DropdownMenu
dropdown_id="mic_device"
selected_id={currentSelectedMicDevice.data}
@@ -178,7 +178,7 @@ const Speaker_Container = () => {
<div className={styles.device_contents}>
<div className={styles.device_auto_select_wrapper}>
<p className={styles.device_secondary_label}>{t("config_page.device.speaker_device.label_auto_select")}</p>
<p className={styles.device_secondary_label}>{t("config_page.device.label_auto_select")}</p>
<SwitchBox
variable={currentEnableAutoSpeakerSelect}
toggleFunction={toggleEnableAutoSpeakerSelect}
@@ -186,7 +186,7 @@ const Speaker_Container = () => {
</div>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.device.mic_host_device.label_device")}</p>
<p className={styles.device_secondary_label}>{t("config_page.device.label_device")}</p>
<DropdownMenu
dropdown_id="speaker_device"
label={t("config_page.device.speaker_device.label")}

View File

@@ -1,7 +1,6 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import styles from "./Transcription.module.scss";
import { updateLabelsById } from "@utils";
import { updateLabelsById, genNumObjArray } from "@utils";
import {
useMicRecordTimeout,
@@ -21,7 +20,6 @@ import {
} from "@logics_configs";
import {
EntryContainer,
WordFilterContainer,
DownloadModelsContainer,
RadioButtonContainer,
@@ -59,82 +57,61 @@ const Mic_Container = () => {
const MicRecordTimeout_Box = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentMicRecordTimeout, setMicRecordTimeout } = useMicRecordTimeout();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setMicRecordTimeout(value);
}
const selectFunction = (selected_data) => {
setMicRecordTimeout(selected_data.selected_id);
};
useEffect(()=> {
setUiVariable(currentMicRecordTimeout.data);
}, [currentMicRecordTimeout]);
return (
<EntryContainer
<DropdownMenuContainer
dropdown_id="mic_record_timeout"
label={t("config_page.transcription.mic_record_timeout.label")}
desc={t("config_page.transcription.mic_record_timeout.desc")}
ui_variable={ui_variable}
onChange={onChangeFunction}
selected_id={currentMicRecordTimeout.data}
list={genNumObjArray(31)}
selectFunction={selectFunction}
state={currentMicRecordTimeout.state}
/>
);
};
const MicPhraseTimeout_Box = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentMicPhraseTimeout, setMicPhraseTimeout } = useMicPhraseTimeout();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setMicPhraseTimeout(value);
}
const selectFunction = (selected_data) => {
setMicPhraseTimeout(selected_data.selected_id);
};
useEffect(()=> {
setUiVariable(currentMicPhraseTimeout.data);
}, [currentMicPhraseTimeout]);
return (
<EntryContainer
<DropdownMenuContainer
dropdown_id="mic_phrase_timeout"
label={t("config_page.transcription.mic_phrase_timeout.label")}
desc={t("config_page.transcription.mic_phrase_timeout.desc")}
ui_variable={ui_variable}
onChange={onChangeFunction}
selected_id={currentMicPhraseTimeout.data}
list={genNumObjArray(31)}
selectFunction={selectFunction}
state={currentMicPhraseTimeout.state}
/>
);
};
const MicMaxWords_Box = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentMicMaxWords, setMicMaxWords } = useMicMaxWords();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setMicMaxWords(value);
}
const selectFunction = (selected_data) => {
setMicMaxWords(selected_data.selected_id);
};
useEffect(()=> {
setUiVariable(currentMicMaxWords.data);
}, [currentMicMaxWords]);
return (
<EntryContainer
<DropdownMenuContainer
dropdown_id="mic_max_phrase"
label={t("config_page.transcription.mic_max_phrase.label")}
desc={t("config_page.transcription.mic_max_phrase.desc")}
ui_variable={ui_variable}
onChange={onChangeFunction}
selected_id={currentMicMaxWords.data}
list={genNumObjArray(31)}
selectFunction={selectFunction}
state={currentMicMaxWords.state}
/>
);
};
@@ -167,82 +144,60 @@ const Speaker_Container = () => {
const SpeakerRecordTimeout_Box = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentSpeakerRecordTimeout, setSpeakerRecordTimeout } = useSpeakerRecordTimeout();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setSpeakerRecordTimeout(value);
}
const selectFunction = (selected_data) => {
setSpeakerRecordTimeout(selected_data.selected_id);
};
useEffect(()=> {
setUiVariable(currentSpeakerRecordTimeout.data);
}, [currentSpeakerRecordTimeout]);
return (
<EntryContainer
label={t("config_page.transcription.speaker_record_timeout.label")}
<DropdownMenuContainer
dropdown_id="speaker_record_timeout"
desc={t("config_page.transcription.speaker_record_timeout.desc")}
ui_variable={ui_variable}
onChange={onChangeFunction}
label={t("config_page.transcription.speaker_record_timeout.label")}
selected_id={currentSpeakerRecordTimeout.data}
list={genNumObjArray(31)}
selectFunction={selectFunction}
state={currentSpeakerRecordTimeout.state}
/>
);
};
const SpeakerPhraseTimeout_Box = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentSpeakerPhraseTimeout, setSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setSpeakerPhraseTimeout(value);
}
const selectFunction = (selected_data) => {
setSpeakerPhraseTimeout(selected_data.selected_id);
};
useEffect(()=> {
setUiVariable(currentSpeakerPhraseTimeout.data);
}, [currentSpeakerPhraseTimeout]);
return (
<EntryContainer
<DropdownMenuContainer
dropdown_id="speaker_phrase_timeout"
label={t("config_page.transcription.speaker_phrase_timeout.label")}
desc={t("config_page.transcription.speaker_phrase_timeout.desc")}
ui_variable={ui_variable}
onChange={onChangeFunction}
selected_id={currentSpeakerPhraseTimeout.data}
list={genNumObjArray(31)}
selectFunction={selectFunction}
state={currentSpeakerPhraseTimeout.state}
/>
);
};
const SpeakerMaxWords_Box = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentSpeakerMaxWords, setSpeakerMaxWords } = useSpeakerMaxWords();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setSpeakerMaxWords(value);
}
const selectFunction = (selected_data) => {
setSpeakerMaxWords(selected_data.selected_id);
};
useEffect(()=> {
setUiVariable(currentSpeakerMaxWords.data);
}, [currentSpeakerMaxWords]);
return (
<EntryContainer
<DropdownMenuContainer
dropdown_id="speaker_max_phrase"
label={t("config_page.transcription.speaker_max_phrase.label")}
desc={t("config_page.transcription.speaker_max_phrase.desc")}
ui_variable={ui_variable}
onChange={onChangeFunction}
selected_id={currentSpeakerMaxWords.data}
list={genNumObjArray(61)}
selectFunction={selectFunction}
state={currentSpeakerMaxWords.state}
/>
);
};

View File

@@ -56,7 +56,10 @@ const CTranslate2WeightType_Box = () => {
return (
<>
<DownloadModelsContainer
label={t("config_page.translation.ctranslate2_weight_type.label")}
label={t(
"config_page.translation.ctranslate2_weight_type.label",
{ctranslate2: "CTranslate2"}
)}
desc={t(
"config_page.translation.ctranslate2_weight_type.desc",
{translator: t("main_page.translator")}
@@ -89,10 +92,13 @@ const CTranslation2ComputeDevice_Box = () => {
const { currentComputeMode } = useComputeMode();
const ctranslate2_compute_device_label = t("config_page.translation.ctranslate2_compute_device.label", {
ctranslate2: "Ctranslate2"
});
if (currentComputeMode.data === "cpu") {
return (
<ComputeDeviceContainer
label={t("config_page.translation.ctranslate2_compute_device.label")}
label={ctranslate2_compute_device_label}
selected_id={target_index}
list={list_for_ui}
selectFunction={selectFunction}
@@ -104,8 +110,7 @@ const CTranslation2ComputeDevice_Box = () => {
return (
<DropdownMenuContainer
dropdown_id="ctranslate2_compute_device"
label={t("config_page.translation.ctranslate2_compute_device.label")}
// desc={t("config_page.translation.ctranslate2_compute_device.label")}
label={ctranslate2_compute_device_label}
selected_id={target_index}
list={list_for_ui}
selectFunction={selectFunction}

View File

@@ -43,9 +43,16 @@ const Tab = (props) => {
[styles["is_selected"]]: (currentSelectedConfigTabId.data === props.tab_id) ? true : false
});
const getLabel = () => {
if (props.tab_id === "vr") return "VR";
if (props.tab_id === "supporters") return "Supporters";
if (props.tab_id === "about_vrct") return "About VRCT";
return t(`config_page.side_menu_labels.${props.tab_id}`);
};
return (
<div className={tab_container_class_names} onClick={onclickFunction}>
<p className={styles.tab_text}>{t(`config_page.side_menu_labels.${props.tab_id}`)}</p>
<p className={styles.tab_text}>{getLabel()}</p>
<div className={switch_indicator_class_names}></div>
</div>
);

View File

@@ -9,6 +9,7 @@
flex-direction: column;
justify-content: space-between;
overflow-y: auto;
// overflow-x: hidden;
height: 100%;
max-height: 60rem;
}
@@ -59,7 +60,9 @@
}
.tab_text {
overflow: hidden;
font-size: 1.6rem;
text-overflow: ellipsis;
}
.separated_tabs_wrapper {

View File

@@ -16,7 +16,12 @@
position: absolute;
left: 0;
background-color: var(--dark_800_color);
padding: 1.2rem;
padding: 0 2rem 0 1.6rem;
height: 100%;
min-width: 8rem;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover{
background-color: var(--dark_750_color);

View File

@@ -16,11 +16,12 @@ export const TranslatorSelectorOpenButton = () => {
currentSelectedTranslationEngines,
} = useLanguageSettings();
const new_labels = [
{id: "CTranslate2", label: t("main_page.translator_ctranslate2")}
];
// const new_labels = [
// {id: "CTranslate2", label: "AI\nCTranslate2"}
// ];
const translation_engines = updateLabelsById(currentTranslationEngines.data, new_labels);
const translation_engines = currentTranslationEngines.data;
// const translation_engines = updateLabelsById(currentTranslationEngines.data, new_labels);
const selected_engine_id = currentSelectedTranslationEngines.data[currentSelectedPresetTabNumber.data];
@@ -74,7 +75,7 @@ export const TranslatorSelectorOpenButton = () => {
return (
<div className={styles.container}>
<div className={styles.translator_selector_button} onClick={openTranslatorSelector}>
<p className={styles.label}>{t("main_page.translator")}: </p>
<p className={styles.label}>{t("main_page.translator")}:</p>
<p className={styles.label}>{selected_label}</p>
{is_selected_same_language
? <WarningSvg className={styles.warning_svg}/>

View File

@@ -15,12 +15,13 @@ export const TranslatorSelector = ({selected_id, translation_engines, is_selecte
<div className={styles.wrapper}>
{columns.map((column, column_index) => (
<div className={styles.column_wrapper} key={`column_${column_index}`}>
{column.map(({ id, label, is_available }) => (
{column.map(({ id, label, is_available, is_default }) => (
<TranslatorBox
key={id}
id={id}
label={label}
is_available={is_available}
is_default={is_default}
is_selected={(id === selected_id)}
/>
))}
@@ -33,7 +34,7 @@ export const TranslatorSelector = ({selected_id, translation_engines, is_selecte
{t("main_page.translator_selector.is_selected_same_language", {
your_language: t("main_page.your_language"),
target_language: t("main_page.target_language"),
translator_ctranslate2: t("main_page.translator_ctranslate2"),
ctranslate2: "CTranslate2",
})}
</p>
</div>
@@ -45,6 +46,7 @@ export const TranslatorSelector = ({selected_id, translation_engines, is_selecte
};
const TranslatorBox = (props) => {
const { t } = useTranslation();
const { setSelectedTranslationEngines} = useLanguageSettings();
const { updateIsOpenedTranslatorSelector} = useStore_IsOpenedTranslatorSelector();
@@ -53,6 +55,10 @@ const TranslatorBox = (props) => {
{ [styles.is_selected]: props.is_selected },
{ [styles.is_available]: props.is_available }
);
const label_default_class_name = clsx(
styles.label_default,
{ [styles.is_selected]: props.is_selected },
);
const selectTranslator = () => {
if (props.is_selected === false) {
@@ -60,9 +66,11 @@ const TranslatorBox = (props) => {
}
updateIsOpenedTranslatorSelector(false);
};
return (
<div className={box_class_name} onClick={selectTranslator}>
<p className={styles.translator_name}>{props.label}</p>
{props.is_default && <p className={label_default_class_name}>{t("main_page.translator_label_default")}</p>}
</div>
);
};

View File

@@ -17,26 +17,26 @@
}
.wrapper {
// padding: 1rem;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1rem;
gap: 1.4rem;
}
.column_wrapper {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
gap: 1.2rem;
}
$box_size: 6.8rem;
$box_size: 6.2rem;
.box {
width: $box_size;
position: relative;
width: 9.4rem;
height: $box_size;
background-color: var(--dark_875_color);
display: flex;
@@ -44,17 +44,17 @@ $box_size: 6.8rem;
align-items: center;
white-space: pre-wrap;
text-align: center;
border-radius: 0.6rem;
border-radius: 0.2rem;
cursor: pointer;
&:hover {
background-color: var(--dark_825_color);
}
&:active {
background-color: var(--dark_900_color);
border: 0.1rem solid var(--primary_300_color);
outline: 0.1rem solid var(--primary_300_color);
}
&.is_selected {
border: 0.2rem solid var(--primary_300_color);
outline: 0.2rem solid var(--primary_300_color);
}
&:not(.is_available) {
pointer-events: none;
@@ -69,6 +69,22 @@ $box_size: 6.8rem;
font-size: 1.4rem;
}
.label_default {
background-color: var(--dark_875_color);
outline: 0.1rem solid var(--dark_1000_color);
padding: 0.2rem 0.4rem;
border-radius: 0.2rem;
font-size: 1.2rem;
position: absolute;
top: -0.8rem;
right: -0.8rem;
pointer-events: none;
&.is_selected {
outline: 0.1rem solid var(--primary_300_color);
}
}
.is_selected_same_language_wrapper {
position: absolute;
bottom: 0;

View File

@@ -78,7 +78,9 @@ $pending_label_color: var(--dark_500_color);
}
.toggle_control {
@include toggle_control_styles;
// @include toggle_control_styles;
@include toggle_control_styles($toggle_width: 3.6rem, $toggle_height: 1.4rem);
display: flex;
justify-content: end;
align-items: center;

View File

@@ -48,35 +48,41 @@ $toggle_width: 4rem;
$toggle_height: 1.6rem;
$toggle_gutter: 0.1rem;
$toggle_radius: 50%;
$toggle_control_speed: .15s;
$toggle_control_speed: 0.15s;
$toggle_control_ease: ease-out;
$toggle_radius: calc($toggle_height / 2);
$toggle_control_size: $toggle_height - calc($toggle_gutter * 2);
@mixin toggle_control_styles(
$toggle_width: $toggle_width,
$toggle_height: $toggle_height,
$toggle_gutter: $toggle_gutter,
$toggle_background_color_on: $toggle_background_color_on,
$toggle_background_color_off: $toggle_background_color_off,
$toggle_control_color: $toggle_control_color,
$toggle_control_speed: $toggle_control_speed,
$toggle_control_ease: $toggle_control_ease
) {
$toggle_radius: calc($toggle_height / 2);
$toggle_control_size: calc($toggle_height - ($toggle_gutter * 2));
@mixin toggle_control_styles {
display: block;
position: relative;
height: 100%;
width: auto;
.control {
position: relative;
height: $toggle_height;
width: $toggle_width;
height: $toggle_height;
border-radius: $toggle_radius;
background-color: $toggle_background_color_off;
transition: background-color $toggle_control_speed $toggle_control_ease;
&:after {
content: "";
position: absolute;
left: $toggle_gutter;
top: $toggle_gutter;
left: $toggle_gutter;
width: $toggle_control_size;
height: $toggle_control_size;
border-radius: $toggle_radius;
background: $toggle_control_color;
transition: left $toggle_control_speed $toggle_control_ease;
}
&.is_pending:after{
&.is_pending:after {
background-color: var(--dark_600_color);
}
&.is_hovered {

View File

@@ -0,0 +1,124 @@
import { useTranslation } from "react-i18next";
import {
useNotificationStatus,
} from "@logics_common";
import {
useMicRecordTimeout,
useMicPhraseTimeout,
useMicMaxWords,
useSpeakerRecordTimeout,
useSpeakerPhraseTimeout,
useSpeakerMaxWords,
useDeepLAuthKey,
} from "@logics_configs";
import { ui_configs } from "../ui_configs";
export const _useBackendErrorHandling = () => {
const { t } = useTranslation();
const { showNotification_Error } = useNotificationStatus();
const { updateMicRecordTimeout } = useMicRecordTimeout();
const { updateMicPhraseTimeout } = useMicPhraseTimeout();
const { updateMicMaxWords } = useMicMaxWords();
const { updateSpeakerRecordTimeout } = useSpeakerRecordTimeout();
const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
const { updateSpeakerMaxWords } = useSpeakerMaxWords();
const { updateDeepLAuthKey } = useDeepLAuthKey();
const errorHandling_Backend = ({message, data, endpoint}) => {
switch (message) {
case "No mic device detected":
showNotification_Error(t("common_error.no_device_mic"));
break;
case "No Speaker device detected":
showNotification_Error(t("common_error.no_device_speaker"));
break;
case "Mic energy threshold value is out of range":
showNotification_Error(t("common_error.threshold_invalid_value",
{ min: ui_configs.mic_threshold_min, max: ui_configs.mic_threshold_max },
));
break;
case "Speaker energy threshold value is out of range":
showNotification_Error(t("common_error.threshold_invalid_value",
{ min: ui_configs.speaker_threshold_min, max: ui_configs.speaker_threshold_max },
));
break;
case "CTranslate2 weight download error":
showNotification_Error(t("common_error.failed_download_weight_ctranslate2"));
break;
case "Whisper weight download error":
showNotification_Error(t("common_error.failed_download_weight_whisper"));
break;
case "Translation engine limit error":
showNotification_Error(t("common_error.translation_limit"));
break;
case "DeepL auth key length is not correct":
updateDeepLAuthKey(data);
showNotification_Error(t("common_error.deepl_auth_key_invalid_length"));
break;
case "Authentication failure of deepL auth key":
updateDeepLAuthKey(data);
showNotification_Error(t("common_error.deepl_auth_key_failed_authentication"));
break;
case "Mic record timeout value is out of range":
updateMicRecordTimeout(data);
showNotification_Error(
t("common_error.invalid_value_mic_record_timeout",
{ mic_phrase_timeout_label: t("config_page.transcription.mic_phrase_timeout.label") }
));
break;
case "Mic phrase timeout value is out of range":
updateMicPhraseTimeout(data);
showNotification_Error(
t("common_error.invalid_value_mic_phrase_timeout",
{ mic_record_timeout_label: t("config_page.transcription.mic_record_timeout.label") }
));
break;
case "Mic max phrases value is out of range":
updateMicMaxWords(data);
showNotification_Error(t("common_error.invalid_value_mic_max_phrase"));
break;
case "Speaker record timeout value is out of range":
updateSpeakerRecordTimeout(data);
showNotification_Error(
t("common_error.invalid_value_speaker_record_timeout",
{ speaker_phrase_timeout_label: t("config_page.transcription.speaker_phrase_timeout.label") }
));
break;
case "Speaker phrase timeout value is out of range":
updateSpeakerPhraseTimeout(data);
showNotification_Error(
t("common_error.invalid_value_speaker_phrase_timeout",
{ speaker_record_timeout_label: t("config_page.transcription.speaker_record_timeout.label") }
));
break;
case "Speaker max phrases value is out of range":
updateSpeakerMaxWords(data);
showNotification_Error(t("common_error.invalid_value_speaker_max_phrase"));
break;
default:
if (endpoint === "/set/data/deepl_auth_key") updateDeepLAuthKey(data);
showNotification_Error(message);
break;
}
}
return {
errorHandling_Backend,
}
};

View File

@@ -15,7 +15,7 @@ export const useNotificationStatus = () => {
});
};
const showNotification_Success = (message) => {
const showNotification_Success = (message, options = {}) => {
updateNotificationStatus({
status: "success",
is_open: true,

View File

@@ -1,7 +1,11 @@
import { useStore_DeepLAuthKey } from "@store";
import { useStdoutToPython } from "@logics/useStdoutToPython";
import { useTranslation } from "react-i18next";
import { useNotificationStatus } from "@logics_common";
export const useDeepLAuthKey = () => {
const { t } = useTranslation();
const { showNotification_Success, showNotification_Error } = useNotificationStatus();
const { asyncStdoutToPython } = useStdoutToPython();
const { currentDeepLAuthKey, updateDeepLAuthKey, pendingDeepLAuthKey } = useStore_DeepLAuthKey();
@@ -14,6 +18,10 @@ export const useDeepLAuthKey = () => {
pendingDeepLAuthKey();
asyncStdoutToPython("/set/data/deepl_auth_key", selected_deepl_auth_key);
};
const saveSuccessDeepLAuthKey = (saved_deepl_auth_key) => {
updateDeepLAuthKey(saved_deepl_auth_key);
showNotification_Success(t("config_page.translation.deepl_auth_key.auth_key_success"));
};
const deleteDeepLAuthKey = () => {
pendingDeepLAuthKey();
@@ -25,6 +33,7 @@ export const useDeepLAuthKey = () => {
getDeepLAuthKey,
updateDeepLAuthKey,
setDeepLAuthKey,
saveSuccessDeepLAuthKey,
deleteDeepLAuthKey,
};
};

View File

@@ -1,6 +1,8 @@
import { translator_status } from "@ui_configs";
import { arrayToObject } from "@utils";
import { _useBackendErrorHandling } from "./_useBackendErrorHandling";
import {
useIsVrctAvailable,
useNotificationStatus,
@@ -146,7 +148,7 @@ export const useReceiveRoutes = () => {
const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
const { updateSpeakerMaxWords } = useSpeakerMaxWords();
const { updateDeepLAuthKey } = useDeepLAuthKey();
const { updateDeepLAuthKey, saveSuccessDeepLAuthKey } = useDeepLAuthKey();
const { updateSelectedCTranslate2WeightType } = useSelectedCTranslate2WeightType();
const {
updateDownloadedCTranslate2WeightTypeStatus,
@@ -184,6 +186,10 @@ export const useReceiveRoutes = () => {
const { handleNetworkConnection } = useHandleNetworkConnection();
const {
errorHandling_Backend,
} = _useBackendErrorHandling();
const routes = {
// Common
"/run/feed_watchdog": () => {},
@@ -346,7 +352,7 @@ export const useReceiveRoutes = () => {
// Translation
"/get/data/deepl_auth_key": updateDeepLAuthKey,
"/set/data/deepl_auth_key": updateDeepLAuthKey,
"/set/data/deepl_auth_key": saveSuccessDeepLAuthKey,
"/delete/data/deepl_auth_key": () => updateDeepLAuthKey(""),
"/get/data/ctranslate2_weight_type": updateSelectedCTranslate2WeightType,
@@ -498,16 +504,25 @@ export const useReceiveRoutes = () => {
"/get/data/transcription_engines": ()=>{}, // Not implemented on UI yet. (if ai_models has not been detected, this will be blank array[]. if the ai_models are ok but just network has not connected, it'l be only ["Whisper"])
};
const error_routes = {
"/set/data/mic_record_timeout": updateMicRecordTimeout,
"/set/data/mic_phrase_timeout": updateMicPhraseTimeout,
"/set/data/mic_max_phrases": updateMicMaxWords,
const error_status_routes = {
"/run/error_device": errorHandling_Backend,
"/set/data/speaker_record_timeout": updateSpeakerRecordTimeout,
"/set/data/speaker_phrase_timeout": updateSpeakerPhraseTimeout,
"/set/data/speaker_max_phrases": updateSpeakerMaxWords,
"/run/error_ctranslate2_weight": errorHandling_Backend,
"/run/error_whisper_weight": errorHandling_Backend,
"/set/data/deepl_auth_key": updateDeepLAuthKey,
"/set/data/deepl_auth_key": errorHandling_Backend,
"/run/error_translation_engine": errorHandling_Backend,
"/set/data/mic_threshold": errorHandling_Backend,
"/set/data/mic_record_timeout": errorHandling_Backend,
"/set/data/mic_phrase_timeout": errorHandling_Backend,
"/set/data/mic_max_phrases": errorHandling_Backend,
"/set/data/speaker_threshold": errorHandling_Backend,
"/set/data/speaker_record_timeout": errorHandling_Backend,
"/set/data/speaker_phrase_timeout": errorHandling_Backend,
"/set/data/speaker_max_phrases": errorHandling_Backend,
};
@@ -519,22 +534,37 @@ export const useReceiveRoutes = () => {
}
};
const handleInvalidEndpoint = (parsed_data) => {
console.error(`Invalid endpoint: ${parsed_data.endpoint}\nresult: ${JSON.stringify(parsed_data.result)}`);
};
if (parsed_data.endpoint === "/run/initialization_complete") {
initDataSyncProcess(parsed_data.result);
updateIsBackendReady(true);
return;
};
switch (parsed_data.status) {
case 200:
if (parsed_data.endpoint === "/run/initialization_complete") {
initDataSyncProcess(parsed_data.result);
updateIsBackendReady(true);
break;
};
const route = routes[parsed_data.endpoint];
(route) ? route(parsed_data.result) : console.error(`Invalid endpoint: ${parsed_data.endpoint}\nresult: ${JSON.stringify(parsed_data.result)}`);
if (route) {
route(parsed_data.result);
} else {
handleInvalidEndpoint(parsed_data);
}
break;
case 400:
const error_route = error_routes[parsed_data.endpoint];
(error_route) ? error_route(parsed_data.result.data) : console.error(`Invalid endpoint: ${parsed_data.endpoint}\nresult: ${JSON.stringify(parsed_data.result)}`);
console.error(`status 400: ${JSON.stringify(parsed_data.result)}`);
showNotification_Error(parsed_data.result.message);
const error_route = error_status_routes[parsed_data.endpoint];
if (error_route) {
error_route({
message: parsed_data.result.message,
data: parsed_data.result.data,
endpoint: parsed_data.endpoint,
});
} else {
handleInvalidEndpoint(parsed_data);
}
break;
case 348:

View File

@@ -54,11 +54,11 @@ export const ui_configs = {
export const translator_status = [
{ id: "DeepL", label: "DeepL", is_available: false },
{ id: "DeepL_API", label: `DeepL\nAPI`, is_available: false },
{ id: "DeepL_API", label: `DeepL API`, is_available: false },
{ id: "Google", label: "Google", is_available: false },
{ id: "Bing", label: "Bing", is_available: false },
{ id: "Papago", label: "Papago", is_available: false },
{ id: "CTranslate2", label: `Internal\n(Default)`, is_available: false },
{ id: "CTranslate2", label: `AI\nCTranslate2`, is_available: false, is_default: true },
];
export const ctranslate2_weight_type_status = [

View File

@@ -49,4 +49,12 @@ export const updateLabelsById = (data_array, updates) => {
const update = updates.find(update_item => update_item.id === item.id);
return update ? { ...item, label: update.label } : item;
});
};
export const genNumArray = (count, start_from = 0) => {
return [...Array(count).keys()].map(i => i + start_from);
};
export const genNumObjArray = (count, start_from = 0) => {
return arrayToObject(genNumArray(count, start_from));
};