[Update] Config Page: Add Appearance Tab. Add UI Language section.(Functionally, too)
This commit is contained in:
@@ -11,7 +11,7 @@ const resources = {
|
|||||||
en: { translation: translation_en },
|
en: { translation: translation_en },
|
||||||
ja: { translation: translation_ja },
|
ja: { translation: translation_ja },
|
||||||
ko: { translation: translation_ko },
|
ko: { translation: translation_ko },
|
||||||
zh_Hant: { translation: translation_zh_Hant },
|
"zh-Hant": { translation: translation_zh_Hant },
|
||||||
};
|
};
|
||||||
|
|
||||||
i18n
|
i18n
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export const App = () => {
|
|||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<StartPythonFacadeComponent />
|
<StartPythonFacadeComponent />
|
||||||
|
<UiLanguageController />
|
||||||
<ConfigPage />
|
<ConfigPage />
|
||||||
<MainPage />
|
<MainPage />
|
||||||
</div>
|
</div>
|
||||||
@@ -25,6 +26,7 @@ import { useMicThreshold } from "@logics_configs/useMicThreshold";
|
|||||||
import { useSpeakerThreshold } from "@logics_configs/useSpeakerThreshold";
|
import { useSpeakerThreshold } from "@logics_configs/useSpeakerThreshold";
|
||||||
import { useEnableAutoClearMessageBox } from "@logics_configs/useEnableAutoClearMessageBox";
|
import { useEnableAutoClearMessageBox } from "@logics_configs/useEnableAutoClearMessageBox";
|
||||||
import { useSendMessageButtonType } from "@logics_configs/useSendMessageButtonType";
|
import { useSendMessageButtonType } from "@logics_configs/useSendMessageButtonType";
|
||||||
|
import { useUiLanguage } from "@logics_configs/useUiLanguage";
|
||||||
|
|
||||||
const StartPythonFacadeComponent = () => {
|
const StartPythonFacadeComponent = () => {
|
||||||
const { asyncStartPython } = useStartPython();
|
const { asyncStartPython } = useStartPython();
|
||||||
@@ -39,12 +41,15 @@ const StartPythonFacadeComponent = () => {
|
|||||||
const { getSpeakerThreshold, getEnableAutomaticSpeakerThreshold } = useSpeakerThreshold();
|
const { getSpeakerThreshold, getEnableAutomaticSpeakerThreshold } = useSpeakerThreshold();
|
||||||
const { getEnableAutoClearMessageBox } = useEnableAutoClearMessageBox();
|
const { getEnableAutoClearMessageBox } = useEnableAutoClearMessageBox();
|
||||||
const { getSendMessageButtonType } = useSendMessageButtonType();
|
const { getSendMessageButtonType } = useSendMessageButtonType();
|
||||||
|
const { getUiLanguage } = useUiLanguage();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
main_page.setDecorations(true);
|
main_page.setDecorations(true);
|
||||||
if (!hasRunRef.current) {
|
if (!hasRunRef.current) {
|
||||||
asyncStartPython().then((result) => {
|
asyncStartPython().then((result) => {
|
||||||
|
getUiLanguage();
|
||||||
|
|
||||||
getSoftwareVersion();
|
getSoftwareVersion();
|
||||||
getSelectedMicHost();
|
getSelectedMicHost();
|
||||||
getSelectedMicDevice();
|
getSelectedMicDevice();
|
||||||
@@ -64,5 +69,16 @@ const StartPythonFacadeComponent = () => {
|
|||||||
return () => hasRunRef.current = true;
|
return () => hasRunRef.current = true;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
const UiLanguageController = () => {
|
||||||
|
const { currentUiLanguage } = useUiLanguage();
|
||||||
|
const { i18n } = useTranslation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
i18n.changeLanguage(currentUiLanguage.data);
|
||||||
|
}, [currentUiLanguage]);
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@@ -12,8 +12,8 @@ export const SettingBox = () => {
|
|||||||
return <Device />;
|
return <Device />;
|
||||||
// case "others":
|
// case "others":
|
||||||
// return <Others />;
|
// return <Others />;
|
||||||
// case "appearance":
|
case "appearance":
|
||||||
// return <Appearance />;
|
return <Appearance />;
|
||||||
// case "about_vrct":
|
// case "about_vrct":
|
||||||
// return <AboutVrct />;
|
// return <AboutVrct />;
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import FolderOpenSvg from "@images/folder_open.svg?react";
|
import styles from "./Appearance.module.scss";
|
||||||
|
|
||||||
import { useSettingBox } from "../components/useSettingBox";
|
import { useSettingBox } from "../components/useSettingBox";
|
||||||
import { useStore_SelectedMicDevice, useStore_MicDeviceList } from "@store";
|
import { useStore_SelectedMicDevice, useStore_MicDeviceList } from "@store";
|
||||||
export const Appearance = () => {
|
export const Appearance = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { currentSelectedMicDevice, updateSelectedMicDevice } = useStore_SelectedMicDevice();
|
// const { currentSelectedMicDevice, updateSelectedMicDevice } = useStore_SelectedMicDevice();
|
||||||
const { currentMicDeviceList } = useStore_MicDeviceList();
|
// const { currentMicDeviceList } = useStore_MicDeviceList();
|
||||||
const {
|
const {
|
||||||
DropdownMenuContainer,
|
DropdownMenuContainer,
|
||||||
SliderContainer,
|
// SliderContainer,
|
||||||
CheckboxContainer,
|
// CheckboxContainer,
|
||||||
SwitchboxContainer,
|
// SwitchboxContainer,
|
||||||
EntryContainer,
|
// EntryContainer,
|
||||||
ThresholdContainer,
|
// ThresholdContainer,
|
||||||
RadioButtonContainer,
|
// RadioButtonContainer,
|
||||||
DeeplAuthKeyContainer,
|
// DeeplAuthKeyContainer,
|
||||||
MessageFormatContainer,
|
// MessageFormatContainer,
|
||||||
WordFilterContainer,
|
// WordFilterContainer,
|
||||||
ActionButtonContainer,
|
// ActionButtonContainer,
|
||||||
} = useSettingBox();
|
} = useSettingBox();
|
||||||
|
|
||||||
const selectFunction = (selected_data) => {
|
const selectFunction = (selected_data) => {
|
||||||
@@ -34,8 +34,13 @@ export const Appearance = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DropdownMenuContainer dropdown_id="mic_host" label="Mic Host/Driver" desc="description" selected_id="b" list={{a: "A", b: "B", c: "C"}} />
|
<UiLanguageContainer
|
||||||
<DropdownMenuContainer dropdown_id="mic_device" label="Mic Device" desc="description" selected_id={currentSelectedMicDevice.data} list={currentMicDeviceList} selectFunction={selectFunction} state={currentSelectedMicDevice.state} />
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{/* <DropdownMenuContainer dropdown_id="mic_device" label="Mic Device" desc="description" selected_id={currentSelectedMicDevice.data} list={currentMicDeviceList} selectFunction={selectFunction} state={currentSelectedMicDevice.state} />
|
||||||
|
|
||||||
<SliderContainer label="Transparent" desc="description" min="0" max="3000"/>
|
<SliderContainer label="Transparent" desc="description" min="0" max="3000"/>
|
||||||
<CheckboxContainer label="Transparent" desc="description" checkbox_id="checkbox_id_1"/>
|
<CheckboxContainer label="Transparent" desc="description" checkbox_id="checkbox_id_1"/>
|
||||||
@@ -61,8 +66,44 @@ export const Appearance = () => {
|
|||||||
|
|
||||||
<WordFilterContainer label={t(`config_page.mic_word_filter.label`)} desc={t(`config_page.mic_word_filter.desc`)}/>
|
<WordFilterContainer label={t(`config_page.mic_word_filter.label`)} desc={t(`config_page.mic_word_filter.desc`)}/>
|
||||||
|
|
||||||
<ActionButtonContainer label={t(`config_page.open_config_filepath.label`)} IconComponent={FolderOpenSvg} OnclickFunction={()=>{}}/>
|
<ActionButtonContainer label={t(`config_page.open_config_filepath.label`)} IconComponent={FolderOpenSvg} OnclickFunction={()=>{}}/> */}
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
import { LabelComponent } from "../components/label_component/LabelComponent";
|
||||||
|
import { useUiLanguage } from "@logics_configs/useUiLanguage";
|
||||||
|
|
||||||
|
const UiLanguageContainer = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { currentUiLanguage, setUiLanguage } = useUiLanguage();
|
||||||
|
|
||||||
|
const SELECTABLE_UI_LANGUAGES_DICT = {
|
||||||
|
en: "English",
|
||||||
|
ja: "日本語",
|
||||||
|
ko: "한국어",
|
||||||
|
"zh-Hant": "繁體中文",
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.ui_language_container}>
|
||||||
|
<LabelComponent label={t("config_page.ui_language.label")} />
|
||||||
|
<div className={styles.ui_language_selector_container}>
|
||||||
|
{currentUiLanguage.state === "loading" && <span className={styles.loader}></span>}
|
||||||
|
{Object.entries(SELECTABLE_UI_LANGUAGES_DICT).map(([key, value]) => (
|
||||||
|
<label key={key} className={clsx(styles.radio_button_wrapper, { [styles.is_selected]: currentUiLanguage.data === key } )}>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio"
|
||||||
|
value={key}
|
||||||
|
onChange={() => setUiLanguage(key)}
|
||||||
|
checked={currentUiLanguage.data === key}
|
||||||
|
/>
|
||||||
|
<p className={styles.radio_button_label}>{value}</p>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
@import "@scss_mixins";
|
||||||
|
|
||||||
|
.ui_language_container {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui_language_selector_container {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.radio_button_wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
gap: 0.6rem;
|
||||||
|
padding: 0.6rem 1rem;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
position: relative;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--dark_850_color);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: var(--dark_925_color);
|
||||||
|
}
|
||||||
|
&.is_selected {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="radio"] {
|
||||||
|
appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
width: 1.6rem;
|
||||||
|
height: 1.6rem;
|
||||||
|
border: 0.2rem solid var(--dark_600_color);
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: border-color .1s ease, border-width .1s ease;
|
||||||
|
cursor: inherit;
|
||||||
|
&:checked {
|
||||||
|
border-color: var(--primary_400_color);
|
||||||
|
border-width: 0.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio_button_label {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
@include loader(2rem, 0.2rem, right, -3rem);
|
||||||
|
}
|
||||||
24
src-ui/logics/configs/useUiLanguage.js
Normal file
24
src-ui/logics/configs/useUiLanguage.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { useStore_UiLanguage } from "@store";
|
||||||
|
import { useStdoutToPython } from "@logics/useStdoutToPython";
|
||||||
|
|
||||||
|
export const useUiLanguage = () => {
|
||||||
|
const { asyncStdoutToPython } = useStdoutToPython();
|
||||||
|
const { currentUiLanguage, updateUiLanguage } = useStore_UiLanguage();
|
||||||
|
|
||||||
|
const getUiLanguage = () => {
|
||||||
|
updateUiLanguage(() => new Promise(() => {}));
|
||||||
|
asyncStdoutToPython("/config/ui_language");
|
||||||
|
};
|
||||||
|
|
||||||
|
const setUiLanguage = (selected_ui_language) => {
|
||||||
|
updateUiLanguage(() => new Promise(() => {}));
|
||||||
|
asyncStdoutToPython("/controller/callback_set_ui_language", selected_ui_language);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentUiLanguage,
|
||||||
|
getUiLanguage,
|
||||||
|
updateUiLanguage,
|
||||||
|
setUiLanguage,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -15,6 +15,8 @@ import { useSpeakerThreshold } from "@logics_configs/useSpeakerThreshold";
|
|||||||
import { useEnableAutoClearMessageBox } from "@logics_configs/useEnableAutoClearMessageBox";
|
import { useEnableAutoClearMessageBox } from "@logics_configs/useEnableAutoClearMessageBox";
|
||||||
import { useSendMessageButtonType } from "@logics_configs/useSendMessageButtonType";
|
import { useSendMessageButtonType } from "@logics_configs/useSendMessageButtonType";
|
||||||
|
|
||||||
|
import { useUiLanguage } from "@logics_configs/useUiLanguage";
|
||||||
|
|
||||||
|
|
||||||
export const useReceiveRoutes = () => {
|
export const useReceiveRoutes = () => {
|
||||||
const {
|
const {
|
||||||
@@ -43,6 +45,8 @@ export const useReceiveRoutes = () => {
|
|||||||
const { updateEnableAutoClearMessageBox } = useEnableAutoClearMessageBox();
|
const { updateEnableAutoClearMessageBox } = useEnableAutoClearMessageBox();
|
||||||
const { updateSendMessageButtonType } = useSendMessageButtonType();
|
const { updateSendMessageButtonType } = useSendMessageButtonType();
|
||||||
|
|
||||||
|
const { updateUiLanguage } = useUiLanguage();
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
updateVolumeVariable_Mic,
|
updateVolumeVariable_Mic,
|
||||||
@@ -101,7 +105,10 @@ export const useReceiveRoutes = () => {
|
|||||||
"/controller/callback_disable_mic_dynamic_energy_threshold": updateEnableAutomaticMicThreshold,
|
"/controller/callback_disable_mic_dynamic_energy_threshold": updateEnableAutomaticMicThreshold,
|
||||||
"/config/input_speaker_dynamic_energy_threshold": updateEnableAutomaticSpeakerThreshold,
|
"/config/input_speaker_dynamic_energy_threshold": updateEnableAutomaticSpeakerThreshold,
|
||||||
"/controller/callback_enable_speaker_dynamic_energy_threshold": updateEnableAutomaticSpeakerThreshold,
|
"/controller/callback_enable_speaker_dynamic_energy_threshold": updateEnableAutomaticSpeakerThreshold,
|
||||||
"/controller/callback_disable_speaker_dynamic_energy_threshold": updateEnableAutomaticSpeakerThreshold,
|
|
||||||
|
"/config/ui_language": updateUiLanguage,
|
||||||
|
"/controller/callback_set_ui_language": updateUiLanguage,
|
||||||
|
|
||||||
|
|
||||||
"/controller/callback_messagebox_send": updateSentMessageLogById,
|
"/controller/callback_messagebox_send": updateSentMessageLogById,
|
||||||
"/action/transcription_send_mic_message": addSentMessageLog,
|
"/action/transcription_send_mic_message": addSentMessageLog,
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ const createAsyncAtomWithHook = (initialValue, base_ame) => {
|
|||||||
|
|
||||||
export const { atomInstance: Atom_SoftwareVersion, useHook: useStore_SoftwareVersion } = createAtomWithHook("-", "SoftwareVersion");
|
export const { atomInstance: Atom_SoftwareVersion, useHook: useStore_SoftwareVersion } = createAtomWithHook("-", "SoftwareVersion");
|
||||||
|
|
||||||
export const { atomInstance: Atom_UiLanguage, useHook: useStore_UiLanguage } = createAtomWithHook("en", "UiLanguage");
|
|
||||||
export const { atomInstance: Atom_TranslationStatus, useHook: useStore_TranslationStatus } = createAsyncAtomWithHook(false, "TranslationStatus");
|
export const { atomInstance: Atom_TranslationStatus, useHook: useStore_TranslationStatus } = createAsyncAtomWithHook(false, "TranslationStatus");
|
||||||
export const { atomInstance: Atom_TranscriptionSendStatus, useHook: useStore_TranscriptionSendStatus } = createAsyncAtomWithHook(false, "TranscriptionSendStatus");
|
export const { atomInstance: Atom_TranscriptionSendStatus, useHook: useStore_TranscriptionSendStatus } = createAsyncAtomWithHook(false, "TranscriptionSendStatus");
|
||||||
export const { atomInstance: Atom_TranscriptionReceiveStatus, useHook: useStore_TranscriptionReceiveStatus } = createAsyncAtomWithHook(false, "TranscriptionReceiveStatus");
|
export const { atomInstance: Atom_TranscriptionReceiveStatus, useHook: useStore_TranscriptionReceiveStatus } = createAsyncAtomWithHook(false, "TranscriptionReceiveStatus");
|
||||||
@@ -136,6 +135,17 @@ export const { atomInstance: Atom_SpeakerThreshold, useHook: useStore_SpeakerThr
|
|||||||
export const { atomInstance: Atom_EnableAutomaticMicThreshold, useHook: useStore_EnableAutomaticMicThreshold } = createAsyncAtomWithHook(false, "EnableAutomaticMicThreshold");
|
export const { atomInstance: Atom_EnableAutomaticMicThreshold, useHook: useStore_EnableAutomaticMicThreshold } = createAsyncAtomWithHook(false, "EnableAutomaticMicThreshold");
|
||||||
export const { atomInstance: Atom_EnableAutomaticSpeakerThreshold, useHook: useStore_EnableAutomaticSpeakerThreshold } = createAsyncAtomWithHook(false, "EnableAutomaticSpeakerThreshold");
|
export const { atomInstance: Atom_EnableAutomaticSpeakerThreshold, useHook: useStore_EnableAutomaticSpeakerThreshold } = createAsyncAtomWithHook(false, "EnableAutomaticSpeakerThreshold");
|
||||||
|
|
||||||
|
|
||||||
|
// Appearance
|
||||||
|
export const { atomInstance: Atom_UiLanguage, useHook: useStore_UiLanguage } = createAsyncAtomWithHook("en", "UiLanguage");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const { atomInstance: Atom_SendMessageFormat, useHook: useStore_SendMessageFormat } = createAtomWithHook({
|
export const { atomInstance: Atom_SendMessageFormat, useHook: useStore_SendMessageFormat } = createAtomWithHook({
|
||||||
before: "",
|
before: "",
|
||||||
after: "",
|
after: "",
|
||||||
|
|||||||
Reference in New Issue
Block a user